vimc-common.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * vimc-common.c Virtual Media Controller Driver
  4. *
  5. * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
  6. */
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <media/v4l2-ctrls.h>
  10. #include "vimc-common.h"
  11. /*
  12. * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
  13. * in the scaler)
  14. */
  15. static const struct vimc_pix_map vimc_pix_map_list[] = {
  16. /* TODO: add all missing formats */
  17. /* RGB formats */
  18. {
  19. .code = {
  20. MEDIA_BUS_FMT_BGR888_1X24,
  21. MEDIA_BUS_FMT_BGR888_3X8
  22. },
  23. .pixelformat = V4L2_PIX_FMT_BGR24,
  24. .bpp = 3,
  25. .bayer = false,
  26. },
  27. {
  28. .code = {
  29. MEDIA_BUS_FMT_RGB888_1X24,
  30. MEDIA_BUS_FMT_RGB888_2X12_BE,
  31. MEDIA_BUS_FMT_RGB888_2X12_LE,
  32. MEDIA_BUS_FMT_RGB888_3X8,
  33. MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
  34. MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
  35. MEDIA_BUS_FMT_RGB888_1X32_PADHI,
  36. MEDIA_BUS_FMT_GBR888_1X24
  37. },
  38. .pixelformat = V4L2_PIX_FMT_RGB24,
  39. .bpp = 3,
  40. .bayer = false,
  41. },
  42. {
  43. .code = { MEDIA_BUS_FMT_ARGB8888_1X32 },
  44. .pixelformat = V4L2_PIX_FMT_ARGB32,
  45. .bpp = 4,
  46. .bayer = false,
  47. },
  48. /* Bayer formats */
  49. {
  50. .code = { MEDIA_BUS_FMT_SBGGR8_1X8 },
  51. .pixelformat = V4L2_PIX_FMT_SBGGR8,
  52. .bpp = 1,
  53. .bayer = true,
  54. },
  55. {
  56. .code = { MEDIA_BUS_FMT_SGBRG8_1X8 },
  57. .pixelformat = V4L2_PIX_FMT_SGBRG8,
  58. .bpp = 1,
  59. .bayer = true,
  60. },
  61. {
  62. .code = { MEDIA_BUS_FMT_SGRBG8_1X8 },
  63. .pixelformat = V4L2_PIX_FMT_SGRBG8,
  64. .bpp = 1,
  65. .bayer = true,
  66. },
  67. {
  68. .code = { MEDIA_BUS_FMT_SRGGB8_1X8 },
  69. .pixelformat = V4L2_PIX_FMT_SRGGB8,
  70. .bpp = 1,
  71. .bayer = true,
  72. },
  73. {
  74. .code = { MEDIA_BUS_FMT_SBGGR10_1X10 },
  75. .pixelformat = V4L2_PIX_FMT_SBGGR10,
  76. .bpp = 2,
  77. .bayer = true,
  78. },
  79. {
  80. .code = { MEDIA_BUS_FMT_SGBRG10_1X10 },
  81. .pixelformat = V4L2_PIX_FMT_SGBRG10,
  82. .bpp = 2,
  83. .bayer = true,
  84. },
  85. {
  86. .code = { MEDIA_BUS_FMT_SGRBG10_1X10 },
  87. .pixelformat = V4L2_PIX_FMT_SGRBG10,
  88. .bpp = 2,
  89. .bayer = true,
  90. },
  91. {
  92. .code = { MEDIA_BUS_FMT_SRGGB10_1X10 },
  93. .pixelformat = V4L2_PIX_FMT_SRGGB10,
  94. .bpp = 2,
  95. .bayer = true,
  96. },
  97. /* 10bit raw bayer a-law compressed to 8 bits */
  98. {
  99. .code = { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 },
  100. .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
  101. .bpp = 1,
  102. .bayer = true,
  103. },
  104. {
  105. .code = { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 },
  106. .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
  107. .bpp = 1,
  108. .bayer = true,
  109. },
  110. {
  111. .code = { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 },
  112. .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
  113. .bpp = 1,
  114. .bayer = true,
  115. },
  116. {
  117. .code = { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 },
  118. .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
  119. .bpp = 1,
  120. .bayer = true,
  121. },
  122. /* 10bit raw bayer DPCM compressed to 8 bits */
  123. {
  124. .code = { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 },
  125. .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
  126. .bpp = 1,
  127. .bayer = true,
  128. },
  129. {
  130. .code = { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 },
  131. .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
  132. .bpp = 1,
  133. .bayer = true,
  134. },
  135. {
  136. .code = { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 },
  137. .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
  138. .bpp = 1,
  139. .bayer = true,
  140. },
  141. {
  142. .code = { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 },
  143. .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
  144. .bpp = 1,
  145. .bayer = true,
  146. },
  147. {
  148. .code = { MEDIA_BUS_FMT_SBGGR12_1X12 },
  149. .pixelformat = V4L2_PIX_FMT_SBGGR12,
  150. .bpp = 2,
  151. .bayer = true,
  152. },
  153. {
  154. .code = { MEDIA_BUS_FMT_SGBRG12_1X12 },
  155. .pixelformat = V4L2_PIX_FMT_SGBRG12,
  156. .bpp = 2,
  157. .bayer = true,
  158. },
  159. {
  160. .code = { MEDIA_BUS_FMT_SGRBG12_1X12 },
  161. .pixelformat = V4L2_PIX_FMT_SGRBG12,
  162. .bpp = 2,
  163. .bayer = true,
  164. },
  165. {
  166. .code = { MEDIA_BUS_FMT_SRGGB12_1X12 },
  167. .pixelformat = V4L2_PIX_FMT_SRGGB12,
  168. .bpp = 2,
  169. .bayer = true,
  170. },
  171. };
  172. bool vimc_is_source(struct media_entity *ent)
  173. {
  174. unsigned int i;
  175. for (i = 0; i < ent->num_pads; i++)
  176. if (ent->pads[i].flags & MEDIA_PAD_FL_SINK)
  177. return false;
  178. return true;
  179. }
  180. const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
  181. {
  182. if (i >= ARRAY_SIZE(vimc_pix_map_list))
  183. return NULL;
  184. return &vimc_pix_map_list[i];
  185. }
  186. u32 vimc_mbus_code_by_index(unsigned int index)
  187. {
  188. unsigned int i, j;
  189. for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
  190. for (j = 0; j < ARRAY_SIZE(vimc_pix_map_list[i].code); j++) {
  191. if (!vimc_pix_map_list[i].code[j])
  192. break;
  193. if (!index)
  194. return vimc_pix_map_list[i].code[j];
  195. index--;
  196. }
  197. }
  198. return 0;
  199. }
  200. const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
  201. {
  202. unsigned int i, j;
  203. for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
  204. for (j = 0; j < ARRAY_SIZE(vimc_pix_map_list[i].code); j++) {
  205. if (vimc_pix_map_list[i].code[j] == code)
  206. return &vimc_pix_map_list[i];
  207. }
  208. }
  209. return NULL;
  210. }
  211. const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
  212. {
  213. unsigned int i;
  214. for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
  215. if (vimc_pix_map_list[i].pixelformat == pixelformat)
  216. return &vimc_pix_map_list[i];
  217. }
  218. return NULL;
  219. }
  220. static int vimc_get_pix_format(struct media_pad *pad,
  221. struct v4l2_pix_format *fmt)
  222. {
  223. if (is_media_entity_v4l2_subdev(pad->entity)) {
  224. struct v4l2_subdev *sd =
  225. media_entity_to_v4l2_subdev(pad->entity);
  226. struct v4l2_subdev_format sd_fmt = {
  227. .which = V4L2_SUBDEV_FORMAT_ACTIVE,
  228. .pad = pad->index,
  229. };
  230. const struct vimc_pix_map *pix_map;
  231. int ret;
  232. ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
  233. if (ret)
  234. return ret;
  235. v4l2_fill_pix_format(fmt, &sd_fmt.format);
  236. pix_map = vimc_pix_map_by_code(sd_fmt.format.code);
  237. fmt->pixelformat = pix_map->pixelformat;
  238. } else if (is_media_entity_v4l2_video_device(pad->entity)) {
  239. struct video_device *vdev = container_of(pad->entity,
  240. struct video_device,
  241. entity);
  242. struct vimc_ent_device *ved = video_get_drvdata(vdev);
  243. if (!ved->vdev_get_format)
  244. return -ENOIOCTLCMD;
  245. ved->vdev_get_format(ved, fmt);
  246. } else {
  247. return -EINVAL;
  248. }
  249. return 0;
  250. }
  251. int vimc_vdev_link_validate(struct media_link *link)
  252. {
  253. struct v4l2_pix_format source_fmt, sink_fmt;
  254. int ret;
  255. ret = vimc_get_pix_format(link->source, &source_fmt);
  256. if (ret)
  257. return ret;
  258. ret = vimc_get_pix_format(link->sink, &sink_fmt);
  259. if (ret)
  260. return ret;
  261. pr_info("vimc link validate: "
  262. "%s:src:%dx%d (0x%x, %d, %d, %d, %d) "
  263. "%s:snk:%dx%d (0x%x, %d, %d, %d, %d)\n",
  264. /* src */
  265. link->source->entity->name,
  266. source_fmt.width, source_fmt.height,
  267. source_fmt.pixelformat, source_fmt.colorspace,
  268. source_fmt.quantization, source_fmt.xfer_func,
  269. source_fmt.ycbcr_enc,
  270. /* sink */
  271. link->sink->entity->name,
  272. sink_fmt.width, sink_fmt.height,
  273. sink_fmt.pixelformat, sink_fmt.colorspace,
  274. sink_fmt.quantization, sink_fmt.xfer_func,
  275. sink_fmt.ycbcr_enc);
  276. /* The width, height and pixelformat must match. */
  277. if (source_fmt.width != sink_fmt.width ||
  278. source_fmt.height != sink_fmt.height ||
  279. source_fmt.pixelformat != sink_fmt.pixelformat)
  280. return -EPIPE;
  281. /*
  282. * The field order must match, or the sink field order must be NONE
  283. * to support interlaced hardware connected to bridges that support
  284. * progressive formats only.
  285. */
  286. if (source_fmt.field != sink_fmt.field &&
  287. sink_fmt.field != V4L2_FIELD_NONE)
  288. return -EPIPE;
  289. /*
  290. * If colorspace is DEFAULT, then assume all the colorimetry is also
  291. * DEFAULT, return 0 to skip comparing the other colorimetry parameters
  292. */
  293. if (source_fmt.colorspace == V4L2_COLORSPACE_DEFAULT ||
  294. sink_fmt.colorspace == V4L2_COLORSPACE_DEFAULT)
  295. return 0;
  296. /* Colorspace must match. */
  297. if (source_fmt.colorspace != sink_fmt.colorspace)
  298. return -EPIPE;
  299. /* Colorimetry must match if they are not set to DEFAULT */
  300. if (source_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
  301. sink_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
  302. source_fmt.ycbcr_enc != sink_fmt.ycbcr_enc)
  303. return -EPIPE;
  304. if (source_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
  305. sink_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
  306. source_fmt.quantization != sink_fmt.quantization)
  307. return -EPIPE;
  308. if (source_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
  309. sink_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
  310. source_fmt.xfer_func != sink_fmt.xfer_func)
  311. return -EPIPE;
  312. return 0;
  313. }
  314. static const struct media_entity_operations vimc_ent_sd_mops = {
  315. .link_validate = v4l2_subdev_link_validate,
  316. };
  317. int vimc_ent_sd_register(struct vimc_ent_device *ved,
  318. struct v4l2_subdev *sd,
  319. struct v4l2_device *v4l2_dev,
  320. const char *const name,
  321. u32 function,
  322. u16 num_pads,
  323. struct media_pad *pads,
  324. const struct v4l2_subdev_internal_ops *int_ops,
  325. const struct v4l2_subdev_ops *sd_ops)
  326. {
  327. int ret;
  328. /* Fill the vimc_ent_device struct */
  329. ved->ent = &sd->entity;
  330. /* Initialize the subdev */
  331. v4l2_subdev_init(sd, sd_ops);
  332. sd->internal_ops = int_ops;
  333. sd->entity.function = function;
  334. sd->entity.ops = &vimc_ent_sd_mops;
  335. sd->owner = THIS_MODULE;
  336. strscpy(sd->name, name, sizeof(sd->name));
  337. v4l2_set_subdevdata(sd, ved);
  338. /* Expose this subdev to user space */
  339. sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
  340. if (sd->ctrl_handler)
  341. sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
  342. /* Initialize the media entity */
  343. ret = media_entity_pads_init(&sd->entity, num_pads, pads);
  344. if (ret)
  345. return ret;
  346. /*
  347. * Finalize the subdev initialization if it supports active states. Use
  348. * the control handler lock as the state lock if available.
  349. */
  350. if (int_ops && int_ops->init_state) {
  351. if (sd->ctrl_handler)
  352. sd->state_lock = sd->ctrl_handler->lock;
  353. ret = v4l2_subdev_init_finalize(sd);
  354. if (ret) {
  355. dev_err(v4l2_dev->dev,
  356. "%s: subdev initialization failed (err=%d)\n",
  357. name, ret);
  358. goto err_clean_m_ent;
  359. }
  360. }
  361. /* Register the subdev with the v4l2 and the media framework */
  362. ret = v4l2_device_register_subdev(v4l2_dev, sd);
  363. if (ret) {
  364. dev_err(v4l2_dev->dev,
  365. "%s: subdev register failed (err=%d)\n",
  366. name, ret);
  367. goto err_clean_sd;
  368. }
  369. return 0;
  370. err_clean_sd:
  371. v4l2_subdev_cleanup(sd);
  372. err_clean_m_ent:
  373. media_entity_cleanup(&sd->entity);
  374. return ret;
  375. }