1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Microchip Image Sensor Controller (ISC) driver
4  *
5  * Copyright (C) 2016-2019 Microchip Technology, Inc.
6  *
7  * Author: Songjun Wu
8  * Author: Eugen Hristev <eugen.hristev@microchip.com>
9  *
10  *
11  * Sensor-->PFE-->WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB-->RLP-->DMA
12  *
13  * ISC video pipeline integrates the following submodules:
14  * PFE: Parallel Front End to sample the camera sensor input stream
15  *  WB: Programmable white balance in the Bayer domain
16  * CFA: Color filter array interpolation module
17  *  CC: Programmable color correction
18  * GAM: Gamma correction
19  * CSC: Programmable color space conversion
20  * CBC: Contrast and Brightness control
21  * SUB: This module performs YCbCr444 to YCbCr420 chrominance subsampling
22  * RLP: This module performs rounding, range limiting
23  *      and packing of the incoming data
24  */
25 
26 #include <linux/clk.h>
27 #include <linux/clkdev.h>
28 #include <linux/clk-provider.h>
29 #include <linux/delay.h>
30 #include <linux/interrupt.h>
31 #include <linux/math64.h>
32 #include <linux/module.h>
33 #include <linux/of.h>
34 #include <linux/of_graph.h>
35 #include <linux/platform_device.h>
36 #include <linux/pm_runtime.h>
37 #include <linux/regmap.h>
38 #include <linux/videodev2.h>
39 
40 #include <media/v4l2-ctrls.h>
41 #include <media/v4l2-device.h>
42 #include <media/v4l2-event.h>
43 #include <media/v4l2-image-sizes.h>
44 #include <media/v4l2-ioctl.h>
45 #include <media/v4l2-fwnode.h>
46 #include <media/v4l2-subdev.h>
47 #include <media/videobuf2-dma-contig.h>
48 
49 #include "microchip-isc-regs.h"
50 #include "microchip-isc.h"
51 
52 #define ISC_SAMA5D2_MAX_SUPPORT_WIDTH   2592
53 #define ISC_SAMA5D2_MAX_SUPPORT_HEIGHT  1944
54 
55 #define ISC_SAMA5D2_PIPELINE \
56 	(WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \
57 	CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE)
58 
59 /* This is a list of the formats that the ISC can *output* */
60 static const struct isc_format sama5d2_controller_formats[] = {
61 	{
62 		.fourcc		= V4L2_PIX_FMT_ARGB444,
63 	}, {
64 		.fourcc		= V4L2_PIX_FMT_ARGB555,
65 	}, {
66 		.fourcc		= V4L2_PIX_FMT_RGB565,
67 	}, {
68 		.fourcc		= V4L2_PIX_FMT_ABGR32,
69 	}, {
70 		.fourcc		= V4L2_PIX_FMT_XBGR32,
71 	}, {
72 		.fourcc		= V4L2_PIX_FMT_YUV420,
73 	}, {
74 		.fourcc		= V4L2_PIX_FMT_YUYV,
75 	}, {
76 		.fourcc		= V4L2_PIX_FMT_YUV422P,
77 	}, {
78 		.fourcc		= V4L2_PIX_FMT_GREY,
79 	}, {
80 		.fourcc		= V4L2_PIX_FMT_Y10,
81 	}, {
82 		.fourcc		= V4L2_PIX_FMT_SBGGR8,
83 		.raw		= true,
84 	}, {
85 		.fourcc		= V4L2_PIX_FMT_SGBRG8,
86 		.raw		= true,
87 	}, {
88 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
89 		.raw		= true,
90 	}, {
91 		.fourcc		= V4L2_PIX_FMT_SRGGB8,
92 		.raw		= true,
93 	}, {
94 		.fourcc		= V4L2_PIX_FMT_SBGGR10,
95 		.raw		= true,
96 	}, {
97 		.fourcc		= V4L2_PIX_FMT_SGBRG10,
98 		.raw		= true,
99 	}, {
100 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
101 		.raw		= true,
102 	}, {
103 		.fourcc		= V4L2_PIX_FMT_SRGGB10,
104 		.raw		= true,
105 	}, {
106 		.fourcc		= V4L2_PIX_FMT_SBGGR12,
107 		.raw		= true,
108 	}, {
109 		.fourcc		= V4L2_PIX_FMT_SGBRG12,
110 		.raw		= true,
111 	}, {
112 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
113 		.raw		= true,
114 	}, {
115 		.fourcc		= V4L2_PIX_FMT_SRGGB12,
116 		.raw		= true,
117 	},
118 };
119 
120 /* This is a list of formats that the ISC can receive as *input* */
121 static struct isc_format sama5d2_formats_list[] = {
122 	{
123 		.fourcc		= V4L2_PIX_FMT_SBGGR8,
124 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
125 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
126 		.cfa_baycfg	= ISC_BAY_CFG_BGBG,
127 	},
128 	{
129 		.fourcc		= V4L2_PIX_FMT_SGBRG8,
130 		.mbus_code	= MEDIA_BUS_FMT_SGBRG8_1X8,
131 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
132 		.cfa_baycfg	= ISC_BAY_CFG_GBGB,
133 	},
134 	{
135 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
136 		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
137 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
138 		.cfa_baycfg	= ISC_BAY_CFG_GRGR,
139 	},
140 	{
141 		.fourcc		= V4L2_PIX_FMT_SRGGB8,
142 		.mbus_code	= MEDIA_BUS_FMT_SRGGB8_1X8,
143 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
144 		.cfa_baycfg	= ISC_BAY_CFG_RGRG,
145 	},
146 	{
147 		.fourcc		= V4L2_PIX_FMT_SBGGR10,
148 		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
149 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TEN,
150 		.cfa_baycfg	= ISC_BAY_CFG_RGRG,
151 	},
152 	{
153 		.fourcc		= V4L2_PIX_FMT_SGBRG10,
154 		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
155 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TEN,
156 		.cfa_baycfg	= ISC_BAY_CFG_GBGB,
157 	},
158 	{
159 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
160 		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
161 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TEN,
162 		.cfa_baycfg	= ISC_BAY_CFG_GRGR,
163 	},
164 	{
165 		.fourcc		= V4L2_PIX_FMT_SRGGB10,
166 		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
167 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TEN,
168 		.cfa_baycfg	= ISC_BAY_CFG_RGRG,
169 	},
170 	{
171 		.fourcc		= V4L2_PIX_FMT_SBGGR12,
172 		.mbus_code	= MEDIA_BUS_FMT_SBGGR12_1X12,
173 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TWELVE,
174 		.cfa_baycfg	= ISC_BAY_CFG_BGBG,
175 	},
176 	{
177 		.fourcc		= V4L2_PIX_FMT_SGBRG12,
178 		.mbus_code	= MEDIA_BUS_FMT_SGBRG12_1X12,
179 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TWELVE,
180 		.cfa_baycfg	= ISC_BAY_CFG_GBGB,
181 	},
182 	{
183 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
184 		.mbus_code	= MEDIA_BUS_FMT_SGRBG12_1X12,
185 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TWELVE,
186 		.cfa_baycfg	= ISC_BAY_CFG_GRGR,
187 	},
188 	{
189 		.fourcc		= V4L2_PIX_FMT_SRGGB12,
190 		.mbus_code	= MEDIA_BUS_FMT_SRGGB12_1X12,
191 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TWELVE,
192 		.cfa_baycfg	= ISC_BAY_CFG_RGRG,
193 	},
194 	{
195 		.fourcc		= V4L2_PIX_FMT_GREY,
196 		.mbus_code	= MEDIA_BUS_FMT_Y8_1X8,
197 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
198 	},
199 	{
200 		.fourcc		= V4L2_PIX_FMT_YUYV,
201 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
202 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
203 	},
204 	{
205 		.fourcc		= V4L2_PIX_FMT_RGB565,
206 		.mbus_code	= MEDIA_BUS_FMT_RGB565_2X8_LE,
207 		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
208 	},
209 	{
210 		.fourcc		= V4L2_PIX_FMT_Y10,
211 		.mbus_code	= MEDIA_BUS_FMT_Y10_1X10,
212 		.pfe_cfg0_bps	= ISC_PFG_CFG0_BPS_TEN,
213 	},
214 
215 };
216 
217 static void isc_sama5d2_config_csc(struct isc_device *isc)
218 {
219 	struct regmap *regmap = isc->regmap;
220 
221 	/* Convert RGB to YUV */
222 	regmap_write(regmap, ISC_CSC_YR_YG + isc->offsets.csc,
223 		     0x42 | (0x81 << 16));
224 	regmap_write(regmap, ISC_CSC_YB_OY + isc->offsets.csc,
225 		     0x19 | (0x10 << 16));
226 	regmap_write(regmap, ISC_CSC_CBR_CBG + isc->offsets.csc,
227 		     0xFDA | (0xFB6 << 16));
228 	regmap_write(regmap, ISC_CSC_CBB_OCB + isc->offsets.csc,
229 		     0x70 | (0x80 << 16));
230 	regmap_write(regmap, ISC_CSC_CRR_CRG + isc->offsets.csc,
231 		     0x70 | (0xFA2 << 16));
232 	regmap_write(regmap, ISC_CSC_CRB_OCR + isc->offsets.csc,
233 		     0xFEE | (0x80 << 16));
234 }
235 
236 static void isc_sama5d2_config_cbc(struct isc_device *isc)
237 {
238 	struct regmap *regmap = isc->regmap;
239 
240 	regmap_write(regmap, ISC_CBC_BRIGHT + isc->offsets.cbc,
241 		     isc->ctrls.brightness);
242 	regmap_write(regmap, ISC_CBC_CONTRAST + isc->offsets.cbc,
243 		     isc->ctrls.contrast);
244 }
245 
246 static void isc_sama5d2_config_cc(struct isc_device *isc)
247 {
248 	struct regmap *regmap = isc->regmap;
249 
250 	/* Configure each register at the neutral fixed point 1.0 or 0.0 */
251 	regmap_write(regmap, ISC_CC_RR_RG, (1 << 8));
252 	regmap_write(regmap, ISC_CC_RB_OR, 0);
253 	regmap_write(regmap, ISC_CC_GR_GG, (1 << 8) << 16);
254 	regmap_write(regmap, ISC_CC_GB_OG, 0);
255 	regmap_write(regmap, ISC_CC_BR_BG, 0);
256 	regmap_write(regmap, ISC_CC_BB_OB, (1 << 8));
257 }
258 
259 static void isc_sama5d2_config_ctrls(struct isc_device *isc,
260 				     const struct v4l2_ctrl_ops *ops)
261 {
262 	struct isc_ctrls *ctrls = &isc->ctrls;
263 	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
264 
265 	ctrls->contrast = 256;
266 
267 	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256);
268 }
269 
270 static void isc_sama5d2_config_dpc(struct isc_device *isc)
271 {
272 	/* This module is not present on sama5d2 pipeline */
273 }
274 
275 static void isc_sama5d2_config_gam(struct isc_device *isc)
276 {
277 	/* No specific gamma configuration */
278 }
279 
280 static void isc_sama5d2_config_rlp(struct isc_device *isc)
281 {
282 	struct regmap *regmap = isc->regmap;
283 	u32 rlp_mode = isc->config.rlp_cfg_mode;
284 
285 	/*
286 	 * In sama5d2, the YUV planar modes and the YUYV modes are treated
287 	 * in the same way in RLP register.
288 	 * Normally, YYCC mode should be Luma(n) - Color B(n) - Color R (n)
289 	 * and YCYC should be Luma(n + 1) - Color B (n) - Luma (n) - Color R (n)
290 	 * but in sama5d2, the YCYC mode does not exist, and YYCC must be
291 	 * selected for both planar and interleaved modes, as in fact
292 	 * both modes are supported.
293 	 *
294 	 * Thus, if the YCYC mode is selected, replace it with the
295 	 * sama5d2-compliant mode which is YYCC .
296 	 */
297 	if ((rlp_mode & ISC_RLP_CFG_MODE_MASK) == ISC_RLP_CFG_MODE_YCYC) {
298 		rlp_mode &= ~ISC_RLP_CFG_MODE_MASK;
299 		rlp_mode |= ISC_RLP_CFG_MODE_YYCC;
300 	}
301 
302 	regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp,
303 			   ISC_RLP_CFG_MODE_MASK, rlp_mode);
304 }
305 
306 static void isc_sama5d2_adapt_pipeline(struct isc_device *isc)
307 {
308 	isc->try_config.bits_pipeline &= ISC_SAMA5D2_PIPELINE;
309 }
310 
311 /* Gamma table with gamma 1/2.2 */
312 static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = {
313 	/* 0 --> gamma 1/1.8 */
314 	{      0x65,  0x66002F,  0x950025,  0xBB0020,  0xDB001D,  0xF8001A,
315 	  0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012,
316 	  0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F,
317 	  0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E,
318 	  0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C,
319 	  0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B,
320 	  0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A,
321 	  0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A,
322 	  0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A,
323 	  0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009,
324 	  0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 },
325 
326 	/* 1 --> gamma 1/2 */
327 	{      0x7F,  0x800034,  0xB50028,  0xDE0021, 0x100001E, 0x11E001B,
328 	  0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013,
329 	  0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F,
330 	  0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D,
331 	  0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B,
332 	  0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A,
333 	  0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A,
334 	  0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009,
335 	  0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009,
336 	  0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009,
337 	  0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 },
338 
339 	/* 2 --> gamma 1/2.2 */
340 	{      0x99,  0x9B0038,  0xD4002A,  0xFF0023, 0x122001F, 0x141001B,
341 	  0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012,
342 	  0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F,
343 	  0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C,
344 	  0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B,
345 	  0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A,
346 	  0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009,
347 	  0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009,
348 	  0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008,
349 	  0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007,
350 	  0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 },
351 };
352 
353 static int isc_parse_dt(struct device *dev, struct isc_device *isc)
354 {
355 	struct device_node *np = dev->of_node;
356 	struct device_node *epn = NULL;
357 	struct isc_subdev_entity *subdev_entity;
358 	unsigned int flags;
359 	int ret;
360 
361 	INIT_LIST_HEAD(&isc->subdev_entities);
362 
363 	while (1) {
364 		struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 };
365 
366 		epn = of_graph_get_next_endpoint(np, epn);
367 		if (!epn)
368 			return 0;
369 
370 		ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
371 						 &v4l2_epn);
372 		if (ret) {
373 			ret = -EINVAL;
374 			dev_err(dev, "Could not parse the endpoint\n");
375 			break;
376 		}
377 
378 		subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity),
379 					     GFP_KERNEL);
380 		if (!subdev_entity) {
381 			ret = -ENOMEM;
382 			break;
383 		}
384 		subdev_entity->epn = epn;
385 
386 		flags = v4l2_epn.bus.parallel.flags;
387 
388 		if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
389 			subdev_entity->pfe_cfg0 = ISC_PFE_CFG0_HPOL_LOW;
390 
391 		if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
392 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_VPOL_LOW;
393 
394 		if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
395 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW;
396 
397 		if (v4l2_epn.bus_type == V4L2_MBUS_BT656)
398 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC |
399 					ISC_PFE_CFG0_CCIR656;
400 
401 		list_add_tail(&subdev_entity->list, &isc->subdev_entities);
402 	}
403 	of_node_put(epn);
404 
405 	return ret;
406 }
407 
408 static int microchip_isc_probe(struct platform_device *pdev)
409 {
410 	struct device *dev = &pdev->dev;
411 	struct isc_device *isc;
412 	struct resource *res;
413 	void __iomem *io_base;
414 	struct isc_subdev_entity *subdev_entity;
415 	int irq;
416 	int ret;
417 	u32 ver;
418 
419 	isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL);
420 	if (!isc)
421 		return -ENOMEM;
422 
423 	platform_set_drvdata(pdev, isc);
424 	isc->dev = dev;
425 
426 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
427 	io_base = devm_ioremap_resource(dev, res);
428 	if (IS_ERR(io_base))
429 		return PTR_ERR(io_base);
430 
431 	isc->regmap = devm_regmap_init_mmio(dev, io_base, &microchip_isc_regmap_config);
432 	if (IS_ERR(isc->regmap)) {
433 		ret = PTR_ERR(isc->regmap);
434 		dev_err(dev, "failed to init register map: %d\n", ret);
435 		return ret;
436 	}
437 
438 	irq = platform_get_irq(pdev, 0);
439 	if (irq < 0)
440 		return irq;
441 
442 	ret = devm_request_irq(dev, irq, microchip_isc_interrupt, 0,
443 			       "microchip-sama5d2-isc", isc);
444 	if (ret < 0) {
445 		dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
446 			irq, ret);
447 		return ret;
448 	}
449 
450 	isc->gamma_table = isc_sama5d2_gamma_table;
451 	isc->gamma_max = 2;
452 
453 	isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH;
454 	isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT;
455 
456 	isc->config_dpc = isc_sama5d2_config_dpc;
457 	isc->config_csc = isc_sama5d2_config_csc;
458 	isc->config_cbc = isc_sama5d2_config_cbc;
459 	isc->config_cc = isc_sama5d2_config_cc;
460 	isc->config_gam = isc_sama5d2_config_gam;
461 	isc->config_rlp = isc_sama5d2_config_rlp;
462 	isc->config_ctrls = isc_sama5d2_config_ctrls;
463 
464 	isc->adapt_pipeline = isc_sama5d2_adapt_pipeline;
465 
466 	isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET;
467 	isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET;
468 	isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET;
469 	isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET;
470 	isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET;
471 	isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET;
472 	isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET;
473 	isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET;
474 	isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET;
475 
476 	isc->controller_formats = sama5d2_controller_formats;
477 	isc->controller_formats_size = ARRAY_SIZE(sama5d2_controller_formats);
478 	isc->formats_list = sama5d2_formats_list;
479 	isc->formats_list_size = ARRAY_SIZE(sama5d2_formats_list);
480 
481 	/* sama5d2-isc - 8 bits per beat */
482 	isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8;
483 
484 	/* sama5d2-isc : ISPCK is required and mandatory */
485 	isc->ispck_required = true;
486 
487 	ret = microchip_isc_pipeline_init(isc);
488 	if (ret)
489 		return ret;
490 
491 	isc->hclock = devm_clk_get(dev, "hclock");
492 	if (IS_ERR(isc->hclock)) {
493 		ret = PTR_ERR(isc->hclock);
494 		dev_err(dev, "failed to get hclock: %d\n", ret);
495 		return ret;
496 	}
497 
498 	ret = clk_prepare_enable(isc->hclock);
499 	if (ret) {
500 		dev_err(dev, "failed to enable hclock: %d\n", ret);
501 		return ret;
502 	}
503 
504 	ret = microchip_isc_clk_init(isc);
505 	if (ret) {
506 		dev_err(dev, "failed to init isc clock: %d\n", ret);
507 		goto unprepare_hclk;
508 	}
509 	ret = v4l2_device_register(dev, &isc->v4l2_dev);
510 	if (ret) {
511 		dev_err(dev, "unable to register v4l2 device.\n");
512 		goto unprepare_clk;
513 	}
514 
515 	ret = isc_parse_dt(dev, isc);
516 	if (ret) {
517 		dev_err(dev, "fail to parse device tree\n");
518 		goto unregister_v4l2_device;
519 	}
520 
521 	if (list_empty(&isc->subdev_entities)) {
522 		dev_err(dev, "no subdev found\n");
523 		ret = -ENODEV;
524 		goto unregister_v4l2_device;
525 	}
526 
527 	list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
528 		struct v4l2_async_subdev *asd;
529 		struct fwnode_handle *fwnode =
530 			of_fwnode_handle(subdev_entity->epn);
531 
532 		v4l2_async_nf_init(&subdev_entity->notifier);
533 
534 		asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier,
535 						      fwnode,
536 						      struct v4l2_async_subdev);
537 
538 		of_node_put(subdev_entity->epn);
539 		subdev_entity->epn = NULL;
540 
541 		if (IS_ERR(asd)) {
542 			ret = PTR_ERR(asd);
543 			goto cleanup_subdev;
544 		}
545 
546 		subdev_entity->notifier.ops = &microchip_isc_async_ops;
547 
548 		ret = v4l2_async_nf_register(&isc->v4l2_dev,
549 					     &subdev_entity->notifier);
550 		if (ret) {
551 			dev_err(dev, "fail to register async notifier\n");
552 			goto cleanup_subdev;
553 		}
554 
555 		if (video_is_registered(&isc->video_dev))
556 			break;
557 	}
558 
559 	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
560 
561 	ret = isc_mc_init(isc, ver);
562 	if (ret < 0)
563 		goto isc_probe_mc_init_err;
564 
565 	pm_runtime_set_active(dev);
566 	pm_runtime_enable(dev);
567 	pm_request_idle(dev);
568 
569 	isc->ispck = isc->isc_clks[ISC_ISPCK].clk;
570 
571 	ret = clk_prepare_enable(isc->ispck);
572 	if (ret) {
573 		dev_err(dev, "failed to enable ispck: %d\n", ret);
574 		goto disable_pm;
575 	}
576 
577 	/* ispck should be greater or equal to hclock */
578 	ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock));
579 	if (ret) {
580 		dev_err(dev, "failed to set ispck rate: %d\n", ret);
581 		goto unprepare_clk;
582 	}
583 
584 	dev_info(dev, "Microchip ISC version %x\n", ver);
585 
586 	return 0;
587 
588 unprepare_clk:
589 	clk_disable_unprepare(isc->ispck);
590 
591 disable_pm:
592 	pm_runtime_disable(dev);
593 
594 isc_probe_mc_init_err:
595 	isc_mc_cleanup(isc);
596 
597 cleanup_subdev:
598 	microchip_isc_subdev_cleanup(isc);
599 
600 unregister_v4l2_device:
601 	v4l2_device_unregister(&isc->v4l2_dev);
602 
603 unprepare_hclk:
604 	clk_disable_unprepare(isc->hclock);
605 
606 	microchip_isc_clk_cleanup(isc);
607 
608 	return ret;
609 }
610 
611 static int microchip_isc_remove(struct platform_device *pdev)
612 {
613 	struct isc_device *isc = platform_get_drvdata(pdev);
614 
615 	pm_runtime_disable(&pdev->dev);
616 
617 	isc_mc_cleanup(isc);
618 
619 	microchip_isc_subdev_cleanup(isc);
620 
621 	v4l2_device_unregister(&isc->v4l2_dev);
622 
623 	clk_disable_unprepare(isc->ispck);
624 	clk_disable_unprepare(isc->hclock);
625 
626 	microchip_isc_clk_cleanup(isc);
627 
628 	return 0;
629 }
630 
631 static int __maybe_unused isc_runtime_suspend(struct device *dev)
632 {
633 	struct isc_device *isc = dev_get_drvdata(dev);
634 
635 	clk_disable_unprepare(isc->ispck);
636 	clk_disable_unprepare(isc->hclock);
637 
638 	return 0;
639 }
640 
641 static int __maybe_unused isc_runtime_resume(struct device *dev)
642 {
643 	struct isc_device *isc = dev_get_drvdata(dev);
644 	int ret;
645 
646 	ret = clk_prepare_enable(isc->hclock);
647 	if (ret)
648 		return ret;
649 
650 	ret = clk_prepare_enable(isc->ispck);
651 	if (ret)
652 		clk_disable_unprepare(isc->hclock);
653 
654 	return ret;
655 }
656 
657 static const struct dev_pm_ops microchip_isc_dev_pm_ops = {
658 	SET_RUNTIME_PM_OPS(isc_runtime_suspend, isc_runtime_resume, NULL)
659 };
660 
661 #if IS_ENABLED(CONFIG_OF)
662 static const struct of_device_id microchip_isc_of_match[] = {
663 	{ .compatible = "atmel,sama5d2-isc" },
664 	{ }
665 };
666 MODULE_DEVICE_TABLE(of, microchip_isc_of_match);
667 #endif
668 
669 static struct platform_driver microchip_isc_driver = {
670 	.probe	= microchip_isc_probe,
671 	.remove	= microchip_isc_remove,
672 	.driver	= {
673 		.name		= "microchip-sama5d2-isc",
674 		.pm		= &microchip_isc_dev_pm_ops,
675 		.of_match_table = of_match_ptr(microchip_isc_of_match),
676 	},
677 };
678 
679 module_platform_driver(microchip_isc_driver);
680 
681 MODULE_AUTHOR("Songjun Wu");
682 MODULE_DESCRIPTION("The V4L2 driver for Microchip-ISC");
683 MODULE_LICENSE("GPL v2");
684