soc_mediabus.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * soc-camera media bus helper routines
  3. *
  4. * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <media/v4l2-device.h>
  13. #include <media/v4l2-mediabus.h>
  14. #include <media/soc_mediabus.h>
  15. static const struct soc_mbus_lookup mbus_fmt[] = {
  16. {
  17. .code = V4L2_MBUS_FMT_YUYV8_2X8,
  18. .fmt = {
  19. .fourcc = V4L2_PIX_FMT_YUYV,
  20. .name = "YUYV",
  21. .bits_per_sample = 8,
  22. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  23. .order = SOC_MBUS_ORDER_LE,
  24. },
  25. }, {
  26. .code = V4L2_MBUS_FMT_YVYU8_2X8,
  27. .fmt = {
  28. .fourcc = V4L2_PIX_FMT_YVYU,
  29. .name = "YVYU",
  30. .bits_per_sample = 8,
  31. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  32. .order = SOC_MBUS_ORDER_LE,
  33. },
  34. }, {
  35. .code = V4L2_MBUS_FMT_UYVY8_2X8,
  36. .fmt = {
  37. .fourcc = V4L2_PIX_FMT_UYVY,
  38. .name = "UYVY",
  39. .bits_per_sample = 8,
  40. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  41. .order = SOC_MBUS_ORDER_LE,
  42. },
  43. }, {
  44. .code = V4L2_MBUS_FMT_VYUY8_2X8,
  45. .fmt = {
  46. .fourcc = V4L2_PIX_FMT_VYUY,
  47. .name = "VYUY",
  48. .bits_per_sample = 8,
  49. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  50. .order = SOC_MBUS_ORDER_LE,
  51. },
  52. }, {
  53. .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
  54. .fmt = {
  55. .fourcc = V4L2_PIX_FMT_RGB555,
  56. .name = "RGB555",
  57. .bits_per_sample = 8,
  58. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  59. .order = SOC_MBUS_ORDER_LE,
  60. },
  61. }, {
  62. .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
  63. .fmt = {
  64. .fourcc = V4L2_PIX_FMT_RGB555X,
  65. .name = "RGB555X",
  66. .bits_per_sample = 8,
  67. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  68. .order = SOC_MBUS_ORDER_LE,
  69. },
  70. }, {
  71. .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
  72. .fmt = {
  73. .fourcc = V4L2_PIX_FMT_RGB565,
  74. .name = "RGB565",
  75. .bits_per_sample = 8,
  76. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  77. .order = SOC_MBUS_ORDER_LE,
  78. },
  79. }, {
  80. .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
  81. .fmt = {
  82. .fourcc = V4L2_PIX_FMT_RGB565X,
  83. .name = "RGB565X",
  84. .bits_per_sample = 8,
  85. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  86. .order = SOC_MBUS_ORDER_LE,
  87. },
  88. }, {
  89. .code = V4L2_MBUS_FMT_SBGGR8_1X8,
  90. .fmt = {
  91. .fourcc = V4L2_PIX_FMT_SBGGR8,
  92. .name = "Bayer 8 BGGR",
  93. .bits_per_sample = 8,
  94. .packing = SOC_MBUS_PACKING_NONE,
  95. .order = SOC_MBUS_ORDER_LE,
  96. },
  97. }, {
  98. .code = V4L2_MBUS_FMT_SBGGR10_1X10,
  99. .fmt = {
  100. .fourcc = V4L2_PIX_FMT_SBGGR10,
  101. .name = "Bayer 10 BGGR",
  102. .bits_per_sample = 10,
  103. .packing = SOC_MBUS_PACKING_EXTEND16,
  104. .order = SOC_MBUS_ORDER_LE,
  105. },
  106. }, {
  107. .code = V4L2_MBUS_FMT_Y8_1X8,
  108. .fmt = {
  109. .fourcc = V4L2_PIX_FMT_GREY,
  110. .name = "Grey",
  111. .bits_per_sample = 8,
  112. .packing = SOC_MBUS_PACKING_NONE,
  113. .order = SOC_MBUS_ORDER_LE,
  114. },
  115. }, {
  116. .code = V4L2_MBUS_FMT_Y10_1X10,
  117. .fmt = {
  118. .fourcc = V4L2_PIX_FMT_Y10,
  119. .name = "Grey 10bit",
  120. .bits_per_sample = 10,
  121. .packing = SOC_MBUS_PACKING_EXTEND16,
  122. .order = SOC_MBUS_ORDER_LE,
  123. },
  124. }, {
  125. .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
  126. .fmt = {
  127. .fourcc = V4L2_PIX_FMT_SBGGR10,
  128. .name = "Bayer 10 BGGR",
  129. .bits_per_sample = 8,
  130. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  131. .order = SOC_MBUS_ORDER_LE,
  132. },
  133. }, {
  134. .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
  135. .fmt = {
  136. .fourcc = V4L2_PIX_FMT_SBGGR10,
  137. .name = "Bayer 10 BGGR",
  138. .bits_per_sample = 8,
  139. .packing = SOC_MBUS_PACKING_2X8_PADLO,
  140. .order = SOC_MBUS_ORDER_LE,
  141. },
  142. }, {
  143. .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
  144. .fmt = {
  145. .fourcc = V4L2_PIX_FMT_SBGGR10,
  146. .name = "Bayer 10 BGGR",
  147. .bits_per_sample = 8,
  148. .packing = SOC_MBUS_PACKING_2X8_PADHI,
  149. .order = SOC_MBUS_ORDER_BE,
  150. },
  151. }, {
  152. .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
  153. .fmt = {
  154. .fourcc = V4L2_PIX_FMT_SBGGR10,
  155. .name = "Bayer 10 BGGR",
  156. .bits_per_sample = 8,
  157. .packing = SOC_MBUS_PACKING_2X8_PADLO,
  158. .order = SOC_MBUS_ORDER_BE,
  159. },
  160. }, {
  161. .code = V4L2_MBUS_FMT_JPEG_1X8,
  162. .fmt = {
  163. .fourcc = V4L2_PIX_FMT_JPEG,
  164. .name = "JPEG",
  165. .bits_per_sample = 8,
  166. .packing = SOC_MBUS_PACKING_VARIABLE,
  167. .order = SOC_MBUS_ORDER_LE,
  168. },
  169. },
  170. };
  171. int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
  172. {
  173. switch (mf->packing) {
  174. case SOC_MBUS_PACKING_NONE:
  175. case SOC_MBUS_PACKING_EXTEND16:
  176. return 1;
  177. case SOC_MBUS_PACKING_2X8_PADHI:
  178. case SOC_MBUS_PACKING_2X8_PADLO:
  179. return 2;
  180. case SOC_MBUS_PACKING_VARIABLE:
  181. return 0;
  182. }
  183. return -EINVAL;
  184. }
  185. EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
  186. s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
  187. {
  188. switch (mf->packing) {
  189. case SOC_MBUS_PACKING_NONE:
  190. return width * mf->bits_per_sample / 8;
  191. case SOC_MBUS_PACKING_2X8_PADHI:
  192. case SOC_MBUS_PACKING_2X8_PADLO:
  193. case SOC_MBUS_PACKING_EXTEND16:
  194. return width * 2;
  195. case SOC_MBUS_PACKING_VARIABLE:
  196. return 0;
  197. }
  198. return -EINVAL;
  199. }
  200. EXPORT_SYMBOL(soc_mbus_bytes_per_line);
  201. const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
  202. enum v4l2_mbus_pixelcode code,
  203. const struct soc_mbus_lookup *lookup,
  204. int n)
  205. {
  206. int i;
  207. for (i = 0; i < n; i++)
  208. if (lookup[i].code == code)
  209. return &lookup[i].fmt;
  210. return NULL;
  211. }
  212. EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
  213. const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
  214. enum v4l2_mbus_pixelcode code)
  215. {
  216. return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
  217. }
  218. EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
  219. static int __init soc_mbus_init(void)
  220. {
  221. return 0;
  222. }
  223. static void __exit soc_mbus_exit(void)
  224. {
  225. }
  226. module_init(soc_mbus_init);
  227. module_exit(soc_mbus_exit);
  228. MODULE_DESCRIPTION("soc-camera media bus interface");
  229. MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
  230. MODULE_LICENSE("GPL v2");