1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for Renesas R-Car VIN
4  *
5  * Copyright (C) 2016 Renesas Electronics Corp.
6  * Copyright (C) 2011-2013 Renesas Solutions Corp.
7  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8  * Copyright (C) 2008 Magnus Damm
9  *
10  * Based on the soc-camera rcar_vin driver
11  */
12 
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/of_graph.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/slab.h>
20 #include <linux/sys_soc.h>
21 
22 #include <media/v4l2-async.h>
23 #include <media/v4l2-fwnode.h>
24 #include <media/v4l2-mc.h>
25 
26 #include "rcar-vin.h"
27 
28 /*
29  * The companion CSI-2 receiver driver (rcar-csi2) is known
30  * and we know it has one source pad (pad 0) and four sink
31  * pads (pad 1-4). So to translate a pad on the remote
32  * CSI-2 receiver to/from the VIN internal channel number simply
33  * subtract/add one from the pad/channel number.
34  */
35 #define rvin_group_csi_pad_to_channel(pad) ((pad) - 1)
36 #define rvin_group_csi_channel_to_pad(channel) ((channel) + 1)
37 
38 /*
39  * Not all VINs are created equal, master VINs control the
40  * routing for other VIN's. We can figure out which VIN is
41  * master by looking at a VINs id.
42  */
43 #define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
44 
45 #define v4l2_dev_to_vin(d)	container_of(d, struct rvin_dev, v4l2_dev)
46 
47 /* -----------------------------------------------------------------------------
48  * Gen3 Group Allocator
49  */
50 
51 /* FIXME:  This should if we find a system that supports more
52  * than one group for the whole system be replaced with a linked
53  * list of groups. And eventually all of this should be replaced
54  * with a global device allocator API.
55  *
56  * But for now this works as on all supported systems there will
57  * be only one group for all instances.
58  */
59 
60 static DEFINE_MUTEX(rvin_group_lock);
61 static struct rvin_group *rvin_group_data;
62 
rvin_group_cleanup(struct rvin_group * group)63 static void rvin_group_cleanup(struct rvin_group *group)
64 {
65 	media_device_cleanup(&group->mdev);
66 	mutex_destroy(&group->lock);
67 }
68 
rvin_group_init(struct rvin_group * group,struct rvin_dev * vin,int (* link_setup)(struct rvin_dev *),const struct media_device_ops * ops)69 static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,
70 			   int (*link_setup)(struct rvin_dev *),
71 			   const struct media_device_ops *ops)
72 {
73 	struct media_device *mdev = &group->mdev;
74 	const struct of_device_id *match;
75 	struct device_node *np;
76 
77 	mutex_init(&group->lock);
78 
79 	/* Count number of VINs in the system */
80 	group->count = 0;
81 	for_each_matching_node(np, vin->dev->driver->of_match_table)
82 		if (of_device_is_available(np))
83 			group->count++;
84 
85 	vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
86 
87 	group->link_setup = link_setup;
88 
89 	mdev->dev = vin->dev;
90 	mdev->ops = ops;
91 
92 	match = of_match_node(vin->dev->driver->of_match_table,
93 			      vin->dev->of_node);
94 
95 	strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
96 	strscpy(mdev->model, match->compatible, sizeof(mdev->model));
97 	snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
98 		 dev_name(mdev->dev));
99 
100 	media_device_init(mdev);
101 
102 	return 0;
103 }
104 
rvin_group_release(struct kref * kref)105 static void rvin_group_release(struct kref *kref)
106 {
107 	struct rvin_group *group =
108 		container_of(kref, struct rvin_group, refcount);
109 
110 	mutex_lock(&rvin_group_lock);
111 
112 	rvin_group_data = NULL;
113 
114 	rvin_group_cleanup(group);
115 
116 	kfree(group);
117 
118 	mutex_unlock(&rvin_group_lock);
119 }
120 
rvin_group_get(struct rvin_dev * vin,int (* link_setup)(struct rvin_dev *),const struct media_device_ops * ops)121 static int rvin_group_get(struct rvin_dev *vin,
122 			  int (*link_setup)(struct rvin_dev *),
123 			  const struct media_device_ops *ops)
124 {
125 	struct rvin_group *group;
126 	u32 id;
127 	int ret;
128 
129 	/* Make sure VIN id is present and sane */
130 	ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
131 	if (ret) {
132 		vin_err(vin, "%pOF: No renesas,id property found\n",
133 			vin->dev->of_node);
134 		return -EINVAL;
135 	}
136 
137 	if (id >= RCAR_VIN_NUM) {
138 		vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
139 			vin->dev->of_node, id);
140 		return -EINVAL;
141 	}
142 
143 	/* Join or create a VIN group */
144 	mutex_lock(&rvin_group_lock);
145 	if (rvin_group_data) {
146 		group = rvin_group_data;
147 		kref_get(&group->refcount);
148 	} else {
149 		group = kzalloc(sizeof(*group), GFP_KERNEL);
150 		if (!group) {
151 			ret = -ENOMEM;
152 			goto err_group;
153 		}
154 
155 		ret = rvin_group_init(group, vin, link_setup, ops);
156 		if (ret) {
157 			kfree(group);
158 			vin_err(vin, "Failed to initialize group\n");
159 			goto err_group;
160 		}
161 
162 		kref_init(&group->refcount);
163 
164 		rvin_group_data = group;
165 	}
166 	mutex_unlock(&rvin_group_lock);
167 
168 	/* Add VIN to group */
169 	mutex_lock(&group->lock);
170 
171 	if (group->vin[id]) {
172 		vin_err(vin, "Duplicate renesas,id property value %u\n", id);
173 		mutex_unlock(&group->lock);
174 		kref_put(&group->refcount, rvin_group_release);
175 		return -EINVAL;
176 	}
177 
178 	group->vin[id] = vin;
179 
180 	vin->id = id;
181 	vin->group = group;
182 	vin->v4l2_dev.mdev = &group->mdev;
183 
184 	mutex_unlock(&group->lock);
185 
186 	return 0;
187 err_group:
188 	mutex_unlock(&rvin_group_lock);
189 	return ret;
190 }
191 
rvin_group_put(struct rvin_dev * vin)192 static void rvin_group_put(struct rvin_dev *vin)
193 {
194 	struct rvin_group *group = vin->group;
195 
196 	mutex_lock(&group->lock);
197 
198 	vin->group = NULL;
199 	vin->v4l2_dev.mdev = NULL;
200 
201 	if (WARN_ON(group->vin[vin->id] != vin))
202 		goto out;
203 
204 	group->vin[vin->id] = NULL;
205 out:
206 	mutex_unlock(&group->lock);
207 
208 	kref_put(&group->refcount, rvin_group_release);
209 }
210 
211 /* group lock should be held when calling this function. */
rvin_group_entity_to_remote_id(struct rvin_group * group,struct media_entity * entity)212 static int rvin_group_entity_to_remote_id(struct rvin_group *group,
213 					  struct media_entity *entity)
214 {
215 	struct v4l2_subdev *sd;
216 	unsigned int i;
217 
218 	sd = media_entity_to_v4l2_subdev(entity);
219 
220 	for (i = 0; i < RVIN_REMOTES_MAX; i++)
221 		if (group->remotes[i].subdev == sd)
222 			return i;
223 
224 	return -ENODEV;
225 }
226 
rvin_group_notify_complete(struct v4l2_async_notifier * notifier)227 static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
228 {
229 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
230 	unsigned int i;
231 	int ret;
232 
233 	ret = media_device_register(&vin->group->mdev);
234 	if (ret)
235 		return ret;
236 
237 	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
238 	if (ret) {
239 		vin_err(vin, "Failed to register subdev nodes\n");
240 		return ret;
241 	}
242 
243 	/* Register all video nodes for the group. */
244 	for (i = 0; i < RCAR_VIN_NUM; i++) {
245 		if (vin->group->vin[i] &&
246 		    !video_is_registered(&vin->group->vin[i]->vdev)) {
247 			ret = rvin_v4l2_register(vin->group->vin[i]);
248 			if (ret)
249 				return ret;
250 		}
251 	}
252 
253 	return vin->group->link_setup(vin);
254 }
255 
rvin_group_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)256 static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
257 				     struct v4l2_subdev *subdev,
258 				     struct v4l2_async_subdev *asd)
259 {
260 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
261 	unsigned int i;
262 
263 	for (i = 0; i < RCAR_VIN_NUM; i++)
264 		if (vin->group->vin[i])
265 			rvin_v4l2_unregister(vin->group->vin[i]);
266 
267 	mutex_lock(&vin->group->lock);
268 
269 	for (i = 0; i < RVIN_CSI_MAX; i++) {
270 		if (vin->group->remotes[i].asd != asd)
271 			continue;
272 		vin->group->remotes[i].subdev = NULL;
273 		vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
274 		break;
275 	}
276 
277 	mutex_unlock(&vin->group->lock);
278 
279 	media_device_unregister(&vin->group->mdev);
280 }
281 
rvin_group_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)282 static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
283 				   struct v4l2_subdev *subdev,
284 				   struct v4l2_async_subdev *asd)
285 {
286 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
287 	unsigned int i;
288 
289 	mutex_lock(&vin->group->lock);
290 
291 	for (i = 0; i < RVIN_CSI_MAX; i++) {
292 		if (vin->group->remotes[i].asd != asd)
293 			continue;
294 		vin->group->remotes[i].subdev = subdev;
295 		vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
296 		break;
297 	}
298 
299 	mutex_unlock(&vin->group->lock);
300 
301 	return 0;
302 }
303 
304 static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
305 	.bound = rvin_group_notify_bound,
306 	.unbind = rvin_group_notify_unbind,
307 	.complete = rvin_group_notify_complete,
308 };
309 
rvin_group_parse_of(struct rvin_dev * vin,unsigned int port,unsigned int id)310 static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port,
311 			       unsigned int id)
312 {
313 	struct fwnode_handle *ep, *fwnode;
314 	struct v4l2_fwnode_endpoint vep = {
315 		.bus_type = V4L2_MBUS_CSI2_DPHY,
316 	};
317 	struct v4l2_async_subdev *asd;
318 	int ret;
319 
320 	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), port, id, 0);
321 	if (!ep)
322 		return 0;
323 
324 	fwnode = fwnode_graph_get_remote_endpoint(ep);
325 	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
326 	fwnode_handle_put(ep);
327 	if (ret) {
328 		vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
329 		ret = -EINVAL;
330 		goto out;
331 	}
332 
333 	asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode,
334 				       struct v4l2_async_subdev);
335 	if (IS_ERR(asd)) {
336 		ret = PTR_ERR(asd);
337 		goto out;
338 	}
339 
340 	vin->group->remotes[vep.base.id].asd = asd;
341 
342 	vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
343 		to_of_node(fwnode), vep.base.id);
344 out:
345 	fwnode_handle_put(fwnode);
346 
347 	return ret;
348 }
349 
rvin_group_notifier_cleanup(struct rvin_dev * vin)350 static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
351 {
352 	mutex_lock(&vin->group->lock);
353 	if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
354 		v4l2_async_nf_unregister(&vin->group->notifier);
355 		v4l2_async_nf_cleanup(&vin->group->notifier);
356 	}
357 	mutex_unlock(&vin->group->lock);
358 }
359 
rvin_group_notifier_init(struct rvin_dev * vin,unsigned int port,unsigned int max_id)360 static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,
361 				    unsigned int max_id)
362 {
363 	unsigned int count = 0, vin_mask = 0;
364 	unsigned int i, id;
365 	int ret;
366 
367 	mutex_lock(&vin->group->lock);
368 
369 	/* If not all VIN's are registered don't register the notifier. */
370 	for (i = 0; i < RCAR_VIN_NUM; i++) {
371 		if (vin->group->vin[i]) {
372 			count++;
373 			vin_mask |= BIT(i);
374 		}
375 	}
376 
377 	if (vin->group->count != count) {
378 		mutex_unlock(&vin->group->lock);
379 		return 0;
380 	}
381 
382 	mutex_unlock(&vin->group->lock);
383 
384 	v4l2_async_nf_init(&vin->group->notifier);
385 
386 	/*
387 	 * Some subdevices may overlap but the parser function can handle it and
388 	 * each subdevice will only be registered once with the group notifier.
389 	 */
390 	for (i = 0; i < RCAR_VIN_NUM; i++) {
391 		if (!(vin_mask & BIT(i)))
392 			continue;
393 
394 		for (id = 0; id < max_id; id++) {
395 			if (vin->group->remotes[id].asd)
396 				continue;
397 
398 			ret = rvin_group_parse_of(vin->group->vin[i], port, id);
399 			if (ret)
400 				return ret;
401 		}
402 	}
403 
404 	if (list_empty(&vin->group->notifier.asd_list))
405 		return 0;
406 
407 	vin->group->notifier.ops = &rvin_group_notify_ops;
408 	ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier);
409 	if (ret < 0) {
410 		vin_err(vin, "Notifier registration failed\n");
411 		v4l2_async_nf_cleanup(&vin->group->notifier);
412 		return ret;
413 	}
414 
415 	return 0;
416 }
417 
418 /* -----------------------------------------------------------------------------
419  * Controls
420  */
421 
rvin_s_ctrl(struct v4l2_ctrl * ctrl)422 static int rvin_s_ctrl(struct v4l2_ctrl *ctrl)
423 {
424 	struct rvin_dev *vin =
425 		container_of(ctrl->handler, struct rvin_dev, ctrl_handler);
426 
427 	switch (ctrl->id) {
428 	case V4L2_CID_ALPHA_COMPONENT:
429 		rvin_set_alpha(vin, ctrl->val);
430 		break;
431 	}
432 
433 	return 0;
434 }
435 
436 static const struct v4l2_ctrl_ops rvin_ctrl_ops = {
437 	.s_ctrl = rvin_s_ctrl,
438 };
439 
rvin_free_controls(struct rvin_dev * vin)440 static void rvin_free_controls(struct rvin_dev *vin)
441 {
442 	v4l2_ctrl_handler_free(&vin->ctrl_handler);
443 	vin->vdev.ctrl_handler = NULL;
444 }
445 
rvin_create_controls(struct rvin_dev * vin,struct v4l2_subdev * subdev)446 static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)
447 {
448 	int ret;
449 
450 	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
451 	if (ret < 0)
452 		return ret;
453 
454 	/* The VIN directly deals with alpha component. */
455 	v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
456 			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
457 
458 	if (vin->ctrl_handler.error) {
459 		ret = vin->ctrl_handler.error;
460 		rvin_free_controls(vin);
461 		return ret;
462 	}
463 
464 	/* For the non-MC mode add controls from the subdevice. */
465 	if (subdev) {
466 		ret = v4l2_ctrl_add_handler(&vin->ctrl_handler,
467 					    subdev->ctrl_handler, NULL, true);
468 		if (ret < 0) {
469 			rvin_free_controls(vin);
470 			return ret;
471 		}
472 	}
473 
474 	vin->vdev.ctrl_handler = &vin->ctrl_handler;
475 
476 	return 0;
477 }
478 
479 /* -----------------------------------------------------------------------------
480  * Async notifier
481  */
482 
rvin_find_pad(struct v4l2_subdev * sd,int direction)483 static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
484 {
485 	unsigned int pad;
486 
487 	if (sd->entity.num_pads <= 1)
488 		return 0;
489 
490 	for (pad = 0; pad < sd->entity.num_pads; pad++)
491 		if (sd->entity.pads[pad].flags & direction)
492 			return pad;
493 
494 	return -EINVAL;
495 }
496 
497 /* -----------------------------------------------------------------------------
498  * Parallel async notifier
499  */
500 
501 /* The vin lock should be held when calling the subdevice attach and detach */
rvin_parallel_subdevice_attach(struct rvin_dev * vin,struct v4l2_subdev * subdev)502 static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
503 					  struct v4l2_subdev *subdev)
504 {
505 	struct v4l2_subdev_mbus_code_enum code = {
506 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
507 	};
508 	int ret;
509 
510 	/* Find source and sink pad of remote subdevice */
511 	ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
512 	if (ret < 0)
513 		return ret;
514 	vin->parallel.source_pad = ret;
515 
516 	ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
517 	vin->parallel.sink_pad = ret < 0 ? 0 : ret;
518 
519 	if (vin->info->use_mc) {
520 		vin->parallel.subdev = subdev;
521 		return 0;
522 	}
523 
524 	/* Find compatible subdevices mbus format */
525 	vin->mbus_code = 0;
526 	code.index = 0;
527 	code.pad = vin->parallel.source_pad;
528 	while (!vin->mbus_code &&
529 	       !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
530 		code.index++;
531 		switch (code.code) {
532 		case MEDIA_BUS_FMT_YUYV8_1X16:
533 		case MEDIA_BUS_FMT_UYVY8_1X16:
534 		case MEDIA_BUS_FMT_UYVY8_2X8:
535 		case MEDIA_BUS_FMT_UYVY10_2X10:
536 		case MEDIA_BUS_FMT_RGB888_1X24:
537 			vin->mbus_code = code.code;
538 			vin_dbg(vin, "Found media bus format for %s: %d\n",
539 				subdev->name, vin->mbus_code);
540 			break;
541 		default:
542 			break;
543 		}
544 	}
545 
546 	if (!vin->mbus_code) {
547 		vin_err(vin, "Unsupported media bus format for %s\n",
548 			subdev->name);
549 		return -EINVAL;
550 	}
551 
552 	/* Read tvnorms */
553 	ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms);
554 	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
555 		return ret;
556 
557 	/* Read standard */
558 	vin->std = V4L2_STD_UNKNOWN;
559 	ret = v4l2_subdev_call(subdev, video, g_std, &vin->std);
560 	if (ret < 0 && ret != -ENOIOCTLCMD)
561 		return ret;
562 
563 	/* Add the controls */
564 	ret = rvin_create_controls(vin, subdev);
565 	if (ret < 0)
566 		return ret;
567 
568 	vin->parallel.subdev = subdev;
569 
570 	return 0;
571 }
572 
rvin_parallel_subdevice_detach(struct rvin_dev * vin)573 static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
574 {
575 	rvin_v4l2_unregister(vin);
576 	vin->parallel.subdev = NULL;
577 
578 	if (!vin->info->use_mc)
579 		rvin_free_controls(vin);
580 }
581 
rvin_parallel_notify_complete(struct v4l2_async_notifier * notifier)582 static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
583 {
584 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
585 	struct media_entity *source;
586 	struct media_entity *sink;
587 	int ret;
588 
589 	ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
590 	if (ret < 0) {
591 		vin_err(vin, "Failed to register subdev nodes\n");
592 		return ret;
593 	}
594 
595 	if (!video_is_registered(&vin->vdev)) {
596 		ret = rvin_v4l2_register(vin);
597 		if (ret < 0)
598 			return ret;
599 	}
600 
601 	if (!vin->info->use_mc)
602 		return 0;
603 
604 	/* If we're running with media-controller, link the subdevs. */
605 	source = &vin->parallel.subdev->entity;
606 	sink = &vin->vdev.entity;
607 
608 	ret = media_create_pad_link(source, vin->parallel.source_pad,
609 				    sink, vin->parallel.sink_pad, 0);
610 	if (ret)
611 		vin_err(vin, "Error adding link from %s to %s: %d\n",
612 			source->name, sink->name, ret);
613 
614 	return ret;
615 }
616 
rvin_parallel_notify_unbind(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)617 static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
618 					struct v4l2_subdev *subdev,
619 					struct v4l2_async_subdev *asd)
620 {
621 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
622 
623 	vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name);
624 
625 	mutex_lock(&vin->lock);
626 	rvin_parallel_subdevice_detach(vin);
627 	mutex_unlock(&vin->lock);
628 }
629 
rvin_parallel_notify_bound(struct v4l2_async_notifier * notifier,struct v4l2_subdev * subdev,struct v4l2_async_subdev * asd)630 static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
631 				      struct v4l2_subdev *subdev,
632 				      struct v4l2_async_subdev *asd)
633 {
634 	struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
635 	int ret;
636 
637 	mutex_lock(&vin->lock);
638 	ret = rvin_parallel_subdevice_attach(vin, subdev);
639 	mutex_unlock(&vin->lock);
640 	if (ret)
641 		return ret;
642 
643 	v4l2_set_subdev_hostdata(subdev, vin);
644 
645 	vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
646 		subdev->name, vin->parallel.source_pad,
647 		vin->parallel.sink_pad);
648 
649 	return 0;
650 }
651 
652 static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = {
653 	.bound = rvin_parallel_notify_bound,
654 	.unbind = rvin_parallel_notify_unbind,
655 	.complete = rvin_parallel_notify_complete,
656 };
657 
rvin_parallel_parse_of(struct rvin_dev * vin)658 static int rvin_parallel_parse_of(struct rvin_dev *vin)
659 {
660 	struct fwnode_handle *ep, *fwnode;
661 	struct v4l2_fwnode_endpoint vep = {
662 		.bus_type = V4L2_MBUS_UNKNOWN,
663 	};
664 	struct v4l2_async_subdev *asd;
665 	int ret;
666 
667 	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0);
668 	if (!ep)
669 		return 0;
670 
671 	fwnode = fwnode_graph_get_remote_endpoint(ep);
672 	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
673 	fwnode_handle_put(ep);
674 	if (ret) {
675 		vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
676 		ret = -EINVAL;
677 		goto out;
678 	}
679 
680 	switch (vep.bus_type) {
681 	case V4L2_MBUS_PARALLEL:
682 	case V4L2_MBUS_BT656:
683 		vin_dbg(vin, "Found %s media bus\n",
684 			vep.bus_type == V4L2_MBUS_PARALLEL ?
685 			"PARALLEL" : "BT656");
686 		vin->parallel.mbus_type = vep.bus_type;
687 		vin->parallel.bus = vep.bus.parallel;
688 		break;
689 	default:
690 		vin_err(vin, "Unknown media bus type\n");
691 		ret = -EINVAL;
692 		goto out;
693 	}
694 
695 	asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode,
696 				       struct v4l2_async_subdev);
697 	if (IS_ERR(asd)) {
698 		ret = PTR_ERR(asd);
699 		goto out;
700 	}
701 
702 	vin->parallel.asd = asd;
703 
704 	vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode));
705 out:
706 	fwnode_handle_put(fwnode);
707 
708 	return ret;
709 }
710 
rvin_parallel_cleanup(struct rvin_dev * vin)711 static void rvin_parallel_cleanup(struct rvin_dev *vin)
712 {
713 	v4l2_async_nf_unregister(&vin->notifier);
714 	v4l2_async_nf_cleanup(&vin->notifier);
715 }
716 
rvin_parallel_init(struct rvin_dev * vin)717 static int rvin_parallel_init(struct rvin_dev *vin)
718 {
719 	int ret;
720 
721 	v4l2_async_nf_init(&vin->notifier);
722 
723 	ret = rvin_parallel_parse_of(vin);
724 	if (ret)
725 		return ret;
726 
727 	if (!vin->parallel.asd)
728 		return -ENODEV;
729 
730 	vin_dbg(vin, "Found parallel subdevice %pOF\n",
731 		to_of_node(vin->parallel.asd->match.fwnode));
732 
733 	vin->notifier.ops = &rvin_parallel_notify_ops;
734 	ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier);
735 	if (ret < 0) {
736 		vin_err(vin, "Notifier registration failed\n");
737 		v4l2_async_nf_cleanup(&vin->notifier);
738 		return ret;
739 	}
740 
741 	return 0;
742 }
743 
744 /* -----------------------------------------------------------------------------
745  * CSI-2
746  */
747 
rvin_csi2_get_mask(struct rvin_dev * vin,enum rvin_csi_id csi_id,unsigned char channel)748 static unsigned int rvin_csi2_get_mask(struct rvin_dev *vin,
749 				       enum rvin_csi_id csi_id,
750 				       unsigned char channel)
751 {
752 	const struct rvin_group_route *route;
753 	unsigned int mask = 0;
754 
755 	for (route = vin->info->routes; route->mask; route++) {
756 		if (route->vin == vin->id &&
757 		    route->csi == csi_id &&
758 		    route->channel == channel) {
759 			vin_dbg(vin,
760 				"Adding route: vin: %d csi: %d channel: %d\n",
761 				route->vin, route->csi, route->channel);
762 			mask |= route->mask;
763 		}
764 	}
765 
766 	return mask;
767 }
768 
769 /*
770  * Link setup for the links between a VIN and a CSI-2 receiver is a bit
771  * complex. The reason for this is that the register controlling routing
772  * is not present in each VIN instance. There are special VINs which
773  * control routing for themselves and other VINs. There are not many
774  * different possible links combinations that can be enabled at the same
775  * time, therefor all already enabled links which are controlled by a
776  * master VIN need to be taken into account when making the decision
777  * if a new link can be enabled or not.
778  *
779  * 1. Find out which VIN the link the user tries to enable is connected to.
780  * 2. Lookup which master VIN controls the links for this VIN.
781  * 3. Start with a bitmask with all bits set.
782  * 4. For each previously enabled link from the master VIN bitwise AND its
783  *    route mask (see documentation for mask in struct rvin_group_route)
784  *    with the bitmask.
785  * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask.
786  * 6. If the bitmask is not empty at this point the new link can be enabled
787  *    while keeping all previous links enabled. Update the CHSEL value of the
788  *    master VIN and inform the user that the link could be enabled.
789  *
790  * Please note that no link can be enabled if any VIN in the group is
791  * currently open.
792  */
rvin_csi2_link_notify(struct media_link * link,u32 flags,unsigned int notification)793 static int rvin_csi2_link_notify(struct media_link *link, u32 flags,
794 				 unsigned int notification)
795 {
796 	struct rvin_group *group = container_of(link->graph_obj.mdev,
797 						struct rvin_group, mdev);
798 	unsigned int master_id, channel, mask_new, i;
799 	unsigned int mask = ~0;
800 	struct media_entity *entity;
801 	struct video_device *vdev;
802 	struct media_pad *csi_pad;
803 	struct rvin_dev *vin = NULL;
804 	int csi_id, ret;
805 
806 	ret = v4l2_pipeline_link_notify(link, flags, notification);
807 	if (ret)
808 		return ret;
809 
810 	/* Only care about link enablement for VIN nodes. */
811 	if (!(flags & MEDIA_LNK_FL_ENABLED) ||
812 	    !is_media_entity_v4l2_video_device(link->sink->entity))
813 		return 0;
814 
815 	/*
816 	 * Don't allow link changes if any entity in the graph is
817 	 * streaming, modifying the CHSEL register fields can disrupt
818 	 * running streams.
819 	 */
820 	media_device_for_each_entity(entity, &group->mdev)
821 		if (entity->stream_count)
822 			return -EBUSY;
823 
824 	mutex_lock(&group->lock);
825 
826 	/* Find the master VIN that controls the routes. */
827 	vdev = media_entity_to_video_device(link->sink->entity);
828 	vin = container_of(vdev, struct rvin_dev, vdev);
829 	master_id = rvin_group_id_to_master(vin->id);
830 
831 	if (WARN_ON(!group->vin[master_id])) {
832 		ret = -ENODEV;
833 		goto out;
834 	}
835 
836 	/* Build a mask for already enabled links. */
837 	for (i = master_id; i < master_id + 4; i++) {
838 		if (!group->vin[i])
839 			continue;
840 
841 		/* Get remote CSI-2, if any. */
842 		csi_pad = media_entity_remote_pad(
843 				&group->vin[i]->vdev.entity.pads[0]);
844 		if (!csi_pad)
845 			continue;
846 
847 		csi_id = rvin_group_entity_to_remote_id(group, csi_pad->entity);
848 		channel = rvin_group_csi_pad_to_channel(csi_pad->index);
849 
850 		mask &= rvin_csi2_get_mask(group->vin[i], csi_id, channel);
851 	}
852 
853 	/* Add the new link to the existing mask and check if it works. */
854 	csi_id = rvin_group_entity_to_remote_id(group, link->source->entity);
855 
856 	if (csi_id == -ENODEV) {
857 		struct v4l2_subdev *sd;
858 
859 		/*
860 		 * Make sure the source entity subdevice is registered as
861 		 * a parallel input of one of the enabled VINs if it is not
862 		 * one of the CSI-2 subdevices.
863 		 *
864 		 * No hardware configuration required for parallel inputs,
865 		 * we can return here.
866 		 */
867 		sd = media_entity_to_v4l2_subdev(link->source->entity);
868 		for (i = 0; i < RCAR_VIN_NUM; i++) {
869 			if (group->vin[i] &&
870 			    group->vin[i]->parallel.subdev == sd) {
871 				group->vin[i]->is_csi = false;
872 				ret = 0;
873 				goto out;
874 			}
875 		}
876 
877 		vin_err(vin, "Subdevice %s not registered to any VIN\n",
878 			link->source->entity->name);
879 		ret = -ENODEV;
880 		goto out;
881 	}
882 
883 	channel = rvin_group_csi_pad_to_channel(link->source->index);
884 	mask_new = mask & rvin_csi2_get_mask(vin, csi_id, channel);
885 	vin_dbg(vin, "Try link change mask: 0x%x new: 0x%x\n", mask, mask_new);
886 
887 	if (!mask_new) {
888 		ret = -EMLINK;
889 		goto out;
890 	}
891 
892 	/* New valid CHSEL found, set the new value. */
893 	ret = rvin_set_channel_routing(group->vin[master_id], __ffs(mask_new));
894 	if (ret)
895 		goto out;
896 
897 	vin->is_csi = true;
898 
899 out:
900 	mutex_unlock(&group->lock);
901 
902 	return ret;
903 }
904 
905 static const struct media_device_ops rvin_csi2_media_ops = {
906 	.link_notify = rvin_csi2_link_notify,
907 };
908 
rvin_csi2_setup_links(struct rvin_dev * vin)909 static int rvin_csi2_setup_links(struct rvin_dev *vin)
910 {
911 	const struct rvin_group_route *route;
912 	int ret = -EINVAL;
913 
914 	/* Create all media device links between VINs and CSI-2's. */
915 	mutex_lock(&vin->group->lock);
916 	for (route = vin->info->routes; route->mask; route++) {
917 		struct media_pad *source_pad, *sink_pad;
918 		struct media_entity *source, *sink;
919 		unsigned int source_idx;
920 
921 		/* Check that VIN is part of the group. */
922 		if (!vin->group->vin[route->vin])
923 			continue;
924 
925 		/* Check that VIN' master is part of the group. */
926 		if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
927 			continue;
928 
929 		/* Check that CSI-2 is part of the group. */
930 		if (!vin->group->remotes[route->csi].subdev)
931 			continue;
932 
933 		source = &vin->group->remotes[route->csi].subdev->entity;
934 		source_idx = rvin_group_csi_channel_to_pad(route->channel);
935 		source_pad = &source->pads[source_idx];
936 
937 		sink = &vin->group->vin[route->vin]->vdev.entity;
938 		sink_pad = &sink->pads[0];
939 
940 		/* Skip if link already exists. */
941 		if (media_entity_find_link(source_pad, sink_pad))
942 			continue;
943 
944 		ret = media_create_pad_link(source, source_idx, sink, 0, 0);
945 		if (ret) {
946 			vin_err(vin, "Error adding link from %s to %s\n",
947 				source->name, sink->name);
948 			break;
949 		}
950 	}
951 	mutex_unlock(&vin->group->lock);
952 
953 	return ret;
954 }
955 
rvin_csi2_cleanup(struct rvin_dev * vin)956 static void rvin_csi2_cleanup(struct rvin_dev *vin)
957 {
958 	rvin_parallel_cleanup(vin);
959 	rvin_group_notifier_cleanup(vin);
960 	rvin_group_put(vin);
961 	rvin_free_controls(vin);
962 }
963 
rvin_csi2_init(struct rvin_dev * vin)964 static int rvin_csi2_init(struct rvin_dev *vin)
965 {
966 	int ret;
967 
968 	vin->pad.flags = MEDIA_PAD_FL_SINK;
969 	ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
970 	if (ret)
971 		return ret;
972 
973 	ret = rvin_create_controls(vin, NULL);
974 	if (ret < 0)
975 		return ret;
976 
977 	ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops);
978 	if (ret)
979 		goto err_controls;
980 
981 	/* It's OK to not have a parallel subdevice. */
982 	ret = rvin_parallel_init(vin);
983 	if (ret && ret != -ENODEV)
984 		goto err_group;
985 
986 	ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX);
987 	if (ret)
988 		goto err_parallel;
989 
990 	return 0;
991 err_parallel:
992 	rvin_parallel_cleanup(vin);
993 err_group:
994 	rvin_group_put(vin);
995 err_controls:
996 	rvin_free_controls(vin);
997 
998 	return ret;
999 }
1000 
1001 /* -----------------------------------------------------------------------------
1002  * ISP
1003  */
1004 
rvin_isp_setup_links(struct rvin_dev * vin)1005 static int rvin_isp_setup_links(struct rvin_dev *vin)
1006 {
1007 	unsigned int i;
1008 	int ret = -EINVAL;
1009 
1010 	/* Create all media device links between VINs and ISP's. */
1011 	mutex_lock(&vin->group->lock);
1012 	for (i = 0; i < RCAR_VIN_NUM; i++) {
1013 		struct media_pad *source_pad, *sink_pad;
1014 		struct media_entity *source, *sink;
1015 		unsigned int source_slot = i / 8;
1016 		unsigned int source_idx = i % 8 + 1;
1017 
1018 		if (!vin->group->vin[i])
1019 			continue;
1020 
1021 		/* Check that ISP is part of the group. */
1022 		if (!vin->group->remotes[source_slot].subdev)
1023 			continue;
1024 
1025 		source = &vin->group->remotes[source_slot].subdev->entity;
1026 		source_pad = &source->pads[source_idx];
1027 
1028 		sink = &vin->group->vin[i]->vdev.entity;
1029 		sink_pad = &sink->pads[0];
1030 
1031 		/* Skip if link already exists. */
1032 		if (media_entity_find_link(source_pad, sink_pad))
1033 			continue;
1034 
1035 		ret = media_create_pad_link(source, source_idx, sink, 0,
1036 					    MEDIA_LNK_FL_ENABLED |
1037 					    MEDIA_LNK_FL_IMMUTABLE);
1038 		if (ret) {
1039 			vin_err(vin, "Error adding link from %s to %s\n",
1040 				source->name, sink->name);
1041 			break;
1042 		}
1043 	}
1044 	mutex_unlock(&vin->group->lock);
1045 
1046 	return ret;
1047 }
1048 
rvin_isp_cleanup(struct rvin_dev * vin)1049 static void rvin_isp_cleanup(struct rvin_dev *vin)
1050 {
1051 	rvin_group_notifier_cleanup(vin);
1052 	rvin_group_put(vin);
1053 	rvin_free_controls(vin);
1054 }
1055 
rvin_isp_init(struct rvin_dev * vin)1056 static int rvin_isp_init(struct rvin_dev *vin)
1057 {
1058 	int ret;
1059 
1060 	vin->pad.flags = MEDIA_PAD_FL_SINK;
1061 	ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
1062 	if (ret)
1063 		return ret;
1064 
1065 	ret = rvin_create_controls(vin, NULL);
1066 	if (ret < 0)
1067 		return ret;
1068 
1069 	ret = rvin_group_get(vin, rvin_isp_setup_links, NULL);
1070 	if (ret)
1071 		goto err_controls;
1072 
1073 	ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX);
1074 	if (ret)
1075 		goto err_group;
1076 
1077 	return 0;
1078 err_group:
1079 	rvin_group_put(vin);
1080 err_controls:
1081 	rvin_free_controls(vin);
1082 
1083 	return ret;
1084 }
1085 
1086 /* -----------------------------------------------------------------------------
1087  * Suspend / Resume
1088  */
1089 
rvin_suspend(struct device * dev)1090 static int __maybe_unused rvin_suspend(struct device *dev)
1091 {
1092 	struct rvin_dev *vin = dev_get_drvdata(dev);
1093 
1094 	if (vin->state != RUNNING)
1095 		return 0;
1096 
1097 	rvin_stop_streaming(vin);
1098 
1099 	vin->state = SUSPENDED;
1100 
1101 	return 0;
1102 }
1103 
rvin_resume(struct device * dev)1104 static int __maybe_unused rvin_resume(struct device *dev)
1105 {
1106 	struct rvin_dev *vin = dev_get_drvdata(dev);
1107 
1108 	if (vin->state != SUSPENDED)
1109 		return 0;
1110 
1111 	/*
1112 	 * Restore group master CHSEL setting.
1113 	 *
1114 	 * This needs to be done by every VIN resuming not only the master
1115 	 * as we don't know if and in which order the master VINs will
1116 	 * be resumed.
1117 	 */
1118 	if (vin->info->use_mc) {
1119 		unsigned int master_id = rvin_group_id_to_master(vin->id);
1120 		struct rvin_dev *master = vin->group->vin[master_id];
1121 		int ret;
1122 
1123 		if (WARN_ON(!master))
1124 			return -ENODEV;
1125 
1126 		ret = rvin_set_channel_routing(master, master->chsel);
1127 		if (ret)
1128 			return ret;
1129 	}
1130 
1131 	return rvin_start_streaming(vin);
1132 }
1133 
1134 /* -----------------------------------------------------------------------------
1135  * Platform Device Driver
1136  */
1137 
1138 static const struct rvin_info rcar_info_h1 = {
1139 	.model = RCAR_H1,
1140 	.use_mc = false,
1141 	.max_width = 2048,
1142 	.max_height = 2048,
1143 };
1144 
1145 static const struct rvin_info rcar_info_m1 = {
1146 	.model = RCAR_M1,
1147 	.use_mc = false,
1148 	.max_width = 2048,
1149 	.max_height = 2048,
1150 };
1151 
1152 static const struct rvin_info rcar_info_gen2 = {
1153 	.model = RCAR_GEN2,
1154 	.use_mc = false,
1155 	.max_width = 2048,
1156 	.max_height = 2048,
1157 };
1158 
1159 static const struct rvin_group_route rcar_info_r8a774e1_routes[] = {
1160 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1161 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1162 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1163 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1164 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1165 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1166 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1167 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1168 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1169 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1170 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1171 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1172 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1173 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1174 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1175 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1176 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1177 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1178 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1179 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1180 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1181 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1182 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1183 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1184 	{ /* Sentinel */ }
1185 };
1186 
1187 static const struct rvin_info rcar_info_r8a774e1 = {
1188 	.model = RCAR_GEN3,
1189 	.use_mc = true,
1190 	.max_width = 4096,
1191 	.max_height = 4096,
1192 	.routes = rcar_info_r8a774e1_routes,
1193 };
1194 
1195 static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
1196 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1197 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1198 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1199 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1200 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1201 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1202 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1203 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1204 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1205 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1206 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1207 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1208 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1209 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1210 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1211 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1212 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1213 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1214 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
1215 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1216 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1217 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1218 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1219 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1220 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1221 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1222 	{ .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1223 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1224 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1225 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1226 	{ .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1227 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1228 	{ /* Sentinel */ }
1229 };
1230 
1231 static const struct rvin_info rcar_info_r8a7795 = {
1232 	.model = RCAR_GEN3,
1233 	.use_mc = true,
1234 	.nv12 = true,
1235 	.max_width = 4096,
1236 	.max_height = 4096,
1237 	.routes = rcar_info_r8a7795_routes,
1238 };
1239 
1240 static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = {
1241 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1242 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1243 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 0, .mask = BIT(2) | BIT(5) },
1244 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1245 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 1, .mask = BIT(1) },
1246 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1247 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1248 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1249 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 1, .mask = BIT(5) },
1250 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 2, .mask = BIT(0) },
1251 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1252 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1253 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1254 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1255 	{ .csi = RVIN_CSI21, .channel = 2, .vin = 2, .mask = BIT(5) },
1256 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1257 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
1258 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 3, .mask = BIT(2) },
1259 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1260 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1261 	{ .csi = RVIN_CSI21, .channel = 3, .vin = 3, .mask = BIT(5) },
1262 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1263 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1264 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 4, .mask = BIT(2) | BIT(5) },
1265 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1266 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 5, .mask = BIT(1) },
1267 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1268 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(3) },
1269 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1270 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 5, .mask = BIT(5) },
1271 	{ .csi = RVIN_CSI21, .channel = 0, .vin = 6, .mask = BIT(0) },
1272 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1273 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1274 	{ .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1275 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1276 	{ .csi = RVIN_CSI21, .channel = 2, .vin = 6, .mask = BIT(5) },
1277 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1278 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
1279 	{ .csi = RVIN_CSI21, .channel = 1, .vin = 7, .mask = BIT(2) },
1280 	{ .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1281 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1282 	{ .csi = RVIN_CSI21, .channel = 3, .vin = 7, .mask = BIT(5) },
1283 	{ /* Sentinel */ }
1284 };
1285 
1286 static const struct rvin_info rcar_info_r8a7795es1 = {
1287 	.model = RCAR_GEN3,
1288 	.use_mc = true,
1289 	.max_width = 4096,
1290 	.max_height = 4096,
1291 	.routes = rcar_info_r8a7795es1_routes,
1292 };
1293 
1294 static const struct rvin_group_route rcar_info_r8a7796_routes[] = {
1295 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1296 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1297 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1298 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1299 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1300 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1301 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1302 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1303 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1304 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1305 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1306 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
1307 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1308 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1309 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1310 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1311 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1312 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1313 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(3) },
1314 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1315 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
1316 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1317 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
1318 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1319 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
1320 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
1321 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
1322 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1323 	{ /* Sentinel */ }
1324 };
1325 
1326 static const struct rvin_info rcar_info_r8a7796 = {
1327 	.model = RCAR_GEN3,
1328 	.use_mc = true,
1329 	.nv12 = true,
1330 	.max_width = 4096,
1331 	.max_height = 4096,
1332 	.routes = rcar_info_r8a7796_routes,
1333 };
1334 
1335 static const struct rvin_group_route rcar_info_r8a77965_routes[] = {
1336 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1337 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
1338 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1339 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
1340 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1341 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1342 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
1343 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
1344 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1345 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
1346 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1347 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
1348 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1349 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
1350 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1351 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
1352 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1353 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
1354 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
1355 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
1356 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1357 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1358 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
1359 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
1360 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
1361 	{ .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
1362 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
1363 	{ .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
1364 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
1365 	{ .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
1366 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
1367 	{ .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
1368 	{ /* Sentinel */ }
1369 };
1370 
1371 static const struct rvin_info rcar_info_r8a77965 = {
1372 	.model = RCAR_GEN3,
1373 	.use_mc = true,
1374 	.nv12 = true,
1375 	.max_width = 4096,
1376 	.max_height = 4096,
1377 	.routes = rcar_info_r8a77965_routes,
1378 };
1379 
1380 static const struct rvin_group_route rcar_info_r8a77970_routes[] = {
1381 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1382 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1383 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
1384 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1385 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1386 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1387 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1388 	{ /* Sentinel */ }
1389 };
1390 
1391 static const struct rvin_info rcar_info_r8a77970 = {
1392 	.model = RCAR_GEN3,
1393 	.use_mc = true,
1394 	.max_width = 4096,
1395 	.max_height = 4096,
1396 	.routes = rcar_info_r8a77970_routes,
1397 };
1398 
1399 static const struct rvin_group_route rcar_info_r8a77980_routes[] = {
1400 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1401 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1402 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1403 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1404 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1405 	{ .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1406 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1407 	{ .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1408 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1409 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
1410 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1411 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1412 	{ .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1413 	{ .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1414 	{ .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1415 	{ .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1416 	{ /* Sentinel */ }
1417 };
1418 
1419 static const struct rvin_info rcar_info_r8a77980 = {
1420 	.model = RCAR_GEN3,
1421 	.use_mc = true,
1422 	.nv12 = true,
1423 	.max_width = 4096,
1424 	.max_height = 4096,
1425 	.routes = rcar_info_r8a77980_routes,
1426 };
1427 
1428 static const struct rvin_group_route rcar_info_r8a77990_routes[] = {
1429 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1430 	{ .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1431 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
1432 	{ .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1433 	{ /* Sentinel */ }
1434 };
1435 
1436 static const struct rvin_info rcar_info_r8a77990 = {
1437 	.model = RCAR_GEN3,
1438 	.use_mc = true,
1439 	.nv12 = true,
1440 	.max_width = 4096,
1441 	.max_height = 4096,
1442 	.routes = rcar_info_r8a77990_routes,
1443 };
1444 
1445 static const struct rvin_group_route rcar_info_r8a77995_routes[] = {
1446 	{ /* Sentinel */ }
1447 };
1448 
1449 static const struct rvin_info rcar_info_r8a77995 = {
1450 	.model = RCAR_GEN3,
1451 	.use_mc = true,
1452 	.nv12 = true,
1453 	.max_width = 4096,
1454 	.max_height = 4096,
1455 	.routes = rcar_info_r8a77995_routes,
1456 };
1457 
1458 static const struct rvin_info rcar_info_r8a779a0 = {
1459 	.model = RCAR_GEN3,
1460 	.use_mc = true,
1461 	.use_isp = true,
1462 	.nv12 = true,
1463 	.max_width = 4096,
1464 	.max_height = 4096,
1465 };
1466 
1467 static const struct of_device_id rvin_of_id_table[] = {
1468 	{
1469 		.compatible = "renesas,vin-r8a774a1",
1470 		.data = &rcar_info_r8a7796,
1471 	},
1472 	{
1473 		.compatible = "renesas,vin-r8a774b1",
1474 		.data = &rcar_info_r8a77965,
1475 	},
1476 	{
1477 		.compatible = "renesas,vin-r8a774c0",
1478 		.data = &rcar_info_r8a77990,
1479 	},
1480 	{
1481 		.compatible = "renesas,vin-r8a774e1",
1482 		.data = &rcar_info_r8a774e1,
1483 	},
1484 	{
1485 		.compatible = "renesas,vin-r8a7778",
1486 		.data = &rcar_info_m1,
1487 	},
1488 	{
1489 		.compatible = "renesas,vin-r8a7779",
1490 		.data = &rcar_info_h1,
1491 	},
1492 	{
1493 		.compatible = "renesas,rcar-gen2-vin",
1494 		.data = &rcar_info_gen2,
1495 	},
1496 	{
1497 		.compatible = "renesas,vin-r8a7795",
1498 		.data = &rcar_info_r8a7795,
1499 	},
1500 	{
1501 		.compatible = "renesas,vin-r8a7796",
1502 		.data = &rcar_info_r8a7796,
1503 	},
1504 	{
1505 		.compatible = "renesas,vin-r8a77961",
1506 		.data = &rcar_info_r8a7796,
1507 	},
1508 	{
1509 		.compatible = "renesas,vin-r8a77965",
1510 		.data = &rcar_info_r8a77965,
1511 	},
1512 	{
1513 		.compatible = "renesas,vin-r8a77970",
1514 		.data = &rcar_info_r8a77970,
1515 	},
1516 	{
1517 		.compatible = "renesas,vin-r8a77980",
1518 		.data = &rcar_info_r8a77980,
1519 	},
1520 	{
1521 		.compatible = "renesas,vin-r8a77990",
1522 		.data = &rcar_info_r8a77990,
1523 	},
1524 	{
1525 		.compatible = "renesas,vin-r8a77995",
1526 		.data = &rcar_info_r8a77995,
1527 	},
1528 	{
1529 		.compatible = "renesas,vin-r8a779a0",
1530 		.data = &rcar_info_r8a779a0,
1531 	},
1532 	{ /* Sentinel */ },
1533 };
1534 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
1535 
1536 static const struct soc_device_attribute r8a7795es1[] = {
1537 	{
1538 		.soc_id = "r8a7795", .revision = "ES1.*",
1539 		.data = &rcar_info_r8a7795es1,
1540 	},
1541 	{ /* Sentinel */ }
1542 };
1543 
rcar_vin_probe(struct platform_device * pdev)1544 static int rcar_vin_probe(struct platform_device *pdev)
1545 {
1546 	const struct soc_device_attribute *attr;
1547 	struct rvin_dev *vin;
1548 	int irq, ret;
1549 
1550 	vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
1551 	if (!vin)
1552 		return -ENOMEM;
1553 
1554 	vin->dev = &pdev->dev;
1555 	vin->info = of_device_get_match_data(&pdev->dev);
1556 	vin->alpha = 0xff;
1557 
1558 	/*
1559 	 * Special care is needed on r8a7795 ES1.x since it
1560 	 * uses different routing than r8a7795 ES2.0.
1561 	 */
1562 	attr = soc_device_match(r8a7795es1);
1563 	if (attr)
1564 		vin->info = attr->data;
1565 
1566 	vin->base = devm_platform_ioremap_resource(pdev, 0);
1567 	if (IS_ERR(vin->base))
1568 		return PTR_ERR(vin->base);
1569 
1570 	irq = platform_get_irq(pdev, 0);
1571 	if (irq < 0)
1572 		return irq;
1573 
1574 	ret = rvin_dma_register(vin, irq);
1575 	if (ret)
1576 		return ret;
1577 
1578 	platform_set_drvdata(pdev, vin);
1579 
1580 	if (vin->info->use_isp)
1581 		ret = rvin_isp_init(vin);
1582 	else if (vin->info->use_mc)
1583 		ret = rvin_csi2_init(vin);
1584 	else
1585 		ret = rvin_parallel_init(vin);
1586 
1587 	if (ret) {
1588 		rvin_dma_unregister(vin);
1589 		return ret;
1590 	}
1591 
1592 	pm_suspend_ignore_children(&pdev->dev, true);
1593 	pm_runtime_enable(&pdev->dev);
1594 
1595 	return 0;
1596 }
1597 
rcar_vin_remove(struct platform_device * pdev)1598 static int rcar_vin_remove(struct platform_device *pdev)
1599 {
1600 	struct rvin_dev *vin = platform_get_drvdata(pdev);
1601 
1602 	pm_runtime_disable(&pdev->dev);
1603 
1604 	rvin_v4l2_unregister(vin);
1605 
1606 	if (vin->info->use_isp)
1607 		rvin_isp_cleanup(vin);
1608 	else if (vin->info->use_mc)
1609 		rvin_csi2_cleanup(vin);
1610 	else
1611 		rvin_parallel_cleanup(vin);
1612 
1613 	rvin_dma_unregister(vin);
1614 
1615 	return 0;
1616 }
1617 
1618 static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
1619 
1620 static struct platform_driver rcar_vin_driver = {
1621 	.driver = {
1622 		.name = "rcar-vin",
1623 		.pm = &rvin_pm_ops,
1624 		.of_match_table = rvin_of_id_table,
1625 	},
1626 	.probe = rcar_vin_probe,
1627 	.remove = rcar_vin_remove,
1628 };
1629 
1630 module_platform_driver(rcar_vin_driver);
1631 
1632 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
1633 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
1634 MODULE_LICENSE("GPL");
1635