1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com>
4  * Copyright 2020-2022 Bootlin
5  * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/of_device.h>
12 #include <linux/phy/phy.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/reset.h>
17 #include <media/mipi-csi2.h>
18 #include <media/v4l2-ctrls.h>
19 #include <media/v4l2-device.h>
20 #include <media/v4l2-fwnode.h>
21 
22 #include "sun8i_a83t_dphy.h"
23 #include "sun8i_a83t_mipi_csi2.h"
24 #include "sun8i_a83t_mipi_csi2_reg.h"
25 
26 /* Format */
27 
28 static const struct sun8i_a83t_mipi_csi2_format
29 sun8i_a83t_mipi_csi2_formats[] = {
30 	{
31 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
32 		.data_type	= MIPI_CSI2_DT_RAW8,
33 		.bpp		= 8,
34 	},
35 	{
36 		.mbus_code	= MEDIA_BUS_FMT_SGBRG8_1X8,
37 		.data_type	= MIPI_CSI2_DT_RAW8,
38 		.bpp		= 8,
39 	},
40 	{
41 		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
42 		.data_type	= MIPI_CSI2_DT_RAW8,
43 		.bpp		= 8,
44 	},
45 	{
46 		.mbus_code	= MEDIA_BUS_FMT_SRGGB8_1X8,
47 		.data_type	= MIPI_CSI2_DT_RAW8,
48 		.bpp		= 8,
49 	},
50 	{
51 		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
52 		.data_type	= MIPI_CSI2_DT_RAW10,
53 		.bpp		= 10,
54 	},
55 	{
56 		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
57 		.data_type	= MIPI_CSI2_DT_RAW10,
58 		.bpp		= 10,
59 	},
60 	{
61 		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
62 		.data_type	= MIPI_CSI2_DT_RAW10,
63 		.bpp		= 10,
64 	},
65 	{
66 		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
67 		.data_type	= MIPI_CSI2_DT_RAW10,
68 		.bpp		= 10,
69 	},
70 };
71 
72 static const struct sun8i_a83t_mipi_csi2_format *
73 sun8i_a83t_mipi_csi2_format_find(u32 mbus_code)
74 {
75 	unsigned int i;
76 
77 	for (i = 0; i < ARRAY_SIZE(sun8i_a83t_mipi_csi2_formats); i++)
78 		if (sun8i_a83t_mipi_csi2_formats[i].mbus_code == mbus_code)
79 			return &sun8i_a83t_mipi_csi2_formats[i];
80 
81 	return NULL;
82 }
83 
84 /* Controller */
85 
86 static void
87 sun8i_a83t_mipi_csi2_init(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
88 {
89 	struct regmap *regmap = csi2_dev->regmap;
90 
91 	/*
92 	 * The Allwinner BSP sets various magic values on a bunch of registers.
93 	 * This is apparently a necessary initialization process that will cause
94 	 * the capture to fail with unsolicited interrupts hitting if skipped.
95 	 *
96 	 * Most of the registers are set to proper values later, except for the
97 	 * two reserved registers. They are said to hold a "hardware lock"
98 	 * value, without more information available.
99 	 */
100 
101 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG, 0);
102 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG,
103 		     SUN8I_A83T_MIPI_CSI2_CTRL_INIT_VALUE);
104 
105 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_REG, 0);
106 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_REG,
107 		     SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_INIT_VALUE);
108 
109 	regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG, 0);
110 	regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG,
111 		     SUN8I_A83T_DPHY_CTRL_INIT_VALUE);
112 
113 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD1_REG, 0);
114 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD1_REG,
115 		     SUN8I_A83T_MIPI_CSI2_RSVD1_HW_LOCK_VALUE);
116 
117 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD2_REG, 0);
118 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD2_REG,
119 		     SUN8I_A83T_MIPI_CSI2_RSVD2_HW_LOCK_VALUE);
120 
121 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG, 0);
122 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG,
123 		     SUN8I_A83T_MIPI_CSI2_CFG_INIT_VALUE);
124 }
125 
126 static void
127 sun8i_a83t_mipi_csi2_enable(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
128 {
129 	struct regmap *regmap = csi2_dev->regmap;
130 
131 	regmap_update_bits(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG,
132 			   SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN,
133 			   SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN);
134 }
135 
136 static void
137 sun8i_a83t_mipi_csi2_disable(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
138 {
139 	struct regmap *regmap = csi2_dev->regmap;
140 
141 	regmap_update_bits(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG,
142 			   SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN, 0);
143 
144 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG, 0);
145 }
146 
147 static void
148 sun8i_a83t_mipi_csi2_configure(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
149 {
150 	struct regmap *regmap = csi2_dev->regmap;
151 	unsigned int lanes_count =
152 		csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes;
153 	struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
154 	const struct sun8i_a83t_mipi_csi2_format *format;
155 	struct device *dev = csi2_dev->dev;
156 	u32 version = 0;
157 
158 	format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code);
159 	if (WARN_ON(!format))
160 		return;
161 
162 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG,
163 		     SUN8I_A83T_MIPI_CSI2_CTRL_RESET_N);
164 
165 	regmap_read(regmap, SUN8I_A83T_MIPI_CSI2_VERSION_REG, &version);
166 
167 	dev_dbg(dev, "A83T MIPI CSI-2 version: %04x\n", version);
168 
169 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG,
170 		     SUN8I_A83T_MIPI_CSI2_CFG_UNPKT_EN |
171 		     SUN8I_A83T_MIPI_CSI2_CFG_SYNC_DLY_CYCLE(8) |
172 		     SUN8I_A83T_MIPI_CSI2_CFG_N_CHANNEL(1) |
173 		     SUN8I_A83T_MIPI_CSI2_CFG_N_LANE(lanes_count));
174 
175 	/*
176 	 * Only a single virtual channel (index 0) is currently supported.
177 	 * While the registers do mention multiple physical channels being
178 	 * available (which can be configured to match a specific virtual
179 	 * channel or data type), it's unclear whether channels > 0 are actually
180 	 * connected and available and the reference source code only makes use
181 	 * of channel 0.
182 	 *
183 	 * Using extra channels would also require matching channels to be
184 	 * available on the CSI (and ISP) side, which is also unsure although
185 	 * some CSI implementations are said to support multiple channels for
186 	 * BT656 time-sharing.
187 	 *
188 	 * We still configure virtual channel numbers to ensure that virtual
189 	 * channel 0 only goes to channel 0.
190 	 */
191 
192 	regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_VCDT0_REG,
193 		     SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(3, 3) |
194 		     SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(2, 2) |
195 		     SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(1, 1) |
196 		     SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(0, 0) |
197 		     SUN8I_A83T_MIPI_CSI2_VCDT0_CH_DT(0, format->data_type));
198 }
199 
200 /* V4L2 Subdev */
201 
202 static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
203 {
204 	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
205 		v4l2_get_subdevdata(subdev);
206 	struct v4l2_subdev *source_subdev = csi2_dev->bridge.source_subdev;
207 	union phy_configure_opts dphy_opts = { 0 };
208 	struct phy_configure_opts_mipi_dphy *dphy_cfg = &dphy_opts.mipi_dphy;
209 	struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
210 	const struct sun8i_a83t_mipi_csi2_format *format;
211 	struct phy *dphy = csi2_dev->dphy;
212 	struct device *dev = csi2_dev->dev;
213 	struct v4l2_ctrl *ctrl;
214 	unsigned int lanes_count =
215 		csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes;
216 	unsigned long pixel_rate;
217 	int ret;
218 
219 	if (!source_subdev)
220 		return -ENODEV;
221 
222 	if (!on) {
223 		v4l2_subdev_call(source_subdev, video, s_stream, 0);
224 		ret = 0;
225 		goto disable;
226 	}
227 
228 	/* Runtime PM */
229 
230 	ret = pm_runtime_resume_and_get(dev);
231 	if (ret < 0)
232 		return ret;
233 
234 	/* Sensor pixel rate */
235 
236 	ctrl = v4l2_ctrl_find(source_subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
237 	if (!ctrl) {
238 		dev_err(dev, "missing sensor pixel rate\n");
239 		ret = -ENODEV;
240 		goto error_pm;
241 	}
242 
243 	pixel_rate = (unsigned long)v4l2_ctrl_g_ctrl_int64(ctrl);
244 	if (!pixel_rate) {
245 		dev_err(dev, "missing (zero) sensor pixel rate\n");
246 		ret = -ENODEV;
247 		goto error_pm;
248 	}
249 
250 	/* D-PHY */
251 
252 	if (!lanes_count) {
253 		dev_err(dev, "missing (zero) MIPI CSI-2 lanes count\n");
254 		ret = -ENODEV;
255 		goto error_pm;
256 	}
257 
258 	format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code);
259 	if (WARN_ON(!format)) {
260 		ret = -ENODEV;
261 		goto error_pm;
262 	}
263 
264 	phy_mipi_dphy_get_default_config(pixel_rate, format->bpp, lanes_count,
265 					 dphy_cfg);
266 
267 	/*
268 	 * Note that our hardware is using DDR, which is not taken in account by
269 	 * phy_mipi_dphy_get_default_config when calculating hs_clk_rate from
270 	 * the pixel rate, lanes count and bpp.
271 	 *
272 	 * The resulting clock rate is basically the symbol rate over the whole
273 	 * link. The actual clock rate is calculated with division by two since
274 	 * DDR samples both on rising and falling edges.
275 	 */
276 
277 	dev_dbg(dev, "A83T MIPI CSI-2 config:\n");
278 	dev_dbg(dev, "%ld pixels/s, %u bits/pixel, %u lanes, %lu Hz clock\n",
279 		pixel_rate, format->bpp, lanes_count,
280 		dphy_cfg->hs_clk_rate / 2);
281 
282 	ret = phy_reset(dphy);
283 	if (ret) {
284 		dev_err(dev, "failed to reset MIPI D-PHY\n");
285 		goto error_pm;
286 	}
287 
288 	ret = phy_configure(dphy, &dphy_opts);
289 	if (ret) {
290 		dev_err(dev, "failed to configure MIPI D-PHY\n");
291 		goto error_pm;
292 	}
293 
294 	/* Controller */
295 
296 	sun8i_a83t_mipi_csi2_configure(csi2_dev);
297 	sun8i_a83t_mipi_csi2_enable(csi2_dev);
298 
299 	/* D-PHY */
300 
301 	ret = phy_power_on(dphy);
302 	if (ret) {
303 		dev_err(dev, "failed to power on MIPI D-PHY\n");
304 		goto error_pm;
305 	}
306 
307 	/* Source */
308 
309 	ret = v4l2_subdev_call(source_subdev, video, s_stream, 1);
310 	if (ret && ret != -ENOIOCTLCMD)
311 		goto disable;
312 
313 	return 0;
314 
315 disable:
316 	phy_power_off(dphy);
317 	sun8i_a83t_mipi_csi2_disable(csi2_dev);
318 
319 error_pm:
320 	pm_runtime_put(dev);
321 
322 	return ret;
323 }
324 
325 static const struct v4l2_subdev_video_ops
326 sun8i_a83t_mipi_csi2_video_ops = {
327 	.s_stream	= sun8i_a83t_mipi_csi2_s_stream,
328 };
329 
330 static void
331 sun8i_a83t_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
332 {
333 	if (!sun8i_a83t_mipi_csi2_format_find(mbus_format->code))
334 		mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code;
335 
336 	mbus_format->field = V4L2_FIELD_NONE;
337 	mbus_format->colorspace = V4L2_COLORSPACE_RAW;
338 	mbus_format->quantization = V4L2_QUANTIZATION_DEFAULT;
339 	mbus_format->xfer_func = V4L2_XFER_FUNC_DEFAULT;
340 }
341 
342 static int sun8i_a83t_mipi_csi2_init_cfg(struct v4l2_subdev *subdev,
343 					 struct v4l2_subdev_state *state)
344 {
345 	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
346 		v4l2_get_subdevdata(subdev);
347 	unsigned int pad = SUN8I_A83T_MIPI_CSI2_PAD_SINK;
348 	struct v4l2_mbus_framefmt *mbus_format =
349 		v4l2_subdev_get_try_format(subdev, state, pad);
350 	struct mutex *lock = &csi2_dev->bridge.lock;
351 
352 	mutex_lock(lock);
353 
354 	mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code;
355 	mbus_format->width = 640;
356 	mbus_format->height = 480;
357 
358 	sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
359 
360 	mutex_unlock(lock);
361 
362 	return 0;
363 }
364 
365 static int
366 sun8i_a83t_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev,
367 				    struct v4l2_subdev_state *state,
368 				    struct v4l2_subdev_mbus_code_enum *code_enum)
369 {
370 	if (code_enum->index >= ARRAY_SIZE(sun8i_a83t_mipi_csi2_formats))
371 		return -EINVAL;
372 
373 	code_enum->code =
374 		sun8i_a83t_mipi_csi2_formats[code_enum->index].mbus_code;
375 
376 	return 0;
377 }
378 
379 static int sun8i_a83t_mipi_csi2_get_fmt(struct v4l2_subdev *subdev,
380 					struct v4l2_subdev_state *state,
381 					struct v4l2_subdev_format *format)
382 {
383 	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
384 		v4l2_get_subdevdata(subdev);
385 	struct v4l2_mbus_framefmt *mbus_format = &format->format;
386 	struct mutex *lock = &csi2_dev->bridge.lock;
387 
388 	mutex_lock(lock);
389 
390 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
391 		*mbus_format = *v4l2_subdev_get_try_format(subdev, state,
392 							   format->pad);
393 	else
394 		*mbus_format = csi2_dev->bridge.mbus_format;
395 
396 	mutex_unlock(lock);
397 
398 	return 0;
399 }
400 
401 static int sun8i_a83t_mipi_csi2_set_fmt(struct v4l2_subdev *subdev,
402 					struct v4l2_subdev_state *state,
403 					struct v4l2_subdev_format *format)
404 {
405 	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
406 		v4l2_get_subdevdata(subdev);
407 	struct v4l2_mbus_framefmt *mbus_format = &format->format;
408 	struct mutex *lock = &csi2_dev->bridge.lock;
409 
410 	mutex_lock(lock);
411 
412 	sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
413 
414 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
415 		*v4l2_subdev_get_try_format(subdev, state, format->pad) =
416 			*mbus_format;
417 	else
418 		csi2_dev->bridge.mbus_format = *mbus_format;
419 
420 	mutex_unlock(lock);
421 
422 	return 0;
423 }
424 
425 static const struct v4l2_subdev_pad_ops sun8i_a83t_mipi_csi2_pad_ops = {
426 	.init_cfg	= sun8i_a83t_mipi_csi2_init_cfg,
427 	.enum_mbus_code	= sun8i_a83t_mipi_csi2_enum_mbus_code,
428 	.get_fmt	= sun8i_a83t_mipi_csi2_get_fmt,
429 	.set_fmt	= sun8i_a83t_mipi_csi2_set_fmt,
430 };
431 
432 static const struct v4l2_subdev_ops sun8i_a83t_mipi_csi2_subdev_ops = {
433 	.video	= &sun8i_a83t_mipi_csi2_video_ops,
434 	.pad	= &sun8i_a83t_mipi_csi2_pad_ops,
435 };
436 
437 /* Media Entity */
438 
439 static const struct media_entity_operations sun8i_a83t_mipi_csi2_entity_ops = {
440 	.link_validate	= v4l2_subdev_link_validate,
441 };
442 
443 /* V4L2 Async */
444 
445 static int
446 sun8i_a83t_mipi_csi2_notifier_bound(struct v4l2_async_notifier *notifier,
447 				    struct v4l2_subdev *remote_subdev,
448 				    struct v4l2_async_subdev *async_subdev)
449 {
450 	struct v4l2_subdev *subdev = notifier->sd;
451 	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
452 		container_of(notifier, struct sun8i_a83t_mipi_csi2_device,
453 			     bridge.notifier);
454 	struct media_entity *sink_entity = &subdev->entity;
455 	struct media_entity *source_entity = &remote_subdev->entity;
456 	struct device *dev = csi2_dev->dev;
457 	int sink_pad_index = 0;
458 	int source_pad_index;
459 	int ret;
460 
461 	ret = media_entity_get_fwnode_pad(source_entity, remote_subdev->fwnode,
462 					  MEDIA_PAD_FL_SOURCE);
463 	if (ret < 0) {
464 		dev_err(dev, "missing source pad in external entity %s\n",
465 			source_entity->name);
466 		return -EINVAL;
467 	}
468 
469 	source_pad_index = ret;
470 
471 	dev_dbg(dev, "creating %s:%u -> %s:%u link\n", source_entity->name,
472 		source_pad_index, sink_entity->name, sink_pad_index);
473 
474 	ret = media_create_pad_link(source_entity, source_pad_index,
475 				    sink_entity, sink_pad_index,
476 				    MEDIA_LNK_FL_ENABLED |
477 				    MEDIA_LNK_FL_IMMUTABLE);
478 	if (ret) {
479 		dev_err(dev, "failed to create %s:%u -> %s:%u link\n",
480 			source_entity->name, source_pad_index,
481 			sink_entity->name, sink_pad_index);
482 		return ret;
483 	}
484 
485 	csi2_dev->bridge.source_subdev = remote_subdev;
486 
487 	return 0;
488 }
489 
490 static const struct v4l2_async_notifier_operations
491 sun8i_a83t_mipi_csi2_notifier_ops = {
492 	.bound	= sun8i_a83t_mipi_csi2_notifier_bound,
493 };
494 
495 /* Bridge */
496 
497 static int
498 sun8i_a83t_mipi_csi2_bridge_source_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
499 {
500 	struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier;
501 	struct v4l2_fwnode_endpoint *endpoint = &csi2_dev->bridge.endpoint;
502 	struct v4l2_async_subdev *subdev_async;
503 	struct fwnode_handle *handle;
504 	struct device *dev = csi2_dev->dev;
505 	int ret;
506 
507 	handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
508 						 FWNODE_GRAPH_ENDPOINT_NEXT);
509 	if (!handle)
510 		return -ENODEV;
511 
512 	endpoint->bus_type = V4L2_MBUS_CSI2_DPHY;
513 
514 	ret = v4l2_fwnode_endpoint_parse(handle, endpoint);
515 	if (ret)
516 		goto complete;
517 
518 	subdev_async =
519 		v4l2_async_nf_add_fwnode_remote(notifier, handle,
520 						struct v4l2_async_subdev);
521 	if (IS_ERR(subdev_async))
522 		ret = PTR_ERR(subdev_async);
523 
524 complete:
525 	fwnode_handle_put(handle);
526 
527 	return ret;
528 }
529 
530 static int
531 sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
532 {
533 	struct sun8i_a83t_mipi_csi2_bridge *bridge = &csi2_dev->bridge;
534 	struct v4l2_subdev *subdev = &bridge->subdev;
535 	struct v4l2_async_notifier *notifier = &bridge->notifier;
536 	struct media_pad *pads = bridge->pads;
537 	struct device *dev = csi2_dev->dev;
538 	bool notifier_registered = false;
539 	int ret;
540 
541 	mutex_init(&bridge->lock);
542 
543 	/* V4L2 Subdev */
544 
545 	v4l2_subdev_init(subdev, &sun8i_a83t_mipi_csi2_subdev_ops);
546 	strscpy(subdev->name, SUN8I_A83T_MIPI_CSI2_NAME, sizeof(subdev->name));
547 	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
548 	subdev->owner = THIS_MODULE;
549 	subdev->dev = dev;
550 
551 	v4l2_set_subdevdata(subdev, csi2_dev);
552 
553 	/* Media Entity */
554 
555 	subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
556 	subdev->entity.ops = &sun8i_a83t_mipi_csi2_entity_ops;
557 
558 	/* Media Pads */
559 
560 	pads[SUN8I_A83T_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
561 						    MEDIA_PAD_FL_MUST_CONNECT;
562 	pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
563 						      MEDIA_PAD_FL_MUST_CONNECT;
564 
565 	ret = media_entity_pads_init(&subdev->entity,
566 				     SUN8I_A83T_MIPI_CSI2_PAD_COUNT, pads);
567 	if (ret)
568 		return ret;
569 
570 	/* V4L2 Async */
571 
572 	v4l2_async_nf_init(notifier);
573 	notifier->ops = &sun8i_a83t_mipi_csi2_notifier_ops;
574 
575 	ret = sun8i_a83t_mipi_csi2_bridge_source_setup(csi2_dev);
576 	if (ret && ret != -ENODEV)
577 		goto error_v4l2_notifier_cleanup;
578 
579 	/* Only register the notifier when a sensor is connected. */
580 	if (ret != -ENODEV) {
581 		ret = v4l2_async_subdev_nf_register(subdev, notifier);
582 		if (ret < 0)
583 			goto error_v4l2_notifier_cleanup;
584 
585 		notifier_registered = true;
586 	}
587 
588 	/* V4L2 Subdev */
589 
590 	ret = v4l2_async_register_subdev(subdev);
591 	if (ret < 0)
592 		goto error_v4l2_notifier_unregister;
593 
594 	return 0;
595 
596 error_v4l2_notifier_unregister:
597 	if (notifier_registered)
598 		v4l2_async_nf_unregister(notifier);
599 
600 error_v4l2_notifier_cleanup:
601 	v4l2_async_nf_cleanup(notifier);
602 
603 	media_entity_cleanup(&subdev->entity);
604 
605 	return ret;
606 }
607 
608 static void
609 sun8i_a83t_mipi_csi2_bridge_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
610 {
611 	struct v4l2_subdev *subdev = &csi2_dev->bridge.subdev;
612 	struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier;
613 
614 	v4l2_async_unregister_subdev(subdev);
615 	v4l2_async_nf_unregister(notifier);
616 	v4l2_async_nf_cleanup(notifier);
617 	media_entity_cleanup(&subdev->entity);
618 }
619 
620 /* Platform */
621 
622 static int sun8i_a83t_mipi_csi2_suspend(struct device *dev)
623 {
624 	struct sun8i_a83t_mipi_csi2_device *csi2_dev = dev_get_drvdata(dev);
625 
626 	clk_disable_unprepare(csi2_dev->clock_misc);
627 	clk_disable_unprepare(csi2_dev->clock_mipi);
628 	clk_disable_unprepare(csi2_dev->clock_mod);
629 	reset_control_assert(csi2_dev->reset);
630 
631 	return 0;
632 }
633 
634 static int sun8i_a83t_mipi_csi2_resume(struct device *dev)
635 {
636 	struct sun8i_a83t_mipi_csi2_device *csi2_dev = dev_get_drvdata(dev);
637 	int ret;
638 
639 	ret = reset_control_deassert(csi2_dev->reset);
640 	if (ret) {
641 		dev_err(dev, "failed to deassert reset\n");
642 		return ret;
643 	}
644 
645 	ret = clk_prepare_enable(csi2_dev->clock_mod);
646 	if (ret) {
647 		dev_err(dev, "failed to enable module clock\n");
648 		goto error_reset;
649 	}
650 
651 	ret = clk_prepare_enable(csi2_dev->clock_mipi);
652 	if (ret) {
653 		dev_err(dev, "failed to enable MIPI clock\n");
654 		goto error_clock_mod;
655 	}
656 
657 	ret = clk_prepare_enable(csi2_dev->clock_misc);
658 	if (ret) {
659 		dev_err(dev, "failed to enable CSI misc clock\n");
660 		goto error_clock_mipi;
661 	}
662 
663 	sun8i_a83t_mipi_csi2_init(csi2_dev);
664 
665 	return 0;
666 
667 error_clock_mipi:
668 	clk_disable_unprepare(csi2_dev->clock_mipi);
669 
670 error_clock_mod:
671 	clk_disable_unprepare(csi2_dev->clock_mod);
672 
673 error_reset:
674 	reset_control_assert(csi2_dev->reset);
675 
676 	return ret;
677 }
678 
679 static const struct dev_pm_ops sun8i_a83t_mipi_csi2_pm_ops = {
680 	.runtime_suspend	= sun8i_a83t_mipi_csi2_suspend,
681 	.runtime_resume		= sun8i_a83t_mipi_csi2_resume,
682 };
683 
684 static const struct regmap_config sun8i_a83t_mipi_csi2_regmap_config = {
685 	.reg_bits       = 32,
686 	.reg_stride     = 4,
687 	.val_bits       = 32,
688 	.max_register	= 0x120,
689 };
690 
691 static int
692 sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev,
693 				     struct platform_device *platform_dev)
694 {
695 	struct device *dev = csi2_dev->dev;
696 	void __iomem *io_base;
697 	int ret;
698 
699 	/* Registers */
700 
701 	io_base = devm_platform_ioremap_resource(platform_dev, 0);
702 	if (IS_ERR(io_base))
703 		return PTR_ERR(io_base);
704 
705 	csi2_dev->regmap =
706 		devm_regmap_init_mmio_clk(dev, "bus", io_base,
707 					  &sun8i_a83t_mipi_csi2_regmap_config);
708 	if (IS_ERR(csi2_dev->regmap)) {
709 		dev_err(dev, "failed to init register map\n");
710 		return PTR_ERR(csi2_dev->regmap);
711 	}
712 
713 	/* Clocks */
714 
715 	csi2_dev->clock_mod = devm_clk_get(dev, "mod");
716 	if (IS_ERR(csi2_dev->clock_mod)) {
717 		dev_err(dev, "failed to acquire mod clock\n");
718 		return PTR_ERR(csi2_dev->clock_mod);
719 	}
720 
721 	ret = clk_set_rate_exclusive(csi2_dev->clock_mod, 297000000);
722 	if (ret) {
723 		dev_err(dev, "failed to set mod clock rate\n");
724 		return ret;
725 	}
726 
727 	csi2_dev->clock_mipi = devm_clk_get(dev, "mipi");
728 	if (IS_ERR(csi2_dev->clock_mipi)) {
729 		dev_err(dev, "failed to acquire mipi clock\n");
730 		ret = PTR_ERR(csi2_dev->clock_mipi);
731 		goto error_clock_rate_exclusive;
732 	}
733 
734 	csi2_dev->clock_misc = devm_clk_get(dev, "misc");
735 	if (IS_ERR(csi2_dev->clock_misc)) {
736 		dev_err(dev, "failed to acquire misc clock\n");
737 		ret = PTR_ERR(csi2_dev->clock_misc);
738 		goto error_clock_rate_exclusive;
739 	}
740 
741 	/* Reset */
742 
743 	csi2_dev->reset = devm_reset_control_get_shared(dev, NULL);
744 	if (IS_ERR(csi2_dev->reset)) {
745 		dev_err(dev, "failed to get reset controller\n");
746 		ret = PTR_ERR(csi2_dev->reset);
747 		goto error_clock_rate_exclusive;
748 	}
749 
750 	/* D-PHY */
751 
752 	ret = sun8i_a83t_dphy_register(csi2_dev);
753 	if (ret) {
754 		dev_err(dev, "failed to initialize MIPI D-PHY\n");
755 		goto error_clock_rate_exclusive;
756 	}
757 
758 	/* Runtime PM */
759 
760 	pm_runtime_enable(dev);
761 
762 	return 0;
763 
764 error_clock_rate_exclusive:
765 	clk_rate_exclusive_put(csi2_dev->clock_mod);
766 
767 	return ret;
768 }
769 
770 static void
771 sun8i_a83t_mipi_csi2_resources_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
772 {
773 	pm_runtime_disable(csi2_dev->dev);
774 	phy_exit(csi2_dev->dphy);
775 	clk_rate_exclusive_put(csi2_dev->clock_mod);
776 }
777 
778 static int sun8i_a83t_mipi_csi2_probe(struct platform_device *platform_dev)
779 {
780 	struct sun8i_a83t_mipi_csi2_device *csi2_dev;
781 	struct device *dev = &platform_dev->dev;
782 	int ret;
783 
784 	csi2_dev = devm_kzalloc(dev, sizeof(*csi2_dev), GFP_KERNEL);
785 	if (!csi2_dev)
786 		return -ENOMEM;
787 
788 	csi2_dev->dev = dev;
789 	platform_set_drvdata(platform_dev, csi2_dev);
790 
791 	ret = sun8i_a83t_mipi_csi2_resources_setup(csi2_dev, platform_dev);
792 	if (ret)
793 		return ret;
794 
795 	ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev);
796 	if (ret)
797 		goto error_resources;
798 
799 	return 0;
800 
801 error_resources:
802 	sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev);
803 
804 	return ret;
805 }
806 
807 static void sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev)
808 {
809 	struct sun8i_a83t_mipi_csi2_device *csi2_dev =
810 		platform_get_drvdata(platform_dev);
811 
812 	sun8i_a83t_mipi_csi2_bridge_cleanup(csi2_dev);
813 	sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev);
814 }
815 
816 static const struct of_device_id sun8i_a83t_mipi_csi2_of_match[] = {
817 	{ .compatible	= "allwinner,sun8i-a83t-mipi-csi2" },
818 	{},
819 };
820 MODULE_DEVICE_TABLE(of, sun8i_a83t_mipi_csi2_of_match);
821 
822 static struct platform_driver sun8i_a83t_mipi_csi2_platform_driver = {
823 	.probe	= sun8i_a83t_mipi_csi2_probe,
824 	.remove_new = sun8i_a83t_mipi_csi2_remove,
825 	.driver	= {
826 		.name		= SUN8I_A83T_MIPI_CSI2_NAME,
827 		.of_match_table	= of_match_ptr(sun8i_a83t_mipi_csi2_of_match),
828 		.pm		= &sun8i_a83t_mipi_csi2_pm_ops,
829 	},
830 };
831 module_platform_driver(sun8i_a83t_mipi_csi2_platform_driver);
832 
833 MODULE_DESCRIPTION("Allwinner A83T MIPI CSI-2 and D-PHY Controller Driver");
834 MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>");
835 MODULE_LICENSE("GPL");
836