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 	void __iomem *io_base;
413 	struct isc_subdev_entity *subdev_entity;
414 	int irq;
415 	int ret;
416 	u32 ver;
417 
418 	isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL);
419 	if (!isc)
420 		return -ENOMEM;
421 
422 	platform_set_drvdata(pdev, isc);
423 	isc->dev = dev;
424 
425 	io_base = devm_platform_ioremap_resource(pdev, 0);
426 	if (IS_ERR(io_base))
427 		return PTR_ERR(io_base);
428 
429 	isc->regmap = devm_regmap_init_mmio(dev, io_base, &microchip_isc_regmap_config);
430 	if (IS_ERR(isc->regmap)) {
431 		ret = PTR_ERR(isc->regmap);
432 		dev_err(dev, "failed to init register map: %d\n", ret);
433 		return ret;
434 	}
435 
436 	irq = platform_get_irq(pdev, 0);
437 	if (irq < 0)
438 		return irq;
439 
440 	ret = devm_request_irq(dev, irq, microchip_isc_interrupt, 0,
441 			       "microchip-sama5d2-isc", isc);
442 	if (ret < 0) {
443 		dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
444 			irq, ret);
445 		return ret;
446 	}
447 
448 	isc->gamma_table = isc_sama5d2_gamma_table;
449 	isc->gamma_max = 2;
450 
451 	isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH;
452 	isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT;
453 
454 	isc->config_dpc = isc_sama5d2_config_dpc;
455 	isc->config_csc = isc_sama5d2_config_csc;
456 	isc->config_cbc = isc_sama5d2_config_cbc;
457 	isc->config_cc = isc_sama5d2_config_cc;
458 	isc->config_gam = isc_sama5d2_config_gam;
459 	isc->config_rlp = isc_sama5d2_config_rlp;
460 	isc->config_ctrls = isc_sama5d2_config_ctrls;
461 
462 	isc->adapt_pipeline = isc_sama5d2_adapt_pipeline;
463 
464 	isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET;
465 	isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET;
466 	isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET;
467 	isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET;
468 	isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET;
469 	isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET;
470 	isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET;
471 	isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET;
472 	isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET;
473 
474 	isc->controller_formats = sama5d2_controller_formats;
475 	isc->controller_formats_size = ARRAY_SIZE(sama5d2_controller_formats);
476 	isc->formats_list = sama5d2_formats_list;
477 	isc->formats_list_size = ARRAY_SIZE(sama5d2_formats_list);
478 
479 	/* sama5d2-isc - 8 bits per beat */
480 	isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8;
481 
482 	/* sama5d2-isc : ISPCK is required and mandatory */
483 	isc->ispck_required = true;
484 
485 	ret = microchip_isc_pipeline_init(isc);
486 	if (ret)
487 		return ret;
488 
489 	isc->hclock = devm_clk_get(dev, "hclock");
490 	if (IS_ERR(isc->hclock)) {
491 		ret = PTR_ERR(isc->hclock);
492 		dev_err(dev, "failed to get hclock: %d\n", ret);
493 		return ret;
494 	}
495 
496 	ret = clk_prepare_enable(isc->hclock);
497 	if (ret) {
498 		dev_err(dev, "failed to enable hclock: %d\n", ret);
499 		return ret;
500 	}
501 
502 	ret = microchip_isc_clk_init(isc);
503 	if (ret) {
504 		dev_err(dev, "failed to init isc clock: %d\n", ret);
505 		goto unprepare_hclk;
506 	}
507 	ret = v4l2_device_register(dev, &isc->v4l2_dev);
508 	if (ret) {
509 		dev_err(dev, "unable to register v4l2 device.\n");
510 		goto unprepare_clk;
511 	}
512 
513 	ret = isc_parse_dt(dev, isc);
514 	if (ret) {
515 		dev_err(dev, "fail to parse device tree\n");
516 		goto unregister_v4l2_device;
517 	}
518 
519 	if (list_empty(&isc->subdev_entities)) {
520 		dev_err(dev, "no subdev found\n");
521 		ret = -ENODEV;
522 		goto unregister_v4l2_device;
523 	}
524 
525 	list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
526 		struct v4l2_async_subdev *asd;
527 		struct fwnode_handle *fwnode =
528 			of_fwnode_handle(subdev_entity->epn);
529 
530 		v4l2_async_nf_init(&subdev_entity->notifier);
531 
532 		asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier,
533 						      fwnode,
534 						      struct v4l2_async_subdev);
535 
536 		of_node_put(subdev_entity->epn);
537 		subdev_entity->epn = NULL;
538 
539 		if (IS_ERR(asd)) {
540 			ret = PTR_ERR(asd);
541 			goto cleanup_subdev;
542 		}
543 
544 		subdev_entity->notifier.ops = &microchip_isc_async_ops;
545 
546 		ret = v4l2_async_nf_register(&isc->v4l2_dev,
547 					     &subdev_entity->notifier);
548 		if (ret) {
549 			dev_err(dev, "fail to register async notifier\n");
550 			goto cleanup_subdev;
551 		}
552 
553 		if (video_is_registered(&isc->video_dev))
554 			break;
555 	}
556 
557 	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
558 
559 	ret = isc_mc_init(isc, ver);
560 	if (ret < 0)
561 		goto isc_probe_mc_init_err;
562 
563 	pm_runtime_set_active(dev);
564 	pm_runtime_enable(dev);
565 	pm_request_idle(dev);
566 
567 	isc->ispck = isc->isc_clks[ISC_ISPCK].clk;
568 
569 	ret = clk_prepare_enable(isc->ispck);
570 	if (ret) {
571 		dev_err(dev, "failed to enable ispck: %d\n", ret);
572 		goto disable_pm;
573 	}
574 
575 	/* ispck should be greater or equal to hclock */
576 	ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock));
577 	if (ret) {
578 		dev_err(dev, "failed to set ispck rate: %d\n", ret);
579 		goto unprepare_clk;
580 	}
581 
582 	dev_info(dev, "Microchip ISC version %x\n", ver);
583 
584 	return 0;
585 
586 unprepare_clk:
587 	clk_disable_unprepare(isc->ispck);
588 
589 disable_pm:
590 	pm_runtime_disable(dev);
591 
592 isc_probe_mc_init_err:
593 	isc_mc_cleanup(isc);
594 
595 cleanup_subdev:
596 	microchip_isc_subdev_cleanup(isc);
597 
598 unregister_v4l2_device:
599 	v4l2_device_unregister(&isc->v4l2_dev);
600 
601 unprepare_hclk:
602 	clk_disable_unprepare(isc->hclock);
603 
604 	microchip_isc_clk_cleanup(isc);
605 
606 	return ret;
607 }
608 
609 static void microchip_isc_remove(struct platform_device *pdev)
610 {
611 	struct isc_device *isc = platform_get_drvdata(pdev);
612 
613 	pm_runtime_disable(&pdev->dev);
614 
615 	isc_mc_cleanup(isc);
616 
617 	microchip_isc_subdev_cleanup(isc);
618 
619 	v4l2_device_unregister(&isc->v4l2_dev);
620 
621 	clk_disable_unprepare(isc->ispck);
622 	clk_disable_unprepare(isc->hclock);
623 
624 	microchip_isc_clk_cleanup(isc);
625 }
626 
627 static int __maybe_unused isc_runtime_suspend(struct device *dev)
628 {
629 	struct isc_device *isc = dev_get_drvdata(dev);
630 
631 	clk_disable_unprepare(isc->ispck);
632 	clk_disable_unprepare(isc->hclock);
633 
634 	return 0;
635 }
636 
637 static int __maybe_unused isc_runtime_resume(struct device *dev)
638 {
639 	struct isc_device *isc = dev_get_drvdata(dev);
640 	int ret;
641 
642 	ret = clk_prepare_enable(isc->hclock);
643 	if (ret)
644 		return ret;
645 
646 	ret = clk_prepare_enable(isc->ispck);
647 	if (ret)
648 		clk_disable_unprepare(isc->hclock);
649 
650 	return ret;
651 }
652 
653 static const struct dev_pm_ops microchip_isc_dev_pm_ops = {
654 	SET_RUNTIME_PM_OPS(isc_runtime_suspend, isc_runtime_resume, NULL)
655 };
656 
657 #if IS_ENABLED(CONFIG_OF)
658 static const struct of_device_id microchip_isc_of_match[] = {
659 	{ .compatible = "atmel,sama5d2-isc" },
660 	{ }
661 };
662 MODULE_DEVICE_TABLE(of, microchip_isc_of_match);
663 #endif
664 
665 static struct platform_driver microchip_isc_driver = {
666 	.probe	= microchip_isc_probe,
667 	.remove_new = microchip_isc_remove,
668 	.driver	= {
669 		.name		= "microchip-sama5d2-isc",
670 		.pm		= &microchip_isc_dev_pm_ops,
671 		.of_match_table = of_match_ptr(microchip_isc_of_match),
672 	},
673 };
674 
675 module_platform_driver(microchip_isc_driver);
676 
677 MODULE_AUTHOR("Songjun Wu");
678 MODULE_DESCRIPTION("The V4L2 driver for Microchip-ISC");
679 MODULE_LICENSE("GPL v2");
680