vimc-common.c 9.1 KB

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