Version:  2.0.40 2.2.26 2.4.37 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19

Linux/drivers/media/platform/soc_camera/rcar_vin.c

  1 /*
  2  * SoC-camera host driver for Renesas R-Car VIN unit
  3  *
  4  * Copyright (C) 2011-2013 Renesas Solutions Corp.
  5  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
  6  *
  7  * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
  8  *
  9  * Copyright (C) 2008 Magnus Damm
 10  *
 11  * This program is free software; you can redistribute  it and/or modify it
 12  * under  the terms of  the GNU General  Public License as published by the
 13  * Free Software Foundation;  either version 2 of the  License, or (at your
 14  * option) any later version.
 15  */
 16 
 17 #include <linux/delay.h>
 18 #include <linux/interrupt.h>
 19 #include <linux/io.h>
 20 #include <linux/kernel.h>
 21 #include <linux/module.h>
 22 #include <linux/of.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>
 29 
 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>
 39 
 40 #include "soc_scale_crop.h"
 41 
 42 #define DRV_NAME "rcar_vin"
 43 
 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 */
 91 
 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)
108 
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)
114 
115 /* Video n Frame Capture Register bits */
116 #define VNFC_C_FRAME            (1 << 1)
117 #define VNFC_S_FRAME            (1 << 0)
118 
119 /* Video n Interrupt Enable Register bits */
120 #define VNIE_FIE                (1 << 4)
121 #define VNIE_EFE                (1 << 1)
122 
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)
128 
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)
134 
135 #define VIN_MAX_WIDTH           2048
136 #define VIN_MAX_HEIGHT          2048
137 
138 enum chip_id {
139         RCAR_GEN2,
140         RCAR_H1,
141         RCAR_M1,
142         RCAR_E1,
143 };
144 
145 struct vin_coeff {
146         unsigned short xs_value;
147         u32 coeff_set[24];
148 };
149 
150 static const struct vin_coeff vin_coeff_set[] = {
151         { 0x0000, {
152                 0x00000000,             0x00000000,             0x00000000,
153                 0x00000000,             0x00000000,             0x00000000,
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         },
161         { 0x1000, {
162                 0x000fa400,             0x000fa400,             0x09625902,
163                 0x000003f8,             0x00000403,             0x3de0d9f0,
164                 0x001fffed,             0x00000804,             0x3cc1f9c3,
165                 0x001003de,             0x00000c01,             0x3cb34d7f,
166                 0x002003d2,             0x00000c00,             0x3d24a92d,
167                 0x00200bca,             0x00000bff,             0x3df600d2,
168                 0x002013cc,             0x000007ff,             0x3ed70c7e,
169                 0x00100fde,             0x00000000,             0x3f87c036 },
170         },
171         { 0x1200, {
172                 0x002ffff1,             0x002ffff1,             0x02a0a9c8,
173                 0x002003e7,             0x001ffffa,             0x000185bc,
174                 0x002007dc,             0x000003ff,             0x3e52859c,
175                 0x00200bd4,             0x00000002,             0x3d53996b,
176                 0x00100fd0,             0x00000403,             0x3d04ad2d,
177                 0x00000bd5,             0x00000403,             0x3d35ace7,
178                 0x3ff003e4,             0x00000801,             0x3dc674a1,
179                 0x3fffe800,             0x00000800,             0x3e76f461 },
180         },
181         { 0x1400, {
182                 0x00100be3,             0x00100be3,             0x04d1359a,
183                 0x00000fdb,             0x002003ed,             0x0211fd93,
184                 0x00000fd6,             0x002003f4,             0x0002d97b,
185                 0x000007d6,             0x002ffffb,             0x3e93b956,
186                 0x3ff003da,             0x001003ff,             0x3db49926,
187                 0x3fffefe9,             0x00100001,             0x3d655cee,
188                 0x3fffd400,             0x00000003,             0x3d65f4b6,
189                 0x000fb421,             0x00000402,             0x3dc6547e },
190         },
191         { 0x1600, {
192                 0x00000bdd,             0x00000bdd,             0x06519578,
193                 0x3ff007da,             0x00000be3,             0x03c24973,
194                 0x3ff003d9,             0x00000be9,             0x01b30d5f,
195                 0x3ffff7df,             0x001003f1,             0x0003c542,
196                 0x000fdfec,             0x001003f7,             0x3ec4711d,
197                 0x000fc400,             0x002ffffd,             0x3df504f1,
198                 0x001fa81a,             0x002ffc00,             0x3d957cc2,
199                 0x002f8c3c,             0x00100000,             0x3db5c891 },
200         },
201         { 0x1800, {
202                 0x3ff003dc,             0x3ff003dc,             0x0791e558,
203                 0x000ff7dd,             0x3ff007de,             0x05328554,
204                 0x000fe7e3,             0x3ff00be2,             0x03232546,
205                 0x000fd7ee,             0x000007e9,             0x0143bd30,
206                 0x001fb800,             0x000007ee,             0x00044511,
207                 0x002fa015,             0x000007f4,             0x3ef4bcee,
208                 0x002f8832,             0x001003f9,             0x3e4514c7,
209                 0x001f7853,             0x001003fd,             0x3de54c9f },
210         },
211         { 0x1a00, {
212                 0x000fefe0,             0x000fefe0,             0x08721d3c,
213                 0x001fdbe7,             0x000ffbde,             0x0652a139,
214                 0x001fcbf0,             0x000003df,             0x0463292e,
215                 0x002fb3ff,             0x3ff007e3,             0x0293a91d,
216                 0x002f9c12,             0x3ff00be7,             0x01241905,
217                 0x001f8c29,             0x000007ed,             0x3fe470eb,
218                 0x000f7c46,             0x000007f2,             0x3f04b8ca,
219                 0x3fef7865,             0x000007f6,             0x3e74e4a8 },
220         },
221         { 0x1c00, {
222                 0x001fd3e9,             0x001fd3e9,             0x08f23d26,
223                 0x002fbff3,             0x001fe3e4,             0x0712ad23,
224                 0x002fa800,             0x000ff3e0,             0x05631d1b,
225                 0x001f9810,             0x000ffbe1,             0x03b3890d,
226                 0x000f8c23,             0x000003e3,             0x0233e8fa,
227                 0x3fef843b,             0x000003e7,             0x00f430e4,
228                 0x3fbf8456,             0x3ff00bea,             0x00046cc8,
229                 0x3f8f8c72,             0x3ff00bef,             0x3f3490ac },
230         },
231         { 0x1e00, {
232                 0x001fbbf4,             0x001fbbf4,             0x09425112,
233                 0x001fa800,             0x002fc7ed,             0x0792b110,
234                 0x000f980e,             0x001fdbe6,             0x0613110a,
235                 0x3fff8c20,             0x001fe7e3,             0x04a368fd,
236                 0x3fcf8c33,             0x000ff7e2,             0x0343b8ed,
237                 0x3f9f8c4a,             0x000fffe3,             0x0203f8da,
238                 0x3f5f9c61,             0x000003e6,             0x00e428c5,
239                 0x3f1fb07b,             0x000003eb,             0x3fe440af },
240         },
241         { 0x2000, {
242                 0x000fa400,             0x000fa400,             0x09625902,
243                 0x3fff980c,             0x001fb7f5,             0x0812b0ff,
244                 0x3fdf901c,             0x001fc7ed,             0x06b2fcfa,
245                 0x3faf902d,             0x001fd3e8,             0x055348f1,
246                 0x3f7f983f,             0x001fe3e5,             0x04038ce3,
247                 0x3f3fa454,             0x001fefe3,             0x02e3c8d1,
248                 0x3f0fb86a,             0x001ff7e4,             0x01c3e8c0,
249                 0x3ecfd880,             0x000fffe6,             0x00c404ac },
250         },
251         { 0x2200, {
252                 0x3fdf9c0b,             0x3fdf9c0b,             0x09725cf4,
253                 0x3fbf9818,             0x3fffa400,             0x0842a8f1,
254                 0x3f8f9827,             0x000fb3f7,             0x0702f0ec,
255                 0x3f5fa037,             0x000fc3ef,             0x05d330e4,
256                 0x3f2fac49,             0x001fcfea,             0x04a364d9,
257                 0x3effc05c,             0x001fdbe7,             0x038394ca,
258                 0x3ecfdc6f,             0x001fe7e6,             0x0273b0bb,
259                 0x3ea00083,             0x001fefe6,             0x0183c0a9 },
260         },
261         { 0x2400, {
262                 0x3f9fa014,             0x3f9fa014,             0x098260e6,
263                 0x3f7f9c23,             0x3fcf9c0a,             0x08629ce5,
264                 0x3f4fa431,             0x3fefa400,             0x0742d8e1,
265                 0x3f1fb440,             0x3fffb3f8,             0x062310d9,
266                 0x3eefc850,             0x000fbbf2,             0x050340d0,
267                 0x3ecfe062,             0x000fcbec,             0x041364c2,
268                 0x3ea00073,             0x001fd3ea,             0x03037cb5,
269                 0x3e902086,             0x001fdfe8,             0x022388a5 },
270         },
271         { 0x2600, {
272                 0x3f5fa81e,             0x3f5fa81e,             0x096258da,
273                 0x3f3fac2b,             0x3f8fa412,             0x088290d8,
274                 0x3f0fbc38,             0x3fafa408,             0x0772c8d5,
275                 0x3eefcc47,             0x3fcfa800,             0x0672f4ce,
276                 0x3ecfe456,             0x3fefaffa,             0x05531cc6,
277                 0x3eb00066,             0x3fffbbf3,             0x047334bb,
278                 0x3ea01c77,             0x000fc7ee,             0x039348ae,
279                 0x3ea04486,             0x000fd3eb,             0x02b350a1 },
280         },
281         { 0x2800, {
282                 0x3f2fb426,             0x3f2fb426,             0x094250ce,
283                 0x3f0fc032,             0x3f4fac1b,             0x086284cd,
284                 0x3eefd040,             0x3f7fa811,             0x0782acc9,
285                 0x3ecfe84c,             0x3f9fa807,             0x06a2d8c4,
286                 0x3eb0005b,             0x3fbfac00,             0x05b2f4bc,
287                 0x3eb0186a,             0x3fdfb3fa,             0x04c308b4,
288                 0x3eb04077,             0x3fefbbf4,             0x03f31ca8,
289                 0x3ec06884,             0x000fbff2,             0x03031c9e },
290         },
291         { 0x2a00, {
292                 0x3f0fc42d,             0x3f0fc42d,             0x090240c4,
293                 0x3eefd439,             0x3f2fb822,             0x08526cc2,
294                 0x3edfe845,             0x3f4fb018,             0x078294bf,
295                 0x3ec00051,             0x3f6fac0f,             0x06b2b4bb,
296                 0x3ec0185f,             0x3f8fac07,             0x05e2ccb4,
297                 0x3ec0386b,             0x3fafac00,             0x0502e8ac,
298                 0x3ed05c77,             0x3fcfb3fb,             0x0432f0a3,
299                 0x3ef08482,             0x3fdfbbf6,             0x0372f898 },
300         },
301         { 0x2c00, {
302                 0x3eefdc31,             0x3eefdc31,             0x08e238b8,
303                 0x3edfec3d,             0x3f0fc828,             0x082258b9,
304                 0x3ed00049,             0x3f1fc01e,             0x077278b6,
305                 0x3ed01455,             0x3f3fb815,             0x06c294b2,
306                 0x3ed03460,             0x3f5fb40d,             0x0602acac,
307                 0x3ef0506c,             0x3f7fb006,             0x0542c0a4,
308                 0x3f107476,             0x3f9fb400,             0x0472c89d,
309                 0x3f309c80,             0x3fbfb7fc,             0x03b2cc94 },
310         },
311         { 0x2e00, {
312                 0x3eefec37,             0x3eefec37,             0x088220b0,
313                 0x3ee00041,             0x3effdc2d,             0x07f244ae,
314                 0x3ee0144c,             0x3f0fd023,             0x07625cad,
315                 0x3ef02c57,             0x3f1fc81a,             0x06c274a9,
316                 0x3f004861,             0x3f3fbc13,             0x060288a6,
317                 0x3f20686b,             0x3f5fb80c,             0x05529c9e,
318                 0x3f408c74,             0x3f6fb805,             0x04b2ac96,
319                 0x3f80ac7e,             0x3f8fb800,             0x0402ac8e },
320         },
321         { 0x3000, {
322                 0x3ef0003a,             0x3ef0003a,             0x084210a6,
323                 0x3ef01045,             0x3effec32,             0x07b228a7,
324                 0x3f00284e,             0x3f0fdc29,             0x073244a4,
325                 0x3f104058,             0x3f0fd420,             0x06a258a2,
326                 0x3f305c62,             0x3f2fc818,             0x0612689d,
327                 0x3f508069,             0x3f3fc011,             0x05728496,
328                 0x3f80a072,             0x3f4fc00a,             0x04d28c90,
329                 0x3fc0c07b,             0x3f6fbc04,             0x04429088 },
330         },
331         { 0x3200, {
332                 0x3f00103e,             0x3f00103e,             0x07f1fc9e,
333                 0x3f102447,             0x3f000035,             0x0782149d,
334                 0x3f203c4f,             0x3f0ff02c,             0x07122c9c,
335                 0x3f405458,             0x3f0fe424,             0x06924099,
336                 0x3f607061,             0x3f1fd41d,             0x06024c97,
337                 0x3f909068,             0x3f2fcc16,             0x05726490,
338                 0x3fc0b070,             0x3f3fc80f,             0x04f26c8a,
339                 0x0000d077,             0x3f4fc409,             0x04627484 },
340         },
341         { 0x3400, {
342                 0x3f202040,             0x3f202040,             0x07a1e898,
343                 0x3f303449,             0x3f100c38,             0x0741fc98,
344                 0x3f504c50,             0x3f10002f,             0x06e21495,
345                 0x3f706459,             0x3f1ff028,             0x06722492,
346                 0x3fa08060,             0x3f1fe421,             0x05f2348f,
347                 0x3fd09c67,             0x3f1fdc19,             0x05824c89,
348                 0x0000bc6e,             0x3f2fd014,             0x04f25086,
349                 0x0040dc74,             0x3f3fcc0d,             0x04825c7f },
350         },
351         { 0x3600, {
352                 0x3f403042,             0x3f403042,             0x0761d890,
353                 0x3f504848,             0x3f301c3b,             0x0701f090,
354                 0x3f805c50,             0x3f200c33,             0x06a2008f,
355                 0x3fa07458,             0x3f10002b,             0x06520c8d,
356                 0x3fd0905e,             0x3f1ff424,             0x05e22089,
357                 0x0000ac65,             0x3f1fe81d,             0x05823483,
358                 0x0030cc6a,             0x3f2fdc18,             0x04f23c81,
359                 0x0080e871,             0x3f2fd412,             0x0482407c },
360         },
361         { 0x3800, {
362                 0x3f604043,             0x3f604043,             0x0721c88a,
363                 0x3f80544a,             0x3f502c3c,             0x06d1d88a,
364                 0x3fb06851,             0x3f301c35,             0x0681e889,
365                 0x3fd08456,             0x3f30082f,             0x0611fc88,
366                 0x00009c5d,             0x3f200027,             0x05d20884,
367                 0x0030b863,             0x3f2ff421,             0x05621880,
368                 0x0070d468,             0x3f2fe81b,             0x0502247c,
369                 0x00c0ec6f,             0x3f2fe015,             0x04a22877 },
370         },
371         { 0x3a00, {
372                 0x3f904c44,             0x3f904c44,             0x06e1b884,
373                 0x3fb0604a,             0x3f70383e,             0x0691c885,
374                 0x3fe07451,             0x3f502c36,             0x0661d483,
375                 0x00009055,             0x3f401831,             0x0601ec81,
376                 0x0030a85b,             0x3f300c2a,             0x05b1f480,
377                 0x0070c061,             0x3f300024,             0x0562047a,
378                 0x00b0d867,             0x3f3ff41e,             0x05020c77,
379                 0x00f0f46b,             0x3f2fec19,             0x04a21474 },
380         },
381         { 0x3c00, {
382                 0x3fb05c43,             0x3fb05c43,             0x06c1b07e,
383                 0x3fe06c4b,             0x3f902c3f,             0x0681c081,
384                 0x0000844f,             0x3f703838,             0x0631cc7d,
385                 0x00309855,             0x3f602433,             0x05d1d47e,
386                 0x0060b459,             0x3f50142e,             0x0581e47b,
387                 0x00a0c85f,             0x3f400828,             0x0531f078,
388                 0x00e0e064,             0x3f300021,             0x0501fc73,
389                 0x00b0fc6a,             0x3f3ff41d,             0x04a20873 },
390         },
391         { 0x3e00, {
392                 0x3fe06444,             0x3fe06444,             0x0681a07a,
393                 0x00007849,             0x3fc0503f,             0x0641b07a,
394                 0x0020904d,             0x3fa0403a,             0x05f1c07a,
395                 0x0060a453,             0x3f803034,             0x05c1c878,
396                 0x0090b858,             0x3f70202f,             0x0571d477,
397                 0x00d0d05d,             0x3f501829,             0x0531e073,
398                 0x0110e462,             0x3f500825,             0x04e1e471,
399                 0x01510065,             0x3f40001f,             0x04a1f06d },
400         },
401         { 0x4000, {
402                 0x00007044,             0x00007044,             0x06519476,
403                 0x00208448,             0x3fe05c3f,             0x0621a476,
404                 0x0050984d,             0x3fc04c3a,             0x05e1b075,
405                 0x0080ac52,             0x3fa03c35,             0x05a1b875,
406                 0x00c0c056,             0x3f803030,             0x0561c473,
407                 0x0100d45b,             0x3f70202b,             0x0521d46f,
408                 0x0140e860,             0x3f601427,             0x04d1d46e,
409                 0x01810064,             0x3f500822,             0x0491dc6b },
410         },
411         { 0x5000, {
412                 0x0110a442,             0x0110a442,             0x0551545e,
413                 0x0140b045,             0x00e0983f,             0x0531585f,
414                 0x0160c047,             0x00c08c3c,             0x0511645e,
415                 0x0190cc4a,             0x00908039,             0x04f1685f,
416                 0x01c0dc4c,             0x00707436,             0x04d1705e,
417                 0x0200e850,             0x00506833,             0x04b1785b,
418                 0x0230f453,             0x00305c30,             0x0491805a,
419                 0x02710056,             0x0010542d,             0x04718059 },
420         },
421         { 0x6000, {
422                 0x01c0bc40,             0x01c0bc40,             0x04c13052,
423                 0x01e0c841,             0x01a0b43d,             0x04c13851,
424                 0x0210cc44,             0x0180a83c,             0x04a13453,
425                 0x0230d845,             0x0160a03a,             0x04913c52,
426                 0x0260e047,             0x01409838,             0x04714052,
427                 0x0280ec49,             0x01208c37,             0x04514c50,
428                 0x02b0f44b,             0x01008435,             0x04414c50,
429                 0x02d1004c,             0x00e07c33,             0x0431544f },
430         },
431         { 0x7000, {
432                 0x0230c83e,             0x0230c83e,             0x04711c4c,
433                 0x0250d03f,             0x0210c43c,             0x0471204b,
434                 0x0270d840,             0x0200b83c,             0x0451244b,
435                 0x0290dc42,             0x01e0b43a,             0x0441244c,
436                 0x02b0e443,             0x01c0b038,             0x0441284b,
437                 0x02d0ec44,             0x01b0a438,             0x0421304a,
438                 0x02f0f445,             0x0190a036,             0x04213449,
439                 0x0310f847,             0x01709c34,             0x04213848 },
440         },
441         { 0x8000, {
442                 0x0280d03d,             0x0280d03d,             0x04310c48,
443                 0x02a0d43e,             0x0270c83c,             0x04311047,
444                 0x02b0dc3e,             0x0250c83a,             0x04311447,
445                 0x02d0e040,             0x0240c03a,             0x04211446,
446                 0x02e0e840,             0x0220bc39,             0x04111847,
447                 0x0300e842,             0x0210b438,             0x04012445,
448                 0x0310f043,             0x0200b037,             0x04012045,
449                 0x0330f444,             0x01e0ac36,             0x03f12445 },
450         },
451         { 0xefff, {
452                 0x0340dc3a,             0x0340dc3a,             0x03b0ec40,
453                 0x0340e03a,             0x0330e039,             0x03c0f03e,
454                 0x0350e03b,             0x0330dc39,             0x03c0ec3e,
455                 0x0350e43a,             0x0320dc38,             0x03c0f43e,
456                 0x0360e43b,             0x0320d839,             0x03b0f03e,
457                 0x0360e83b,             0x0310d838,             0x03c0fc3b,
458                 0x0370e83b,             0x0310d439,             0x03a0f83d,
459                 0x0370e83c,             0x0300d438,             0x03b0fc3c },
460         }
461 };
462 
463 enum rcar_vin_state {
464         STOPPED = 0,
465         RUNNING,
466         STOPPING,
467 };
468 
469 struct rcar_vin_priv {
470         void __iomem                    *base;
471         spinlock_t                      lock;
472         int                             sequence;
473         /* State of the VIN module in capturing mode */
474         enum rcar_vin_state             state;
475         struct soc_camera_host          ici;
476         struct list_head                capture;
477 #define MAX_BUFFER_NUM                  3
478         struct vb2_buffer               *queue_buf[MAX_BUFFER_NUM];
479         struct vb2_alloc_ctx            *alloc_ctx;
480         enum v4l2_field                 field;
481         unsigned int                    pdata_flags;
482         unsigned int                    vb_count;
483         unsigned int                    nr_hw_slots;
484         bool                            request_to_stop;
485         struct completion               capture_stop;
486         enum chip_id                    chip;
487 };
488 
489 #define is_continuous_transfer(priv)    (priv->vb_count > MAX_BUFFER_NUM)
490 
491 struct rcar_vin_buffer {
492         struct vb2_buffer               vb;
493         struct list_head                list;
494 };
495 
496 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
497                                                        struct rcar_vin_buffer, \
498                                                        vb)->list)
499 
500 struct rcar_vin_cam {
501         /* VIN offsets within the camera output, before the VIN scaler */
502         unsigned int                    vin_left;
503         unsigned int                    vin_top;
504         /* Client output, as seen by the VIN */
505         unsigned int                    width;
506         unsigned int                    height;
507         /* User window from S_FMT */
508         unsigned int out_width;
509         unsigned int out_height;
510         /*
511          * User window from S_CROP / G_CROP, produced by client cropping and
512          * scaling, VIN scaling and VIN cropping, mapped back onto the client
513          * input window
514          */
515         struct v4l2_rect                subrect;
516         /* Camera cropping rectangle */
517         struct v4l2_rect                rect;
518         const struct soc_mbus_pixelfmt  *extra_fmt;
519 };
520 
521 /*
522  * .queue_setup() is called to check whether the driver can accept the requested
523  * number of buffers and to fill in plane sizes for the current frame format if
524  * required
525  */
526 static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
527                                    const struct v4l2_format *fmt,
528                                    unsigned int *count,
529                                    unsigned int *num_planes,
530                                    unsigned int sizes[], void *alloc_ctxs[])
531 {
532         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
533         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
534         struct rcar_vin_priv *priv = ici->priv;
535 
536         if (fmt) {
537                 const struct soc_camera_format_xlate *xlate;
538                 unsigned int bytes_per_line;
539                 int ret;
540 
541                 xlate = soc_camera_xlate_by_fourcc(icd,
542                                                    fmt->fmt.pix.pixelformat);
543                 if (!xlate)
544                         return -EINVAL;
545                 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
546                                               xlate->host_fmt);
547                 if (ret < 0)
548                         return ret;
549 
550                 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
551 
552                 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
553                                           fmt->fmt.pix.height);
554                 if (ret < 0)
555                         return ret;
556 
557                 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
558         } else {
559                 /* Called from VIDIOC_REQBUFS or in compatibility mode */
560                 sizes[0] = icd->sizeimage;
561         }
562 
563         alloc_ctxs[0] = priv->alloc_ctx;
564 
565         if (!vq->num_buffers)
566                 priv->sequence = 0;
567 
568         if (!*count)
569                 *count = 2;
570         priv->vb_count = *count;
571 
572         *num_planes = 1;
573 
574         /* Number of hardware slots */
575         if (is_continuous_transfer(priv))
576                 priv->nr_hw_slots = MAX_BUFFER_NUM;
577         else
578                 priv->nr_hw_slots = 1;
579 
580         dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
581 
582         return 0;
583 }
584 
585 static int rcar_vin_setup(struct rcar_vin_priv *priv)
586 {
587         struct soc_camera_device *icd = priv->ici.icd;
588         struct rcar_vin_cam *cam = icd->host_priv;
589         u32 vnmc, dmr, interrupts;
590         bool progressive = false, output_is_yuv = false;
591 
592         switch (priv->field) {
593         case V4L2_FIELD_TOP:
594                 vnmc = VNMC_IM_ODD;
595                 break;
596         case V4L2_FIELD_BOTTOM:
597                 vnmc = VNMC_IM_EVEN;
598                 break;
599         case V4L2_FIELD_INTERLACED:
600         case V4L2_FIELD_INTERLACED_TB:
601                 vnmc = VNMC_IM_FULL;
602                 break;
603         case V4L2_FIELD_INTERLACED_BT:
604                 vnmc = VNMC_IM_FULL | VNMC_FOC;
605                 break;
606         case V4L2_FIELD_NONE:
607                 if (is_continuous_transfer(priv)) {
608                         vnmc = VNMC_IM_ODD_EVEN;
609                         progressive = true;
610                 } else {
611                         vnmc = VNMC_IM_ODD;
612                 }
613                 break;
614         default:
615                 vnmc = VNMC_IM_ODD;
616                 break;
617         }
618 
619         /* input interface */
620         switch (icd->current_fmt->code) {
621         case MEDIA_BUS_FMT_YUYV8_1X16:
622                 /* BT.601/BT.1358 16bit YCbCr422 */
623                 vnmc |= VNMC_INF_YUV16;
624                 break;
625         case MEDIA_BUS_FMT_YUYV8_2X8:
626                 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
627                 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
628                         VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
629                 break;
630         case MEDIA_BUS_FMT_YUYV10_2X10:
631                 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
632                 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
633                         VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
634                 break;
635         default:
636                 break;
637         }
638 
639         /* output format */
640         switch (icd->current_fmt->host_fmt->fourcc) {
641         case V4L2_PIX_FMT_NV16:
642                 iowrite32(ALIGN(cam->width * cam->height, 0x80),
643                           priv->base + VNUVAOF_REG);
644                 dmr = VNDMR_DTMD_YCSEP;
645                 output_is_yuv = true;
646                 break;
647         case V4L2_PIX_FMT_YUYV:
648                 dmr = VNDMR_BPSM;
649                 output_is_yuv = true;
650                 break;
651         case V4L2_PIX_FMT_UYVY:
652                 dmr = 0;
653                 output_is_yuv = true;
654                 break;
655         case V4L2_PIX_FMT_RGB555X:
656                 dmr = VNDMR_DTMD_ARGB1555;
657                 break;
658         case V4L2_PIX_FMT_RGB565:
659                 dmr = 0;
660                 break;
661         case V4L2_PIX_FMT_RGB32:
662                 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
663                     priv->chip == RCAR_E1) {
664                         dmr = VNDMR_EXRGB;
665                         break;
666                 }
667         default:
668                 dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
669                          icd->current_fmt->host_fmt->fourcc);
670                 return -EINVAL;
671         }
672 
673         /* Always update on field change */
674         vnmc |= VNMC_VUP;
675 
676         /* If input and output use the same colorspace, use bypass mode */
677         if (output_is_yuv)
678                 vnmc |= VNMC_BPS;
679 
680         /* progressive or interlaced mode */
681         interrupts = progressive ? VNIE_FIE : VNIE_EFE;
682 
683         /* ack interrupts */
684         iowrite32(interrupts, priv->base + VNINTS_REG);
685         /* enable interrupts */
686         iowrite32(interrupts, priv->base + VNIE_REG);
687         /* start capturing */
688         iowrite32(dmr, priv->base + VNDMR_REG);
689         iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
690 
691         return 0;
692 }
693 
694 static void rcar_vin_capture(struct rcar_vin_priv *priv)
695 {
696         if (is_continuous_transfer(priv))
697                 /* Continuous Frame Capture Mode */
698                 iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
699         else
700                 /* Single Frame Capture Mode */
701                 iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
702 }
703 
704 static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
705 {
706         priv->state = STOPPING;
707 
708         /* set continuous & single transfer off */
709         iowrite32(0, priv->base + VNFC_REG);
710         /* disable capture (release DMA buffer), reset */
711         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
712                   priv->base + VNMC_REG);
713 
714         /* update the status if stopped already */
715         if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
716                 priv->state = STOPPED;
717 }
718 
719 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
720 {
721         int slot;
722 
723         for (slot = 0; slot < priv->nr_hw_slots; slot++)
724                 if (priv->queue_buf[slot] == NULL)
725                         return slot;
726 
727         return -1;
728 }
729 
730 static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
731 {
732         /* Ensure all HW slots are filled */
733         return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
734 }
735 
736 /* Moves a buffer from the queue to the HW slots */
737 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
738 {
739         struct vb2_buffer *vb;
740         dma_addr_t phys_addr_top;
741         int slot;
742 
743         if (list_empty(&priv->capture))
744                 return 0;
745 
746         /* Find a free HW slot */
747         slot = rcar_vin_get_free_hw_slot(priv);
748         if (slot < 0)
749                 return 0;
750 
751         vb = &list_entry(priv->capture.next, struct rcar_vin_buffer, list)->vb;
752         list_del_init(to_buf_list(vb));
753         priv->queue_buf[slot] = vb;
754         phys_addr_top = vb2_dma_contig_plane_dma_addr(vb, 0);
755         iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
756 
757         return 1;
758 }
759 
760 static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
761 {
762         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
763         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
764         struct rcar_vin_priv *priv = ici->priv;
765         unsigned long size;
766 
767         size = icd->sizeimage;
768 
769         if (vb2_plane_size(vb, 0) < size) {
770                 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
771                         vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
772                 goto error;
773         }
774 
775         vb2_set_plane_payload(vb, 0, size);
776 
777         dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
778                 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
779 
780         spin_lock_irq(&priv->lock);
781 
782         list_add_tail(to_buf_list(vb), &priv->capture);
783         rcar_vin_fill_hw_slot(priv);
784 
785         /* If we weren't running, and have enough buffers, start capturing! */
786         if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
787                 if (rcar_vin_setup(priv)) {
788                         /* Submit error */
789                         list_del_init(to_buf_list(vb));
790                         spin_unlock_irq(&priv->lock);
791                         goto error;
792                 }
793                 priv->request_to_stop = false;
794                 init_completion(&priv->capture_stop);
795                 priv->state = RUNNING;
796                 rcar_vin_capture(priv);
797         }
798 
799         spin_unlock_irq(&priv->lock);
800 
801         return;
802 
803 error:
804         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
805 }
806 
807 static void rcar_vin_videobuf_release(struct vb2_buffer *vb)
808 {
809         struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
810         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
811         struct rcar_vin_priv *priv = ici->priv;
812         unsigned int i;
813         int buf_in_use = 0;
814 
815         spin_lock_irq(&priv->lock);
816 
817         /* Is the buffer in use by the VIN hardware? */
818         for (i = 0; i < MAX_BUFFER_NUM; i++) {
819                 if (priv->queue_buf[i] == vb) {
820                         buf_in_use = 1;
821                         break;
822                 }
823         }
824 
825         if (buf_in_use) {
826                 while (priv->state != STOPPED) {
827 
828                         /* issue stop if running */
829                         if (priv->state == RUNNING)
830                                 rcar_vin_request_capture_stop(priv);
831 
832                         /* wait until capturing has been stopped */
833                         if (priv->state == STOPPING) {
834                                 priv->request_to_stop = true;
835                                 spin_unlock_irq(&priv->lock);
836                                 wait_for_completion(&priv->capture_stop);
837                                 spin_lock_irq(&priv->lock);
838                         }
839                 }
840                 /*
841                  * Capturing has now stopped. The buffer we have been asked
842                  * to release could be any of the current buffers in use, so
843                  * release all buffers that are in use by HW
844                  */
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;
850                         }
851                 }
852         } else {
853                 list_del_init(to_buf_list(vb));
854         }
855 
856         spin_unlock_irq(&priv->lock);
857 }
858 
859 static int rcar_vin_videobuf_init(struct vb2_buffer *vb)
860 {
861         INIT_LIST_HEAD(to_buf_list(vb));
862         return 0;
863 }
864 
865 static void rcar_vin_stop_streaming(struct vb2_queue *vq)
866 {
867         struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
868         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
869         struct rcar_vin_priv *priv = ici->priv;
870         struct list_head *buf_head, *tmp;
871 
872         spin_lock_irq(&priv->lock);
873         list_for_each_safe(buf_head, tmp, &priv->capture)
874                 list_del_init(buf_head);
875         spin_unlock_irq(&priv->lock);
876 }
877 
878 static struct vb2_ops rcar_vin_vb2_ops = {
879         .queue_setup    = rcar_vin_videobuf_setup,
880         .buf_init       = rcar_vin_videobuf_init,
881         .buf_cleanup    = rcar_vin_videobuf_release,
882         .buf_queue      = rcar_vin_videobuf_queue,
883         .stop_streaming = rcar_vin_stop_streaming,
884         .wait_prepare   = soc_camera_unlock,
885         .wait_finish    = soc_camera_lock,
886 };
887 
888 static irqreturn_t rcar_vin_irq(int irq, void *data)
889 {
890         struct rcar_vin_priv *priv = data;
891         u32 int_status;
892         bool can_run = false, hw_stopped;
893         int slot;
894         unsigned int handled = 0;
895 
896         spin_lock(&priv->lock);
897 
898         int_status = ioread32(priv->base + VNINTS_REG);
899         if (!int_status)
900                 goto done;
901         /* ack interrupts */
902         iowrite32(int_status, priv->base + VNINTS_REG);
903         handled = 1;
904 
905         /* nothing to do if capture status is 'STOPPED' */
906         if (priv->state == STOPPED)
907                 goto done;
908 
909         hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
910 
911         if (!priv->request_to_stop) {
912                 if (is_continuous_transfer(priv))
913                         slot = (ioread32(priv->base + VNMS_REG) &
914                                 VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
915                 else
916                         slot = 0;
917 
918                 priv->queue_buf[slot]->v4l2_buf.field = priv->field;
919                 priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
920                 do_gettimeofday(&priv->queue_buf[slot]->v4l2_buf.timestamp);
921                 vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
922                 priv->queue_buf[slot] = NULL;
923 
924                 if (priv->state != STOPPING)
925                         can_run = rcar_vin_fill_hw_slot(priv);
926 
927                 if (hw_stopped || !can_run) {
928                         priv->state = STOPPED;
929                 } else if (is_continuous_transfer(priv) &&
930                            list_empty(&priv->capture) &&
931                            priv->state == RUNNING) {
932                         /*
933                          * The continuous capturing requires an explicit stop
934                          * operation when there is no buffer to be set into
935                          * the VnMBm registers.
936                          */
937                         rcar_vin_request_capture_stop(priv);
938                 } else {
939                         rcar_vin_capture(priv);
940                 }
941 
942         } else if (hw_stopped) {
943                 priv->state = STOPPED;
944                 priv->request_to_stop = false;
945                 complete(&priv->capture_stop);
946         }
947 
948 done:
949         spin_unlock(&priv->lock);
950 
951         return IRQ_RETVAL(handled);
952 }
953 
954 static int rcar_vin_add_device(struct soc_camera_device *icd)
955 {
956         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
957         struct rcar_vin_priv *priv = ici->priv;
958         int i;
959 
960         for (i = 0; i < MAX_BUFFER_NUM; i++)
961                 priv->queue_buf[i] = NULL;
962 
963         pm_runtime_get_sync(ici->v4l2_dev.dev);
964 
965         dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
966                 icd->devnum);
967 
968         return 0;
969 }
970 
971 static void rcar_vin_remove_device(struct soc_camera_device *icd)
972 {
973         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
974         struct rcar_vin_priv *priv = ici->priv;
975         struct vb2_buffer *vb;
976         int i;
977 
978         /* disable capture, disable interrupts */
979         iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
980                   priv->base + VNMC_REG);
981         iowrite32(0, priv->base + VNIE_REG);
982 
983         priv->state = STOPPED;
984         priv->request_to_stop = false;
985 
986         /* make sure active buffer is cancelled */
987         spin_lock_irq(&priv->lock);
988         for (i = 0; i < MAX_BUFFER_NUM; i++) {
989                 vb = priv->queue_buf[i];
990                 if (vb) {
991                         list_del_init(to_buf_list(vb));
992                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
993                 }
994         }
995         spin_unlock_irq(&priv->lock);
996 
997         pm_runtime_put(ici->v4l2_dev.dev);
998 
999         dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
1000                 icd->devnum);
1001 }
1002 
1003 /* Called with .host_lock held */
1004 static int rcar_vin_clock_start(struct soc_camera_host *ici)
1005 {
1006         /* VIN does not have "mclk" */
1007         return 0;
1008 }
1009 
1010 /* Called with .host_lock held */
1011 static void rcar_vin_clock_stop(struct soc_camera_host *ici)
1012 {
1013         /* VIN does not have "mclk" */
1014 }
1015 
1016 static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
1017 {
1018         int i;
1019         const struct vin_coeff *p_prev_set = NULL;
1020         const struct vin_coeff *p_set = NULL;
1021 
1022         /* Look for suitable coefficient values */
1023         for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
1024                 p_prev_set = p_set;
1025                 p_set = &vin_coeff_set[i];
1026 
1027                 if (xs < p_set->xs_value)
1028                         break;
1029         }
1030 
1031         /* Use previous value if its XS value is closer */
1032         if (p_prev_set && p_set &&
1033             xs - p_prev_set->xs_value < p_set->xs_value - xs)
1034                 p_set = p_prev_set;
1035 
1036         /* Set coefficient registers */
1037         iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG);
1038         iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG);
1039         iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG);
1040 
1041         iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG);
1042         iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG);
1043         iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG);
1044 
1045         iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG);
1046         iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG);
1047         iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG);
1048 
1049         iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG);
1050         iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG);
1051         iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG);
1052 
1053         iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG);
1054         iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG);
1055         iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG);
1056 
1057         iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG);
1058         iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG);
1059         iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG);
1060 
1061         iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG);
1062         iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG);
1063         iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG);
1064 
1065         iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG);
1066         iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG);
1067         iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG);
1068 }
1069 
1070 /* rect is guaranteed to not exceed the scaled camera rectangle */
1071 static int rcar_vin_set_rect(struct soc_camera_device *icd)
1072 {
1073         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1074         struct rcar_vin_cam *cam = icd->host_priv;
1075         struct rcar_vin_priv *priv = ici->priv;
1076         unsigned int left_offset, top_offset;
1077         unsigned char dsize = 0;
1078         struct v4l2_rect *cam_subrect = &cam->subrect;
1079         u32 value;
1080 
1081         dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
1082                 icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
1083 
1084         left_offset = cam->vin_left;
1085         top_offset = cam->vin_top;
1086 
1087         if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
1088             priv->chip == RCAR_E1)
1089                 dsize = 1;
1090 
1091         dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
1092                 cam->width, cam->height, cam->vin_left, cam->vin_top);
1093         dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
1094                 cam_subrect->width, cam_subrect->height,
1095                 cam_subrect->left, cam_subrect->top);
1096 
1097         /* Set Start/End Pixel/Line Pre-Clip */
1098         iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
1099         iowrite32((left_offset + cam_subrect->width - 1) << dsize,
1100                   priv->base + VNEPPRC_REG);
1101         switch (priv->field) {
1102         case V4L2_FIELD_INTERLACED:
1103         case V4L2_FIELD_INTERLACED_TB:
1104         case V4L2_FIELD_INTERLACED_BT:
1105                 iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
1106                 iowrite32((top_offset + cam_subrect->height) / 2 - 1,
1107                           priv->base + VNELPRC_REG);
1108                 break;
1109         default:
1110                 iowrite32(top_offset, priv->base + VNSLPRC_REG);
1111                 iowrite32(top_offset + cam_subrect->height - 1,
1112                           priv->base + VNELPRC_REG);
1113                 break;
1114         }
1115 
1116         /* Set scaling coefficient */
1117         value = 0;
1118         if (cam_subrect->height != cam->out_height)
1119                 value = (4096 * cam_subrect->height) / cam->out_height;
1120         dev_dbg(icd->parent, "YS Value: %x\n", value);
1121         iowrite32(value, priv->base + VNYS_REG);
1122 
1123         value = 0;
1124         if (cam_subrect->width != cam->out_width)
1125                 value = (4096 * cam_subrect->width) / cam->out_width;
1126 
1127         /* Horizontal upscaling is up to double size */
1128         if (0 < value && value < 2048)
1129                 value = 2048;
1130 
1131         dev_dbg(icd->parent, "XS Value: %x\n", value);
1132         iowrite32(value, priv->base + VNXS_REG);
1133 
1134         /* Horizontal upscaling is carried out by scaling down from double size */
1135         if (value < 4096)
1136                 value *= 2;
1137 
1138         set_coeff(priv, value);
1139 
1140         /* Set Start/End Pixel/Line Post-Clip */
1141         iowrite32(0, priv->base + VNSPPOC_REG);
1142         iowrite32(0, priv->base + VNSLPOC_REG);
1143         iowrite32((cam->out_width - 1) << dsize, priv->base + VNEPPOC_REG);
1144         switch (priv->field) {
1145         case V4L2_FIELD_INTERLACED:
1146         case V4L2_FIELD_INTERLACED_TB:
1147         case V4L2_FIELD_INTERLACED_BT:
1148                 iowrite32(cam->out_height / 2 - 1,
1149                           priv->base + VNELPOC_REG);
1150                 break;
1151         default:
1152                 iowrite32(cam->out_height - 1, priv->base + VNELPOC_REG);
1153                 break;
1154         }
1155 
1156         iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
1157 
1158         return 0;
1159 }
1160 
1161 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
1162 {
1163         *vnmc = ioread32(priv->base + VNMC_REG);
1164         /* module disable */
1165         iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
1166 }
1167 
1168 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
1169 {
1170         unsigned long timeout = jiffies + 10 * HZ;
1171 
1172         /*
1173          * Wait until the end of the current frame. It can take a long time,
1174          * but if it has been aborted by a MRST1 reset, it should exit sooner.
1175          */
1176         while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
1177                 time_before(jiffies, timeout))
1178                 msleep(1);
1179 
1180         if (time_after(jiffies, timeout)) {
1181                 dev_err(priv->ici.v4l2_dev.dev,
1182                         "Timeout waiting for frame end! Interface problem?\n");
1183                 return;
1184         }
1185 
1186         iowrite32(vnmc, priv->base + VNMC_REG);
1187 }
1188 
1189 #define VIN_MBUS_FLAGS  (V4L2_MBUS_MASTER |             \
1190                          V4L2_MBUS_PCLK_SAMPLE_RISING | \
1191                          V4L2_MBUS_HSYNC_ACTIVE_HIGH |  \
1192                          V4L2_MBUS_HSYNC_ACTIVE_LOW |   \
1193                          V4L2_MBUS_VSYNC_ACTIVE_HIGH |  \
1194                          V4L2_MBUS_VSYNC_ACTIVE_LOW |   \
1195                          V4L2_MBUS_DATA_ACTIVE_HIGH)
1196 
1197 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
1198 {
1199         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1200         struct rcar_vin_priv *priv = ici->priv;
1201         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1202         struct v4l2_mbus_config cfg;
1203         unsigned long common_flags;
1204         u32 vnmc;
1205         u32 val;
1206         int ret;
1207 
1208         capture_stop_preserve(priv, &vnmc);
1209 
1210         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1211         if (!ret) {
1212                 common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1213                 if (!common_flags) {
1214                         dev_warn(icd->parent,
1215                                  "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1216                                  cfg.flags, VIN_MBUS_FLAGS);
1217                         return -EINVAL;
1218                 }
1219         } else if (ret != -ENOIOCTLCMD) {
1220                 return ret;
1221         } else {
1222                 common_flags = VIN_MBUS_FLAGS;
1223         }
1224 
1225         /* Make choises, based on platform preferences */
1226         if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1227             (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1228                 if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
1229                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1230                 else
1231                         common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1232         }
1233 
1234         if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1235             (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1236                 if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
1237                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1238                 else
1239                         common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1240         }
1241 
1242         cfg.flags = common_flags;
1243         ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1244         if (ret < 0 && ret != -ENOIOCTLCMD)
1245                 return ret;
1246 
1247         val = VNDMR2_FTEV | VNDMR2_VLV(1);
1248         if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
1249                 val |= VNDMR2_VPS;
1250         if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
1251                 val |= VNDMR2_HPS;
1252         iowrite32(val, priv->base + VNDMR2_REG);
1253 
1254         ret = rcar_vin_set_rect(icd);
1255         if (ret < 0)
1256                 return ret;
1257 
1258         capture_restore(priv, vnmc);
1259 
1260         return 0;
1261 }
1262 
1263 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
1264                                   unsigned char buswidth)
1265 {
1266         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1267         struct v4l2_mbus_config cfg;
1268         int ret;
1269 
1270         ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1271         if (ret == -ENOIOCTLCMD)
1272                 return 0;
1273         else if (ret)
1274                 return ret;
1275 
1276         if (buswidth > 24)
1277                 return -EINVAL;
1278 
1279         /* check is there common mbus flags */
1280         ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1281         if (ret)
1282                 return 0;
1283 
1284         dev_warn(icd->parent,
1285                 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1286                  cfg.flags, VIN_MBUS_FLAGS);
1287 
1288         return -EINVAL;
1289 }
1290 
1291 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1292 {
1293         return  fmt->packing == SOC_MBUS_PACKING_NONE ||
1294                 (fmt->bits_per_sample > 8 &&
1295                  fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1296 }
1297 
1298 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
1299         {
1300                 .fourcc                 = V4L2_PIX_FMT_NV16,
1301                 .name                   = "NV16",
1302                 .bits_per_sample        = 8,
1303                 .packing                = SOC_MBUS_PACKING_2X8_PADHI,
1304                 .order                  = SOC_MBUS_ORDER_LE,
1305                 .layout                 = SOC_MBUS_LAYOUT_PLANAR_Y_C,
1306         },
1307         {
1308                 .fourcc                 = V4L2_PIX_FMT_YUYV,
1309                 .name                   = "YUYV",
1310                 .bits_per_sample        = 16,
1311                 .packing                = SOC_MBUS_PACKING_NONE,
1312                 .order                  = SOC_MBUS_ORDER_LE,
1313                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1314         },
1315         {
1316                 .fourcc                 = V4L2_PIX_FMT_UYVY,
1317                 .name                   = "UYVY",
1318                 .bits_per_sample        = 16,
1319                 .packing                = SOC_MBUS_PACKING_NONE,
1320                 .order                  = SOC_MBUS_ORDER_LE,
1321                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1322         },
1323         {
1324                 .fourcc                 = V4L2_PIX_FMT_RGB565,
1325                 .name                   = "RGB565",
1326                 .bits_per_sample        = 16,
1327                 .packing                = SOC_MBUS_PACKING_NONE,
1328                 .order                  = SOC_MBUS_ORDER_LE,
1329                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1330         },
1331         {
1332                 .fourcc                 = V4L2_PIX_FMT_RGB555X,
1333                 .name                   = "ARGB1555",
1334                 .bits_per_sample        = 16,
1335                 .packing                = SOC_MBUS_PACKING_NONE,
1336                 .order                  = SOC_MBUS_ORDER_LE,
1337                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1338         },
1339         {
1340                 .fourcc                 = V4L2_PIX_FMT_RGB32,
1341                 .name                   = "RGB888",
1342                 .bits_per_sample        = 32,
1343                 .packing                = SOC_MBUS_PACKING_NONE,
1344                 .order                  = SOC_MBUS_ORDER_LE,
1345                 .layout                 = SOC_MBUS_LAYOUT_PACKED,
1346         },
1347 };
1348 
1349 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
1350                                 struct soc_camera_format_xlate *xlate)
1351 {
1352         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1353         struct device *dev = icd->parent;
1354         int ret, k, n;
1355         int formats = 0;
1356         struct rcar_vin_cam *cam;
1357         u32 code;
1358         const struct soc_mbus_pixelfmt *fmt;
1359 
1360         ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1361         if (ret < 0)
1362                 return 0;
1363 
1364         fmt = soc_mbus_get_fmtdesc(code);
1365         if (!fmt) {
1366                 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
1367                 return 0;
1368         }
1369 
1370         ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
1371         if (ret < 0)
1372                 return 0;
1373 
1374         if (!icd->host_priv) {
1375                 struct v4l2_mbus_framefmt mf;
1376                 struct v4l2_rect rect;
1377                 struct device *dev = icd->parent;
1378                 int shift;
1379 
1380                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1381                 if (ret < 0)
1382                         return ret;
1383 
1384                 /* Cache current client geometry */
1385                 ret = soc_camera_client_g_rect(sd, &rect);
1386                 if (ret == -ENOIOCTLCMD) {
1387                         /* Sensor driver doesn't support cropping */
1388                         rect.left = 0;
1389                         rect.top = 0;
1390                         rect.width = mf.width;
1391                         rect.height = mf.height;
1392                 } else if (ret < 0) {
1393                         return ret;
1394                 }
1395 
1396                 /*
1397                  * If sensor proposes too large format then try smaller ones:
1398                  * 1280x960, 640x480, 320x240
1399                  */
1400                 for (shift = 0; shift < 3; shift++) {
1401                         if (mf.width <= VIN_MAX_WIDTH &&
1402                             mf.height <= VIN_MAX_HEIGHT)
1403                                 break;
1404 
1405                         mf.width = 1280 >> shift;
1406                         mf.height = 960 >> shift;
1407                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
1408                                                          soc_camera_grp_id(icd),
1409                                                          video, s_mbus_fmt,
1410                                                          &mf);
1411                         if (ret < 0)
1412                                 return ret;
1413                 }
1414 
1415                 if (shift == 3) {
1416                         dev_err(dev,
1417                                 "Failed to configure the client below %ux%u\n",
1418                                 mf.width, mf.height);
1419                         return -EIO;
1420                 }
1421 
1422                 dev_dbg(dev, "camera fmt %ux%u\n", mf.width, mf.height);
1423 
1424                 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1425                 if (!cam)
1426                         return -ENOMEM;
1427                 /*
1428                  * We are called with current camera crop,
1429                  * initialise subrect with it
1430                  */
1431                 cam->rect = rect;
1432                 cam->subrect = rect;
1433                 cam->width = mf.width;
1434                 cam->height = mf.height;
1435                 cam->out_width  = mf.width;
1436                 cam->out_height = mf.height;
1437 
1438                 icd->host_priv = cam;
1439         } else {
1440                 cam = icd->host_priv;
1441         }
1442 
1443         /* Beginning of a pass */
1444         if (!idx)
1445                 cam->extra_fmt = NULL;
1446 
1447         switch (code) {
1448         case MEDIA_BUS_FMT_YUYV8_1X16:
1449         case MEDIA_BUS_FMT_YUYV8_2X8:
1450         case MEDIA_BUS_FMT_YUYV10_2X10:
1451                 if (cam->extra_fmt)
1452                         break;
1453 
1454                 /* Add all our formats that can be generated by VIN */
1455                 cam->extra_fmt = rcar_vin_formats;
1456 
1457                 n = ARRAY_SIZE(rcar_vin_formats);
1458                 formats += n;
1459                 for (k = 0; xlate && k < n; k++, xlate++) {
1460                         xlate->host_fmt = &rcar_vin_formats[k];
1461                         xlate->code = code;
1462                         dev_dbg(dev, "Providing format %s using code %d\n",
1463                                 rcar_vin_formats[k].name, code);
1464                 }
1465                 break;
1466         default:
1467                 if (!rcar_vin_packing_supported(fmt))
1468                         return 0;
1469 
1470                 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1471                         fmt->name);
1472                 break;
1473         }
1474 
1475         /* Generic pass-through */
1476         formats++;
1477         if (xlate) {
1478                 xlate->host_fmt = fmt;
1479                 xlate->code = code;
1480                 xlate++;
1481         }
1482 
1483         return formats;
1484 }
1485 
1486 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1487 {
1488         kfree(icd->host_priv);
1489         icd->host_priv = NULL;
1490 }
1491 
1492 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1493                              const struct v4l2_crop *a)
1494 {
1495         struct v4l2_crop a_writable = *a;
1496         const struct v4l2_rect *rect = &a_writable.c;
1497         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1498         struct rcar_vin_priv *priv = ici->priv;
1499         struct v4l2_crop cam_crop;
1500         struct rcar_vin_cam *cam = icd->host_priv;
1501         struct v4l2_rect *cam_rect = &cam_crop.c;
1502         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1503         struct device *dev = icd->parent;
1504         struct v4l2_mbus_framefmt mf;
1505         u32 vnmc;
1506         int ret, i;
1507 
1508         dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1509                 rect->left, rect->top);
1510 
1511         /* During camera cropping its output window can change too, stop VIN */
1512         capture_stop_preserve(priv, &vnmc);
1513         dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1514 
1515         /* Apply iterative camera S_CROP for new input window. */
1516         ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1517                                        &cam->rect, &cam->subrect);
1518         if (ret < 0)
1519                 return ret;
1520 
1521         dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1522                 cam_rect->width, cam_rect->height,
1523                 cam_rect->left, cam_rect->top);
1524 
1525         /* On success cam_crop contains current camera crop */
1526 
1527         /* Retrieve camera output window */
1528         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1529         if (ret < 0)
1530                 return ret;
1531 
1532         if (mf.width > VIN_MAX_WIDTH || mf.height > VIN_MAX_HEIGHT)
1533                 return -EINVAL;
1534 
1535         /* Cache camera output window */
1536         cam->width = mf.width;
1537         cam->height = mf.height;
1538 
1539         icd->user_width  = cam->width;
1540         icd->user_height = cam->height;
1541 
1542         cam->vin_left = rect->left & ~1;
1543         cam->vin_top = rect->top & ~1;
1544 
1545         /* Use VIN cropping to crop to the new window. */
1546         ret = rcar_vin_set_rect(icd);
1547         if (ret < 0)
1548                 return ret;
1549 
1550         cam->subrect = *rect;
1551 
1552         dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1553                 icd->user_width, icd->user_height,
1554                 cam->vin_left, cam->vin_top);
1555 
1556         /* Restore capture */
1557         for (i = 0; i < MAX_BUFFER_NUM; i++) {
1558                 if (priv->queue_buf[i] && priv->state == STOPPED) {
1559                         vnmc |= VNMC_ME;
1560                         break;
1561                 }
1562         }
1563         capture_restore(priv, vnmc);
1564 
1565         /* Even if only camera cropping succeeded */
1566         return ret;
1567 }
1568 
1569 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1570                              struct v4l2_crop *a)
1571 {
1572         struct rcar_vin_cam *cam = icd->host_priv;
1573 
1574         a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1575         a->c = cam->subrect;
1576 
1577         return 0;
1578 }
1579 
1580 /* Similar to set_crop multistage iterative algorithm */
1581 static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1582                             struct v4l2_format *f)
1583 {
1584         struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1585         struct rcar_vin_priv *priv = ici->priv;
1586         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1587         struct rcar_vin_cam *cam = icd->host_priv;
1588         struct v4l2_pix_format *pix = &f->fmt.pix;
1589         struct v4l2_mbus_framefmt mf;
1590         struct device *dev = icd->parent;
1591         __u32 pixfmt = pix->pixelformat;
1592         const struct soc_camera_format_xlate *xlate;
1593         unsigned int vin_sub_width = 0, vin_sub_height = 0;
1594         int ret;
1595         bool can_scale;
1596         enum v4l2_field field;
1597         v4l2_std_id std;
1598 
1599         dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1600                 pixfmt, pix->width, pix->height);
1601 
1602         switch (pix->field) {
1603         default:
1604                 pix->field = V4L2_FIELD_NONE;
1605                 /* fall-through */
1606         case V4L2_FIELD_NONE:
1607         case V4L2_FIELD_TOP:
1608         case V4L2_FIELD_BOTTOM:
1609         case V4L2_FIELD_INTERLACED_TB:
1610         case V4L2_FIELD_INTERLACED_BT:
1611                 field = pix->field;
1612                 break;
1613         case V4L2_FIELD_INTERLACED:
1614                 /* Query for standard if not explicitly mentioned _TB/_BT */
1615                 ret = v4l2_subdev_call(sd, video, querystd, &std);
1616                 if (ret < 0)
1617                         std = V4L2_STD_625_50;
1618 
1619                 field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1620                                                 V4L2_FIELD_INTERLACED_BT;
1621                 break;
1622         }
1623 
1624         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1625         if (!xlate) {
1626                 dev_warn(dev, "Format %x not found\n", pixfmt);
1627                 return -EINVAL;
1628         }
1629         /* Calculate client output geometry */
1630         soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1631                                       12);
1632         mf.field = pix->field;
1633         mf.colorspace = pix->colorspace;
1634         mf.code  = xlate->code;
1635 
1636         switch (pixfmt) {
1637         case V4L2_PIX_FMT_RGB32:
1638                 can_scale = priv->chip != RCAR_E1;
1639                 break;
1640         case V4L2_PIX_FMT_UYVY:
1641         case V4L2_PIX_FMT_YUYV:
1642         case V4L2_PIX_FMT_RGB565:
1643         case V4L2_PIX_FMT_RGB555X:
1644                 can_scale = true;
1645                 break;
1646         default:
1647                 can_scale = false;
1648                 break;
1649         }
1650 
1651         dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1652 
1653         ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1654                                       &mf, &vin_sub_width, &vin_sub_height,
1655                                       can_scale, 12);
1656 
1657         /* Done with the camera. Now see if we can improve the result */
1658         dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1659                 ret, mf.width, mf.height, pix->width, pix->height);
1660 
1661         if (ret == -ENOIOCTLCMD)
1662                 dev_dbg(dev, "Sensor doesn't support scaling\n");
1663         else if (ret < 0)
1664                 return ret;
1665 
1666         if (mf.code != xlate->code)
1667                 return -EINVAL;
1668 
1669         /* Prepare VIN crop */
1670         cam->width = mf.width;
1671         cam->height = mf.height;
1672 
1673         /* Use VIN scaling to scale to the requested user window. */
1674 
1675         /* We cannot scale up */
1676         if (pix->width > vin_sub_width)
1677                 vin_sub_width = pix->width;
1678 
1679         if (pix->height > vin_sub_height)
1680                 vin_sub_height = pix->height;
1681 
1682         pix->colorspace = mf.colorspace;
1683 
1684         if (!can_scale) {
1685                 pix->width = vin_sub_width;
1686                 pix->height = vin_sub_height;
1687         }
1688 
1689         /*
1690          * We have calculated CFLCR, the actual configuration will be performed
1691          * in rcar_vin_set_bus_param()
1692          */
1693 
1694         dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1695                 vin_sub_width, pix->width, vin_sub_height, pix->height);
1696 
1697         cam->out_width = pix->width;
1698         cam->out_height = pix->height;
1699 
1700         icd->current_fmt = xlate;
1701 
1702         priv->field = field;
1703 
1704         return 0;
1705 }
1706 
1707 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1708                             struct v4l2_format *f)
1709 {
1710         const struct soc_camera_format_xlate *xlate;
1711         struct v4l2_pix_format *pix = &f->fmt.pix;
1712         struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1713         struct v4l2_mbus_framefmt mf;
1714         __u32 pixfmt = pix->pixelformat;
1715         int width, height;
1716         int ret;
1717 
1718         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1719         if (!xlate) {
1720                 xlate = icd->current_fmt;
1721                 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1722                         pixfmt, xlate->host_fmt->fourcc);
1723                 pixfmt = xlate->host_fmt->fourcc;
1724                 pix->pixelformat = pixfmt;
1725                 pix->colorspace = icd->colorspace;
1726         }
1727 
1728         /* FIXME: calculate using depth and bus width */
1729         v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1730                               &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1731 
1732         width = pix->width;
1733         height = pix->height;
1734 
1735         /* let soc-camera calculate these values */
1736         pix->bytesperline = 0;
1737         pix->sizeimage = 0;
1738 
1739         /* limit to sensor capabilities */
1740         mf.width = pix->width;
1741         mf.height = pix->height;
1742         mf.field = pix->field;
1743         mf.code = xlate->code;
1744         mf.colorspace = pix->colorspace;
1745 
1746         ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1747                                          video, try_mbus_fmt, &mf);
1748         if (ret < 0)
1749                 return ret;
1750 
1751         /* Adjust only if VIN cannot scale */
1752         if (pix->width > mf.width * 2)
1753                 pix->width = mf.width * 2;
1754         if (pix->height > mf.height * 3)
1755                 pix->height = mf.height * 3;
1756 
1757         pix->field = mf.field;
1758         pix->colorspace = mf.colorspace;
1759 
1760         if (pixfmt == V4L2_PIX_FMT_NV16) {
1761                 /* FIXME: check against rect_max after converting soc-camera */
1762                 /* We can scale precisely, need a bigger image from camera */
1763                 if (pix->width < width || pix->height < height) {
1764                         /*
1765                          * We presume, the sensor behaves sanely, i.e. if
1766                          * requested a bigger rectangle, it will not return a
1767                          * smaller one.
1768                          */
1769                         mf.width = VIN_MAX_WIDTH;
1770                         mf.height = VIN_MAX_HEIGHT;
1771                         ret = v4l2_device_call_until_err(sd->v4l2_dev,
1772                                                          soc_camera_grp_id(icd),
1773                                                          video, try_mbus_fmt,
1774                                                          &mf);
1775                         if (ret < 0) {
1776                                 dev_err(icd->parent,
1777                                         "client try_fmt() = %d\n", ret);
1778                                 return ret;
1779                         }
1780                 }
1781                 /* We will scale exactly */
1782                 if (mf.width > width)
1783                         pix->width = width;
1784                 if (mf.height > height)
1785                         pix->height = height;
1786         }
1787 
1788         return ret;
1789 }
1790 
1791 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1792 {
1793         struct soc_camera_device *icd = file->private_data;
1794 
1795         return vb2_poll(&icd->vb2_vidq, file, pt);
1796 }
1797 
1798 static int rcar_vin_querycap(struct soc_camera_host *ici,
1799                              struct v4l2_capability *cap)
1800 {
1801         strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1802         cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1803         cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1804 
1805         return 0;
1806 }
1807 
1808 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1809                                    struct soc_camera_device *icd)
1810 {
1811         vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1812         vq->io_modes = VB2_MMAP | VB2_USERPTR;
1813         vq->drv_priv = icd;
1814         vq->ops = &rcar_vin_vb2_ops;
1815         vq->mem_ops = &vb2_dma_contig_memops;
1816         vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
1817         vq->timestamp_flags  = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1818 
1819         return vb2_queue_init(vq);
1820 }
1821 
1822 static struct soc_camera_host_ops rcar_vin_host_ops = {
1823         .owner          = THIS_MODULE,
1824         .add            = rcar_vin_add_device,
1825         .remove         = rcar_vin_remove_device,
1826         .clock_start    = rcar_vin_clock_start,
1827         .clock_stop     = rcar_vin_clock_stop,
1828         .get_formats    = rcar_vin_get_formats,
1829         .put_formats    = rcar_vin_put_formats,
1830         .get_crop       = rcar_vin_get_crop,
1831         .set_crop       = rcar_vin_set_crop,
1832         .try_fmt        = rcar_vin_try_fmt,
1833         .set_fmt        = rcar_vin_set_fmt,
1834         .poll           = rcar_vin_poll,
1835         .querycap       = rcar_vin_querycap,
1836         .set_bus_param  = rcar_vin_set_bus_param,
1837         .init_videobuf2 = rcar_vin_init_videobuf2,
1838 };
1839 
1840 #ifdef CONFIG_OF
1841 static struct of_device_id rcar_vin_of_table[] = {
1842         { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
1843         { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
1844         { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
1845         { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
1846         { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
1847         { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
1848         { },
1849 };
1850 MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1851 #endif
1852 
1853 static struct platform_device_id rcar_vin_id_table[] = {
1854         { "r8a7791-vin",  RCAR_GEN2 },
1855         { "r8a7790-vin",  RCAR_GEN2 },
1856         { "r8a7779-vin",  RCAR_H1 },
1857         { "r8a7778-vin",  RCAR_M1 },
1858         { "uPD35004-vin", RCAR_E1 },
1859         {},
1860 };
1861 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1862 
1863 static int rcar_vin_probe(struct platform_device *pdev)
1864 {
1865         const struct of_device_id *match = NULL;
1866         struct rcar_vin_priv *priv;
1867         struct resource *mem;
1868         struct rcar_vin_platform_data *pdata;
1869         unsigned int pdata_flags;
1870         int irq, ret;
1871 
1872         if (pdev->dev.of_node) {
1873                 struct v4l2_of_endpoint ep;
1874                 struct device_node *np;
1875 
1876                 match = of_match_device(of_match_ptr(rcar_vin_of_table),
1877                                         &pdev->dev);
1878 
1879                 np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1880                 if (!np) {
1881                         dev_err(&pdev->dev, "could not find endpoint\n");
1882                         return -EINVAL;
1883                 }
1884 
1885                 ret = v4l2_of_parse_endpoint(np, &ep);
1886                 if (ret) {
1887                         dev_err(&pdev->dev, "could not parse endpoint\n");
1888                         return ret;
1889                 }
1890 
1891                 if (ep.bus_type == V4L2_MBUS_BT656)
1892                         pdata_flags = RCAR_VIN_BT656;
1893                 else {
1894                         pdata_flags = 0;
1895                         if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1896                                 pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
1897                         if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1898                                 pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
1899                 }
1900 
1901                 of_node_put(np);
1902 
1903                 dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1904         } else {
1905                 pdata = pdev->dev.platform_data;
1906                 if (!pdata || !pdata->flags) {
1907                         dev_err(&pdev->dev, "platform data not set\n");
1908                         return -EINVAL;
1909                 }
1910                 pdata_flags = pdata->flags;
1911         }
1912 
1913         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1914         if (mem == NULL)
1915                 return -EINVAL;
1916 
1917         irq = platform_get_irq(pdev, 0);
1918         if (irq <= 0)
1919                 return -EINVAL;
1920 
1921         priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1922                             GFP_KERNEL);
1923         if (!priv)
1924                 return -ENOMEM;
1925 
1926         priv->base = devm_ioremap_resource(&pdev->dev, mem);
1927         if (IS_ERR(priv->base))
1928                 return PTR_ERR(priv->base);
1929 
1930         ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1931                                dev_name(&pdev->dev), priv);
1932         if (ret)
1933                 return ret;
1934 
1935         priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1936         if (IS_ERR(priv->alloc_ctx))
1937                 return PTR_ERR(priv->alloc_ctx);
1938 
1939         priv->ici.priv = priv;
1940         priv->ici.v4l2_dev.dev = &pdev->dev;
1941         priv->ici.drv_name = dev_name(&pdev->dev);
1942         priv->ici.ops = &rcar_vin_host_ops;
1943 
1944         priv->pdata_flags = pdata_flags;
1945         if (!match) {
1946                 priv->ici.nr = pdev->id;
1947                 priv->chip = pdev->id_entry->driver_data;
1948         } else {
1949                 priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1950                 priv->chip = (enum chip_id)match->data;
1951         }
1952 
1953         spin_lock_init(&priv->lock);
1954         INIT_LIST_HEAD(&priv->capture);
1955 
1956         priv->state = STOPPED;
1957 
1958         pm_suspend_ignore_children(&pdev->dev, true);
1959         pm_runtime_enable(&pdev->dev);
1960 
1961         ret = soc_camera_host_register(&priv->ici);
1962         if (ret)
1963                 goto cleanup;
1964 
1965         return 0;
1966 
1967 cleanup:
1968         pm_runtime_disable(&pdev->dev);
1969         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1970 
1971         return ret;
1972 }
1973 
1974 static int rcar_vin_remove(struct platform_device *pdev)
1975 {
1976         struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1977         struct rcar_vin_priv *priv = container_of(soc_host,
1978                                                   struct rcar_vin_priv, ici);
1979 
1980         soc_camera_host_unregister(soc_host);
1981         pm_runtime_disable(&pdev->dev);
1982         vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1983 
1984         return 0;
1985 }
1986 
1987 static struct platform_driver rcar_vin_driver = {
1988         .probe          = rcar_vin_probe,
1989         .remove         = rcar_vin_remove,
1990         .driver         = {
1991                 .name           = DRV_NAME,
1992                 .of_match_table = of_match_ptr(rcar_vin_of_table),
1993         },
1994         .id_table       = rcar_vin_id_table,
1995 };
1996 
1997 module_platform_driver(rcar_vin_driver);
1998 
1999 MODULE_LICENSE("GPL");
2000 MODULE_ALIAS("platform:rcar_vin");
2001 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
2002 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us