rcar-core.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274
  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. #include <linux/module.h>
  13. #include <linux/of.h>
  14. #include <linux/of_device.h>
  15. #include <linux/of_graph.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/pm_runtime.h>
  18. #include <linux/slab.h>
  19. #include <linux/sys_soc.h>
  20. #include <media/v4l2-async.h>
  21. #include <media/v4l2-fwnode.h>
  22. #include <media/v4l2-mc.h>
  23. #include "rcar-vin.h"
  24. /*
  25. * The companion CSI-2 receiver driver (rcar-csi2) is known
  26. * and we know it has one source pad (pad 0) and four sink
  27. * pads (pad 1-4). So to translate a pad on the remote
  28. * CSI-2 receiver to/from the VIN internal channel number simply
  29. * subtract/add one from the pad/channel number.
  30. */
  31. #define rvin_group_csi_pad_to_channel(pad) ((pad) - 1)
  32. #define rvin_group_csi_channel_to_pad(channel) ((channel) + 1)
  33. /*
  34. * Not all VINs are created equal, master VINs control the
  35. * routing for other VIN's. We can figure out which VIN is
  36. * master by looking at a VINs id.
  37. */
  38. #define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4)
  39. #define v4l2_dev_to_vin(d) container_of(d, struct rvin_dev, v4l2_dev)
  40. /* -----------------------------------------------------------------------------
  41. * Media Controller link notification
  42. */
  43. /* group lock should be held when calling this function. */
  44. static int rvin_group_entity_to_csi_id(struct rvin_group *group,
  45. struct media_entity *entity)
  46. {
  47. struct v4l2_subdev *sd;
  48. unsigned int i;
  49. sd = media_entity_to_v4l2_subdev(entity);
  50. for (i = 0; i < RVIN_CSI_MAX; i++)
  51. if (group->csi[i].subdev == sd)
  52. return i;
  53. return -ENODEV;
  54. }
  55. static unsigned int rvin_group_get_mask(struct rvin_dev *vin,
  56. enum rvin_csi_id csi_id,
  57. unsigned char channel)
  58. {
  59. const struct rvin_group_route *route;
  60. unsigned int mask = 0;
  61. for (route = vin->info->routes; route->mask; route++) {
  62. if (route->vin == vin->id &&
  63. route->csi == csi_id &&
  64. route->channel == channel) {
  65. vin_dbg(vin,
  66. "Adding route: vin: %d csi: %d channel: %d\n",
  67. route->vin, route->csi, route->channel);
  68. mask |= route->mask;
  69. }
  70. }
  71. return mask;
  72. }
  73. /*
  74. * Link setup for the links between a VIN and a CSI-2 receiver is a bit
  75. * complex. The reason for this is that the register controlling routing
  76. * is not present in each VIN instance. There are special VINs which
  77. * control routing for themselves and other VINs. There are not many
  78. * different possible links combinations that can be enabled at the same
  79. * time, therefor all already enabled links which are controlled by a
  80. * master VIN need to be taken into account when making the decision
  81. * if a new link can be enabled or not.
  82. *
  83. * 1. Find out which VIN the link the user tries to enable is connected to.
  84. * 2. Lookup which master VIN controls the links for this VIN.
  85. * 3. Start with a bitmask with all bits set.
  86. * 4. For each previously enabled link from the master VIN bitwise AND its
  87. * route mask (see documentation for mask in struct rvin_group_route)
  88. * with the bitmask.
  89. * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask.
  90. * 6. If the bitmask is not empty at this point the new link can be enabled
  91. * while keeping all previous links enabled. Update the CHSEL value of the
  92. * master VIN and inform the user that the link could be enabled.
  93. *
  94. * Please note that no link can be enabled if any VIN in the group is
  95. * currently open.
  96. */
  97. static int rvin_group_link_notify(struct media_link *link, u32 flags,
  98. unsigned int notification)
  99. {
  100. struct rvin_group *group = container_of(link->graph_obj.mdev,
  101. struct rvin_group, mdev);
  102. unsigned int master_id, channel, mask_new, i;
  103. unsigned int mask = ~0;
  104. struct media_entity *entity;
  105. struct video_device *vdev;
  106. struct media_pad *csi_pad;
  107. struct rvin_dev *vin = NULL;
  108. int csi_id, ret;
  109. ret = v4l2_pipeline_link_notify(link, flags, notification);
  110. if (ret)
  111. return ret;
  112. /* Only care about link enablement for VIN nodes. */
  113. if (!(flags & MEDIA_LNK_FL_ENABLED) ||
  114. !is_media_entity_v4l2_video_device(link->sink->entity))
  115. return 0;
  116. /* If any entity is in use don't allow link changes. */
  117. media_device_for_each_entity(entity, &group->mdev)
  118. if (entity->use_count)
  119. return -EBUSY;
  120. mutex_lock(&group->lock);
  121. /* Find the master VIN that controls the routes. */
  122. vdev = media_entity_to_video_device(link->sink->entity);
  123. vin = container_of(vdev, struct rvin_dev, vdev);
  124. master_id = rvin_group_id_to_master(vin->id);
  125. if (WARN_ON(!group->vin[master_id])) {
  126. ret = -ENODEV;
  127. goto out;
  128. }
  129. /* Build a mask for already enabled links. */
  130. for (i = master_id; i < master_id + 4; i++) {
  131. if (!group->vin[i])
  132. continue;
  133. /* Get remote CSI-2, if any. */
  134. csi_pad = media_entity_remote_pad(
  135. &group->vin[i]->vdev.entity.pads[0]);
  136. if (!csi_pad)
  137. continue;
  138. csi_id = rvin_group_entity_to_csi_id(group, csi_pad->entity);
  139. channel = rvin_group_csi_pad_to_channel(csi_pad->index);
  140. mask &= rvin_group_get_mask(group->vin[i], csi_id, channel);
  141. }
  142. /* Add the new link to the existing mask and check if it works. */
  143. csi_id = rvin_group_entity_to_csi_id(group, link->source->entity);
  144. if (csi_id == -ENODEV) {
  145. struct v4l2_subdev *sd;
  146. unsigned int i;
  147. /*
  148. * Make sure the source entity subdevice is registered as
  149. * a parallel input of one of the enabled VINs if it is not
  150. * one of the CSI-2 subdevices.
  151. *
  152. * No hardware configuration required for parallel inputs,
  153. * we can return here.
  154. */
  155. sd = media_entity_to_v4l2_subdev(link->source->entity);
  156. for (i = 0; i < RCAR_VIN_NUM; i++) {
  157. if (group->vin[i] && group->vin[i]->parallel &&
  158. group->vin[i]->parallel->subdev == sd) {
  159. group->vin[i]->is_csi = false;
  160. ret = 0;
  161. goto out;
  162. }
  163. }
  164. vin_err(vin, "Subdevice %s not registered to any VIN\n",
  165. link->source->entity->name);
  166. ret = -ENODEV;
  167. goto out;
  168. }
  169. channel = rvin_group_csi_pad_to_channel(link->source->index);
  170. mask_new = mask & rvin_group_get_mask(vin, csi_id, channel);
  171. vin_dbg(vin, "Try link change mask: 0x%x new: 0x%x\n", mask, mask_new);
  172. if (!mask_new) {
  173. ret = -EMLINK;
  174. goto out;
  175. }
  176. /* New valid CHSEL found, set the new value. */
  177. ret = rvin_set_channel_routing(group->vin[master_id], __ffs(mask_new));
  178. if (ret)
  179. goto out;
  180. vin->is_csi = true;
  181. out:
  182. mutex_unlock(&group->lock);
  183. return ret;
  184. }
  185. static const struct media_device_ops rvin_media_ops = {
  186. .link_notify = rvin_group_link_notify,
  187. };
  188. /* -----------------------------------------------------------------------------
  189. * Gen3 CSI2 Group Allocator
  190. */
  191. /* FIXME: This should if we find a system that supports more
  192. * than one group for the whole system be replaced with a linked
  193. * list of groups. And eventually all of this should be replaced
  194. * with a global device allocator API.
  195. *
  196. * But for now this works as on all supported systems there will
  197. * be only one group for all instances.
  198. */
  199. static DEFINE_MUTEX(rvin_group_lock);
  200. static struct rvin_group *rvin_group_data;
  201. static void rvin_group_cleanup(struct rvin_group *group)
  202. {
  203. media_device_unregister(&group->mdev);
  204. media_device_cleanup(&group->mdev);
  205. mutex_destroy(&group->lock);
  206. }
  207. static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin)
  208. {
  209. struct media_device *mdev = &group->mdev;
  210. const struct of_device_id *match;
  211. struct device_node *np;
  212. int ret;
  213. mutex_init(&group->lock);
  214. /* Count number of VINs in the system */
  215. group->count = 0;
  216. for_each_matching_node(np, vin->dev->driver->of_match_table)
  217. if (of_device_is_available(np))
  218. group->count++;
  219. vin_dbg(vin, "found %u enabled VIN's in DT", group->count);
  220. mdev->dev = vin->dev;
  221. mdev->ops = &rvin_media_ops;
  222. match = of_match_node(vin->dev->driver->of_match_table,
  223. vin->dev->of_node);
  224. strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
  225. strlcpy(mdev->model, match->compatible, sizeof(mdev->model));
  226. snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
  227. dev_name(mdev->dev));
  228. media_device_init(mdev);
  229. ret = media_device_register(&group->mdev);
  230. if (ret)
  231. rvin_group_cleanup(group);
  232. return ret;
  233. }
  234. static void rvin_group_release(struct kref *kref)
  235. {
  236. struct rvin_group *group =
  237. container_of(kref, struct rvin_group, refcount);
  238. mutex_lock(&rvin_group_lock);
  239. rvin_group_data = NULL;
  240. rvin_group_cleanup(group);
  241. kfree(group);
  242. mutex_unlock(&rvin_group_lock);
  243. }
  244. static int rvin_group_get(struct rvin_dev *vin)
  245. {
  246. struct rvin_group *group;
  247. u32 id;
  248. int ret;
  249. /* Make sure VIN id is present and sane */
  250. ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
  251. if (ret) {
  252. vin_err(vin, "%pOF: No renesas,id property found\n",
  253. vin->dev->of_node);
  254. return -EINVAL;
  255. }
  256. if (id >= RCAR_VIN_NUM) {
  257. vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
  258. vin->dev->of_node, id);
  259. return -EINVAL;
  260. }
  261. /* Join or create a VIN group */
  262. mutex_lock(&rvin_group_lock);
  263. if (rvin_group_data) {
  264. group = rvin_group_data;
  265. kref_get(&group->refcount);
  266. } else {
  267. group = kzalloc(sizeof(*group), GFP_KERNEL);
  268. if (!group) {
  269. ret = -ENOMEM;
  270. goto err_group;
  271. }
  272. ret = rvin_group_init(group, vin);
  273. if (ret) {
  274. kfree(group);
  275. vin_err(vin, "Failed to initialize group\n");
  276. goto err_group;
  277. }
  278. kref_init(&group->refcount);
  279. rvin_group_data = group;
  280. }
  281. mutex_unlock(&rvin_group_lock);
  282. /* Add VIN to group */
  283. mutex_lock(&group->lock);
  284. if (group->vin[id]) {
  285. vin_err(vin, "Duplicate renesas,id property value %u\n", id);
  286. mutex_unlock(&group->lock);
  287. kref_put(&group->refcount, rvin_group_release);
  288. return -EINVAL;
  289. }
  290. group->vin[id] = vin;
  291. vin->id = id;
  292. vin->group = group;
  293. vin->v4l2_dev.mdev = &group->mdev;
  294. mutex_unlock(&group->lock);
  295. return 0;
  296. err_group:
  297. mutex_unlock(&rvin_group_lock);
  298. return ret;
  299. }
  300. static void rvin_group_put(struct rvin_dev *vin)
  301. {
  302. struct rvin_group *group = vin->group;
  303. mutex_lock(&group->lock);
  304. vin->group = NULL;
  305. vin->v4l2_dev.mdev = NULL;
  306. if (WARN_ON(group->vin[vin->id] != vin))
  307. goto out;
  308. group->vin[vin->id] = NULL;
  309. out:
  310. mutex_unlock(&group->lock);
  311. kref_put(&group->refcount, rvin_group_release);
  312. }
  313. /* -----------------------------------------------------------------------------
  314. * Async notifier
  315. */
  316. static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
  317. {
  318. unsigned int pad;
  319. if (sd->entity.num_pads <= 1)
  320. return 0;
  321. for (pad = 0; pad < sd->entity.num_pads; pad++)
  322. if (sd->entity.pads[pad].flags & direction)
  323. return pad;
  324. return -EINVAL;
  325. }
  326. /* -----------------------------------------------------------------------------
  327. * Parallel async notifier
  328. */
  329. /* The vin lock should be held when calling the subdevice attach and detach */
  330. static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
  331. struct v4l2_subdev *subdev)
  332. {
  333. struct v4l2_subdev_mbus_code_enum code = {
  334. .which = V4L2_SUBDEV_FORMAT_ACTIVE,
  335. };
  336. int ret;
  337. /* Find source and sink pad of remote subdevice */
  338. ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
  339. if (ret < 0)
  340. return ret;
  341. vin->parallel->source_pad = ret;
  342. ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
  343. vin->parallel->sink_pad = ret < 0 ? 0 : ret;
  344. if (vin->info->use_mc) {
  345. vin->parallel->subdev = subdev;
  346. return 0;
  347. }
  348. /* Find compatible subdevices mbus format */
  349. vin->mbus_code = 0;
  350. code.index = 0;
  351. code.pad = vin->parallel->source_pad;
  352. while (!vin->mbus_code &&
  353. !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
  354. code.index++;
  355. switch (code.code) {
  356. case MEDIA_BUS_FMT_YUYV8_1X16:
  357. case MEDIA_BUS_FMT_UYVY8_1X16:
  358. case MEDIA_BUS_FMT_UYVY8_2X8:
  359. case MEDIA_BUS_FMT_UYVY10_2X10:
  360. case MEDIA_BUS_FMT_RGB888_1X24:
  361. vin->mbus_code = code.code;
  362. vin_dbg(vin, "Found media bus format for %s: %d\n",
  363. subdev->name, vin->mbus_code);
  364. break;
  365. default:
  366. break;
  367. }
  368. }
  369. if (!vin->mbus_code) {
  370. vin_err(vin, "Unsupported media bus format for %s\n",
  371. subdev->name);
  372. return -EINVAL;
  373. }
  374. /* Read tvnorms */
  375. ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms);
  376. if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
  377. return ret;
  378. /* Read standard */
  379. vin->std = V4L2_STD_UNKNOWN;
  380. ret = v4l2_subdev_call(subdev, video, g_std, &vin->std);
  381. if (ret < 0 && ret != -ENOIOCTLCMD)
  382. return ret;
  383. /* Add the controls */
  384. ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
  385. if (ret < 0)
  386. return ret;
  387. ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
  388. NULL);
  389. if (ret < 0) {
  390. v4l2_ctrl_handler_free(&vin->ctrl_handler);
  391. return ret;
  392. }
  393. vin->vdev.ctrl_handler = &vin->ctrl_handler;
  394. vin->parallel->subdev = subdev;
  395. return 0;
  396. }
  397. static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
  398. {
  399. rvin_v4l2_unregister(vin);
  400. vin->parallel->subdev = NULL;
  401. if (!vin->info->use_mc) {
  402. v4l2_ctrl_handler_free(&vin->ctrl_handler);
  403. vin->vdev.ctrl_handler = NULL;
  404. }
  405. }
  406. static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
  407. {
  408. struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
  409. struct media_entity *source;
  410. struct media_entity *sink;
  411. int ret;
  412. ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
  413. if (ret < 0) {
  414. vin_err(vin, "Failed to register subdev nodes\n");
  415. return ret;
  416. }
  417. if (!video_is_registered(&vin->vdev)) {
  418. ret = rvin_v4l2_register(vin);
  419. if (ret < 0)
  420. return ret;
  421. }
  422. if (!vin->info->use_mc)
  423. return 0;
  424. /* If we're running with media-controller, link the subdevs. */
  425. source = &vin->parallel->subdev->entity;
  426. sink = &vin->vdev.entity;
  427. ret = media_create_pad_link(source, vin->parallel->source_pad,
  428. sink, vin->parallel->sink_pad, 0);
  429. if (ret)
  430. vin_err(vin, "Error adding link from %s to %s: %d\n",
  431. source->name, sink->name, ret);
  432. return ret;
  433. }
  434. static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
  435. struct v4l2_subdev *subdev,
  436. struct v4l2_async_subdev *asd)
  437. {
  438. struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
  439. vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name);
  440. mutex_lock(&vin->lock);
  441. rvin_parallel_subdevice_detach(vin);
  442. mutex_unlock(&vin->lock);
  443. }
  444. static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
  445. struct v4l2_subdev *subdev,
  446. struct v4l2_async_subdev *asd)
  447. {
  448. struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
  449. int ret;
  450. mutex_lock(&vin->lock);
  451. ret = rvin_parallel_subdevice_attach(vin, subdev);
  452. mutex_unlock(&vin->lock);
  453. if (ret)
  454. return ret;
  455. v4l2_set_subdev_hostdata(subdev, vin);
  456. vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
  457. subdev->name, vin->parallel->source_pad,
  458. vin->parallel->sink_pad);
  459. return 0;
  460. }
  461. static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = {
  462. .bound = rvin_parallel_notify_bound,
  463. .unbind = rvin_parallel_notify_unbind,
  464. .complete = rvin_parallel_notify_complete,
  465. };
  466. static int rvin_parallel_parse_v4l2(struct device *dev,
  467. struct v4l2_fwnode_endpoint *vep,
  468. struct v4l2_async_subdev *asd)
  469. {
  470. struct rvin_dev *vin = dev_get_drvdata(dev);
  471. struct rvin_parallel_entity *rvpe =
  472. container_of(asd, struct rvin_parallel_entity, asd);
  473. if (vep->base.port || vep->base.id)
  474. return -ENOTCONN;
  475. vin->parallel = rvpe;
  476. vin->parallel->mbus_type = vep->bus_type;
  477. switch (vin->parallel->mbus_type) {
  478. case V4L2_MBUS_PARALLEL:
  479. vin_dbg(vin, "Found PARALLEL media bus\n");
  480. vin->parallel->mbus_flags = vep->bus.parallel.flags;
  481. break;
  482. case V4L2_MBUS_BT656:
  483. vin_dbg(vin, "Found BT656 media bus\n");
  484. vin->parallel->mbus_flags = 0;
  485. break;
  486. default:
  487. vin_err(vin, "Unknown media bus type\n");
  488. return -EINVAL;
  489. }
  490. return 0;
  491. }
  492. static int rvin_parallel_init(struct rvin_dev *vin)
  493. {
  494. int ret;
  495. ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
  496. vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity),
  497. 0, rvin_parallel_parse_v4l2);
  498. if (ret)
  499. return ret;
  500. /* If using mc, it's fine not to have any input registered. */
  501. if (!vin->parallel)
  502. return vin->info->use_mc ? 0 : -ENODEV;
  503. vin_dbg(vin, "Found parallel subdevice %pOF\n",
  504. to_of_node(vin->parallel->asd.match.fwnode));
  505. vin->notifier.ops = &rvin_parallel_notify_ops;
  506. ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
  507. if (ret < 0) {
  508. vin_err(vin, "Notifier registration failed\n");
  509. v4l2_async_notifier_cleanup(&vin->group->notifier);
  510. return ret;
  511. }
  512. return 0;
  513. }
  514. /* -----------------------------------------------------------------------------
  515. * Group async notifier
  516. */
  517. static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
  518. {
  519. struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
  520. const struct rvin_group_route *route;
  521. unsigned int i;
  522. int ret;
  523. ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
  524. if (ret) {
  525. vin_err(vin, "Failed to register subdev nodes\n");
  526. return ret;
  527. }
  528. /* Register all video nodes for the group. */
  529. for (i = 0; i < RCAR_VIN_NUM; i++) {
  530. if (vin->group->vin[i] &&
  531. !video_is_registered(&vin->group->vin[i]->vdev)) {
  532. ret = rvin_v4l2_register(vin->group->vin[i]);
  533. if (ret)
  534. return ret;
  535. }
  536. }
  537. /* Create all media device links between VINs and CSI-2's. */
  538. mutex_lock(&vin->group->lock);
  539. for (route = vin->info->routes; route->mask; route++) {
  540. struct media_pad *source_pad, *sink_pad;
  541. struct media_entity *source, *sink;
  542. unsigned int source_idx;
  543. /* Check that VIN is part of the group. */
  544. if (!vin->group->vin[route->vin])
  545. continue;
  546. /* Check that VIN' master is part of the group. */
  547. if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
  548. continue;
  549. /* Check that CSI-2 is part of the group. */
  550. if (!vin->group->csi[route->csi].subdev)
  551. continue;
  552. source = &vin->group->csi[route->csi].subdev->entity;
  553. source_idx = rvin_group_csi_channel_to_pad(route->channel);
  554. source_pad = &source->pads[source_idx];
  555. sink = &vin->group->vin[route->vin]->vdev.entity;
  556. sink_pad = &sink->pads[0];
  557. /* Skip if link already exists. */
  558. if (media_entity_find_link(source_pad, sink_pad))
  559. continue;
  560. ret = media_create_pad_link(source, source_idx, sink, 0, 0);
  561. if (ret) {
  562. vin_err(vin, "Error adding link from %s to %s\n",
  563. source->name, sink->name);
  564. break;
  565. }
  566. }
  567. mutex_unlock(&vin->group->lock);
  568. return ret;
  569. }
  570. static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
  571. struct v4l2_subdev *subdev,
  572. struct v4l2_async_subdev *asd)
  573. {
  574. struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
  575. unsigned int i;
  576. for (i = 0; i < RCAR_VIN_NUM; i++)
  577. if (vin->group->vin[i])
  578. rvin_v4l2_unregister(vin->group->vin[i]);
  579. mutex_lock(&vin->group->lock);
  580. for (i = 0; i < RVIN_CSI_MAX; i++) {
  581. if (vin->group->csi[i].fwnode != asd->match.fwnode)
  582. continue;
  583. vin->group->csi[i].subdev = NULL;
  584. vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i);
  585. break;
  586. }
  587. mutex_unlock(&vin->group->lock);
  588. }
  589. static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
  590. struct v4l2_subdev *subdev,
  591. struct v4l2_async_subdev *asd)
  592. {
  593. struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
  594. unsigned int i;
  595. mutex_lock(&vin->group->lock);
  596. for (i = 0; i < RVIN_CSI_MAX; i++) {
  597. if (vin->group->csi[i].fwnode != asd->match.fwnode)
  598. continue;
  599. vin->group->csi[i].subdev = subdev;
  600. vin_dbg(vin, "Bound CSI-2 %s to slot %u\n", subdev->name, i);
  601. break;
  602. }
  603. mutex_unlock(&vin->group->lock);
  604. return 0;
  605. }
  606. static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
  607. .bound = rvin_group_notify_bound,
  608. .unbind = rvin_group_notify_unbind,
  609. .complete = rvin_group_notify_complete,
  610. };
  611. static int rvin_mc_parse_of_endpoint(struct device *dev,
  612. struct v4l2_fwnode_endpoint *vep,
  613. struct v4l2_async_subdev *asd)
  614. {
  615. struct rvin_dev *vin = dev_get_drvdata(dev);
  616. if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX)
  617. return -EINVAL;
  618. if (!of_device_is_available(to_of_node(asd->match.fwnode))) {
  619. vin_dbg(vin, "OF device %pOF disabled, ignoring\n",
  620. to_of_node(asd->match.fwnode));
  621. return -ENOTCONN;
  622. }
  623. if (vin->group->csi[vep->base.id].fwnode) {
  624. vin_dbg(vin, "OF device %pOF already handled\n",
  625. to_of_node(asd->match.fwnode));
  626. return -ENOTCONN;
  627. }
  628. vin->group->csi[vep->base.id].fwnode = asd->match.fwnode;
  629. vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
  630. to_of_node(asd->match.fwnode), vep->base.id);
  631. return 0;
  632. }
  633. static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
  634. {
  635. unsigned int count = 0;
  636. unsigned int i;
  637. int ret;
  638. mutex_lock(&vin->group->lock);
  639. /* If not all VIN's are registered don't register the notifier. */
  640. for (i = 0; i < RCAR_VIN_NUM; i++)
  641. if (vin->group->vin[i])
  642. count++;
  643. if (vin->group->count != count) {
  644. mutex_unlock(&vin->group->lock);
  645. return 0;
  646. }
  647. /*
  648. * Have all VIN's look for CSI-2 subdevices. Some subdevices will
  649. * overlap but the parser function can handle it, so each subdevice
  650. * will only be registered once with the group notifier.
  651. */
  652. for (i = 0; i < RCAR_VIN_NUM; i++) {
  653. if (!vin->group->vin[i])
  654. continue;
  655. ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
  656. vin->group->vin[i]->dev, &vin->group->notifier,
  657. sizeof(struct v4l2_async_subdev), 1,
  658. rvin_mc_parse_of_endpoint);
  659. if (ret) {
  660. mutex_unlock(&vin->group->lock);
  661. return ret;
  662. }
  663. }
  664. mutex_unlock(&vin->group->lock);
  665. if (!vin->group->notifier.num_subdevs)
  666. return 0;
  667. vin->group->notifier.ops = &rvin_group_notify_ops;
  668. ret = v4l2_async_notifier_register(&vin->v4l2_dev,
  669. &vin->group->notifier);
  670. if (ret < 0) {
  671. vin_err(vin, "Notifier registration failed\n");
  672. v4l2_async_notifier_cleanup(&vin->group->notifier);
  673. return ret;
  674. }
  675. return 0;
  676. }
  677. static int rvin_mc_init(struct rvin_dev *vin)
  678. {
  679. int ret;
  680. vin->pad.flags = MEDIA_PAD_FL_SINK;
  681. ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
  682. if (ret)
  683. return ret;
  684. ret = rvin_group_get(vin);
  685. if (ret)
  686. return ret;
  687. ret = rvin_mc_parse_of_graph(vin);
  688. if (ret)
  689. rvin_group_put(vin);
  690. return ret;
  691. }
  692. /* -----------------------------------------------------------------------------
  693. * Platform Device Driver
  694. */
  695. static const struct rvin_info rcar_info_h1 = {
  696. .model = RCAR_H1,
  697. .use_mc = false,
  698. .max_width = 2048,
  699. .max_height = 2048,
  700. };
  701. static const struct rvin_info rcar_info_m1 = {
  702. .model = RCAR_M1,
  703. .use_mc = false,
  704. .max_width = 2048,
  705. .max_height = 2048,
  706. };
  707. static const struct rvin_info rcar_info_gen2 = {
  708. .model = RCAR_GEN2,
  709. .use_mc = false,
  710. .max_width = 2048,
  711. .max_height = 2048,
  712. };
  713. static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
  714. { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
  715. { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
  716. { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
  717. { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
  718. { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
  719. { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
  720. { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
  721. { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
  722. { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
  723. { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
  724. { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
  725. { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
  726. { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
  727. { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
  728. { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
  729. { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
  730. { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
  731. { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
  732. { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
  733. { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
  734. { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
  735. { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
  736. { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
  737. { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
  738. { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
  739. { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
  740. { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
  741. { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
  742. { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
  743. { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
  744. { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
  745. { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
  746. { /* Sentinel */ }
  747. };
  748. static const struct rvin_info rcar_info_r8a7795 = {
  749. .model = RCAR_GEN3,
  750. .use_mc = true,
  751. .max_width = 4096,
  752. .max_height = 4096,
  753. .routes = rcar_info_r8a7795_routes,
  754. };
  755. static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = {
  756. { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
  757. { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
  758. { .csi = RVIN_CSI21, .channel = 0, .vin = 0, .mask = BIT(2) | BIT(5) },
  759. { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
  760. { .csi = RVIN_CSI21, .channel = 0, .vin = 1, .mask = BIT(1) },
  761. { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
  762. { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
  763. { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
  764. { .csi = RVIN_CSI21, .channel = 1, .vin = 1, .mask = BIT(5) },
  765. { .csi = RVIN_CSI21, .channel = 0, .vin = 2, .mask = BIT(0) },
  766. { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
  767. { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
  768. { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
  769. { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
  770. { .csi = RVIN_CSI21, .channel = 2, .vin = 2, .mask = BIT(5) },
  771. { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
  772. { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
  773. { .csi = RVIN_CSI21, .channel = 1, .vin = 3, .mask = BIT(2) },
  774. { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
  775. { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
  776. { .csi = RVIN_CSI21, .channel = 3, .vin = 3, .mask = BIT(5) },
  777. { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
  778. { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
  779. { .csi = RVIN_CSI21, .channel = 0, .vin = 4, .mask = BIT(2) | BIT(5) },
  780. { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
  781. { .csi = RVIN_CSI21, .channel = 0, .vin = 5, .mask = BIT(1) },
  782. { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
  783. { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(3) },
  784. { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
  785. { .csi = RVIN_CSI21, .channel = 1, .vin = 5, .mask = BIT(5) },
  786. { .csi = RVIN_CSI21, .channel = 0, .vin = 6, .mask = BIT(0) },
  787. { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
  788. { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
  789. { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
  790. { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
  791. { .csi = RVIN_CSI21, .channel = 2, .vin = 6, .mask = BIT(5) },
  792. { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
  793. { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
  794. { .csi = RVIN_CSI21, .channel = 1, .vin = 7, .mask = BIT(2) },
  795. { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
  796. { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
  797. { .csi = RVIN_CSI21, .channel = 3, .vin = 7, .mask = BIT(5) },
  798. { /* Sentinel */ }
  799. };
  800. static const struct rvin_info rcar_info_r8a7795es1 = {
  801. .model = RCAR_GEN3,
  802. .use_mc = true,
  803. .max_width = 4096,
  804. .max_height = 4096,
  805. .routes = rcar_info_r8a7795es1_routes,
  806. };
  807. static const struct rvin_group_route rcar_info_r8a7796_routes[] = {
  808. { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
  809. { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
  810. { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
  811. { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
  812. { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
  813. { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
  814. { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
  815. { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
  816. { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
  817. { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
  818. { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
  819. { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) },
  820. { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
  821. { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
  822. { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
  823. { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
  824. { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
  825. { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
  826. { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(3) },
  827. { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
  828. { .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
  829. { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
  830. { .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
  831. { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
  832. { .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
  833. { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) },
  834. { .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
  835. { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
  836. { /* Sentinel */ }
  837. };
  838. static const struct rvin_info rcar_info_r8a7796 = {
  839. .model = RCAR_GEN3,
  840. .use_mc = true,
  841. .max_width = 4096,
  842. .max_height = 4096,
  843. .routes = rcar_info_r8a7796_routes,
  844. };
  845. static const struct rvin_group_route rcar_info_r8a77965_routes[] = {
  846. { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
  847. { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
  848. { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
  849. { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
  850. { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
  851. { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
  852. { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
  853. { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
  854. { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
  855. { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
  856. { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
  857. { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
  858. { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
  859. { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
  860. { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
  861. { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
  862. { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
  863. { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
  864. { .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
  865. { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
  866. { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
  867. { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
  868. { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
  869. { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
  870. { .csi = RVIN_CSI40, .channel = 0, .vin = 6, .mask = BIT(1) },
  871. { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
  872. { .csi = RVIN_CSI40, .channel = 2, .vin = 6, .mask = BIT(3) },
  873. { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
  874. { .csi = RVIN_CSI40, .channel = 1, .vin = 7, .mask = BIT(0) },
  875. { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
  876. { .csi = RVIN_CSI40, .channel = 3, .vin = 7, .mask = BIT(3) },
  877. { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
  878. { /* Sentinel */ }
  879. };
  880. static const struct rvin_info rcar_info_r8a77965 = {
  881. .model = RCAR_GEN3,
  882. .use_mc = true,
  883. .max_width = 4096,
  884. .max_height = 4096,
  885. .routes = rcar_info_r8a77965_routes,
  886. };
  887. static const struct rvin_group_route rcar_info_r8a77970_routes[] = {
  888. { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
  889. { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
  890. { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(3) },
  891. { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
  892. { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
  893. { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
  894. { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
  895. { /* Sentinel */ }
  896. };
  897. static const struct rvin_info rcar_info_r8a77970 = {
  898. .model = RCAR_GEN3,
  899. .use_mc = true,
  900. .max_width = 4096,
  901. .max_height = 4096,
  902. .routes = rcar_info_r8a77970_routes,
  903. };
  904. static const struct rvin_group_route rcar_info_r8a77995_routes[] = {
  905. { /* Sentinel */ }
  906. };
  907. static const struct rvin_info rcar_info_r8a77995 = {
  908. .model = RCAR_GEN3,
  909. .use_mc = true,
  910. .max_width = 4096,
  911. .max_height = 4096,
  912. .routes = rcar_info_r8a77995_routes,
  913. };
  914. static const struct of_device_id rvin_of_id_table[] = {
  915. {
  916. .compatible = "renesas,vin-r8a7778",
  917. .data = &rcar_info_m1,
  918. },
  919. {
  920. .compatible = "renesas,vin-r8a7779",
  921. .data = &rcar_info_h1,
  922. },
  923. {
  924. .compatible = "renesas,vin-r8a7790",
  925. .data = &rcar_info_gen2,
  926. },
  927. {
  928. .compatible = "renesas,vin-r8a7791",
  929. .data = &rcar_info_gen2,
  930. },
  931. {
  932. .compatible = "renesas,vin-r8a7793",
  933. .data = &rcar_info_gen2,
  934. },
  935. {
  936. .compatible = "renesas,vin-r8a7794",
  937. .data = &rcar_info_gen2,
  938. },
  939. {
  940. .compatible = "renesas,rcar-gen2-vin",
  941. .data = &rcar_info_gen2,
  942. },
  943. {
  944. .compatible = "renesas,vin-r8a7795",
  945. .data = &rcar_info_r8a7795,
  946. },
  947. {
  948. .compatible = "renesas,vin-r8a7796",
  949. .data = &rcar_info_r8a7796,
  950. },
  951. {
  952. .compatible = "renesas,vin-r8a77965",
  953. .data = &rcar_info_r8a77965,
  954. },
  955. {
  956. .compatible = "renesas,vin-r8a77970",
  957. .data = &rcar_info_r8a77970,
  958. },
  959. {
  960. .compatible = "renesas,vin-r8a77995",
  961. .data = &rcar_info_r8a77995,
  962. },
  963. { /* Sentinel */ },
  964. };
  965. MODULE_DEVICE_TABLE(of, rvin_of_id_table);
  966. static const struct soc_device_attribute r8a7795es1[] = {
  967. {
  968. .soc_id = "r8a7795", .revision = "ES1.*",
  969. .data = &rcar_info_r8a7795es1,
  970. },
  971. { /* Sentinel */ }
  972. };
  973. static int rcar_vin_probe(struct platform_device *pdev)
  974. {
  975. const struct soc_device_attribute *attr;
  976. struct rvin_dev *vin;
  977. struct resource *mem;
  978. int irq, ret;
  979. vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
  980. if (!vin)
  981. return -ENOMEM;
  982. vin->dev = &pdev->dev;
  983. vin->info = of_device_get_match_data(&pdev->dev);
  984. /*
  985. * Special care is needed on r8a7795 ES1.x since it
  986. * uses different routing than r8a7795 ES2.0.
  987. */
  988. attr = soc_device_match(r8a7795es1);
  989. if (attr)
  990. vin->info = attr->data;
  991. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  992. if (mem == NULL)
  993. return -EINVAL;
  994. vin->base = devm_ioremap_resource(vin->dev, mem);
  995. if (IS_ERR(vin->base))
  996. return PTR_ERR(vin->base);
  997. irq = platform_get_irq(pdev, 0);
  998. if (irq < 0)
  999. return irq;
  1000. ret = rvin_dma_register(vin, irq);
  1001. if (ret)
  1002. return ret;
  1003. platform_set_drvdata(pdev, vin);
  1004. if (vin->info->use_mc) {
  1005. ret = rvin_mc_init(vin);
  1006. if (ret)
  1007. goto error_dma_unregister;
  1008. }
  1009. ret = rvin_parallel_init(vin);
  1010. if (ret)
  1011. goto error_group_unregister;
  1012. pm_suspend_ignore_children(&pdev->dev, true);
  1013. pm_runtime_enable(&pdev->dev);
  1014. return 0;
  1015. error_group_unregister:
  1016. if (vin->info->use_mc) {
  1017. mutex_lock(&vin->group->lock);
  1018. if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
  1019. v4l2_async_notifier_unregister(&vin->group->notifier);
  1020. v4l2_async_notifier_cleanup(&vin->group->notifier);
  1021. }
  1022. mutex_unlock(&vin->group->lock);
  1023. rvin_group_put(vin);
  1024. }
  1025. error_dma_unregister:
  1026. rvin_dma_unregister(vin);
  1027. return ret;
  1028. }
  1029. static int rcar_vin_remove(struct platform_device *pdev)
  1030. {
  1031. struct rvin_dev *vin = platform_get_drvdata(pdev);
  1032. pm_runtime_disable(&pdev->dev);
  1033. rvin_v4l2_unregister(vin);
  1034. v4l2_async_notifier_unregister(&vin->notifier);
  1035. v4l2_async_notifier_cleanup(&vin->notifier);
  1036. if (vin->info->use_mc) {
  1037. mutex_lock(&vin->group->lock);
  1038. if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
  1039. v4l2_async_notifier_unregister(&vin->group->notifier);
  1040. v4l2_async_notifier_cleanup(&vin->group->notifier);
  1041. }
  1042. mutex_unlock(&vin->group->lock);
  1043. rvin_group_put(vin);
  1044. } else {
  1045. v4l2_ctrl_handler_free(&vin->ctrl_handler);
  1046. }
  1047. rvin_dma_unregister(vin);
  1048. return 0;
  1049. }
  1050. static struct platform_driver rcar_vin_driver = {
  1051. .driver = {
  1052. .name = "rcar-vin",
  1053. .of_match_table = rvin_of_id_table,
  1054. },
  1055. .probe = rcar_vin_probe,
  1056. .remove = rcar_vin_remove,
  1057. };
  1058. module_platform_driver(rcar_vin_driver);
  1059. MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
  1060. MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
  1061. MODULE_LICENSE("GPL");