History

Merge tag 'media/v5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab: - New sensor driver: imx219 - Support for some new pixelformats - Support for Sun8i SoC - Added more codecs to meson vdec driver - Prepare for removing the legacy usbvision driver by moving it to staging. This driver has issues and use legacy core APIs. If nobody steps up to address those, it is time for its retirement. - Several cleanups and improvements on drivers, with the addition of new supported boards * tag 'media/v5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (236 commits) media: venus: firmware: Ignore secure call error on first resume media: mtk-vpu: load vpu firmware from the new location media: i2c: video-i2c: fix build errors due to 'imply hwmon' media: MAINTAINERS: add myself to co-maintain Hantro G1/G2 for i.MX8MQ media: hantro: add initial i.MX8MQ support media: dt-bindings: Document i.MX8MQ VPU bindings media: vivid: fix incorrect PA assignment to HDMI outputs media: hantro: Add linux-rockchip mailing list to MAINTAINERS media: cedrus: h264: Fix 4K decoding on H6 media: siano: Use scnprintf() for avoiding potential buffer overflow media: rc: Use scnprintf() for avoiding potential buffer overflow media: allegro: create new struct for channel parameters media: allegro: move mail definitions to separate file media: allegro: pass buffers through firmware media: allegro: verify source and destination buffer in VCU response media: allegro: handle dependency of bitrate and bitrate_peak media: allegro: read bitrate mode directly from control media: allegro: make QP configurable media: allegro: make frame rate configurable media: allegro: skip filler data if possible ...

Linus Torvalds committed 6 years ago

Commit 063d1942 parents 47acac8 2632e7b343 files · +14879 −3012Browse files

Unified · Split

343 files
  1. .mailmap +1 −0
  2. Documentation/devicetree/bindings/display/connector/analog-tv-connector.txt +6 −0
  3. Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml +70 −0
  4. Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml +5 −1
  5. Documentation/devicetree/bindings/media/aspeed-video.txt +3 −2
  6. Documentation/devicetree/bindings/media/i2c/imx219.yaml +114 −0
  7. Documentation/devicetree/bindings/media/i2c/tvp5150.txt +129 −17
  8. Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml +77 −0
  9. Documentation/devicetree/bindings/media/qcom,msm8916-venus.yaml +119 −0
  10. Documentation/devicetree/bindings/media/qcom,msm8996-venus.yaml +172 −0
  11. Documentation/devicetree/bindings/media/qcom,sc7180-venus.yaml +140 −0
  12. Documentation/devicetree/bindings/media/qcom,sdm845-venus-v2.yaml +140 −0
  13. Documentation/devicetree/bindings/media/qcom,sdm845-venus.yaml +156 −0
  14. Documentation/devicetree/bindings/media/qcom,venus.txt +0 −120
  15. Documentation/devicetree/bindings/media/rc.yaml +1 −0
  16. Documentation/devicetree/bindings/media/rockchip-rga.txt +3 −2
  17. Documentation/media/kapi/csi2.rst +1 −1
  18. Documentation/media/kapi/v4l2-dev.rst +2 −2
  19. Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst +5 −5
  20. Documentation/media/uapi/cec/cec-ioc-dqevent.rst +9 −11
  21. Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst +7 −17
  22. Documentation/media/uapi/v4l/buffer.rst +16 −37
  23. Documentation/media/uapi/v4l/dev-sliced-vbi.rst +6 −9
  24. Documentation/media/uapi/v4l/ext-ctrls-codec.rst +16 −0
  25. Documentation/media/uapi/v4l/pixfmt-bayer.rst +1 −0
  26. Documentation/media/uapi/v4l/pixfmt-srggb14.rst +82 −0
  27. Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst +4 −2
  28. Documentation/media/uapi/v4l/pixfmt-v4l2.rst +0 −2
  29. Documentation/media/uapi/v4l/pixfmt-y14.rst +72 −0
  30. Documentation/media/uapi/v4l/subdev-formats.rst +37 −0
  31. Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst +6 −6
  32. Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst +6 −6
  33. Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst +7 −19
  34. Documentation/media/uapi/v4l/vidioc-dqevent.rst +17 −38
  35. Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst +6 −8
  36. Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst +7 −12
  37. Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst +7 −11
  38. Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst +7 −9
  39. Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +18 −27
  40. Documentation/media/uapi/v4l/vidioc-g-fmt.rst +11 −18
  41. Documentation/media/uapi/v4l/vidioc-g-parm.rst +7 −11
  42. Documentation/media/uapi/v4l/vidioc-queryctrl.rst +8 −13
  43. Documentation/media/uapi/v4l/yuv-formats.rst +1 −0
  44. Documentation/media/v4l-drivers/ipu3.rst +7 −4
  45. Documentation/media/v4l-drivers/vivid.rst +60 −3
  46. Documentation/translations/zh_CN/video4linux/v4l2-framework.txt +2 −2
  47. MAINTAINERS +26 −6
  48. arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts +4 −0
  49. drivers/base/property.c +1 −0
  50. drivers/media/Kconfig +3 −3
  51. drivers/media/cec/cec-notifier.c +27 −14
  52. drivers/media/common/saa7146/saa7146_fops.c +5 −7
  53. drivers/media/common/siano/smsdvb-debugfs.c +110 −104
  54. drivers/media/common/videobuf2/videobuf2-core.c +2 −2
  55. drivers/media/common/videobuf2/videobuf2-dma-contig.c +2 −2
  56. drivers/media/dvb-frontends/drx39xyj/drxj.c +2 −2
  57. drivers/media/dvb-frontends/m88ds3103.c +455 −11
  58. drivers/media/dvb-frontends/m88ds3103_priv.h +12 −2
  59. drivers/media/dvb-frontends/tda10071.c +5 −4
  60. drivers/media/i2c/Kconfig +16 −0
  61. drivers/media/i2c/Makefile +1 −0
  62. drivers/media/i2c/adv7180.c +12 −0
  63. drivers/media/i2c/imx214.c +0 −1
  64. drivers/media/i2c/imx219.c +1481 −0
  65. drivers/media/i2c/ov5675.c +73 −9
  66. drivers/media/i2c/ov5695.c +31 −18
  67. drivers/media/i2c/s5c73m3/s5c73m3-ctrls.c +1 −1
  68. drivers/media/i2c/smiapp/smiapp-core.c +129 −130
  69. drivers/media/i2c/smiapp/smiapp-reg.h +4 −0
  70. drivers/media/i2c/smiapp/smiapp-regs.c +20 −51
  71. drivers/media/i2c/smiapp/smiapp.h +43 −1
  72. drivers/media/i2c/tvp5150.c +622 −180
  73. drivers/media/i2c/video-i2c.c +2 −2
  74. drivers/media/mc/mc-entity.c +8 −3
  75. drivers/media/pci/bt8xx/bttv-driver.c +2 −2
  76. drivers/media/pci/cobalt/cobalt-v4l2.c +1 −1
  77. drivers/media/pci/cx18/cx18-streams.c +6 −6
  78. drivers/media/pci/cx23885/cx23885-417.c +1 −1
  79. drivers/media/pci/cx23885/cx23885-video.c +1 −1
  80. drivers/media/pci/cx25821/cx25821-video.c +1 −1
  81. drivers/media/pci/cx88/cx88-blackbird.c +1 −1
  82. drivers/media/pci/cx88/cx88-video.c +1 −1
  83. drivers/media/pci/dt3155/dt3155.c +1 −1
  84. drivers/media/pci/intel/ipu3/ipu3-cio2.c +1 −1
  85. drivers/media/pci/ivtv/ivtv-streams.c +6 −6
  86. drivers/media/pci/meye/meye.c +1 −1
  87. drivers/media/pci/saa7134/saa7134-core.c +1 −1
  88. drivers/media/pci/saa7134/saa7134-empress.c +1 −1
  89. drivers/media/pci/saa7146/hexium_gemini.c +1 −1
  90. drivers/media/pci/saa7146/hexium_orion.c +1 −1
  91. drivers/media/pci/saa7146/mxb.c +1 −1
  92. drivers/media/pci/saa7164/saa7164-encoder.c +1 −1
  93. drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +1 −1
  94. drivers/media/pci/solo6x10/solo6x10-v4l2.c +1 −1
  95. drivers/media/pci/sta2x11/sta2x11_vip.c +1 −1
  96. drivers/media/pci/ttpci/av7110_v4l.c +1 −1
  97. drivers/media/pci/ttpci/budget-av.c +1 −1
  98. drivers/media/pci/tw5864/tw5864-video.c +1 −1
  99. drivers/media/pci/tw68/tw68-video.c +1 −1
  100. drivers/media/pci/tw686x/tw686x-video.c +1 −1
  101. drivers/media/platform/Kconfig +49 −37
  102. drivers/media/platform/am437x/am437x-vpfe.c +7 −6
  103. drivers/media/platform/aspeed-video.c +58 −28
  104. drivers/media/platform/atmel/atmel-isc-base.c +196 −28
  105. drivers/media/platform/atmel/atmel-isc.h +22 −1
  106. drivers/media/platform/atmel/atmel-isi.c +1 −1
  107. drivers/media/platform/coda/coda-common.c +1 −1
  108. drivers/media/platform/davinci/isif.c +1 −1
  109. drivers/media/platform/davinci/vpbe_display.c +1 −1
  110. drivers/media/platform/davinci/vpfe_capture.c +2 −2
  111. drivers/media/platform/davinci/vpif_capture.c +1 −1
  112. drivers/media/platform/davinci/vpif_display.c +1 −1
  113. drivers/media/platform/exynos-gsc/gsc-m2m.c +1 −1
  114. drivers/media/platform/exynos4-is/Kconfig +1 −1
  115. drivers/media/platform/exynos4-is/fimc-capture.c +1 −1
  116. drivers/media/platform/exynos4-is/fimc-isp-video.c +1 −1
  117. drivers/media/platform/exynos4-is/fimc-lite.c +4 −1
  118. drivers/media/platform/exynos4-is/fimc-m2m.c +1 −1
  119. drivers/media/platform/fsl-viu.c +1 −1
  120. drivers/media/platform/imx-pxp.c +1 −1
  121. drivers/media/platform/m2m-deinterlace.c +1 −1
  122. drivers/media/platform/marvell-ccic/mcam-core.c +1 −1
  123. drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +1 −1
  124. drivers/media/platform/mtk-mdp/mtk_mdp_comp.c +6 −0
  125. drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +1 −1
  126. drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c +5 −4
  127. drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +1 −1
  128. drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +1 −1
  129. drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c +25 −4
  130. drivers/media/platform/mtk-vcodec/vdec_vpu_if.c +3 −3
  131. drivers/media/platform/mtk-vcodec/venc_vpu_if.c +6 −6
  132. drivers/media/platform/mtk-vpu/mtk_vpu.c +36 −25
  133. drivers/media/platform/mtk-vpu/mtk_vpu.h +1 −1
  134. drivers/media/platform/mx2_emmaprp.c +1 −1
  135. drivers/media/platform/omap/omap_vout.c +1 −1
  136. drivers/media/platform/omap3isp/ispccdc.c +4 −0
  137. drivers/media/platform/omap3isp/ispvideo.c +4 −4
  138. drivers/media/platform/pxa_camera.c +11 −11
  139. drivers/media/platform/qcom/camss/camss-video.c +3 −3
  140. drivers/media/platform/qcom/venus/Makefile +1 −1
  141. drivers/media/platform/qcom/venus/core.c +104 −63
  142. drivers/media/platform/qcom/venus/core.h +24 −9
  143. drivers/media/platform/qcom/venus/firmware.c +9 −4
  144. drivers/media/platform/qcom/venus/helpers.c +116 −332
  145. drivers/media/platform/qcom/venus/helpers.h +0 −4
  146. drivers/media/platform/qcom/venus/hfi_cmds.c +2 −0
  147. drivers/media/platform/qcom/venus/hfi_helper.h +6 −0
  148. drivers/media/platform/qcom/venus/hfi_parser.c +1 −0
  149. drivers/media/platform/qcom/venus/hfi_parser.h +5 −0
  150. drivers/media/platform/qcom/venus/pm_helpers.c +959 −0
  151. drivers/media/platform/qcom/venus/pm_helpers.h +65 −0
  152. drivers/media/platform/qcom/venus/vdec.c +32 −54
  153. drivers/media/platform/qcom/venus/venc.c +28 −53
  154. drivers/media/platform/qcom/venus/venc_ctrls.c +7 −1
  155. drivers/media/platform/rcar-vin/rcar-dma.c +71 −20
  156. drivers/media/platform/rcar-vin/rcar-v4l2.c +25 −9
  157. drivers/media/platform/rcar-vin/rcar-vin.h +24 −4
  158. drivers/media/platform/rcar_drif.c +8 −4
  159. drivers/media/platform/rcar_fdp1.c +1 −1
  160. drivers/media/platform/rcar_jpu.c +2 −2
  161. drivers/media/platform/renesas-ceu.c +1 −1
  162. drivers/media/platform/rockchip/rga/rga.c +1 −1
  163. drivers/media/platform/s3c-camif/camif-capture.c +1 −1
  164. drivers/media/platform/s5p-g2d/g2d.c +1 −1
  165. drivers/media/platform/s5p-jpeg/jpeg-core.c +2 −2
  166. drivers/media/platform/s5p-mfc/s5p_mfc.c +2 −2
  167. drivers/media/platform/sh_veu.c +1 −1
  168. drivers/media/platform/sh_vou.c +1 −1
  169. drivers/media/platform/sti/bdisp/bdisp-v4l2.c +1 −1
  170. drivers/media/platform/sti/delta/delta-v4l2.c +1 −1
  171. drivers/media/platform/sti/hva/hva-v4l2.c +1 −1
  172. drivers/media/platform/stm32/stm32-cec.c +8 −2
  173. drivers/media/platform/stm32/stm32-dcmi.c +8 −5
  174. drivers/media/platform/sunxi/Makefile +1 −0
  175. drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c +4 −4
  176. drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +4 −4
  177. drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +2 −5
  178. drivers/media/platform/sunxi/sun8i-rotate/Makefile +5 −0
  179. drivers/media/platform/sunxi/sun8i-rotate/sun8i-formats.h +25 −0
  180. drivers/media/platform/sunxi/sun8i-rotate/sun8i-rotate.h +135 −0
  181. drivers/media/platform/sunxi/sun8i-rotate/sun8i_formats.c +273 −0
  182. drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +924 −0
  183. drivers/media/platform/ti-vpe/cal.c +17 −14
  184. drivers/media/platform/ti-vpe/vpe.c +1 −1
  185. drivers/media/platform/via-camera.c +1 −1
  186. drivers/media/platform/vicodec/vicodec-core.c +53 −111
  187. drivers/media/platform/vim2m.c +1 −1
  188. drivers/media/platform/vimc/vimc-capture.c +10 −10
  189. drivers/media/platform/vimc/vimc-common.c +0 −2
  190. drivers/media/platform/vimc/vimc-common.h +13 −14
  191. drivers/media/platform/vimc/vimc-core.c +61 −32
  192. drivers/media/platform/vimc/vimc-debayer.c +4 −17
  193. drivers/media/platform/vimc/vimc-scaler.c +4 −17
  194. drivers/media/platform/vimc/vimc-sensor.c +4 −16
  195. drivers/media/platform/vimc/vimc-streamer.c +14 −3
  196. drivers/media/platform/vivid/vivid-core.c +7 −7
  197. drivers/media/platform/vsp1/vsp1_histo.c +2 −2
  198. drivers/media/platform/vsp1/vsp1_regs.h +1 −1
  199. drivers/media/platform/vsp1/vsp1_video.c +2 −2
  200. drivers/media/platform/xilinx/xilinx-dma.c +8 −7
  201. drivers/media/radio/si470x/Kconfig +2 −2
  202. drivers/media/rc/bpf-lirc.c +0 −5
  203. drivers/media/rc/iguanair.c +1 −1
  204. drivers/media/rc/ir-xmp-decoder.c +1 −1
  205. drivers/media/rc/keymaps/Makefile +1 −0
  206. drivers/media/rc/keymaps/rc-videostrong-kii-pro.c +83 −0
  207. drivers/media/rc/lirc_dev.c +1 −6
  208. drivers/media/rc/nuvoton-cir.c +2 −2
  209. drivers/media/rc/rc-main.c +58 −22
  210. drivers/media/spi/gs1662.c +16 −4
  211. drivers/media/usb/Kconfig +0 −1
  212. drivers/media/usb/Makefile +0 −1
  213. drivers/media/usb/au0828/au0828-video.c +2 −2
  214. drivers/media/usb/b2c2/flexcop-usb.c +3 −3
  215. drivers/media/usb/cpia2/cpia2_v4l.c +1 −1
  216. drivers/media/usb/cx231xx/cx231xx-417.c +1 −1
  217. drivers/media/usb/cx231xx/cx231xx-dvb.c +1 −1
  218. drivers/media/usb/cx231xx/cx231xx-video.c +1 −1
  219. drivers/media/usb/dvb-usb-v2/anysee.c +2 −2
  220. drivers/media/usb/dvb-usb-v2/lmedm04.c +1 −4
  221. drivers/media/usb/dvb-usb-v2/rtl28xxu.c +3 −0
  222. drivers/media/usb/dvb-usb/cxusb-analog.c +6 −6
  223. drivers/media/usb/dvb-usb/dib0700_core.c +2 −2
  224. drivers/media/usb/dvb-usb/dw2102.c +43 −2
  225. drivers/media/usb/em28xx/em28xx-cards.c +18 −0
  226. drivers/media/usb/em28xx/em28xx-dvb.c +60 −0
  227. drivers/media/usb/em28xx/em28xx-video.c +2 −2
  228. drivers/media/usb/em28xx/em28xx.h +1 −0
  229. drivers/media/usb/go7007/go7007-usb.c +3 −1
  230. drivers/media/usb/go7007/go7007-v4l2.c +1 −1
  231. drivers/media/usb/gspca/gspca.c +1 −1
  232. drivers/media/usb/gspca/ov519.c +10 −0
  233. drivers/media/usb/gspca/stv06xx/stv06xx.c +18 −1
  234. drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c +4 −0
  235. drivers/media/usb/gspca/xirlink_cit.c +17 −1
  236. drivers/media/usb/hdpvr/hdpvr-video.c +1 −1
  237. drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +2 −2
  238. drivers/media/usb/pwc/pwc-if.c +1 −1
  239. drivers/media/usb/s2255/s2255drv.c +2 −2
  240. drivers/media/usb/stk1160/stk1160-v4l.c +1 −1
  241. drivers/media/usb/stkwebcam/stk-webcam.c +1 −1
  242. drivers/media/usb/tm6000/tm6000-video.c +2 −2
  243. drivers/media/usb/usbtv/usbtv-core.c +1 −1
  244. drivers/media/usb/usbtv/usbtv-video.c +4 −3
  245. drivers/media/usb/uvc/uvc_driver.c +1 −1
  246. drivers/media/usb/zr364xx/zr364xx.c +1 −1
  247. drivers/media/v4l2-core/v4l2-ctrls.c +9 −2
  248. drivers/media/v4l2-core/v4l2-dev.c +5 −5
  249. drivers/media/v4l2-core/v4l2-device.c +3 −5
  250. drivers/media/v4l2-core/v4l2-fwnode.c +176 −16
  251. drivers/media/v4l2-core/v4l2-i2c.c +5 −5
  252. drivers/media/v4l2-core/v4l2-ioctl.c +7 −2
  253. drivers/media/v4l2-core/v4l2-mc.c +15 −3
  254. drivers/media/v4l2-core/v4l2-mem2mem.c +219 −2
  255. drivers/staging/media/Kconfig +4 −0
  256. drivers/staging/media/Makefile +1 −0
  257. drivers/staging/media/allegro-dvt/Makefile +1 −1
  258. drivers/staging/media/allegro-dvt/allegro-core.c +540 −390
  259. drivers/staging/media/allegro-dvt/allegro-mail.c +37 −0
  260. drivers/staging/media/allegro-dvt/allegro-mail.h +267 −0
  261. drivers/staging/media/hantro/Kconfig +12 −4
  262. drivers/staging/media/hantro/Makefile +3 −0
  263. drivers/staging/media/hantro/hantro.h +1 −1
  264. drivers/staging/media/hantro/hantro_drv.c +14 −1
  265. drivers/staging/media/hantro/hantro_h1_jpeg_enc.c +15 −4
  266. drivers/staging/media/hantro/hantro_hw.h +1 −0
  267. drivers/staging/media/hantro/hantro_jpeg.c +56 −20
  268. drivers/staging/media/hantro/hantro_jpeg.h +1 −1
  269. drivers/staging/media/hantro/hantro_v4l2.c +1 −1
  270. drivers/staging/media/hantro/imx8m_vpu_hw.c +220 −0
  271. drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c +17 −7
  272. drivers/staging/media/imx/imx-media-capture.c +4 −4
  273. drivers/staging/media/imx/imx-media-csc-scaler.c +1 −1
  274. drivers/staging/media/imx/imx-media-csi.c +4 −1
  275. drivers/staging/media/imx/imx-media-utils.c +13 −6
  276. drivers/staging/media/imx/imx7-media-csi.c +23 −1
  277. drivers/staging/media/imx/imx7-mipi-csis.c +15 −1
  278. drivers/staging/media/ipu3/TODO +0 −2
  279. drivers/staging/media/ipu3/ipu3-css.c +3 −3
  280. drivers/staging/media/ipu3/ipu3-css.h +2 −1
  281. drivers/staging/media/ipu3/ipu3-mmu.c +2 −2
  282. drivers/staging/media/ipu3/ipu3-v4l2.c +1 −1
  283. drivers/staging/media/ipu3/ipu3.c +14 −2
  284. drivers/staging/media/meson/vdec/Makefile +2 −2
  285. drivers/staging/media/meson/vdec/codec_h264.c +485 −0
  286. drivers/staging/media/meson/vdec/codec_h264.h +14 −0
  287. drivers/staging/media/meson/vdec/codec_hevc_common.c +297 −0
  288. drivers/staging/media/meson/vdec/codec_hevc_common.h +71 −0
  289. drivers/staging/media/meson/vdec/codec_vp9.c +2141 −0
  290. drivers/staging/media/meson/vdec/codec_vp9.h +13 −0
  291. drivers/staging/media/meson/vdec/esparser.c +166 −34
  292. drivers/staging/media/meson/vdec/hevc_regs.h +218 −0
  293. drivers/staging/media/meson/vdec/vdec.c +68 −39
  294. drivers/staging/media/meson/vdec/vdec.h +12 −2
  295. drivers/staging/media/meson/vdec/vdec_helpers.c +75 −48
  296. drivers/staging/media/meson/vdec/vdec_helpers.h +8 −2
  297. drivers/staging/media/meson/vdec/vdec_hevc.c +231 −0
  298. drivers/staging/media/meson/vdec/vdec_hevc.h +13 −0
  299. drivers/staging/media/meson/vdec/vdec_platform.c +109 −0
  300. drivers/staging/media/omap4iss/iss_video.c +4 −4
  301. drivers/staging/media/rkisp1/TODO +0 −1
  302. drivers/staging/media/rkisp1/rkisp1-capture.c +5 −8
  303. drivers/staging/media/rkisp1/rkisp1-common.h +3 −0
  304. drivers/staging/media/rkisp1/rkisp1-dev.c +9 −11
  305. drivers/staging/media/rkisp1/rkisp1-isp.c +33 −28
  306. drivers/staging/media/rkisp1/rkisp1-params.c +1 −1
  307. drivers/staging/media/rkisp1/rkisp1-resizer.c +16 −11
  308. drivers/staging/media/rkisp1/rkisp1-stats.c +2 −3
  309. drivers/staging/media/soc_camera/soc_camera.c +1 −1
  310. drivers/staging/media/sunxi/cedrus/cedrus.c +1 −1
  311. drivers/staging/media/sunxi/cedrus/cedrus_h264.c +5 −1
  312. drivers/staging/media/tegra-vde/vde.c +9 −46
  313. drivers/staging/media/usbvision/Kconfig +7 −2
  314. drivers/staging/media/usbvision/Makefile +0 −0
  315. drivers/staging/media/usbvision/TODO +11 −0
  316. drivers/staging/media/usbvision/usbvision-cards.c +0 −0
  317. drivers/staging/media/usbvision/usbvision-cards.h +0 −0
  318. drivers/staging/media/usbvision/usbvision-core.c +0 −0
  319. drivers/staging/media/usbvision/usbvision-i2c.c +0 −0
  320. drivers/staging/media/usbvision/usbvision-video.c +1 −1
  321. drivers/staging/media/usbvision/usbvision.h +0 −0
  322. drivers/staging/most/video/video.c +2 −2
  323. drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +1 −1
  324. drivers/usb/gadget/function/f_uvc.c +1 −1
  325. include/dt-bindings/display/sdtv-standards.h +76 −0
  326. include/dt-bindings/media/tvp5150.h +0 −2
  327. include/linux/atmel-isc-media.h +58 −0
  328. include/media/cec-notifier.h +8 −31
  329. include/media/h264-ctrls.h +2 −0
  330. include/media/i2c/smiapp.h +0 −63
  331. include/media/rc-core.h +4 −4
  332. include/media/rc-map.h +3 −2
  333. include/media/v4l2-dev.h +2 −2
  334. include/media/v4l2-device.h +8 −8
  335. include/media/v4l2-fwnode.h +143 −0
  336. include/media/v4l2-mc.h +25 −15
  337. include/media/v4l2-mem2mem.h +133 −0
  338. include/media/v4l2-subdev.h +1 −1
  339. include/media/videobuf2-core.h +5 −2
  340. include/uapi/linux/media-bus-format.h +2 −1
  341. include/uapi/linux/v4l2-controls.h +6 −0
  342. include/uapi/linux/videodev2.h +9 −0
  343. samples/v4l/v4l2-pci-skeleton.c +1 −1
.mailmap+1−0
@@ -244,6 +244,7 @@ Santosh Shilimkar <ssantosh@kernel.org> · 243 unmodified lines
244Santosh Shilimkar <santosh.shilimkar@oracle.org>244Santosh Shilimkar <santosh.shilimkar@oracle.org>
245Sascha Hauer <s.hauer@pengutronix.de>245Sascha Hauer <s.hauer@pengutronix.de>
246S.Çağlar Onur <caglar@pardus.org.tr>246S.Çağlar Onur <caglar@pardus.org.tr>
247Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
247Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk>248Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk>
248Sebastian Reichel <sre@kernel.org> <sre@debian.org>249Sebastian Reichel <sre@kernel.org> <sre@debian.org>
249Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>250Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
Documentation/devicetree/bindings/display/connector/analog-tv-connector.txt+6−0
@@ -6,16 +6,22 @@ Required properties: · 5 unmodified lines
6 6
7Optional properties:7Optional properties:
8- label: a symbolic name for the connector8- label: a symbolic name for the connector
9- sdtv-standards: limit the supported TV standards on a connector to the given
10 ones. If not specified all TV standards are allowed.
11 Possible TV standards are defined in
12 include/dt-bindings/display/sdtv-standards.h.
9 13
10Required nodes:14Required nodes:
11- Video port for TV input15- Video port for TV input
12 16
13Example17Example
14-------18-------
19#include <dt-bindings/display/sdtv-standards.h>
15 20
16tv: connector {21tv: connector {
17 compatible = "composite-video-connector";22 compatible = "composite-video-connector";
18 label = "tv";23 label = "tv";
24 sdtv-standards = <(SDTV_STD_PAL | SDTV_STD_NTSC)>;
19 25
20 port {26 port {
21 tv_connector_in: endpoint {27 tv_connector_in: endpoint {
Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml+70−0
@@ -0,0 +1,70 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/media/allwinner,sun8i-a83t-de2-rotate.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Allwinner A83T DE2 Rotate Device Tree Bindings
8
9maintainers:
10 - Jernej Skrabec <jernej.skrabec@siol.net>
11 - Chen-Yu Tsai <wens@csie.org>
12 - Maxime Ripard <mripard@kernel.org>
13
14description: |-
15 The Allwinner A83T and A64 have a rotation core used for
16 rotating and flipping images.
17
18properties:
19 compatible:
20 oneOf:
21 - const: allwinner,sun8i-a83t-de2-rotate
22 - items:
23 - const: allwinner,sun50i-a64-de2-rotate
24 - const: allwinner,sun8i-a83t-de2-rotate
25
26 reg:
27 maxItems: 1
28
29 interrupts:
30 maxItems: 1
31
32 clocks:
33 items:
34 - description: Rotate interface clock
35 - description: Rotate module clock
36
37 clock-names:
38 items:
39 - const: bus
40 - const: mod
41
42 resets:
43 maxItems: 1
44
45required:
46 - compatible
47 - reg
48 - interrupts
49 - clocks
50
51additionalProperties: false
52
53examples:
54 - |
55 #include <dt-bindings/interrupt-controller/arm-gic.h>
56 #include <dt-bindings/clock/sun8i-de2.h>
57 #include <dt-bindings/reset/sun8i-de2.h>
58
59 rotate: rotate@1020000 {
60 compatible = "allwinner,sun8i-a83t-de2-rotate";
61 reg = <0x1020000 0x10000>;
62 interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
63 clocks = <&display_clocks CLK_BUS_ROT>,
64 <&display_clocks CLK_ROT>;
65 clock-names = "bus",
66 "mod";
67 resets = <&display_clocks RST_ROT>;
68 };
69
70...
Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml+5−1
@@ -17,7 +17,11 @@ description: |- · 16 unmodified lines
17 17
18properties:18properties:
19 compatible:19 compatible:
20 const: allwinner,sun8i-h3-deinterlace20 oneOf:
21 - const: allwinner,sun8i-h3-deinterlace
22 - items:
23 - const: allwinner,sun50i-a64-deinterlace
24 - const: allwinner,sun8i-h3-deinterlace
21 25
22 reg:26 reg:
23 maxItems: 127 maxItems: 1
Documentation/devicetree/bindings/media/aspeed-video.txt+3−2
@@ -1,11 +1,12 @@
1* Device tree bindings for Aspeed Video Engine1* Device tree bindings for Aspeed Video Engine
2 2
3The Video Engine (VE) embedded in the Aspeed AST2400 and AST2500 SOCs can3The Video Engine (VE) embedded in the Aspeed AST2400/2500/2600 SOCs can
4capture and compress video data from digital or analog sources.4capture and compress video data from digital or analog sources.
5 5
6Required properties:6Required properties:
7 - compatible: "aspeed,ast2400-video-engine" or7 - compatible: "aspeed,ast2400-video-engine" or
8 "aspeed,ast2500-video-engine"8 "aspeed,ast2500-video-engine" or
9 "aspeed,ast2600-video-engine"
9 - reg: contains the offset and length of the VE memory region10 - reg: contains the offset and length of the VE memory region
10 - clocks: clock specifiers for the syscon clocks associated with11 - clocks: clock specifiers for the syscon clocks associated with
11 the VE (ordering must match the clock-names property)12 the VE (ordering must match the clock-names property)
Documentation/devicetree/bindings/media/i2c/imx219.yaml+114−0
@@ -0,0 +1,114 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/media/i2c/imx219.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Sony 1/4.0-Inch 8Mpixel CMOS Digital Image Sensor
8
9maintainers:
10 - Dave Stevenson <dave.stevenson@raspberrypi.com>
11
12description: |-
13 The Sony imx219 is a 1/4.0-inch CMOS active pixel digital image sensor
14 with an active array size of 3280H x 2464V. It is programmable through
15 I2C interface. The I2C address is fixed to 0x10 as per sensor data sheet.
16 Image data is sent through MIPI CSI-2, which is configured as either 2 or
17 4 data lanes.
18
19properties:
20 compatible:
21 const: sony,imx219
22
23 reg:
24 description: I2C device address
25 maxItems: 1
26
27 clocks:
28 maxItems: 1
29
30 VDIG-supply:
31 description:
32 Digital I/O voltage supply, 1.8 volts
33
34 VANA-supply:
35 description:
36 Analog voltage supply, 2.8 volts
37
38 VDDL-supply:
39 description:
40 Digital core voltage supply, 1.2 volts
41
42 reset-gpios:
43 description: |-
44 Reference to the GPIO connected to the xclr pin, if any.
45 Must be released (set high) after all supplies are applied.
46
47 # See ../video-interfaces.txt for more details
48 port:
49 type: object
50 properties:
51 endpoint:
52 type: object
53 properties:
54 data-lanes:
55 description: |-
56 The sensor supports either two-lane, or four-lane operation.
57 If this property is omitted four-lane operation is assumed.
58 For two-lane operation the property must be set to <1 2>.
59 items:
60 - const: 1
61 - const: 2
62
63 clock-noncontinuous:
64 type: boolean
65 description: |-
66 MIPI CSI-2 clock is non-continuous if this property is present,
67 otherwise it's continuous.
68
69 link-frequencies:
70 allOf:
71 - $ref: /schemas/types.yaml#/definitions/uint64-array
72 description:
73 Allowed data bus frequencies.
74
75 required:
76 - link-frequencies
77
78required:
79 - compatible
80 - reg
81 - clocks
82 - VANA-supply
83 - VDIG-supply
84 - VDDL-supply
85 - port
86
87additionalProperties: false
88
89examples:
90 - |
91 i2c0 {
92 #address-cells = <1>;
93 #size-cells = <0>;
94
95 imx219: sensor@10 {
96 compatible = "sony,imx219";
97 reg = <0x10>;
98 clocks = <&imx219_clk>;
99 VANA-supply = <&imx219_vana>; /* 2.8v */
100 VDIG-supply = <&imx219_vdig>; /* 1.8v */
101 VDDL-supply = <&imx219_vddl>; /* 1.2v */
102
103 port {
104 imx219_0: endpoint {
105 remote-endpoint = <&csi1_ep>;
106 data-lanes = <1 2>;
107 clock-noncontinuous;
108 link-frequencies = /bits/ 64 <456000000>;
109 };
110 };
111 };
112 };
113
114...
Documentation/devicetree/bindings/media/i2c/tvp5150.txt+129−17
@@ -5,38 +5,150 @@ The TVP5150 and TVP5151 are video decoders that convert baseband NTSC and PAL · 4 unmodified lines
5with discrete syncs or 8-bit ITU-R BT.656 with embedded syncs output formats.5with discrete syncs or 8-bit ITU-R BT.656 with embedded syncs output formats.
6 6
7Required Properties:7Required Properties:
8- compatible: value must be "ti,tvp5150"8====================
9- reg: I2C slave address9- compatible: Value must be "ti,tvp5150".
10- reg: I2C slave address.
10 11
11Optional Properties:12Optional Properties:
12- pdn-gpios: phandle for the GPIO connected to the PDN pin, if any.13====================
13- reset-gpios: phandle for the GPIO connected to the RESETB pin, if any.14- pdn-gpios: Phandle for the GPIO connected to the PDN pin, if any.
15- reset-gpios: Phandle for the GPIO connected to the RESETB pin, if any.
14 16
15The device node must contain one 'port' child node for its digital output17The device node must contain one 'port' child node per device physical input
16video port, in accordance with the video interface bindings defined in18and output port, in accordance with the video interface bindings defined in
17Documentation/devicetree/bindings/media/video-interfaces.txt.19Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes
20are numbered as follows
18 21
19Required Endpoint Properties for parallel synchronization:22 Name Type Port
23 --------------------------------------
24 AIP1A sink 0
25 AIP1B sink 1
26 Y-OUT src 2
20 27
21- hsync-active: active state of the HSYNC signal. Must be <1> (HIGH).28The device node must contain at least one sink port and the src port. Each input
22- vsync-active: active state of the VSYNC signal. Must be <1> (HIGH).29port must be linked to an endpoint defined in [1]. The port/connector layout is
23- field-even-active: field signal level during the even field data30as follows
24 transmission. Must be <0>.
25 31
26If none of hsync-active, vsync-active and field-even-active is specified,32tvp-5150 port@0 (AIP1A)
27the endpoint is assumed to use embedded BT.656 synchronization.33 endpoint@0 -----------> Comp0-Con port
34 endpoint@1 ------+----> Svideo-Con port
35tvp-5150 port@1 (AIP1B) |
36 endpoint@1 ------+
37 endpoint@0 -----------> Comp1-Con port
38tvp-5150 port@2
39 endpoint (video bitstream output at YOUT[0-7] parallel bus)
28 40
29Example:41Required Endpoint Properties for parallel synchronization on output port:
42=========================================================================
43
44- hsync-active: Active state of the HSYNC signal. Must be <1> (HIGH).
45- vsync-active: Active state of the VSYNC signal. Must be <1> (HIGH).
46- field-even-active: Field signal level during the even field data
47 transmission. Must be <0>.
48
49Note: Do not specify any of these properties if you want to use the embedded
50 BT.656 synchronization.
51
52Optional Connector Properties:
53==============================
54
55- sdtv-standards: Set the possible signals to which the hardware tries to lock
56 instead of using the autodetection mechnism. Please look at
57 [1] for more information.
58
59[1] Documentation/devicetree/bindings/display/connector/analog-tv-connector.txt.
60
61Example - three input sources:
62#include <dt-bindings/display/sdtv-standards.h>
63
64comp_connector_0 {
65 compatible = "composite-video-connector";
66 label = "Composite0";
67 sdtv-standards = <SDTV_STD_PAL_M>; /* limit to pal-m signals */
68
69 port {
70 composite0_to_tvp5150: endpoint {
71 remote-endpoint = <&tvp5150_to_composite0>;
72 };
73 };
74};
75
76comp_connector_1 {
77 compatible = "composite-video-connector";
78 label = "Composite1";
79 sdtv-standards = <SDTV_STD_NTSC_M>; /* limit to ntsc-m signals */
80
81 port {
82 composite1_to_tvp5150: endpoint {
83 remote-endpoint = <&tvp5150_to_composite1>;
84 };
85 };
86};
87
88svideo_connector {
89 compatible = "svideo-connector";
90 label = "S-Video";
91
92 port {
93 #address-cells = <1>;
94 #size-cells = <0>;
95
96 svideo_luma_to_tvp5150: endpoint@0 {
97 reg = <0>;
98 remote-endpoint = <&tvp5150_to_svideo_luma>;
99 };
100
101 svideo_chroma_to_tvp5150: endpoint@1 {
102 reg = <1>;
103 remote-endpoint = <&tvp5150_to_svideo_chroma>;
104 };
105 };
106};
30 107
31&i2c2 {108&i2c2 {
32 ...
33 tvp5150@5c {109 tvp5150@5c {
34 compatible = "ti,tvp5150";110 compatible = "ti,tvp5150";
35 reg = <0x5c>;111 reg = <0x5c>;
36 pdn-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>;112 pdn-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>;
37 reset-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>;113 reset-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>;
114 #address-cells = <1>;
115 #size-cells = <0>;
116
117 port@0 {
118 #address-cells = <1>;
119 #size-cells = <0>;
120 reg = <0>;
121
122 tvp5150_to_composite0: endpoint@0 {
123 reg = <0>;
124 remote-endpoint = <&composite0_to_tvp5150>;
125 };
126
127 tvp5150_to_svideo_luma: endpoint@1 {
128 reg = <1>;
129 remote-endpoint = <&svideo_luma_to_tvp5150>;
130 };
131 };
132
133 port@1 {
134 #address-cells = <1>;
135 #size-cells = <0>;
136 reg = <1>;
137
138 tvp5150_to_composite1: endpoint@0 {
139 reg = <0>;
140 remote-endpoint = <&composite1_to_tvp5150>;
141 };
142
143 tvp5150_to_svideo_chroma: endpoint@1 {
144 reg = <1>;
145 remote-endpoint = <&svideo_chroma_to_tvp5150>;
146 };
147 };
148
149 port@2 {
150 reg = <2>;
38 151
39 port {
40 tvp5150_1: endpoint {152 tvp5150_1: endpoint {
41 remote-endpoint = <&ccdc_ep>;153 remote-endpoint = <&ccdc_ep>;
42 };154 };
Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml+77−0
@@ -0,0 +1,77 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
3%YAML 1.2
4---
5$id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
6$schema: "http://devicetree.org/meta-schemas/core.yaml#"
7
8title: Hantro G1/G2 VPU codecs implemented on i.MX8MQ SoCs
9
10maintainers:
11 - Philipp Zabel <p.zabel@pengutronix.de>
12
13description:
14 Hantro G1/G2 video decode accelerators present on i.MX8MQ SoCs.
15
16properties:
17 compatible:
18 const: nxp,imx8mq-vpu
19
20 reg:
21 maxItems: 3
22
23 reg-names:
24 items:
25 - const: g1
26 - const: g2
27 - const: ctrl
28
29 interrupts:
30 maxItems: 2
31
32 interrupt-names:
33 items:
34 - const: g1
35 - const: g2
36
37 clocks:
38 maxItems: 3
39
40 clock-names:
41 items:
42 - const: g1
43 - const: g2
44 - const: bus
45
46 power-domains:
47 maxItems: 1
48
49required:
50 - compatible
51 - reg
52 - reg-names
53 - interrupts
54 - interrupt-names
55 - clocks
56 - clock-names
57
58examples:
59 - |
60 #include <dt-bindings/clock/imx8mq-clock.h>
61 #include <dt-bindings/interrupt-controller/arm-gic.h>
62
63 vpu: video-codec@38300000 {
64 compatible = "nxp,imx8mq-vpu";
65 reg = <0x38300000 0x10000>,
66 <0x38310000 0x10000>,
67 <0x38320000 0x10000>;
68 reg-names = "g1", "g2", "ctrl";
69 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
70 <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
71 interrupt-names = "g1", "g2";
72 clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
73 <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
74 <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
75 clock-names = "g1", "g2", "bus";
76 power-domains = <&pgc_vpu>;
77 };
Documentation/devicetree/bindings/media/qcom,msm8916-venus.yaml+119−0
@@ -0,0 +1,119 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
3%YAML 1.2
4---
5$id: "http://devicetree.org/schemas/media/qcom,msm8916-venus.yaml#"
6$schema: "http://devicetree.org/meta-schemas/core.yaml#"
7
8title: Qualcomm Venus video encode and decode accelerators
9
10maintainers:
11 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
12
13description: |
14 The Venus IP is a video encode and decode accelerator present
15 on Qualcomm platforms
16
17properties:
18 compatible:
19 const: qcom,msm8916-venus
20
21 reg:
22 maxItems: 1
23
24 interrupts:
25 maxItems: 1
26
27 power-domains:
28 maxItems: 1
29
30 clocks:
31 maxItems: 3
32
33 clock-names:
34 items:
35 - const: core
36 - const: iface
37 - const: bus
38
39 iommus:
40 maxItems: 1
41
42 memory-region:
43 maxItems: 1
44
45 video-decoder:
46 type: object
47
48 properties:
49 compatible:
50 const: "venus-decoder"
51
52 required:
53 - compatible
54
55 additionalProperties: false
56
57 video-encoder:
58 type: object
59
60 properties:
61 compatible:
62 const: "venus-encoder"
63
64 required:
65 - compatible
66
67 additionalProperties: false
68
69 video-firmware:
70 type: object
71
72 description: |
73 Firmware subnode is needed when the platform does not
74 have TrustZone.
75
76 properties:
77 iommus:
78 maxItems: 1
79
80 required:
81 - iommus
82
83required:
84 - compatible
85 - reg
86 - interrupts
87 - power-domains
88 - clocks
89 - clock-names
90 - iommus
91 - memory-region
92 - video-decoder
93 - video-encoder
94
95examples:
96 - |
97 #include <dt-bindings/interrupt-controller/arm-gic.h>
98 #include <dt-bindings/clock/qcom,gcc-msm8916.h>
99
100 video-codec@1d00000 {
101 compatible = "qcom,msm8916-venus";
102 reg = <0x01d00000 0xff000>;
103 interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
104 clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
105 <&gcc GCC_VENUS0_AHB_CLK>,
106 <&gcc GCC_VENUS0_AXI_CLK>;
107 clock-names = "core", "iface", "bus";
108 power-domains = <&gcc VENUS_GDSC>;
109 iommus = <&apps_iommu 5>;
110 memory-region = <&venus_mem>;
111
112 video-decoder {
113 compatible = "venus-decoder";
114 };
115
116 video-encoder {
117 compatible = "venus-encoder";
118 };
119 };
Documentation/devicetree/bindings/media/qcom,msm8996-venus.yaml+172−0
@@ -0,0 +1,172 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
3%YAML 1.2
4---
5$id: "http://devicetree.org/schemas/media/qcom,msm8996-venus.yaml#"
6$schema: "http://devicetree.org/meta-schemas/core.yaml#"
7
8title: Qualcomm Venus video encode and decode accelerators
9
10maintainers:
11 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
12
13description: |
14 The Venus IP is a video encode and decode accelerator present
15 on Qualcomm platforms
16
17properties:
18 compatible:
19 const: qcom,msm8996-venus
20
21 reg:
22 maxItems: 1
23
24 interrupts:
25 maxItems: 1
26
27 power-domains:
28 maxItems: 1
29
30 clocks:
31 maxItems: 4
32
33 clock-names:
34 items:
35 - const: core
36 - const: iface
37 - const: bus
38 - const: mbus
39
40 iommus:
41 maxItems: 20
42
43 memory-region:
44 maxItems: 1
45
46 video-decoder:
47 type: object
48
49 properties:
50 compatible:
51 const: venus-decoder
52
53 clocks:
54 maxItems: 1
55
56 clock-names:
57 items:
58 - const: core
59
60 power-domains:
61 maxItems: 1
62
63 required:
64 - compatible
65 - clocks
66 - clock-names
67 - power-domains
68
69 additionalProperties: false
70
71 video-encoder:
72 type: object
73
74 properties:
75 compatible:
76 const: venus-encoder
77
78 clocks:
79 maxItems: 1
80
81 clock-names:
82 items:
83 - const: core
84
85 power-domains:
86 maxItems: 1
87
88 required:
89 - compatible
90 - clocks
91 - clock-names
92 - power-domains
93
94 additionalProperties: false
95
96 video-firmware:
97 type: object
98
99 description: |
100 Firmware subnode is needed when the platform does not
101 have TrustZone.
102
103 properties:
104 iommus:
105 maxItems: 1
106
107 required:
108 - iommus
109
110required:
111 - compatible
112 - reg
113 - interrupts
114 - power-domains
115 - clocks
116 - clock-names
117 - iommus
118 - memory-region
119 - video-decoder
120 - video-encoder
121
122examples:
123 - |
124 #include <dt-bindings/interrupt-controller/arm-gic.h>
125 #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
126
127 video-codec@c00000 {
128 compatible = "qcom,msm8996-venus";
129 reg = <0x00c00000 0xff000>;
130 interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
131 clocks = <&mmcc VIDEO_CORE_CLK>,
132 <&mmcc VIDEO_AHB_CLK>,
133 <&mmcc VIDEO_AXI_CLK>,
134 <&mmcc VIDEO_MAXI_CLK>;
135 clock-names = "core", "iface", "bus", "mbus";
136 power-domains = <&mmcc VENUS_GDSC>;
137 iommus = <&venus_smmu 0x00>,
138 <&venus_smmu 0x01>,
139 <&venus_smmu 0x0a>,
140 <&venus_smmu 0x07>,
141 <&venus_smmu 0x0e>,
142 <&venus_smmu 0x0f>,
143 <&venus_smmu 0x08>,
144 <&venus_smmu 0x09>,
145 <&venus_smmu 0x0b>,
146 <&venus_smmu 0x0c>,
147 <&venus_smmu 0x0d>,
148 <&venus_smmu 0x10>,
149 <&venus_smmu 0x11>,
150 <&venus_smmu 0x21>,
151 <&venus_smmu 0x28>,
152 <&venus_smmu 0x29>,
153 <&venus_smmu 0x2b>,
154 <&venus_smmu 0x2c>,
155 <&venus_smmu 0x2d>,
156 <&venus_smmu 0x31>;
157 memory-region = <&venus_mem>;
158
159 video-decoder {
160 compatible = "venus-decoder";
161 clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
162 clock-names = "core";
163 power-domains = <&mmcc VENUS_CORE0_GDSC>;
164 };
165
166 video-encoder {
167 compatible = "venus-encoder";
168 clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
169 clock-names = "core";
170 power-domains = <&mmcc VENUS_CORE1_GDSC>;
171 };
172 };
Documentation/devicetree/bindings/media/qcom,sc7180-venus.yaml+140−0
@@ -0,0 +1,140 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
3%YAML 1.2
4---
5$id: "http://devicetree.org/schemas/media/qcom,sc7180-venus.yaml#"
6$schema: "http://devicetree.org/meta-schemas/core.yaml#"
7
8title: Qualcomm Venus video encode and decode accelerators
9
10maintainers:
11 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
12
13description: |
14 The Venus IP is a video encode and decode accelerator present
15 on Qualcomm platforms
16
17properties:
18 compatible:
19 const: qcom,sc7180-venus
20
21 reg:
22 maxItems: 1
23
24 interrupts:
25 maxItems: 1
26
27 power-domains:
28 maxItems: 2
29
30 power-domain-names:
31 items:
32 - const: venus
33 - const: vcodec0
34
35 clocks:
36 maxItems: 5
37
38 clock-names:
39 items:
40 - const: core
41 - const: iface
42 - const: bus
43 - const: vcodec0_core
44 - const: vcodec0_bus
45
46 iommus:
47 maxItems: 1
48
49 memory-region:
50 maxItems: 1
51
52 interconnects:
53 maxItems: 2
54
55 interconnect-names:
56 items:
57 - const: video-mem
58 - const: cpu-cfg
59
60 video-decoder:
61 type: object
62
63 properties:
64 compatible:
65 const: venus-decoder
66
67 required:
68 - compatible
69
70 additionalProperties: false
71
72 video-encoder:
73 type: object
74
75 properties:
76 compatible:
77 const: venus-encoder
78
79 required:
80 - compatible
81
82 additionalProperties: false
83
84 video-firmware:
85 type: object
86
87 description: |
88 Firmware subnode is needed when the platform does not
89 have TrustZone.
90
91 properties:
92 iommus:
93 maxItems: 1
94
95 required:
96 - iommus
97
98required:
99 - compatible
100 - reg
101 - interrupts
102 - power-domains
103 - power-domain-names
104 - clocks
105 - clock-names
106 - iommus
107 - memory-region
108 - video-decoder
109 - video-encoder
110
111examples:
112 - |
113 #include <dt-bindings/interrupt-controller/arm-gic.h>
114 #include <dt-bindings/clock/qcom,videocc-sc7180.h>
115
116 venus: video-codec@aa00000 {
117 compatible = "qcom,sc7180-venus";
118 reg = <0 0x0aa00000 0 0xff000>;
119 interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
120 power-domains = <&videocc VENUS_GDSC>,
121 <&videocc VCODEC0_GDSC>;
122 power-domain-names = "venus", "vcodec0";
123 clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
124 <&videocc VIDEO_CC_VENUS_AHB_CLK>,
125 <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>,
126 <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
127 <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
128 clock-names = "core", "iface", "bus",
129 "vcodec0_core", "vcodec0_bus";
130 iommus = <&apps_smmu 0x0c00 0x60>;
131 memory-region = <&venus_mem>;
132
133 video-decoder {
134 compatible = "venus-decoder";
135 };
136
137 video-encoder {
138 compatible = "venus-encoder";
139 };
140 };
Documentation/devicetree/bindings/media/qcom,sdm845-venus-v2.yaml+140−0
@@ -0,0 +1,140 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
3%YAML 1.2
4---
5$id: "http://devicetree.org/schemas/media/qcom,sdm845-venus-v2.yaml#"
6$schema: "http://devicetree.org/meta-schemas/core.yaml#"
7
8title: Qualcomm Venus video encode and decode accelerators
9
10maintainers:
11 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
12
13description: |
14 The Venus IP is a video encode and decode accelerator present
15 on Qualcomm platforms
16
17properties:
18 compatible:
19 const: qcom,sdm845-venus-v2
20
21 reg:
22 maxItems: 1
23
24 interrupts:
25 maxItems: 1
26
27 power-domains:
28 maxItems: 3
29
30 power-domain-names:
31 items:
32 - const: venus
33 - const: vcodec0
34 - const: vcodec1
35
36 clocks:
37 maxItems: 7
38
39 clock-names:
40 items:
41 - const: core
42 - const: iface
43 - const: bus
44 - const: vcodec0_core
45 - const: vcodec0_bus
46 - const: vcodec1_core
47 - const: vcodec1_bus
48
49 iommus:
50 maxItems: 2
51
52 memory-region:
53 maxItems: 1
54
55 video-core0:
56 type: object
57
58 properties:
59 compatible:
60 const: venus-decoder
61
62 required:
63 - compatible
64
65 additionalProperties: false
66
67 video-core1:
68 type: object
69
70 properties:
71 compatible:
72 const: venus-encoder
73
74 required:
75 - compatible
76
77 additionalProperties: false
78
79 video-firmware:
80 type: object
81
82 description: |
83 Firmware subnode is needed when the platform does not
84 have TrustZone.
85
86 properties:
87 iommus:
88 maxItems: 1
89
90 required:
91 - iommus
92
93required:
94 - compatible
95 - reg
96 - interrupts
97 - power-domains
98 - power-domain-names
99 - clocks
100 - clock-names
101 - iommus
102 - memory-region
103 - video-core0
104 - video-core1
105
106examples:
107 - |
108 #include <dt-bindings/interrupt-controller/arm-gic.h>
109 #include <dt-bindings/clock/qcom,videocc-sdm845.h>
110
111 video-codec@aa00000 {
112 compatible = "qcom,sdm845-venus-v2";
113 reg = <0 0x0aa00000 0 0xff000>;
114 interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
115 clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
116 <&videocc VIDEO_CC_VENUS_AHB_CLK>,
117 <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>,
118 <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
119 <&videocc VIDEO_CC_VCODEC0_AXI_CLK>,
120 <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
121 <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
122 clock-names = "core", "iface", "bus",
123 "vcodec0_core", "vcodec0_bus",
124 "vcodec1_core", "vcodec1_bus";
125 power-domains = <&videocc VENUS_GDSC>,
126 <&videocc VCODEC0_GDSC>,
127 <&videocc VCODEC1_GDSC>;
128 power-domain-names = "venus", "vcodec0", "vcodec1";
129 iommus = <&apps_smmu 0x10a0 0x8>,
130 <&apps_smmu 0x10b0 0x0>;
131 memory-region = <&venus_mem>;
132
133 video-core0 {
134 compatible = "venus-decoder";
135 };
136
137 video-core1 {
138 compatible = "venus-encoder";
139 };
140 };
Documentation/devicetree/bindings/media/qcom,sdm845-venus.yaml+156−0
@@ -0,0 +1,156 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2
3%YAML 1.2
4---
5$id: "http://devicetree.org/schemas/media/qcom,sdm845-venus.yaml#"
6$schema: "http://devicetree.org/meta-schemas/core.yaml#"
7
8title: Qualcomm Venus video encode and decode accelerators
9
10maintainers:
11 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
12
13description: |
14 The Venus IP is a video encode and decode accelerator present
15 on Qualcomm platforms
16
17properties:
18 compatible:
19 const: qcom,sdm845-venus
20
21 reg:
22 maxItems: 1
23
24 interrupts:
25 maxItems: 1
26
27 power-domains:
28 maxItems: 1
29
30 clocks:
31 maxItems: 3
32
33 clock-names:
34 items:
35 - const: core
36 - const: iface
37 - const: bus
38
39 iommus:
40 maxItems: 2
41
42 memory-region:
43 maxItems: 1
44
45 video-core0:
46 type: object
47
48 properties:
49 compatible:
50 const: venus-decoder
51
52 clocks:
53 maxItems: 2
54
55 clock-names:
56 items:
57 - const: core
58 - const: bus
59
60 power-domains:
61 maxItems: 1
62
63 required:
64 - compatible
65 - clocks
66 - clock-names
67 - power-domains
68
69 additionalProperties: false
70
71 video-core1:
72 type: object
73
74 properties:
75 compatible:
76 const: venus-encoder
77
78 clocks:
79 maxItems: 2
80
81 clock-names:
82 items:
83 - const: core
84 - const: bus
85
86 power-domains:
87 maxItems: 1
88
89 required:
90 - compatible
91 - clocks
92 - clock-names
93 - power-domains
94
95 additionalProperties: false
96
97 video-firmware:
98 type: object
99
100 description: |
101 Firmware subnode is needed when the platform does not
102 have TrustZone.
103
104 properties:
105 iommus:
106 maxItems: 1
107
108 required:
109 - iommus
110
111required:
112 - compatible
113 - reg
114 - interrupts
115 - power-domains
116 - clocks
117 - clock-names
118 - iommus
119 - memory-region
120 - video-core0
121 - video-core1
122
123examples:
124 - |
125 #include <dt-bindings/interrupt-controller/arm-gic.h>
126 #include <dt-bindings/clock/qcom,videocc-sdm845.h>
127
128 video-codec@aa00000 {
129 compatible = "qcom,sdm845-venus";
130 reg = <0 0x0aa00000 0 0xff000>;
131 interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
132 clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
133 <&videocc VIDEO_CC_VENUS_AHB_CLK>,
134 <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>;
135 clock-names = "core", "iface", "bus";
136 power-domains = <&videocc VENUS_GDSC>;
137 iommus = <&apps_smmu 0x10a0 0x8>,
138 <&apps_smmu 0x10b0 0x0>;
139 memory-region = <&venus_mem>;
140
141 video-core0 {
142 compatible = "venus-decoder";
143 clocks = <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
144 <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
145 clock-names = "core", "bus";
146 power-domains = <&videocc VCODEC0_GDSC>;
147 };
148
149 video-core1 {
150 compatible = "venus-encoder";
151 clocks = <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
152 <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
153 clock-names = "core", "bus";
154 power-domains = <&videocc VCODEC1_GDSC>;
155 };
156 };
Documentation/devicetree/bindings/media/qcom,venus.txt+0−120
@@ -1,120 +0,0 @@
1* Qualcomm Venus video encoder/decoder accelerators
2
3- compatible:
4 Usage: required
5 Value type: <stringlist>
6 Definition: Value should contain one of:
7 - "qcom,msm8916-venus"
8 - "qcom,msm8996-venus"
9 - "qcom,sdm845-venus"
10- reg:
11 Usage: required
12 Value type: <prop-encoded-array>
13 Definition: Register base address and length of the register map.
14- interrupts:
15 Usage: required
16 Value type: <prop-encoded-array>
17 Definition: Should contain interrupt line number.
18- clocks:
19 Usage: required
20 Value type: <prop-encoded-array>
21 Definition: A List of phandle and clock specifier pairs as listed
22 in clock-names property.
23- clock-names:
24 Usage: required for msm8916
25 Value type: <stringlist>
26 Definition: Should contain the following entries:
27 - "core" Core video accelerator clock
28 - "iface" Video accelerator AHB clock
29 - "bus" Video accelerator AXI clock
30- clock-names:
31 Usage: required for msm8996
32 Value type: <stringlist>
33 Definition: Should contain the following entries:
34 - "core" Core video accelerator clock
35 - "iface" Video accelerator AHB clock
36 - "bus" Video accelerator AXI clock
37 - "mbus" Video MAXI clock
38- power-domains:
39 Usage: required
40 Value type: <prop-encoded-array>
41 Definition: A phandle and power domain specifier pairs to the
42 power domain which is responsible for collapsing
43 and restoring power to the peripheral.
44- iommus:
45 Usage: required
46 Value type: <prop-encoded-array>
47 Definition: A list of phandle and IOMMU specifier pairs.
48- memory-region:
49 Usage: required
50 Value type: <phandle>
51 Definition: reference to the reserved-memory for the firmware
52 memory region.
53
54* Subnodes
55The Venus video-codec node must contain two subnodes representing
56video-decoder and video-encoder, and one optional firmware subnode.
57Firmware subnode is needed when the platform does not have TrustZone.
58
59Every of video-encoder or video-decoder subnode should have:
60
61- compatible:
62 Usage: required
63 Value type: <stringlist>
64 Definition: Value should contain "venus-decoder" or "venus-encoder"
65- clocks:
66 Usage: required for msm8996
67 Value type: <prop-encoded-array>
68 Definition: A List of phandle and clock specifier pairs as listed
69 in clock-names property.
70- clock-names:
71 Usage: required for msm8996
72 Value type: <stringlist>
73 Definition: Should contain the following entries:
74 - "core" Subcore video accelerator clock
75
76- power-domains:
77 Usage: required for msm8996
78 Value type: <prop-encoded-array>
79 Definition: A phandle and power domain specifier pairs to the
80 power domain which is responsible for collapsing
81 and restoring power to the subcore.
82
83The firmware subnode must have:
84
85- iommus:
86 Usage: required
87 Value type: <prop-encoded-array>
88 Definition: A list of phandle and IOMMU specifier pairs.
89
90* An Example
91 video-codec@1d00000 {
92 compatible = "qcom,msm8916-venus";
93 reg = <0x01d00000 0xff000>;
94 interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
95 clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
96 <&gcc GCC_VENUS0_AHB_CLK>,
97 <&gcc GCC_VENUS0_AXI_CLK>;
98 clock-names = "core", "iface", "bus";
99 power-domains = <&gcc VENUS_GDSC>;
100 iommus = <&apps_iommu 5>;
101 memory-region = <&venus_mem>;
102
103 video-decoder {
104 compatible = "venus-decoder";
105 clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
106 clock-names = "core";
107 power-domains = <&mmcc VENUS_CORE0_GDSC>;
108 };
109
110 video-encoder {
111 compatible = "venus-encoder";
112 clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
113 clock-names = "core";
114 power-domains = <&mmcc VENUS_CORE1_GDSC>;
115 };
116
117 video-firmware {
118 iommus = <&apps_iommu 0x10b2 0x0>;
119 };
120 };
Documentation/devicetree/bindings/media/rc.yaml+1−0
@@ -143,6 +143,7 @@ properties: · 142 unmodified lines
143 - rc-videomate-k100143 - rc-videomate-k100
144 - rc-videomate-s350144 - rc-videomate-s350
145 - rc-videomate-tv-pvr145 - rc-videomate-tv-pvr
146 - rc-videostrong-kii-pro
146 - rc-wetek-hub147 - rc-wetek-hub
147 - rc-wetek-play2148 - rc-wetek-play2
148 - rc-winfast149 - rc-winfast
Documentation/devicetree/bindings/media/rockchip-rga.txt+3−2
@@ -6,8 +6,9 @@ BitBLT, alpha blending and image blur/sharpness. · 5 unmodified lines
6 6
7Required properties:7Required properties:
8- compatible: value should be one of the following8- compatible: value should be one of the following
9 "rockchip,rk3288-rga";9 "rockchip,rk3228-rga", "rockchip,rk3288-rga": for Rockchip RK3228
10 "rockchip,rk3399-rga";10 "rockchip,rk3288-rga": for Rockchip RK3288
11 "rockchip,rk3399-rga": for Rockchip RK3399
11 12
12- interrupts: RGA interrupt specifier.13- interrupts: RGA interrupt specifier.
13 14
Documentation/media/kapi/csi2.rst+1−1
@@ -74,7 +74,7 @@ Before the receiver driver may enable the CSI-2 transmitter by using · 73 unmodified lines
74the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered74the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered
75the transmitter up by using the75the transmitter up by using the
76:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take76:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
77place either indirectly by using :c:func:`v4l2_pipeline_pm_use` or77place either indirectly by using :c:func:`v4l2_pipeline_pm_get` or
78directly.78directly.
79 79
80Formats80Formats
Documentation/media/kapi/v4l2-dev.rst+2−2
@@ -185,7 +185,7 @@ This will create the character device for you. · 184 unmodified lines
185 185
186.. code-block:: c186.. code-block:: c
187 187
188 err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);188 err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
189 if (err) {189 if (err) {
190 video_device_release(vdev); /* or kfree(my_vdev); */190 video_device_release(vdev); /* or kfree(my_vdev); */
191 return err;191 return err;
@@ -201,7 +201,7 @@ types exist: · 9 unmodified lines
201========================== ==================== ==============================201========================== ==================== ==============================
202:c:type:`vfl_devnode_type` Device name Usage202:c:type:`vfl_devnode_type` Device name Usage
203========================== ==================== ==============================203========================== ==================== ==============================
204``VFL_TYPE_GRABBER`` ``/dev/videoX`` for video input/output devices204``VFL_TYPE_VIDEO`` ``/dev/videoX`` for video input/output devices
205``VFL_TYPE_VBI`` ``/dev/vbiX`` for vertical blank data (i.e.205``VFL_TYPE_VBI`` ``/dev/vbiX`` for vertical blank data (i.e.
206 closed captions, teletext)206 closed captions, teletext)
207``VFL_TYPE_RADIO`` ``/dev/radioX`` for radio tuners207``VFL_TYPE_RADIO`` ``/dev/radioX`` for radio tuners
Documentation/media/uapi/cec/cec-ioc-adap-g-conn-info.rst+5−5
@@ -44,18 +44,18 @@ is only available if the ``CEC_CAP_CONNECTOR_INFO`` capability is set. · 43 unmodified lines
44.. flat-table:: struct cec_connector_info44.. flat-table:: struct cec_connector_info
45 :header-rows: 045 :header-rows: 0
46 :stub-columns: 046 :stub-columns: 0
47 :widths: 1 1 1 847 :widths: 1 1 8
48 48
49 * - __u3249 * - __u32
50 - ``type``50 - ``type``
51 - The type of connector this adapter is associated with.51 - The type of connector this adapter is associated with.
52 * - union52 * - union {
53 - ``(anonymous)``53 - ``(anonymous)``
54 -54 * - ``struct cec_drm_connector_info``
55 * -
56 - ``struct cec_drm_connector_info``
57 - drm55 - drm
58 - :ref:`cec-drm-connector-info`56 - :ref:`cec-drm-connector-info`
57 * - }
58 -
59 59
60 60
61.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|61.. tabularcolumns:: |p{4.4cm}|p{2.5cm}|p{10.6cm}|
Documentation/media/uapi/cec/cec-ioc-dqevent.rst+9−11
@@ -109,35 +109,33 @@ it is guaranteed that the state did change in between the two events. · 108 unmodified lines
109.. flat-table:: struct cec_event109.. flat-table:: struct cec_event
110 :header-rows: 0110 :header-rows: 0
111 :stub-columns: 0111 :stub-columns: 0
112 :widths: 1 1 1 8112 :widths: 1 1 8
113 113
114 * - __u64114 * - __u64
115 - ``ts``115 - ``ts``
116 - :cspan:`1`\ Timestamp of the event in ns.116 - Timestamp of the event in ns.
117 117
118 The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock.118 The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock.
119 119
120 To access the same clock from userspace use :c:func:`clock_gettime`.120 To access the same clock from userspace use :c:func:`clock_gettime`.
121 * - __u32121 * - __u32
122 - ``event``122 - ``event``
123 - :cspan:`1` The CEC event type, see :ref:`cec-events`.123 - The CEC event type, see :ref:`cec-events`.
124 * - __u32124 * - __u32
125 - ``flags``125 - ``flags``
126 - :cspan:`1` Event flags, see :ref:`cec-event-flags`.126 - Event flags, see :ref:`cec-event-flags`.
127 * - union127 * - union {
128 - (anonymous)128 - (anonymous)
129 -129 * - struct cec_event_state_change
130 -
131 * -
132 - struct cec_event_state_change
133 - ``state_change``130 - ``state_change``
134 - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>`131 - The new adapter state as sent by the :ref:`CEC_EVENT_STATE_CHANGE <CEC-EVENT-STATE-CHANGE>`
135 event.132 event.
136 * -133 * - struct cec_event_lost_msgs
137 - struct cec_event_lost_msgs
138 - ``lost_msgs``134 - ``lost_msgs``
139 - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS <CEC-EVENT-LOST-MSGS>`135 - The number of lost messages as sent by the :ref:`CEC_EVENT_LOST_MSGS <CEC-EVENT-LOST-MSGS>`
140 event.136 event.
137 * - }
138 -
141 139
142 140
143.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|141.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst+7−17
@@ -64,12 +64,11 @@ id's until they get an error. · 63 unmodified lines
64.. flat-table:: struct media_entity_desc64.. flat-table:: struct media_entity_desc
65 :header-rows: 065 :header-rows: 0
66 :stub-columns: 066 :stub-columns: 0
67 :widths: 1 1 1 1 867 :widths: 2 2 1 8
68 68
69 * - __u3269 * - __u32
70 - ``id``70 - ``id``
71 -71 -
72 -
73 - Entity ID, set by the application. When the ID is or'ed with72 - Entity ID, set by the application. When the ID is or'ed with
74 ``MEDIA_ENT_ID_FLAG_NEXT``, the driver clears the flag and returns73 ``MEDIA_ENT_ID_FLAG_NEXT``, the driver clears the flag and returns
75 the first entity with a larger ID. Do not expect that the ID will74 the first entity with a larger ID. Do not expect that the ID will
@@ -79,79 +78,70 @@ id's until they get an error. · 3 unmodified lines
79 * - char78 * - char
80 - ``name``\ [32]79 - ``name``\ [32]
81 -80 -
82 -
83 - Entity name as an UTF-8 NULL-terminated string. This name must be unique81 - Entity name as an UTF-8 NULL-terminated string. This name must be unique
84 within the media topology.82 within the media topology.
85 83
86 * - __u3284 * - __u32
87 - ``type``85 - ``type``
88 -86 -
89 -
90 - Entity type, see :ref:`media-entity-functions` for details.87 - Entity type, see :ref:`media-entity-functions` for details.
91 88
92 * - __u3289 * - __u32
93 - ``revision``90 - ``revision``
94 -91 -
95 -
96 - Entity revision. Always zero (obsolete)92 - Entity revision. Always zero (obsolete)
97 93
98 * - __u3294 * - __u32
99 - ``flags``95 - ``flags``
100 -96 -
101 -
102 - Entity flags, see :ref:`media-entity-flag` for details.97 - Entity flags, see :ref:`media-entity-flag` for details.
103 98
104 * - __u3299 * - __u32
105 - ``group_id``100 - ``group_id``
106 -101 -
107 -
108 - Entity group ID. Always zero (obsolete)102 - Entity group ID. Always zero (obsolete)
109 103
110 * - __u16104 * - __u16
111 - ``pads``105 - ``pads``
112 -106 -
113 -
114 - Number of pads107 - Number of pads
115 108
116 * - __u16109 * - __u16
117 - ``links``110 - ``links``
118 -111 -
119 -
120 - Total number of outbound links. Inbound links are not counted in112 - Total number of outbound links. Inbound links are not counted in
121 this field.113 this field.
122 114
123 * - __u32115 * - __u32
124 - ``reserved[4]``116 - ``reserved[4]``
125 -117 -
126 -
127 - Reserved for future extensions. Drivers and applications must set118 - Reserved for future extensions. Drivers and applications must set
128 the array to zero.119 the array to zero.
129 120
130 * - union121 * - union {
122 - (anonymous)
131 123
132 * -124 * - struct
133 - struct
134 - ``dev``125 - ``dev``
135 -126 -
136 - Valid for (sub-)devices that create a single device node.127 - Valid for (sub-)devices that create a single device node.
137 128
138 * -129 * -
139 -
140 - __u32130 - __u32
141 - ``major``131 - ``major``
142 - Device node major number.132 - Device node major number.
143 133
144 * -134 * -
145 -
146 - __u32135 - __u32
147 - ``minor``136 - ``minor``
148 - Device node minor number.137 - Device node minor number.
149 138
150 * -139 * - __u8
151 - __u8
152 - ``raw``\ [184]140 - ``raw``\ [184]
153 -141 -
154 -142 -
143 * - }
144 -
155 145
156 146
157Return Value147Return Value
Documentation/media/uapi/v4l/buffer.rst+16−37
@@ -172,11 +172,10 @@ struct v4l2_buffer · 171 unmodified lines
172.. flat-table:: struct v4l2_buffer172.. flat-table:: struct v4l2_buffer
173 :header-rows: 0173 :header-rows: 0
174 :stub-columns: 0174 :stub-columns: 0
175 :widths: 1 2 1 10175 :widths: 1 2 10
176 176
177 * - __u32177 * - __u32
178 - ``index``178 - ``index``
179 -
180 - Number of the buffer, set by the application except when calling179 - Number of the buffer, set by the application except when calling
181 :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, then it is set by the180 :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, then it is set by the
182 driver. This field can range from zero to the number of buffers181 driver. This field can range from zero to the number of buffers
@@ -186,14 +185,12 @@ struct v4l2_buffer · 3 unmodified lines
186 :ref:`VIDIOC_CREATE_BUFS` minus one.185 :ref:`VIDIOC_CREATE_BUFS` minus one.
187 * - __u32186 * - __u32
188 - ``type``187 - ``type``
189 -
190 - Type of the buffer, same as struct188 - Type of the buffer, same as struct
191 :c:type:`v4l2_format` ``type`` or struct189 :c:type:`v4l2_format` ``type`` or struct
192 :c:type:`v4l2_requestbuffers` ``type``, set190 :c:type:`v4l2_requestbuffers` ``type``, set
193 by the application. See :c:type:`v4l2_buf_type`191 by the application. See :c:type:`v4l2_buf_type`
194 * - __u32192 * - __u32
195 - ``bytesused``193 - ``bytesused``
196 -
197 - The number of bytes occupied by the data in the buffer. It depends194 - The number of bytes occupied by the data in the buffer. It depends
198 on the negotiated data format and may change with each buffer for195 on the negotiated data format and may change with each buffer for
199 compressed variable size data like JPEG images. Drivers must set196 compressed variable size data like JPEG images. Drivers must set
@@ -205,18 +202,15 @@ struct v4l2_buffer · 5 unmodified lines
205 ``planes`` pointer is used instead.202 ``planes`` pointer is used instead.
206 * - __u32203 * - __u32
207 - ``flags``204 - ``flags``
208 -
209 - Flags set by the application or driver, see :ref:`buffer-flags`.205 - Flags set by the application or driver, see :ref:`buffer-flags`.
210 * - __u32206 * - __u32
211 - ``field``207 - ``field``
212 -
213 - Indicates the field order of the image in the buffer, see208 - Indicates the field order of the image in the buffer, see
214 :c:type:`v4l2_field`. This field is not used when the buffer209 :c:type:`v4l2_field`. This field is not used when the buffer
215 contains VBI data. Drivers must set it when ``type`` refers to a210 contains VBI data. Drivers must set it when ``type`` refers to a
216 capture stream, applications when it refers to an output stream.211 capture stream, applications when it refers to an output stream.
217 * - struct timeval212 * - struct timeval
218 - ``timestamp``213 - ``timestamp``
219 -
220 - For capture streams this is time when the first data byte was214 - For capture streams this is time when the first data byte was
221 captured, as returned by the :c:func:`clock_gettime()` function215 captured, as returned by the :c:func:`clock_gettime()` function
222 for the relevant clock id; see ``V4L2_BUF_FLAG_TIMESTAMP_*`` in216 for the relevant clock id; see ``V4L2_BUF_FLAG_TIMESTAMP_*`` in
@@ -229,7 +223,6 @@ struct v4l2_buffer · 6 unmodified lines
229 stream.223 stream.
230 * - struct :c:type:`v4l2_timecode`224 * - struct :c:type:`v4l2_timecode`
231 - ``timecode``225 - ``timecode``
232 -
233 - When the ``V4L2_BUF_FLAG_TIMECODE`` flag is set in ``flags``, this226 - When the ``V4L2_BUF_FLAG_TIMECODE`` flag is set in ``flags``, this
234 structure contains a frame timecode. In227 structure contains a frame timecode. In
235 :c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and228 :c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and
@@ -239,10 +232,9 @@ struct v4l2_buffer · 3 unmodified lines
239 independent of the ``timestamp`` and ``sequence`` fields.232 independent of the ``timestamp`` and ``sequence`` fields.
240 * - __u32233 * - __u32
241 - ``sequence``234 - ``sequence``
242 -
243 - Set by the driver, counting the frames (not fields!) in sequence.235 - Set by the driver, counting the frames (not fields!) in sequence.
244 This field is set for both input and output devices.236 This field is set for both input and output devices.
245 * - :cspan:`3`237 * - :cspan:`2`
246 238
247 In :c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and239 In :c:type:`V4L2_FIELD_ALTERNATE <v4l2_field>` mode the top and
248 bottom field have the same sequence number. The count starts at240 bottom field have the same sequence number. The count starts at
@@ -262,13 +254,11 @@ struct v4l2_buffer · 13 unmodified lines
262 254
263 * - __u32255 * - __u32
264 - ``memory``256 - ``memory``
265 -
266 - This field must be set by applications and/or drivers in257 - This field must be set by applications and/or drivers in
267 accordance with the selected I/O method. See :c:type:`v4l2_memory`258 accordance with the selected I/O method. See :c:type:`v4l2_memory`
268 * - union259 * - union {
269 - ``m``260 - ``m``
270 * -261 * - __u32
271 - __u32
272 - ``offset``262 - ``offset``
273 - For the single-planar API and when ``memory`` is263 - For the single-planar API and when ``memory`` is
274 ``V4L2_MEMORY_MMAP`` this is the offset of the buffer from the264 ``V4L2_MEMORY_MMAP`` this is the offset of the buffer from the
@@ -276,29 +266,27 @@ struct v4l2_buffer · 1 unmodified line
276 and apart of serving as parameter to the266 and apart of serving as parameter to the
277 :ref:`mmap() <func-mmap>` function not useful for applications.267 :ref:`mmap() <func-mmap>` function not useful for applications.
278 See :ref:`mmap` for details268 See :ref:`mmap` for details
279 * -269 * - unsigned long
280 - unsigned long
281 - ``userptr``270 - ``userptr``
282 - For the single-planar API and when ``memory`` is271 - For the single-planar API and when ``memory`` is
283 ``V4L2_MEMORY_USERPTR`` this is a pointer to the buffer (casted to272 ``V4L2_MEMORY_USERPTR`` this is a pointer to the buffer (casted to
284 unsigned long type) in virtual memory, set by the application. See273 unsigned long type) in virtual memory, set by the application. See
285 :ref:`userp` for details.274 :ref:`userp` for details.
286 * -275 * - struct v4l2_plane
287 - struct v4l2_plane
288 - ``*planes``276 - ``*planes``
289 - When using the multi-planar API, contains a userspace pointer to277 - When using the multi-planar API, contains a userspace pointer to
290 an array of struct :c:type:`v4l2_plane`. The size of278 an array of struct :c:type:`v4l2_plane`. The size of
291 the array should be put in the ``length`` field of this279 the array should be put in the ``length`` field of this
292 struct :c:type:`v4l2_buffer` structure.280 struct :c:type:`v4l2_buffer` structure.
293 * -281 * - int
294 - int
295 - ``fd``282 - ``fd``
296 - For the single-plane API and when ``memory`` is283 - For the single-plane API and when ``memory`` is
297 ``V4L2_MEMORY_DMABUF`` this is the file descriptor associated with284 ``V4L2_MEMORY_DMABUF`` this is the file descriptor associated with
298 a DMABUF buffer.285 a DMABUF buffer.
286 * - }
287 -
299 * - __u32288 * - __u32
300 - ``length``289 - ``length``
301 -
302 - Size of the buffer (not the payload) in bytes for the290 - Size of the buffer (not the payload) in bytes for the
303 single-planar API. This is set by the driver based on the calls to291 single-planar API. This is set by the driver based on the calls to
304 :ref:`VIDIOC_REQBUFS` and/or292 :ref:`VIDIOC_REQBUFS` and/or
@@ -308,12 +296,10 @@ struct v4l2_buffer · 3 unmodified lines
308 actual number of valid elements in that array.296 actual number of valid elements in that array.
309 * - __u32297 * - __u32
310 - ``reserved2``298 - ``reserved2``
311 -
312 - A place holder for future extensions. Drivers and applications299 - A place holder for future extensions. Drivers and applications
313 must set this to 0.300 must set this to 0.
314 * - __u32301 * - __u32
315 - ``request_fd``302 - ``request_fd``
316 -
317 - The file descriptor of the request to queue the buffer to. If the flag303 - The file descriptor of the request to queue the buffer to. If the flag
318 ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be304 ``V4L2_BUF_FLAG_REQUEST_FD`` is set, then the buffer will be
319 queued to this request. If the flag is not set, then this field will305 queued to this request. If the flag is not set, then this field will
@@ -344,11 +330,10 @@ struct v4l2_plane · 24 unmodified lines
344.. flat-table::330.. flat-table::
345 :header-rows: 0331 :header-rows: 0
346 :stub-columns: 0332 :stub-columns: 0
347 :widths: 1 1 1 2333 :widths: 1 1 2
348 334
349 * - __u32335 * - __u32
350 - ``bytesused``336 - ``bytesused``
351 -
352 - The number of bytes occupied by data in the plane (its payload).337 - The number of bytes occupied by data in the plane (its payload).
353 Drivers must set this field when ``type`` refers to a capture338 Drivers must set this field when ``type`` refers to a capture
354 stream, applications when it refers to an output stream. If the339 stream, applications when it refers to an output stream. If the
@@ -362,40 +347,35 @@ struct v4l2_plane · 7 unmodified lines
362 which may not be 0.347 which may not be 0.
363 * - __u32348 * - __u32
364 - ``length``349 - ``length``
365 -
366 - Size in bytes of the plane (not its payload). This is set by the350 - Size in bytes of the plane (not its payload). This is set by the
367 driver based on the calls to351 driver based on the calls to
368 :ref:`VIDIOC_REQBUFS` and/or352 :ref:`VIDIOC_REQBUFS` and/or
369 :ref:`VIDIOC_CREATE_BUFS`.353 :ref:`VIDIOC_CREATE_BUFS`.
370 * - union354 * - union {
371 - ``m``355 - ``m``
372 -356 * - __u32
373 -
374 * -
375 - __u32
376 - ``mem_offset``357 - ``mem_offset``
377 - When the memory type in the containing struct358 - When the memory type in the containing struct
378 :c:type:`v4l2_buffer` is ``V4L2_MEMORY_MMAP``, this359 :c:type:`v4l2_buffer` is ``V4L2_MEMORY_MMAP``, this
379 is the value that should be passed to :ref:`mmap() <func-mmap>`,360 is the value that should be passed to :ref:`mmap() <func-mmap>`,
380 similar to the ``offset`` field in struct361 similar to the ``offset`` field in struct
381 :c:type:`v4l2_buffer`.362 :c:type:`v4l2_buffer`.
382 * -363 * - unsigned long
383 - unsigned long
384 - ``userptr``364 - ``userptr``
385 - When the memory type in the containing struct365 - When the memory type in the containing struct
386 :c:type:`v4l2_buffer` is ``V4L2_MEMORY_USERPTR``,366 :c:type:`v4l2_buffer` is ``V4L2_MEMORY_USERPTR``,
387 this is a userspace pointer to the memory allocated for this plane367 this is a userspace pointer to the memory allocated for this plane
388 by an application.368 by an application.
389 * -369 * - int
390 - int
391 - ``fd``370 - ``fd``
392 - When the memory type in the containing struct371 - When the memory type in the containing struct
393 :c:type:`v4l2_buffer` is ``V4L2_MEMORY_DMABUF``,372 :c:type:`v4l2_buffer` is ``V4L2_MEMORY_DMABUF``,
394 this is a file descriptor associated with a DMABUF buffer, similar373 this is a file descriptor associated with a DMABUF buffer, similar
395 to the ``fd`` field in struct :c:type:`v4l2_buffer`.374 to the ``fd`` field in struct :c:type:`v4l2_buffer`.
375 * - }
376 -
396 * - __u32377 * - __u32
397 - ``data_offset``378 - ``data_offset``
398 -
399 - Offset in bytes to video data in the plane. Drivers must set this379 - Offset in bytes to video data in the plane. Drivers must set this
400 field when ``type`` refers to a capture stream, applications when380 field when ``type`` refers to a capture stream, applications when
401 it refers to an output stream.381 it refers to an output stream.
@@ -407,7 +387,6 @@ struct v4l2_plane · 5 unmodified lines
407 at offset ``data_offset`` from the start of the plane.387 at offset ``data_offset`` from the start of the plane.
408 * - __u32388 * - __u32
409 - ``reserved[11]``389 - ``reserved[11]``
410 -
411 - Reserved for future use. Should be zeroed by drivers and390 - Reserved for future use. Should be zeroed by drivers and
412 applications.391 applications.
413 392
Documentation/media/uapi/v4l/dev-sliced-vbi.rst+6−9
@@ -478,33 +478,30 @@ struct v4l2_mpeg_vbi_fmt_ivtv · 477 unmodified lines
478.. flat-table::478.. flat-table::
479 :header-rows: 0479 :header-rows: 0
480 :stub-columns: 0480 :stub-columns: 0
481 :widths: 1 1 1 2481 :widths: 1 1 2
482 482
483 * - __u8483 * - __u8
484 - ``magic``\ [4]484 - ``magic``\ [4]
485 -
486 - A "magic" constant from :ref:`v4l2-mpeg-vbi-fmt-ivtv-magic` that485 - A "magic" constant from :ref:`v4l2-mpeg-vbi-fmt-ivtv-magic` that
487 indicates this is a valid sliced VBI data payload and also486 indicates this is a valid sliced VBI data payload and also
488 indicates which member of the anonymous union, ``itv0`` or487 indicates which member of the anonymous union, ``itv0`` or
489 ``ITV0``, to use for the payload data.488 ``ITV0``, to use for the payload data.
490 * - union489 * - union {
491 - (anonymous)490 - (anonymous)
492 * -491 * - struct :c:type:`v4l2_mpeg_vbi_itv0`
493 - struct :c:type:`v4l2_mpeg_vbi_itv0`
494 - ``itv0``492 - ``itv0``
495 - The primary form of the sliced VBI data payload that contains493 - The primary form of the sliced VBI data payload that contains
496 anywhere from 1 to 35 lines of sliced VBI data. Line masks are494 anywhere from 1 to 35 lines of sliced VBI data. Line masks are
497 provided in this form of the payload indicating which VBI lines495 provided in this form of the payload indicating which VBI lines
498 are provided.496 are provided.
499 * -497 * - struct :ref:`v4l2_mpeg_vbi_ITV0 <v4l2-mpeg-vbi-itv0-1>`
500 - struct :ref:`v4l2_mpeg_vbi_ITV0 <v4l2-mpeg-vbi-itv0-1>`
501 - ``ITV0``498 - ``ITV0``
502 - An alternate form of the sliced VBI data payload used when 36499 - An alternate form of the sliced VBI data payload used when 36
503 lines of sliced VBI data are present. No line masks are provided500 lines of sliced VBI data are present. No line masks are provided
504 in this form of the payload; all valid line mask bits are501 in this form of the payload; all valid line mask bits are
505 implcitly set.502 implcitly set.
506 503 * - }
507 504 -
508 505
509.. _v4l2-mpeg-vbi-fmt-ivtv-magic:506.. _v4l2-mpeg-vbi-fmt-ivtv-magic:
510 507
Documentation/media/uapi/v4l/ext-ctrls-codec.rst+16−0
@@ -2028,6 +2028,22 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - · 2027 unmodified lines
2028 * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``2028 * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
2029 - 0x000000042029 - 0x00000004
2030 - The DPB entry is a long term reference frame2030 - The DPB entry is a long term reference frame
2031 * - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD``
2032 - 0x00000008
2033 - The DPB entry is a field reference, which means only one of the field
2034 will be used when decoding the new frame/field. When not set the DPB
2035 entry is a frame reference (both fields will be used). Note that this
2036 flag does not say anything about the number of fields contained in the
2037 reference frame, it just describes the one used to decode the new
2038 field/frame
2039 * - ``V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD``
2040 - 0x00000010
2041 - The DPB entry is a bottom field reference (only the bottom field of the
2042 reference frame is needed to decode the new frame/field). Only valid if
2043 V4L2_H264_DPB_ENTRY_FLAG_FIELD is set. When
2044 V4L2_H264_DPB_ENTRY_FLAG_FIELD is set but
2045 V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD is not, that means the
2046 DPB entry is a top field reference
2031 2047
2032``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``2048``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
2033 Specifies the decoding mode to use. Currently exposes slice-based and2049 Specifies the decoding mode to use. Currently exposes slice-based and
Documentation/media/uapi/v4l/pixfmt-bayer.rst+1−0
@@ -34,5 +34,6 @@ orders. See also `the Wikipedia article on Bayer filter · 33 unmodified lines
34 pixfmt-srggb10-ipu334 pixfmt-srggb10-ipu3
35 pixfmt-srggb1235 pixfmt-srggb12
36 pixfmt-srggb12p36 pixfmt-srggb12p
37 pixfmt-srggb14
37 pixfmt-srggb14p38 pixfmt-srggb14p
38 pixfmt-srggb1639 pixfmt-srggb16
Documentation/media/uapi/v4l/pixfmt-srggb14.rst+82−0
@@ -0,0 +1,82 @@
1.. Permission is granted to copy, distribute and/or modify this
2.. document under the terms of the GNU Free Documentation License,
3.. Version 1.1 or any later version published by the Free Software
4.. Foundation, with no Invariant Sections, no Front-Cover Texts
5.. and no Back-Cover Texts. A copy of the license is included at
6.. Documentation/media/uapi/fdl-appendix.rst.
7..
8.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
9
10.. _V4L2-PIX-FMT-SRGGB14:
11.. _v4l2-pix-fmt-sbggr14:
12.. _v4l2-pix-fmt-sgbrg14:
13.. _v4l2-pix-fmt-sgrbg14:
14
15
16***************************************************************************************************************************
17V4L2_PIX_FMT_SRGGB14 ('RG14'), V4L2_PIX_FMT_SGRBG14 ('GR14'), V4L2_PIX_FMT_SGBRG14 ('GB14'), V4L2_PIX_FMT_SBGGR14 ('BG14'),
18***************************************************************************************************************************
19
20
2114-bit Bayer formats expanded to 16 bits
22
23
24Description
25===========
26
27These four pixel formats are raw sRGB / Bayer formats with 14 bits per
28colour. Each sample is stored in a 16-bit word, with two unused high
29bits filled with zeros. Each n-pixel row contains n/2 green samples
30and n/2 blue or red samples, with alternating red and blue rows. Bytes
31are stored in memory in little endian order. They are conventionally
32described as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an
33example of a small V4L2_PIX_FMT_SBGGR14 image:
34
35**Byte Order.**
36Each cell is one byte, the two most significant bits in the high bytes are
37zero.
38
39
40
41.. flat-table::
42 :header-rows: 0
43 :stub-columns: 0
44 :widths: 2 1 1 1 1 1 1 1 1
45
46
47 * - start + 0:
48 - B\ :sub:`00low`
49 - B\ :sub:`00high`
50 - G\ :sub:`01low`
51 - G\ :sub:`01high`
52 - B\ :sub:`02low`
53 - B\ :sub:`02high`
54 - G\ :sub:`03low`
55 - G\ :sub:`03high`
56 * - start + 8:
57 - G\ :sub:`10low`
58 - G\ :sub:`10high`
59 - R\ :sub:`11low`
60 - R\ :sub:`11high`
61 - G\ :sub:`12low`
62 - G\ :sub:`12high`
63 - R\ :sub:`13low`
64 - R\ :sub:`13high`
65 * - start + 16:
66 - B\ :sub:`20low`
67 - B\ :sub:`20high`
68 - G\ :sub:`21low`
69 - G\ :sub:`21high`
70 - B\ :sub:`22low`
71 - B\ :sub:`22high`
72 - G\ :sub:`23low`
73 - G\ :sub:`23high`
74 * - start + 24:
75 - G\ :sub:`30low`
76 - G\ :sub:`30high`
77 - R\ :sub:`31low`
78 - R\ :sub:`31high`
79 - G\ :sub:`32low`
80 - G\ :sub:`32high`
81 - R\ :sub:`33low`
82 - R\ :sub:`33high`
Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst+4−2
@@ -100,7 +100,8 @@ describing all planes of that format. · 99 unmodified lines
100 * - __u8100 * - __u8
101 - ``flags``101 - ``flags``
102 - Flags set by the application or driver, see :ref:`format-flags`.102 - Flags set by the application or driver, see :ref:`format-flags`.
103 * - :cspan:`2` union { (anonymous)103 * - union {
104 - (anonymous)
104 * - __u8105 * - __u8
105 - ``ycbcr_enc``106 - ``ycbcr_enc``
106 - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.107 - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
@@ -113,7 +114,8 @@ describing all planes of that format. · 6 unmodified lines
113 This information supplements the ``colorspace`` and must be set by114 This information supplements the ``colorspace`` and must be set by
114 the driver for capture streams and by the application for output115 the driver for capture streams and by the application for output
115 streams, see :ref:`colorspaces`.116 streams, see :ref:`colorspaces`.
116 * - :cspan:`2` }117 * - }
118 -
117 * - __u8119 * - __u8
118 - ``quantization``120 - ``quantization``
119 - Quantization range, from enum :c:type:`v4l2_quantization`.121 - Quantization range, from enum :c:type:`v4l2_quantization`.
Documentation/media/uapi/v4l/pixfmt-v4l2.rst+0−2
@@ -143,7 +143,6 @@ Single-planar format structure · 142 unmodified lines
143 - Flags set by the application or driver, see :ref:`format-flags`.143 - Flags set by the application or driver, see :ref:`format-flags`.
144 * - union {144 * - union {
145 - (anonymous)145 - (anonymous)
146 -
147 * - __u32146 * - __u32
148 - ``ycbcr_enc``147 - ``ycbcr_enc``
149 - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.148 - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`.
@@ -158,7 +157,6 @@ Single-planar format structure · 8 unmodified lines
158 streams, see :ref:`colorspaces`.157 streams, see :ref:`colorspaces`.
159 * - }158 * - }
160 -159 -
161 -
162 * - __u32160 * - __u32
163 - ``quantization``161 - ``quantization``
164 - Quantization range, from enum :c:type:`v4l2_quantization`.162 - Quantization range, from enum :c:type:`v4l2_quantization`.
Documentation/media/uapi/v4l/pixfmt-y14.rst+72−0
@@ -0,0 +1,72 @@
1.. Permission is granted to copy, distribute and/or modify this
2.. document under the terms of the GNU Free Documentation License,
3.. Version 1.1 or any later version published by the Free Software
4.. Foundation, with no Invariant Sections, no Front-Cover Texts
5.. and no Back-Cover Texts. A copy of the license is included at
6.. Documentation/media/uapi/fdl-appendix.rst.
7..
8.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
9
10.. _V4L2-PIX-FMT-Y14:
11
12*************************
13V4L2_PIX_FMT_Y14 ('Y14 ')
14*************************
15
16
17Grey-scale image
18
19
20Description
21===========
22
23This is a grey-scale image with a depth of 14 bits per pixel. Pixels are
24stored in 16-bit words with unused high bits padded with 0. The least
25significant byte is stored at lower memory addresses (little-endian).
26
27**Byte Order.**
28Each cell is one byte.
29
30
31
32
33.. flat-table::
34 :header-rows: 0
35 :stub-columns: 0
36
37 * - start + 0:
38 - Y'\ :sub:`00low`
39 - Y'\ :sub:`00high`
40 - Y'\ :sub:`01low`
41 - Y'\ :sub:`01high`
42 - Y'\ :sub:`02low`
43 - Y'\ :sub:`02high`
44 - Y'\ :sub:`03low`
45 - Y'\ :sub:`03high`
46 * - start + 8:
47 - Y'\ :sub:`10low`
48 - Y'\ :sub:`10high`
49 - Y'\ :sub:`11low`
50 - Y'\ :sub:`11high`
51 - Y'\ :sub:`12low`
52 - Y'\ :sub:`12high`
53 - Y'\ :sub:`13low`
54 - Y'\ :sub:`13high`
55 * - start + 16:
56 - Y'\ :sub:`20low`
57 - Y'\ :sub:`20high`
58 - Y'\ :sub:`21low`
59 - Y'\ :sub:`21high`
60 - Y'\ :sub:`22low`
61 - Y'\ :sub:`22high`
62 - Y'\ :sub:`23low`
63 - Y'\ :sub:`23high`
64 * - start + 24:
65 - Y'\ :sub:`30low`
66 - Y'\ :sub:`30high`
67 - Y'\ :sub:`31low`
68 - Y'\ :sub:`31high`
69 - Y'\ :sub:`32low`
70 - Y'\ :sub:`32high`
71 - Y'\ :sub:`33low`
72 - Y'\ :sub:`33high`
Documentation/media/uapi/v4l/subdev-formats.rst+37−0
@@ -5792,6 +5792,43 @@ the following codes. · 5791 unmodified lines
5792 - u\ :sub:`2`5792 - u\ :sub:`2`
5793 - u\ :sub:`1`5793 - u\ :sub:`1`
5794 - u\ :sub:`0`5794 - u\ :sub:`0`
5795 * .. _MEDIA-BUS-FMT-Y14-1X14:
5796
5797 - MEDIA_BUS_FMT_Y14_1X14
5798 - 0x202d
5799 -
5800 -
5801 -
5802 -
5803 -
5804 -
5805 -
5806 -
5807 -
5808 -
5809 -
5810 -
5811 -
5812 -
5813 -
5814 -
5815 -
5816 -
5817 -
5818 - y\ :sub:`13`
5819 - y\ :sub:`12`
5820 - y\ :sub:`11`
5821 - y\ :sub:`10`
5822 - y\ :sub:`9`
5823 - y\ :sub:`8`
5824 - y\ :sub:`7`
5825 - y\ :sub:`6`
5826 - y\ :sub:`5`
5827 - y\ :sub:`4`
5828 - y\ :sub:`3`
5829 - y\ :sub:`2`
5830 - y\ :sub:`1`
5831 - y\ :sub:`0`
5795 * .. _MEDIA-BUS-FMT-UYVY8-1X16:5832 * .. _MEDIA-BUS-FMT-UYVY8-1X16:
5796 5833
5797 - MEDIA_BUS_FMT_UYVY8_1X165834 - MEDIA_BUS_FMT_UYVY8_1X16
Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst+6−6
@@ -91,23 +91,23 @@ instructions. · 90 unmodified lines
91.. flat-table:: struct v4l2_dbg_match91.. flat-table:: struct v4l2_dbg_match
92 :header-rows: 092 :header-rows: 0
93 :stub-columns: 093 :stub-columns: 0
94 :widths: 1 1 1 294 :widths: 1 1 2
95 95
96 * - __u3296 * - __u32
97 - ``type``97 - ``type``
98 - See :ref:`name-chip-match-types` for a list of possible types.98 - See :ref:`name-chip-match-types` for a list of possible types.
99 * - union99 * - union {
100 - (anonymous)100 - (anonymous)
101 * -101 * - __u32
102 - __u32
103 - ``addr``102 - ``addr``
104 - Match a chip by this number, interpreted according to the ``type``103 - Match a chip by this number, interpreted according to the ``type``
105 field.104 field.
106 * -105 * - char
107 - char
108 - ``name[32]``106 - ``name[32]``
109 - Match a chip by this name, interpreted according to the ``type``107 - Match a chip by this name, interpreted according to the ``type``
110 field. Currently unused.108 field. Currently unused.
109 * - }
110 -
111 111
112 112
113 113
Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst+6−6
@@ -100,23 +100,23 @@ instructions. · 99 unmodified lines
100.. flat-table:: struct v4l2_dbg_match100.. flat-table:: struct v4l2_dbg_match
101 :header-rows: 0101 :header-rows: 0
102 :stub-columns: 0102 :stub-columns: 0
103 :widths: 1 1 1 2103 :widths: 1 1 2
104 104
105 * - __u32105 * - __u32
106 - ``type``106 - ``type``
107 - See :ref:`chip-match-types` for a list of possible types.107 - See :ref:`chip-match-types` for a list of possible types.
108 * - union108 * - union {
109 - (anonymous)109 - (anonymous)
110 * -110 * - __u32
111 - __u32
112 - ``addr``111 - ``addr``
113 - Match a chip by this number, interpreted according to the ``type``112 - Match a chip by this number, interpreted according to the ``type``
114 field.113 field.
115 * -114 * - char
116 - char
117 - ``name[32]``115 - ``name[32]``
118 - Match a chip by this name, interpreted according to the ``type``116 - Match a chip by this name, interpreted according to the ``type``
119 field. Currently unused.117 field. Currently unused.
118 * - }
119 -
120 120
121 121
122 122
Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst+7−19
@@ -77,32 +77,25 @@ introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decod · 76 unmodified lines
77.. flat-table:: struct v4l2_decoder_cmd77.. flat-table:: struct v4l2_decoder_cmd
78 :header-rows: 078 :header-rows: 0
79 :stub-columns: 079 :stub-columns: 0
80 :widths: 11 24 12 16 10680 :widths: 1 1 1 3
81 81
82 * - __u3282 * - __u32
83 - ``cmd``83 - ``cmd``
84 -84 -
85 -
86 - The decoder command, see :ref:`decoder-cmds`.85 - The decoder command, see :ref:`decoder-cmds`.
87 * - __u3286 * - __u32
88 - ``flags``87 - ``flags``
89 -88 -
90 -
91 - Flags to go with the command. If no flags are defined for this89 - Flags to go with the command. If no flags are defined for this
92 command, drivers and applications must set this field to zero.90 command, drivers and applications must set this field to zero.
93 * - union91 * - union {
94 - (anonymous)92 - (anonymous)
95 -93 * - struct
96 -
97 -
98 * -
99 - struct
100 - ``start``94 - ``start``
101 -95 -
102 - Structure containing additional data for the96 - Structure containing additional data for the
103 ``V4L2_DEC_CMD_START`` command.97 ``V4L2_DEC_CMD_START`` command.
104 * -98 * -
105 -
106 - __s3299 - __s32
107 - ``speed``100 - ``speed``
108 - Playback speed and direction. The playback speed is defined as101 - Playback speed and direction. The playback speed is defined as
@@ -113,7 +106,6 @@ introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decod · 4 unmodified lines
113 of 1 steps just one frame forward, a speed of -1 steps just one106 of 1 steps just one frame forward, a speed of -1 steps just one
114 frame back.107 frame back.
115 * -108 * -
116 -
117 - __u32109 - __u32
118 - ``format``110 - ``format``
119 - Format restrictions. This field is set by the driver, not the111 - Format restrictions. This field is set by the driver, not the
@@ -124,30 +116,26 @@ introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decod · 4 unmodified lines
124 GOPs, which it can then play in reverse order. So to implement116 GOPs, which it can then play in reverse order. So to implement
125 reverse playback the application must feed the decoder the last117 reverse playback the application must feed the decoder the last
126 GOP in the video file, then the GOP before that, etc. etc.118 GOP in the video file, then the GOP before that, etc. etc.
127 * -119 * - struct
128 - struct
129 - ``stop``120 - ``stop``
130 -121 -
131 - Structure containing additional data for the ``V4L2_DEC_CMD_STOP``122 - Structure containing additional data for the ``V4L2_DEC_CMD_STOP``
132 command.123 command.
133 * -124 * -
134 -
135 - __u64125 - __u64
136 - ``pts``126 - ``pts``
137 - Stop playback at this ``pts`` or immediately if the playback is127 - Stop playback at this ``pts`` or immediately if the playback is
138 already past that timestamp. Leave to 0 if you want to stop after128 already past that timestamp. Leave to 0 if you want to stop after
139 the last frame was decoded.129 the last frame was decoded.
140 * -130 * - struct
141 - struct
142 - ``raw``131 - ``raw``
143 -
144 -
145 * -132 * -
146 -
147 - __u32133 - __u32
148 - ``data``\ [16]134 - ``data``\ [16]
149 - Reserved for future extensions. Drivers and applications must set135 - Reserved for future extensions. Drivers and applications must set
150 the array to zero.136 the array to zero.
137 * - }
138 -
151 139
152 140
153 141
Documentation/media/uapi/v4l/vidioc-dqevent.rst+17−38
@@ -55,66 +55,54 @@ call. · 54 unmodified lines
55.. flat-table:: struct v4l2_event55.. flat-table:: struct v4l2_event
56 :header-rows: 056 :header-rows: 0
57 :stub-columns: 057 :stub-columns: 0
58 :widths: 1 1 2 158 :widths: 1 1 2
59 59
60 * - __u3260 * - __u32
61 - ``type``61 - ``type``
62 -
63 - Type of the event, see :ref:`event-type`.62 - Type of the event, see :ref:`event-type`.
64 * - union63 * - union {
65 - ``u``64 - ``u``
66 -65 * - struct :c:type:`v4l2_event_vsync`
67 -
68 * -
69 - struct :c:type:`v4l2_event_vsync`
70 - ``vsync``66 - ``vsync``
71 - Event data for event ``V4L2_EVENT_VSYNC``.67 - Event data for event ``V4L2_EVENT_VSYNC``.
72 * -68 * - struct :c:type:`v4l2_event_ctrl`
73 - struct :c:type:`v4l2_event_ctrl`
74 - ``ctrl``69 - ``ctrl``
75 - Event data for event ``V4L2_EVENT_CTRL``.70 - Event data for event ``V4L2_EVENT_CTRL``.
76 * -71 * - struct :c:type:`v4l2_event_frame_sync`
77 - struct :c:type:`v4l2_event_frame_sync`
78 - ``frame_sync``72 - ``frame_sync``
79 - Event data for event ``V4L2_EVENT_FRAME_SYNC``.73 - Event data for event ``V4L2_EVENT_FRAME_SYNC``.
80 * -74 * - struct :c:type:`v4l2_event_motion_det`
81 - struct :c:type:`v4l2_event_motion_det`
82 - ``motion_det``75 - ``motion_det``
83 - Event data for event V4L2_EVENT_MOTION_DET.76 - Event data for event V4L2_EVENT_MOTION_DET.
84 * -77 * - struct :c:type:`v4l2_event_src_change`
85 - struct :c:type:`v4l2_event_src_change`
86 - ``src_change``78 - ``src_change``
87 - Event data for event V4L2_EVENT_SOURCE_CHANGE.79 - Event data for event V4L2_EVENT_SOURCE_CHANGE.
88 * -80 * - __u8
89 - __u8
90 - ``data``\ [64]81 - ``data``\ [64]
91 - Event data. Defined by the event type. The union should be used to82 - Event data. Defined by the event type. The union should be used to
92 define easily accessible type for events.83 define easily accessible type for events.
84 * - }
85 -
93 * - __u3286 * - __u32
94 - ``pending``87 - ``pending``
95 -
96 - Number of pending events excluding this one.88 - Number of pending events excluding this one.
97 * - __u3289 * - __u32
98 - ``sequence``90 - ``sequence``
99 -
100 - Event sequence number. The sequence number is incremented for91 - Event sequence number. The sequence number is incremented for
101 every subscribed event that takes place. If sequence numbers are92 every subscribed event that takes place. If sequence numbers are
102 not contiguous it means that events have been lost.93 not contiguous it means that events have been lost.
103 * - struct timespec94 * - struct timespec
104 - ``timestamp``95 - ``timestamp``
105 -
106 - Event timestamp. The timestamp has been taken from the96 - Event timestamp. The timestamp has been taken from the
107 ``CLOCK_MONOTONIC`` clock. To access the same clock outside V4L2,97 ``CLOCK_MONOTONIC`` clock. To access the same clock outside V4L2,
108 use :c:func:`clock_gettime`.98 use :c:func:`clock_gettime`.
109 * - u3299 * - u32
110 - ``id``100 - ``id``
111 -
112 - The ID associated with the event source. If the event does not101 - The ID associated with the event source. If the event does not
113 have an associated ID (this depends on the event type), then this102 have an associated ID (this depends on the event type), then this
114 is 0.103 is 0.
115 * - __u32104 * - __u32
116 - ``reserved``\ [8]105 - ``reserved``\ [8]
117 -
118 - Reserved for future extensions. Drivers must set the array to106 - Reserved for future extensions. Drivers must set the array to
119 zero.107 zero.
120 108
@@ -233,54 +221,45 @@ call. · 112 unmodified lines
233.. flat-table:: struct v4l2_event_ctrl221.. flat-table:: struct v4l2_event_ctrl
234 :header-rows: 0222 :header-rows: 0
235 :stub-columns: 0223 :stub-columns: 0
236 :widths: 1 1 2 1224 :widths: 1 1 2
237 225
238 * - __u32226 * - __u32
239 - ``changes``227 - ``changes``
240 -
241 - A bitmask that tells what has changed. See228 - A bitmask that tells what has changed. See
242 :ref:`ctrl-changes-flags`.229 :ref:`ctrl-changes-flags`.
243 * - __u32230 * - __u32
244 - ``type``231 - ``type``
245 -
246 - The type of the control. See enum232 - The type of the control. See enum
247 :c:type:`v4l2_ctrl_type`.233 :c:type:`v4l2_ctrl_type`.
248 * - union (anonymous)234 * - union {
249 -235 - (anonymous)
250 -236 * - __s32
251 -
252 * -
253 - __s32
254 - ``value``237 - ``value``
255 - The 32-bit value of the control for 32-bit control types. This is238 - The 32-bit value of the control for 32-bit control types. This is
256 0 for string controls since the value of a string cannot be passed239 0 for string controls since the value of a string cannot be passed
257 using :ref:`VIDIOC_DQEVENT`.240 using :ref:`VIDIOC_DQEVENT`.
258 * -241 * - __s64
259 - __s64
260 - ``value64``242 - ``value64``
261 - The 64-bit value of the control for 64-bit control types.243 - The 64-bit value of the control for 64-bit control types.
244 * - }
245 -
262 * - __u32246 * - __u32
263 - ``flags``247 - ``flags``
264 -
265 - The control flags. See :ref:`control-flags`.248 - The control flags. See :ref:`control-flags`.
266 * - __s32249 * - __s32
267 - ``minimum``250 - ``minimum``
268 -
269 - The minimum value of the control. See struct251 - The minimum value of the control. See struct
270 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.252 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.
271 * - __s32253 * - __s32
272 - ``maximum``254 - ``maximum``
273 -
274 - The maximum value of the control. See struct255 - The maximum value of the control. See struct
275 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.256 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.
276 * - __s32257 * - __s32
277 - ``step``258 - ``step``
278 -
279 - The step value of the control. See struct259 - The step value of the control. See struct
280 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.260 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.
281 * - __s32261 * - __s32
282 - ``default_value``262 - ``default_value``
283 -
284 - The default value value of the control. See struct263 - The default value value of the control. See struct
285 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.264 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.
286 265
Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst+6−8
@@ -112,7 +112,7 @@ that doesn't support them will return an ``EINVAL`` error code. · 111 unmodified lines
112.. flat-table:: struct v4l2_dv_timings_cap112.. flat-table:: struct v4l2_dv_timings_cap
113 :header-rows: 0113 :header-rows: 0
114 :stub-columns: 0114 :stub-columns: 0
115 :widths: 1 1 2 1115 :widths: 1 1 2
116 116
117 * - __u32117 * - __u32
118 - ``type``118 - ``type``
@@ -127,16 +127,14 @@ that doesn't support them will return an ``EINVAL`` error code. · 8 unmodified lines
127 - Reserved for future extensions.127 - Reserved for future extensions.
128 128
129 Drivers and applications must set the array to zero.129 Drivers and applications must set the array to zero.
130 * - union130 * - union {
131 -131 - (anonymous)
132 -132 * - struct :c:type:`v4l2_bt_timings_cap`
133 * -
134 - struct :c:type:`v4l2_bt_timings_cap`
135 - ``bt``133 - ``bt``
136 - BT.656/1120 timings capabilities of the hardware.134 - BT.656/1120 timings capabilities of the hardware.
137 * -135 * - __u32
138 - __u32
139 - ``raw_data``\ [32]136 - ``raw_data``\ [32]
137 * - }
140 -138 -
141 139
142.. tabularcolumns:: |p{7.0cm}|p{10.5cm}|140.. tabularcolumns:: |p{7.0cm}|p{10.5cm}|
Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst+7−12
@@ -138,36 +138,31 @@ application should zero out all members except for the *IN* fields. · 137 unmodified lines
138 138
139 * - __u32139 * - __u32
140 - ``index``140 - ``index``
141 -
142 - IN: Index of the given frame interval in the enumeration.141 - IN: Index of the given frame interval in the enumeration.
143 * - __u32142 * - __u32
144 - ``pixel_format``143 - ``pixel_format``
145 -
146 - IN: Pixel format for which the frame intervals are enumerated.144 - IN: Pixel format for which the frame intervals are enumerated.
147 * - __u32145 * - __u32
148 - ``width``146 - ``width``
149 -
150 - IN: Frame width for which the frame intervals are enumerated.147 - IN: Frame width for which the frame intervals are enumerated.
151 * - __u32148 * - __u32
152 - ``height``149 - ``height``
153 -
154 - IN: Frame height for which the frame intervals are enumerated.150 - IN: Frame height for which the frame intervals are enumerated.
155 * - __u32151 * - __u32
156 - ``type``152 - ``type``
157 -
158 - OUT: Frame interval type the device supports.153 - OUT: Frame interval type the device supports.
159 * - union154 * - union {
160 -155 - (anonymous)
161 -
162 - OUT: Frame interval with the given index.156 - OUT: Frame interval with the given index.
163 * -157 * - struct :c:type:`v4l2_fract`
164 - struct :c:type:`v4l2_fract`
165 - ``discrete``158 - ``discrete``
166 - Frame interval [s].159 - Frame interval [s].
167 * -160 * - struct :c:type:`v4l2_frmival_stepwise`
168 - struct :c:type:`v4l2_frmival_stepwise`
169 - ``stepwise``161 - ``stepwise``
170 -162 -
163 * - }
164 -
165 -
171 * - __u32166 * - __u32
172 - ``reserved[2]``167 - ``reserved[2]``
173 -168 -
Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst+7−11
@@ -155,31 +155,27 @@ application should zero out all members except for the *IN* fields. · 154 unmodified lines
155 155
156 * - __u32156 * - __u32
157 - ``index``157 - ``index``
158 -
159 - IN: Index of the given frame size in the enumeration.158 - IN: Index of the given frame size in the enumeration.
160 * - __u32159 * - __u32
161 - ``pixel_format``160 - ``pixel_format``
162 -
163 - IN: Pixel format for which the frame sizes are enumerated.161 - IN: Pixel format for which the frame sizes are enumerated.
164 * - __u32162 * - __u32
165 - ``type``163 - ``type``
166 -
167 - OUT: Frame size type the device supports.164 - OUT: Frame size type the device supports.
168 * - union165 * - union {
169 -166 - (anonymous)
170 -
171 - OUT: Frame size with the given index.167 - OUT: Frame size with the given index.
172 * -168 * - struct :c:type:`v4l2_frmsize_discrete`
173 - struct :c:type:`v4l2_frmsize_discrete`
174 - ``discrete``169 - ``discrete``
175 -170 -
176 * -171 * - struct :c:type:`v4l2_frmsize_stepwise`
177 - struct :c:type:`v4l2_frmsize_stepwise`
178 - ``stepwise``172 - ``stepwise``
179 -173 -
174 * - }
175 -
176 -
180 * - __u32177 * - __u32
181 - ``reserved[2]``178 - ``reserved[2]``
182 -
183 - Reserved space for future use. Must be zeroed by drivers and179 - Reserved space for future use. Must be zeroed by drivers and
184 applications.180 applications.
185 181
Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst+7−9
@@ -179,23 +179,21 @@ EBUSY · 178 unmodified lines
179.. flat-table:: struct v4l2_dv_timings179.. flat-table:: struct v4l2_dv_timings
180 :header-rows: 0180 :header-rows: 0
181 :stub-columns: 0181 :stub-columns: 0
182 :widths: 1 1 2 1182 :widths: 1 1 2
183 183
184 * - __u32184 * - __u32
185 - ``type``185 - ``type``
186 -
187 - Type of DV timings as listed in :ref:`dv-timing-types`.186 - Type of DV timings as listed in :ref:`dv-timing-types`.
188 * - union187 * - union {
189 -188 - (anonymous)
190 -189 * - struct :c:type:`v4l2_bt_timings`
191 * -
192 - struct :c:type:`v4l2_bt_timings`
193 - ``bt``190 - ``bt``
194 - Timings defined by BT.656/1120 specifications191 - Timings defined by BT.656/1120 specifications
195 * -192 * - __u32
196 - __u32
197 - ``reserved``\ [32]193 - ``reserved``\ [32]
198 -194 -
195 * - }
196 -
199 197
200.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|198.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
201 199
Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst+18−27
@@ -136,15 +136,13 @@ still cause this situation. · 135 unmodified lines
136.. flat-table:: struct v4l2_ext_control136.. flat-table:: struct v4l2_ext_control
137 :header-rows: 0137 :header-rows: 0
138 :stub-columns: 0138 :stub-columns: 0
139 :widths: 1 1 1 2139 :widths: 1 1 2
140 140
141 * - __u32141 * - __u32
142 - ``id``142 - ``id``
143 -
144 - Identifies the control, set by the application.143 - Identifies the control, set by the application.
145 * - __u32144 * - __u32
146 - ``size``145 - ``size``
147 -
148 - The total size in bytes of the payload of this control. This is146 - The total size in bytes of the payload of this control. This is
149 normally 0, but for pointer controls this should be set to the147 normally 0, but for pointer controls this should be set to the
150 size of the memory containing the payload, or that will receive148 size of the memory containing the payload, or that will receive
@@ -161,55 +159,48 @@ still cause this situation. · 10 unmodified lines
161 *length* of the string may well be much smaller.159 *length* of the string may well be much smaller.
162 * - __u32160 * - __u32
163 - ``reserved2``\ [1]161 - ``reserved2``\ [1]
164 -
165 - Reserved for future extensions. Drivers and applications must set162 - Reserved for future extensions. Drivers and applications must set
166 the array to zero.163 the array to zero.
167 * - union164 * - union {
168 - (anonymous)165 - (anonymous)
169 * -166 * - __s32
170 - __s32
171 - ``value``167 - ``value``
172 - New value or current value. Valid if this control is not of type168 - New value or current value. Valid if this control is not of type
173 ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is169 ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
174 not set.170 not set.
175 * -171 * - __s64
176 - __s64
177 - ``value64``172 - ``value64``
178 - New value or current value. Valid if this control is of type173 - New value or current value. Valid if this control is of type
179 ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is174 ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
180 not set.175 not set.
181 * -176 * - char *
182 - char *
183 - ``string``177 - ``string``
184 - A pointer to a string. Valid if this control is of type178 - A pointer to a string. Valid if this control is of type
185 ``V4L2_CTRL_TYPE_STRING``.179 ``V4L2_CTRL_TYPE_STRING``.
186 * -180 * - __u8 *
187 - __u8 *
188 - ``p_u8``181 - ``p_u8``
189 - A pointer to a matrix control of unsigned 8-bit values. Valid if182 - A pointer to a matrix control of unsigned 8-bit values. Valid if
190 this control is of type ``V4L2_CTRL_TYPE_U8``.183 this control is of type ``V4L2_CTRL_TYPE_U8``.
191 * -184 * - __u16 *
192 - __u16 *
193 - ``p_u16``185 - ``p_u16``
194 - A pointer to a matrix control of unsigned 16-bit values. Valid if186 - A pointer to a matrix control of unsigned 16-bit values. Valid if
195 this control is of type ``V4L2_CTRL_TYPE_U16``.187 this control is of type ``V4L2_CTRL_TYPE_U16``.
196 * -188 * - __u32 *
197 - __u32 *
198 - ``p_u32``189 - ``p_u32``
199 - A pointer to a matrix control of unsigned 32-bit values. Valid if190 - A pointer to a matrix control of unsigned 32-bit values. Valid if
200 this control is of type ``V4L2_CTRL_TYPE_U32``.191 this control is of type ``V4L2_CTRL_TYPE_U32``.
201 * -192 * - :c:type:`v4l2_area` *
202 - :c:type:`v4l2_area` *
203 - ``p_area``193 - ``p_area``
204 - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is194 - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is
205 of type ``V4L2_CTRL_TYPE_AREA``.195 of type ``V4L2_CTRL_TYPE_AREA``.
206 * -196 * - void *
207 - void *
208 - ``ptr``197 - ``ptr``
209 - A pointer to a compound type which can be an N-dimensional array198 - A pointer to a compound type which can be an N-dimensional array
210 and/or a compound type (the control's type is >=199 and/or a compound type (the control's type is >=
211 ``V4L2_CTRL_COMPOUND_TYPES``). Valid if200 ``V4L2_CTRL_COMPOUND_TYPES``). Valid if
212 ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set for this control.201 ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set for this control.
202 * - }
203 -
213 204
214 205
215.. tabularcolumns:: |p{4.0cm}|p{2.2cm}|p{2.1cm}|p{8.2cm}|206.. tabularcolumns:: |p{4.0cm}|p{2.2cm}|p{2.1cm}|p{8.2cm}|
@@ -221,12 +212,11 @@ still cause this situation. · 5 unmodified lines
221.. flat-table:: struct v4l2_ext_controls212.. flat-table:: struct v4l2_ext_controls
222 :header-rows: 0213 :header-rows: 0
223 :stub-columns: 0214 :stub-columns: 0
224 :widths: 1 1 2 1215 :widths: 1 1 2
225 216
226 * - union217 * - union {
227 - (anonymous)218 - (anonymous)
228 * -219 * - __u32
229 - __u32
230 - ``ctrl_class``220 - ``ctrl_class``
231 - The control class to which all controls belong, see221 - The control class to which all controls belong, see
232 :ref:`ctrl-class`. Drivers that use a kernel framework for222 :ref:`ctrl-class`. Drivers that use a kernel framework for
@@ -235,8 +225,7 @@ still cause this situation. · 2 unmodified lines
235 support this can be tested by setting ``ctrl_class`` to 0 and225 support this can be tested by setting ``ctrl_class`` to 0 and
236 calling :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with a ``count`` of 0. If that226 calling :ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` with a ``count`` of 0. If that
237 succeeds, then the driver supports this feature.227 succeeds, then the driver supports this feature.
238 * -228 * - __u32
239 - __u32
240 - ``which``229 - ``which``
241 - Which value of the control to get/set/try.230 - Which value of the control to get/set/try.
242 ``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the231 ``V4L2_CTRL_WHICH_CUR_VAL`` will return the current value of the
@@ -261,6 +250,8 @@ still cause this situation. · 18 unmodified lines
261 by setting ctrl_class to ``V4L2_CTRL_WHICH_CUR_VAL`` and calling250 by setting ctrl_class to ``V4L2_CTRL_WHICH_CUR_VAL`` and calling
262 VIDIOC_TRY_EXT_CTRLS with a count of 0. If that fails, then the251 VIDIOC_TRY_EXT_CTRLS with a count of 0. If that fails, then the
263 driver does not support ``V4L2_CTRL_WHICH_CUR_VAL``.252 driver does not support ``V4L2_CTRL_WHICH_CUR_VAL``.
253 * - }
254 -
264 * - __u32255 * - __u32
265 - ``count``256 - ``count``
266 - The number of controls in the controls array. May also be zero.257 - The number of controls in the controls array. May also be zero.
Documentation/media/uapi/v4l/vidioc-g-fmt.rst+11−18
@@ -103,51 +103,44 @@ The format as returned by :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` must be identical · 102 unmodified lines
103 103
104 * - __u32104 * - __u32
105 - ``type``105 - ``type``
106 -
107 - Type of the data stream, see :c:type:`v4l2_buf_type`.106 - Type of the data stream, see :c:type:`v4l2_buf_type`.
108 * - union107 * - union {
109 - ``fmt``108 - ``fmt``
110 * -109 * - struct :c:type:`v4l2_pix_format`
111 - struct :c:type:`v4l2_pix_format`
112 - ``pix``110 - ``pix``
113 - Definition of an image format, see :ref:`pixfmt`, used by video111 - Definition of an image format, see :ref:`pixfmt`, used by video
114 capture and output devices.112 capture and output devices.
115 * -113 * - struct :c:type:`v4l2_pix_format_mplane`
116 - struct :c:type:`v4l2_pix_format_mplane`
117 - ``pix_mp``114 - ``pix_mp``
118 - Definition of an image format, see :ref:`pixfmt`, used by video115 - Definition of an image format, see :ref:`pixfmt`, used by video
119 capture and output devices that support the116 capture and output devices that support the
120 :ref:`multi-planar version of the API <planar-apis>`.117 :ref:`multi-planar version of the API <planar-apis>`.
121 * -118 * - struct :c:type:`v4l2_window`
122 - struct :c:type:`v4l2_window`
123 - ``win``119 - ``win``
124 - Definition of an overlaid image, see :ref:`overlay`, used by120 - Definition of an overlaid image, see :ref:`overlay`, used by
125 video overlay devices.121 video overlay devices.
126 * -122 * - struct :c:type:`v4l2_vbi_format`
127 - struct :c:type:`v4l2_vbi_format`
128 - ``vbi``123 - ``vbi``
129 - Raw VBI capture or output parameters. This is discussed in more124 - Raw VBI capture or output parameters. This is discussed in more
130 detail in :ref:`raw-vbi`. Used by raw VBI capture and output125 detail in :ref:`raw-vbi`. Used by raw VBI capture and output
131 devices.126 devices.
132 * -127 * - struct :c:type:`v4l2_sliced_vbi_format`
133 - struct :c:type:`v4l2_sliced_vbi_format`
134 - ``sliced``128 - ``sliced``
135 - Sliced VBI capture or output parameters. See :ref:`sliced` for129 - Sliced VBI capture or output parameters. See :ref:`sliced` for
136 details. Used by sliced VBI capture and output devices.130 details. Used by sliced VBI capture and output devices.
137 * -131 * - struct :c:type:`v4l2_sdr_format`
138 - struct :c:type:`v4l2_sdr_format`
139 - ``sdr``132 - ``sdr``
140 - Definition of a data format, see :ref:`pixfmt`, used by SDR133 - Definition of a data format, see :ref:`pixfmt`, used by SDR
141 capture and output devices.134 capture and output devices.
142 * -135 * - struct :c:type:`v4l2_meta_format`
143 - struct :c:type:`v4l2_meta_format`
144 - ``meta``136 - ``meta``
145 - Definition of a metadata format, see :ref:`meta-formats`, used by137 - Definition of a metadata format, see :ref:`meta-formats`, used by
146 metadata capture devices.138 metadata capture devices.
147 * -139 * - __u8
148 - __u8
149 - ``raw_data``\ [200]140 - ``raw_data``\ [200]
150 - Place holder for future extensions.141 - Place holder for future extensions.
142 * - }
143 -
151 144
152 145
153Return Value146Return Value
Documentation/media/uapi/v4l/vidioc-g-parm.rst+7−11
@@ -69,33 +69,29 @@ union holding separate parameters for input and output devices. · 68 unmodified lines
69.. flat-table:: struct v4l2_streamparm69.. flat-table:: struct v4l2_streamparm
70 :header-rows: 070 :header-rows: 0
71 :stub-columns: 071 :stub-columns: 0
72 :widths: 1 1 1 272 :widths: 1 1 2
73 73
74 * - __u3274 * - __u32
75 - ``type``75 - ``type``
76 -
77 - The buffer (stream) type, same as struct76 - The buffer (stream) type, same as struct
78 :c:type:`v4l2_format` ``type``, set by the77 :c:type:`v4l2_format` ``type``, set by the
79 application. See :c:type:`v4l2_buf_type`.78 application. See :c:type:`v4l2_buf_type`.
80 * - union79 * - union {
81 - ``parm``80 - ``parm``
82 -81 * - struct :c:type:`v4l2_captureparm`
83 -
84 * -
85 - struct :c:type:`v4l2_captureparm`
86 - ``capture``82 - ``capture``
87 - Parameters for capture devices, used when ``type`` is83 - Parameters for capture devices, used when ``type`` is
88 ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or84 ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
89 ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``.85 ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``.
90 * -86 * - struct :c:type:`v4l2_outputparm`
91 - struct :c:type:`v4l2_outputparm`
92 - ``output``87 - ``output``
93 - Parameters for output devices, used when ``type`` is88 - Parameters for output devices, used when ``type`` is
94 ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.89 ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.
95 * -90 * - __u8
96 - __u8
97 - ``raw_data``\ [200]91 - ``raw_data``\ [200]
98 - A place holder for future extensions.92 - A place holder for future extensions.
93 * - }
94 -
99 95
100 96
101 97
Documentation/media/uapi/v4l/vidioc-queryctrl.rst+8−13
@@ -290,34 +290,29 @@ See also the examples in :ref:`control`. · 289 unmodified lines
290.. flat-table:: struct v4l2_querymenu290.. flat-table:: struct v4l2_querymenu
291 :header-rows: 0291 :header-rows: 0
292 :stub-columns: 0292 :stub-columns: 0
293 :widths: 1 1 2 1293 :widths: 1 1 2
294 294
295 * - __u32295 * - __u32
296 -
297 - ``id``296 - ``id``
298 - Identifies the control, set by the application from the respective297 - Identifies the control, set by the application from the respective
299 struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` ``id``.298 struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` ``id``.
300 * - __u32299 * - __u32
301 -
302 - ``index``300 - ``index``
303 - Index of the menu item, starting at zero, set by the application.301 - Index of the menu item, starting at zero, set by the application.
304 * - union302 * - union {
305 -303 - (anonymous)
306 -304 * - __u8
307 -
308 * -
309 - __u8
310 - ``name``\ [32]305 - ``name``\ [32]
311 - Name of the menu item, a NUL-terminated ASCII string. This306 - Name of the menu item, a NUL-terminated ASCII string. This
312 information is intended for the user. This field is valid for307 information is intended for the user. This field is valid for
313 ``V4L2_CTRL_TYPE_MENU`` type controls.308 ``V4L2_CTRL_TYPE_MENU`` type controls.
314 * -309 * - __s64
315 - __s64
316 - ``value``310 - ``value``
317 - Value of the integer menu item. This field is valid for311 - Value of the integer menu item. This field is valid for
318 ``V4L2_CTRL_TYPE_INTEGER_MENU`` type controls.312 ``V4L2_CTRL_TYPE_INTEGER_MENU`` type controls.
319 * - __u32313 * - }
320 -314 -
315 * - __u32
321 - ``reserved``316 - ``reserved``
322 - Reserved for future extensions. Drivers must set the array to317 - Reserved for future extensions. Drivers must set the array to
323 zero.318 zero.
@@ -378,7 +373,7 @@ See also the examples in :ref:`control`. · 54 unmodified lines
378 - 0373 - 0
379 - 0374 - 0
380 - A control which performs an action when set. Drivers must ignore375 - A control which performs an action when set. Drivers must ignore
381 the value passed with ``VIDIOC_S_CTRL`` and return an ``EINVAL`` error376 the value passed with ``VIDIOC_S_CTRL`` and return an ``EACCES`` error
382 code on a ``VIDIOC_G_CTRL`` attempt.377 code on a ``VIDIOC_G_CTRL`` attempt.
383 * - ``V4L2_CTRL_TYPE_INTEGER64``378 * - ``V4L2_CTRL_TYPE_INTEGER64``
384 - any379 - any
Documentation/media/uapi/v4l/yuv-formats.rst+1−0
@@ -35,6 +35,7 @@ to brightness information. · 34 unmodified lines
35 pixfmt-grey35 pixfmt-grey
36 pixfmt-y1036 pixfmt-y10
37 pixfmt-y1237 pixfmt-y12
38 pixfmt-y14
38 pixfmt-y10b39 pixfmt-y10b
39 pixfmt-y10p40 pixfmt-y10p
40 pixfmt-y1641 pixfmt-y16
Documentation/media/v4l-drivers/ipu3.rst+7−4
@@ -311,10 +311,13 @@ Down Scaler and GDC blocks should be configured with the supported resolutions · 310 unmodified lines
311as each hardware block has its own alignment requirement.311as each hardware block has its own alignment requirement.
312 312
313You must configure the output resolution of the hardware blocks smartly to meet313You must configure the output resolution of the hardware blocks smartly to meet
314the hardware requirement along with keeping the maximum field of view.314the hardware requirement along with keeping the maximum field of view. The
315The intermediate resolutions can be generated by specific tool and this315intermediate resolutions can be generated by specific tool -
316information can be obtained by looking at the following IPU3 ImgU configuration316
317table.317https://github.com/intel/intel-ipu3-pipecfg
318
319This tool can be used to generate intermediate resolutions. More information can
320be obtained by looking at the following IPU3 ImgU configuration table.
318 321
319https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master322https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master
320 323
Documentation/media/v4l-drivers/vivid.rst+60−3
@@ -4,9 +4,9 @@ The Virtual Video Test Driver (vivid) · 3 unmodified lines
4=====================================4=====================================
5 5
6This driver emulates video4linux hardware of various types: video capture, video6This driver emulates video4linux hardware of various types: video capture, video
7output, vbi capture and output, radio receivers and transmitters and a software7output, vbi capture and output, metadata capture and output, radio receivers and
8defined radio receiver. In addition a simple framebuffer device is available for8transmitters, touch capture and a software defined radio receiver. In addition a
9testing capture and output overlays.9simple framebuffer device is available for testing capture and output overlays.
10 10
11Up to 64 vivid instances can be created, each with up to 16 inputs and 16 outputs.11Up to 64 vivid instances can be created, each with up to 16 inputs and 16 outputs.
12 12
@@ -36,6 +36,8 @@ This document describes the features implemented by this driver: · 23 unmodified lines
36- Radio receiver and transmitter support, including RDS support36- Radio receiver and transmitter support, including RDS support
37- Software defined radio (SDR) support37- Software defined radio (SDR) support
38- Capture and output overlay support38- Capture and output overlay support
39- Metadata capture and output support
40- Touch capture support
39 41
40These features will be described in more detail below.42These features will be described in more detail below.
41 43
@@ -69,6 +71,9 @@ all configurable using the following module options: · 27 unmodified lines
69 - bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both71 - bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
70 - bit 12: Radio Transmitter node72 - bit 12: Radio Transmitter node
71 - bit 16: Framebuffer for testing overlays73 - bit 16: Framebuffer for testing overlays
74 - bit 17: Metadata Capture node
75 - bit 18: Metadata Output node
76 - bit 19: Touch Capture node
72 77
73 So to create four instances, the first two with just one video capture78 So to create four instances, the first two with just one video capture
74 device, the second two with just one video output device you would pass79 device, the second two with just one video output device you would pass
@@ -175,6 +180,21 @@ all configurable using the following module options: · 100 unmodified lines
175 give the desired swradioX start number for each SDR capture device.180 give the desired swradioX start number for each SDR capture device.
176 The default is -1 which will just take the first free number.181 The default is -1 which will just take the first free number.
177 182
183- meta_cap_nr:
184
185 give the desired videoX start number for each metadata capture device.
186 The default is -1 which will just take the first free number.
187
188- meta_out_nr:
189
190 give the desired videoX start number for each metadata output device.
191 The default is -1 which will just take the first free number.
192
193- touch_cap_nr:
194
195 give the desired v4l-touchX start number for each touch capture device.
196 The default is -1 which will just take the first free number.
197
178- ccs_cap_mode:198- ccs_cap_mode:
179 199
180 specify the allowed video capture crop/compose/scaling combination200 specify the allowed video capture crop/compose/scaling combination
@@ -547,6 +567,33 @@ The generated data contains the In-phase and Quadrature components of a · 366 unmodified lines
5471 kHz tone that has an amplitude of sqrt(2).5671 kHz tone that has an amplitude of sqrt(2).
548 568
549 569
570Metadata Capture
571----------------
572
573The Metadata capture generates UVC format metadata. The PTS and SCR are
574transmitted based on the values set in vivid contols.
575
576The Metadata device will only work for the Webcam input, it will give
577back an error for all other inputs.
578
579
580Metadata Output
581---------------
582
583The Metadata output can be used to set brightness, contrast, saturation and hue.
584
585The Metadata device will only work for the Webcam output, it will give
586back an error for all other outputs.
587
588
589Touch Capture
590-------------
591
592The Touch capture generates touch patterns simulating single tap, double tap,
593triple tap, move from left to right, zoom in, zoom out, palm press (simulating
594a large area being pressed on a touchpad), and simulating 16 simultaneous
595touch points.
596
550Controls597Controls
551--------598--------
552 599
@@ -1049,6 +1096,16 @@ FM Radio Modulator Controls · 496 unmodified lines
1049 to pass the RDS blocks to the driver, or "Controls" where the RDS data1096 to pass the RDS blocks to the driver, or "Controls" where the RDS data
1050 is Provided by the RDS controls mentioned above.1097 is Provided by the RDS controls mentioned above.
1051 1098
1099Metadata Capture Controls
1100~~~~~~~~~~~~~~~~~~~~~~~~~~
1101
1102- Generate PTS
1103
1104 if set, then the generated metadata stream contains Presentation timestamp.
1105
1106- Generate SCR
1107
1108 if set, then the generated metadata stream contains Source Clock information.
1052 1109
1053Video, VBI and RDS Looping1110Video, VBI and RDS Looping
1054--------------------------1111--------------------------
Documentation/translations/zh_CN/video4linux/v4l2-framework.txt+2−2
@@ -649,7 +649,7 @@ video_device注册 · 648 unmodified lines
649 649
650接下来你需要注册视频设备:这会为你创建一个字符设备。650接下来你需要注册视频设备:这会为你创建一个字符设备。
651 651
652 err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);652 err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
653 if (err) {653 if (err) {
654 video_device_release(vdev); /* or kfree(my_vdev); */654 video_device_release(vdev); /* or kfree(my_vdev); */
655 return err;655 return err;
@@ -660,7 +660,7 @@ video_device注册 · 4 unmodified lines
660 660
661注册哪种设备是根据类型(type)参数。存在以下类型:661注册哪种设备是根据类型(type)参数。存在以下类型:
662 662
663VFL_TYPE_GRABBER: 用于视频输入/输出设备的 videoX663VFL_TYPE_VIDEO: 用于视频输入/输出设备的 videoX
664VFL_TYPE_VBI: 用于垂直消隐数据的 vbiX (例如,隐藏式字幕,图文电视)664VFL_TYPE_VBI: 用于垂直消隐数据的 vbiX (例如,隐藏式字幕,图文电视)
665VFL_TYPE_RADIO: 用于广播调谐器的 radioX665VFL_TYPE_RADIO: 用于广播调谐器的 radioX
666 666
MAINTAINERS+26−6
@@ -10963,6 +10963,7 @@ F: drivers/media/platform/atmel/atmel-isc.h · 10962 unmodified lines
10963F: drivers/media/platform/atmel/atmel-isc-base.c10963F: drivers/media/platform/atmel/atmel-isc-base.c
10964F: drivers/media/platform/atmel/atmel-isc-regs.h10964F: drivers/media/platform/atmel/atmel-isc-regs.h
10965F: Documentation/devicetree/bindings/media/atmel-isc.txt10965F: Documentation/devicetree/bindings/media/atmel-isc.txt
10966F: include/linux/atmel-isc-media.h
10966 10967
10967MICROCHIP ISI DRIVER10968MICROCHIP ISI DRIVER
10968M: Eugen Hristev <eugen.hristev@microchip.com>10969M: Eugen Hristev <eugen.hristev@microchip.com>
@@ -13914,6 +13915,7 @@ L: linux-arm-msm@vger.kernel.org · 2945 unmodified lines
13914T: git git://linuxtv.org/media_tree.git13915T: git git://linuxtv.org/media_tree.git
13915S: Maintained13916S: Maintained
13916F: drivers/media/platform/qcom/venus/13917F: drivers/media/platform/qcom/venus/
13918F: Documentation/devicetree/bindings/media/*venus*
13917 13919
13918QUALCOMM WCN36XX WIRELESS DRIVER13920QUALCOMM WCN36XX WIRELESS DRIVER
13919M: Kalle Valo <kvalo@codeaurora.org>13921M: Kalle Valo <kvalo@codeaurora.org>
@@ -14328,9 +14330,12 @@ F: Documentation/devicetree/bindings/media/rockchip-rga.txt · 408 unmodified lines
14328 14330
14329HANTRO VPU CODEC DRIVER14331HANTRO VPU CODEC DRIVER
14330M: Ezequiel Garcia <ezequiel@collabora.com>14332M: Ezequiel Garcia <ezequiel@collabora.com>
14333M: Philipp Zabel <p.zabel@pengutronix.de>
14331L: linux-media@vger.kernel.org14334L: linux-media@vger.kernel.org
14335L: linux-rockchip@lists.infradead.org
14332S: Maintained14336S: Maintained
14333F: drivers/staging/media/hantro/14337F: drivers/staging/media/hantro/
14338F: Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
14334F: Documentation/devicetree/bindings/media/rockchip-vpu.txt14339F: Documentation/devicetree/bindings/media/rockchip-vpu.txt
14335 14340
14336ROCKER DRIVER14341ROCKER DRIVER
@@ -14377,6 +14382,14 @@ F: include/net/rose.h · 40 unmodified lines
14377F: include/uapi/linux/rose.h14382F: include/uapi/linux/rose.h
14378F: net/rose/14383F: net/rose/
14379 14384
14385ROTATION DRIVER FOR ALLWINNER A83T
14386M: Jernej Skrabec <jernej.skrabec@siol.net>
14387L: linux-media@vger.kernel.org
14388T: git git://linuxtv.org/media_tree.git
14389S: Maintained
14390F: drivers/media/platform/sunxi/sun8i-rotate/
14391F: Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
14392
14380RTL2830 MEDIA DRIVER14393RTL2830 MEDIA DRIVER
14381M: Antti Palosaari <crope@iki.fi>14394M: Antti Palosaari <crope@iki.fi>
14382L: linux-media@vger.kernel.org14395L: linux-media@vger.kernel.org
@@ -15347,11 +15360,10 @@ S: Odd Fixes · 964 unmodified lines
15347F: drivers/net/ethernet/smsc/smc91x.*15360F: drivers/net/ethernet/smsc/smc91x.*
15348 15361
15349SMIA AND SMIA++ IMAGE SENSOR DRIVER15362SMIA AND SMIA++ IMAGE SENSOR DRIVER
15350M: Sakari Ailus <sakari.ailus@iki.fi>15363M: Sakari Ailus <sakari.ailus@linux.intel.com>
15351L: linux-media@vger.kernel.org15364L: linux-media@vger.kernel.org
15352S: Maintained15365S: Maintained
15353F: drivers/media/i2c/smiapp/15366F: drivers/media/i2c/smiapp/
15354F: include/media/i2c/smiapp.h
15355F: drivers/media/i2c/smiapp-pll.c15367F: drivers/media/i2c/smiapp-pll.c
15356F: drivers/media/i2c/smiapp-pll.h15368F: drivers/media/i2c/smiapp-pll.h
15357F: include/uapi/linux/smiapp.h15369F: include/uapi/linux/smiapp.h
@@ -15530,6 +15542,14 @@ S: Maintained · 172 unmodified lines
15530F: drivers/media/i2c/imx214.c15542F: drivers/media/i2c/imx214.c
15531F: Documentation/devicetree/bindings/media/i2c/sony,imx214.txt15543F: Documentation/devicetree/bindings/media/i2c/sony,imx214.txt
15532 15544
15545SONY IMX219 SENSOR DRIVER
15546M: Dave Stevenson <dave.stevenson@raspberrypi.com>
15547L: linux-media@vger.kernel.org
15548T: git git://linuxtv.org/media_tree.git
15549S: Maintained
15550F: drivers/media/i2c/imx219.c
15551F: Documentation/devicetree/bindings/media/i2c/imx219.yaml
15552
15533SONY IMX258 SENSOR DRIVER15553SONY IMX258 SENSOR DRIVER
15534M: Sakari Ailus <sakari.ailus@linux.intel.com>15554M: Sakari Ailus <sakari.ailus@linux.intel.com>
15535L: linux-media@vger.kernel.org15555L: linux-media@vger.kernel.org
@@ -16763,12 +16783,12 @@ F: sound/soc/codecs/twl4030* · 1227 unmodified lines
16763TI VPE/CAL DRIVERS16783TI VPE/CAL DRIVERS
16764M: Benoit Parrot <bparrot@ti.com>16784M: Benoit Parrot <bparrot@ti.com>
16765L: linux-media@vger.kernel.org16785L: linux-media@vger.kernel.org
16786S: Maintained
16766W: http://linuxtv.org/16787W: http://linuxtv.org/
16767Q: http://patchwork.linuxtv.org/project/linux-media/list/16788Q: http://patchwork.linuxtv.org/project/linux-media/list/
16768S: Maintained
16769F: drivers/media/platform/ti-vpe/
16770F: Documentation/devicetree/bindings/media/ti,vpe.yaml
16771F: Documentation/devicetree/bindings/media/ti,cal.yaml16789F: Documentation/devicetree/bindings/media/ti,cal.yaml
16790F: Documentation/devicetree/bindings/media/ti,vpe.yaml
16791F: drivers/media/platform/ti-vpe/
16772 16792
16773TI WILINK WIRELESS DRIVERS16793TI WILINK WIRELESS DRIVERS
16774L: linux-wireless@vger.kernel.org16794L: linux-wireless@vger.kernel.org
@@ -17460,7 +17480,7 @@ L: linux-media@vger.kernel.org · 685 unmodified lines
17460T: git git://linuxtv.org/media_tree.git17480T: git git://linuxtv.org/media_tree.git
17461W: https://linuxtv.org17481W: https://linuxtv.org
17462S: Odd Fixes17482S: Odd Fixes
17463F: drivers/media/usb/usbvision/17483F: drivers/staging/media/usbvision/
17464 17484
17465USB WEBCAM GADGET17485USB WEBCAM GADGET
17466M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>17486M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts+4−0
@@ -76,3 +76,7 @@ · 75 unmodified lines
76 };76 };
77 };77 };
78};78};
79
80&ir {
81 linux,rc-map-name = "rc-videostrong-kii-pro";
82};
drivers/base/property.c+1−0
@@ -566,6 +566,7 @@ const char *fwnode_get_name(const struct fwnode_handle *fwnode) · 565 unmodified lines
566{566{
567 return fwnode_call_ptr_op(fwnode, get_name);567 return fwnode_call_ptr_op(fwnode, get_name);
568}568}
569EXPORT_SYMBOL_GPL(fwnode_get_name);
569 570
570/**571/**
571 * fwnode_get_name_prefix - Return the prefix of node for printing purposes572 * fwnode_get_name_prefix - Return the prefix of node for printing purposes
drivers/media/Kconfig+3−3
@@ -208,9 +208,9 @@ config MEDIA_SUBDRV_AUTOSELECT · 207 unmodified lines
208 If unsure say Y.208 If unsure say Y.
209 209
210config MEDIA_HIDE_ANCILLARY_SUBDRV210config MEDIA_HIDE_ANCILLARY_SUBDRV
211 bool211 bool
212 depends on MEDIA_SUBDRV_AUTOSELECT && !COMPILE_TEST && !EXPERT212 depends on MEDIA_SUBDRV_AUTOSELECT && !COMPILE_TEST && !EXPERT
213 default y213 default y
214 214
215config MEDIA_ATTACH215config MEDIA_ATTACH
216 bool216 bool
drivers/media/cec/cec-notifier.c+27−14
@@ -23,7 +23,7 @@ struct cec_notifier { · 22 unmodified lines
23 struct kref kref;23 struct kref kref;
24 struct device *hdmi_dev;24 struct device *hdmi_dev;
25 struct cec_connector_info conn_info;25 struct cec_connector_info conn_info;
26 const char *conn_name;26 const char *port_name;
27 struct cec_adapter *cec_adap;27 struct cec_adapter *cec_adap;
28 28
29 u16 phys_addr;29 u16 phys_addr;
@@ -32,16 +32,30 @@ struct cec_notifier { · 2 unmodified lines
32static LIST_HEAD(cec_notifiers);32static LIST_HEAD(cec_notifiers);
33static DEFINE_MUTEX(cec_notifiers_lock);33static DEFINE_MUTEX(cec_notifiers_lock);
34 34
35struct cec_notifier *35/**
36cec_notifier_get_conn(struct device *hdmi_dev, const char *conn_name)36 * cec_notifier_get_conn - find or create a new cec_notifier for the given
37 * device and connector tuple.
38 * @hdmi_dev: device that sends the events.
39 * @port_name: the connector name from which the event occurs
40 *
41 * If a notifier for device @dev already exists, then increase the refcount
42 * and return that notifier.
43 *
44 * If it doesn't exist, then allocate a new notifier struct and return a
45 * pointer to that new struct.
46 *
47 * Return NULL if the memory could not be allocated.
48 */
49static struct cec_notifier *
50cec_notifier_get_conn(struct device *hdmi_dev, const char *port_name)
37{51{
38 struct cec_notifier *n;52 struct cec_notifier *n;
39 53
40 mutex_lock(&cec_notifiers_lock);54 mutex_lock(&cec_notifiers_lock);
41 list_for_each_entry(n, &cec_notifiers, head) {55 list_for_each_entry(n, &cec_notifiers, head) {
42 if (n->hdmi_dev == hdmi_dev &&56 if (n->hdmi_dev == hdmi_dev &&
43 (!conn_name ||57 (!port_name ||
44 (n->conn_name && !strcmp(n->conn_name, conn_name)))) {58 (n->port_name && !strcmp(n->port_name, port_name)))) {
45 kref_get(&n->kref);59 kref_get(&n->kref);
46 mutex_unlock(&cec_notifiers_lock);60 mutex_unlock(&cec_notifiers_lock);
47 return n;61 return n;
@@ -51,9 +65,9 @@ cec_notifier_get_conn(struct device *hdmi_dev, const char *conn_name) · 3 unmodified lines
51 if (!n)65 if (!n)
52 goto unlock;66 goto unlock;
53 n->hdmi_dev = hdmi_dev;67 n->hdmi_dev = hdmi_dev;
54 if (conn_name) {68 if (port_name) {
55 n->conn_name = kstrdup(conn_name, GFP_KERNEL);69 n->port_name = kstrdup(port_name, GFP_KERNEL);
56 if (!n->conn_name) {70 if (!n->port_name) {
57 kfree(n);71 kfree(n);
58 n = NULL;72 n = NULL;
59 goto unlock;73 goto unlock;
@@ -68,7 +82,6 @@ unlock: · 8 unmodified lines
68 mutex_unlock(&cec_notifiers_lock);82 mutex_unlock(&cec_notifiers_lock);
69 return n;83 return n;
70}84}
71EXPORT_SYMBOL_GPL(cec_notifier_get_conn);
72 85
73static void cec_notifier_release(struct kref *kref)86static void cec_notifier_release(struct kref *kref)
74{87{
@@ -76,7 +89,7 @@ static void cec_notifier_release(struct kref *kref) · 1 unmodified line
76 container_of(kref, struct cec_notifier, kref);89 container_of(kref, struct cec_notifier, kref);
77 90
78 list_del(&n->head);91 list_del(&n->head);
79 kfree(n->conn_name);92 kfree(n->port_name);
80 kfree(n);93 kfree(n);
81}94}
82 95
@@ -88,10 +101,10 @@ static void cec_notifier_put(struct cec_notifier *n) · 5 unmodified lines
88}101}
89 102
90struct cec_notifier *103struct cec_notifier *
91cec_notifier_conn_register(struct device *hdmi_dev, const char *conn_name,104cec_notifier_conn_register(struct device *hdmi_dev, const char *port_name,
92 const struct cec_connector_info *conn_info)105 const struct cec_connector_info *conn_info)
93{106{
94 struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, conn_name);107 struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, port_name);
95 108
96 if (!n)109 if (!n)
97 return n;110 return n;
@@ -129,7 +142,7 @@ void cec_notifier_conn_unregister(struct cec_notifier *n) · 31 unmodified lines
129EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);142EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);
130 143
131struct cec_notifier *144struct cec_notifier *
132cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *conn_name,145cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *port_name,
133 struct cec_adapter *adap)146 struct cec_adapter *adap)
134{147{
135 struct cec_notifier *n;148 struct cec_notifier *n;
@@ -137,7 +150,7 @@ cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *conn_name, · 1 unmodified line
137 if (WARN_ON(!adap))150 if (WARN_ON(!adap))
138 return NULL;151 return NULL;
139 152
140 n = cec_notifier_get_conn(hdmi_dev, conn_name);153 n = cec_notifier_get_conn(hdmi_dev, port_name);
141 if (!n)154 if (!n)
142 return n;155 return n;
143 156
drivers/media/common/saa7146/saa7146_fops.c+5−7
@@ -97,8 +97,6 @@ void saa7146_buffer_finish(struct saa7146_dev *dev, · 96 unmodified lines
97 DEB_EE("dev:%p, dmaq:%p, state:%d\n", dev, q, state);97 DEB_EE("dev:%p, dmaq:%p, state:%d\n", dev, q, state);
98 DEB_EE("q->curr:%p\n", q->curr);98 DEB_EE("q->curr:%p\n", q->curr);
99 99
100 BUG_ON(!q->curr);
101
102 /* finish current buffer */100 /* finish current buffer */
103 if (NULL == q->curr) {101 if (NULL == q->curr) {
104 DEB_D("aiii. no current buffer\n");102 DEB_D("aiii. no current buffer\n");
@@ -296,7 +294,7 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma) · 191 unmodified lines
296 int res;294 int res;
297 295
298 switch (vdev->vfl_type) {296 switch (vdev->vfl_type) {
299 case VFL_TYPE_GRABBER: {297 case VFL_TYPE_VIDEO: {
300 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",298 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",
301 file, vma);299 file, vma);
302 q = &fh->video_q;300 q = &fh->video_q;
@@ -378,7 +376,7 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof · 75 unmodified lines
378 int ret;376 int ret;
379 377
380 switch (vdev->vfl_type) {378 switch (vdev->vfl_type) {
381 case VFL_TYPE_GRABBER:379 case VFL_TYPE_VIDEO:
382/*380/*
383 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun",381 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun",
384 file, data, (unsigned long)count);382 file, data, (unsigned long)count);
@@ -409,7 +407,7 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou · 24 unmodified lines
409 int ret;407 int ret;
410 408
411 switch (vdev->vfl_type) {409 switch (vdev->vfl_type) {
412 case VFL_TYPE_GRABBER:410 case VFL_TYPE_VIDEO:
413 return -EINVAL;411 return -EINVAL;
414 case VFL_TYPE_VBI:412 case VFL_TYPE_VBI:
415 if (fh->dev->ext_vv_data->vbi_fops.write) {413 if (fh->dev->ext_vv_data->vbi_fops.write) {
@@ -597,7 +595,7 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev, · 181 unmodified lines
597 DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);595 DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);
598 596
599 vfd->fops = &video_fops;597 vfd->fops = &video_fops;
600 if (type == VFL_TYPE_GRABBER)598 if (type == VFL_TYPE_VIDEO)
601 vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;599 vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
602 else600 else
603 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;601 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
@@ -611,7 +609,7 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev, · 7 unmodified lines
611 vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |609 vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
612 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;610 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
613 vfd->device_caps |= dev->ext_vv_data->capabilities;611 vfd->device_caps |= dev->ext_vv_data->capabilities;
614 if (type == VFL_TYPE_GRABBER)612 if (type == VFL_TYPE_VIDEO)
615 vfd->device_caps &=613 vfd->device_caps &=
616 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);614 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
617 else615 else
drivers/media/common/siano/smsdvb-debugfs.c+110−104
@@ -45,88 +45,88 @@ static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data, · 44 unmodified lines
45 45
46 buf = debug_data->stats_data;46 buf = debug_data->stats_data;
47 47
48 n += snprintf(&buf[n], PAGE_SIZE - n,48 n += scnprintf(&buf[n], PAGE_SIZE - n,
49 "is_rf_locked = %d\n", p->is_rf_locked);49 "is_rf_locked = %d\n", p->is_rf_locked);
50 n += snprintf(&buf[n], PAGE_SIZE - n,50 n += scnprintf(&buf[n], PAGE_SIZE - n,
51 "is_demod_locked = %d\n", p->is_demod_locked);51 "is_demod_locked = %d\n", p->is_demod_locked);
52 n += snprintf(&buf[n], PAGE_SIZE - n,52 n += scnprintf(&buf[n], PAGE_SIZE - n,
53 "is_external_lna_on = %d\n", p->is_external_lna_on);53 "is_external_lna_on = %d\n", p->is_external_lna_on);
54 n += snprintf(&buf[n], PAGE_SIZE - n,54 n += scnprintf(&buf[n], PAGE_SIZE - n,
55 "SNR = %d\n", p->SNR);55 "SNR = %d\n", p->SNR);
56 n += snprintf(&buf[n], PAGE_SIZE - n,56 n += scnprintf(&buf[n], PAGE_SIZE - n,
57 "ber = %d\n", p->ber);57 "ber = %d\n", p->ber);
58 n += snprintf(&buf[n], PAGE_SIZE - n,58 n += scnprintf(&buf[n], PAGE_SIZE - n,
59 "FIB_CRC = %d\n", p->FIB_CRC);59 "FIB_CRC = %d\n", p->FIB_CRC);
60 n += snprintf(&buf[n], PAGE_SIZE - n,60 n += scnprintf(&buf[n], PAGE_SIZE - n,
61 "ts_per = %d\n", p->ts_per);61 "ts_per = %d\n", p->ts_per);
62 n += snprintf(&buf[n], PAGE_SIZE - n,62 n += scnprintf(&buf[n], PAGE_SIZE - n,
63 "MFER = %d\n", p->MFER);63 "MFER = %d\n", p->MFER);
64 n += snprintf(&buf[n], PAGE_SIZE - n,64 n += scnprintf(&buf[n], PAGE_SIZE - n,
65 "RSSI = %d\n", p->RSSI);65 "RSSI = %d\n", p->RSSI);
66 n += snprintf(&buf[n], PAGE_SIZE - n,66 n += scnprintf(&buf[n], PAGE_SIZE - n,
67 "in_band_pwr = %d\n", p->in_band_pwr);67 "in_band_pwr = %d\n", p->in_band_pwr);
68 n += snprintf(&buf[n], PAGE_SIZE - n,68 n += scnprintf(&buf[n], PAGE_SIZE - n,
69 "carrier_offset = %d\n", p->carrier_offset);69 "carrier_offset = %d\n", p->carrier_offset);
70 n += snprintf(&buf[n], PAGE_SIZE - n,70 n += scnprintf(&buf[n], PAGE_SIZE - n,
71 "modem_state = %d\n", p->modem_state);71 "modem_state = %d\n", p->modem_state);
72 n += snprintf(&buf[n], PAGE_SIZE - n,72 n += scnprintf(&buf[n], PAGE_SIZE - n,
73 "frequency = %d\n", p->frequency);73 "frequency = %d\n", p->frequency);
74 n += snprintf(&buf[n], PAGE_SIZE - n,74 n += scnprintf(&buf[n], PAGE_SIZE - n,
75 "bandwidth = %d\n", p->bandwidth);75 "bandwidth = %d\n", p->bandwidth);
76 n += snprintf(&buf[n], PAGE_SIZE - n,76 n += scnprintf(&buf[n], PAGE_SIZE - n,
77 "transmission_mode = %d\n", p->transmission_mode);77 "transmission_mode = %d\n", p->transmission_mode);
78 n += snprintf(&buf[n], PAGE_SIZE - n,78 n += scnprintf(&buf[n], PAGE_SIZE - n,
79 "modem_state = %d\n", p->modem_state);79 "modem_state = %d\n", p->modem_state);
80 n += snprintf(&buf[n], PAGE_SIZE - n,80 n += scnprintf(&buf[n], PAGE_SIZE - n,
81 "guard_interval = %d\n", p->guard_interval);81 "guard_interval = %d\n", p->guard_interval);
82 n += snprintf(&buf[n], PAGE_SIZE - n,82 n += scnprintf(&buf[n], PAGE_SIZE - n,
83 "code_rate = %d\n", p->code_rate);83 "code_rate = %d\n", p->code_rate);
84 n += snprintf(&buf[n], PAGE_SIZE - n,84 n += scnprintf(&buf[n], PAGE_SIZE - n,
85 "lp_code_rate = %d\n", p->lp_code_rate);85 "lp_code_rate = %d\n", p->lp_code_rate);
86 n += snprintf(&buf[n], PAGE_SIZE - n,86 n += scnprintf(&buf[n], PAGE_SIZE - n,
87 "hierarchy = %d\n", p->hierarchy);87 "hierarchy = %d\n", p->hierarchy);
88 n += snprintf(&buf[n], PAGE_SIZE - n,88 n += scnprintf(&buf[n], PAGE_SIZE - n,
89 "constellation = %d\n", p->constellation);89 "constellation = %d\n", p->constellation);
90 n += snprintf(&buf[n], PAGE_SIZE - n,90 n += scnprintf(&buf[n], PAGE_SIZE - n,
91 "burst_size = %d\n", p->burst_size);91 "burst_size = %d\n", p->burst_size);
92 n += snprintf(&buf[n], PAGE_SIZE - n,92 n += scnprintf(&buf[n], PAGE_SIZE - n,
93 "burst_duration = %d\n", p->burst_duration);93 "burst_duration = %d\n", p->burst_duration);
94 n += snprintf(&buf[n], PAGE_SIZE - n,94 n += scnprintf(&buf[n], PAGE_SIZE - n,
95 "burst_cycle_time = %d\n", p->burst_cycle_time);95 "burst_cycle_time = %d\n", p->burst_cycle_time);
96 n += snprintf(&buf[n], PAGE_SIZE - n,96 n += scnprintf(&buf[n], PAGE_SIZE - n,
97 "calc_burst_cycle_time = %d\n",97 "calc_burst_cycle_time = %d\n",
98 p->calc_burst_cycle_time);98 p->calc_burst_cycle_time);
99 n += snprintf(&buf[n], PAGE_SIZE - n,99 n += scnprintf(&buf[n], PAGE_SIZE - n,
100 "num_of_rows = %d\n", p->num_of_rows);100 "num_of_rows = %d\n", p->num_of_rows);
101 n += snprintf(&buf[n], PAGE_SIZE - n,101 n += scnprintf(&buf[n], PAGE_SIZE - n,
102 "num_of_padd_cols = %d\n", p->num_of_padd_cols);102 "num_of_padd_cols = %d\n", p->num_of_padd_cols);
103 n += snprintf(&buf[n], PAGE_SIZE - n,103 n += scnprintf(&buf[n], PAGE_SIZE - n,
104 "num_of_punct_cols = %d\n", p->num_of_punct_cols);104 "num_of_punct_cols = %d\n", p->num_of_punct_cols);
105 n += snprintf(&buf[n], PAGE_SIZE - n,105 n += scnprintf(&buf[n], PAGE_SIZE - n,
106 "error_ts_packets = %d\n", p->error_ts_packets);106 "error_ts_packets = %d\n", p->error_ts_packets);
107 n += snprintf(&buf[n], PAGE_SIZE - n,107 n += scnprintf(&buf[n], PAGE_SIZE - n,
108 "total_ts_packets = %d\n", p->total_ts_packets);108 "total_ts_packets = %d\n", p->total_ts_packets);
109 n += snprintf(&buf[n], PAGE_SIZE - n,109 n += scnprintf(&buf[n], PAGE_SIZE - n,
110 "num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);110 "num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
111 n += snprintf(&buf[n], PAGE_SIZE - n,111 n += scnprintf(&buf[n], PAGE_SIZE - n,
112 "num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);112 "num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
113 n += snprintf(&buf[n], PAGE_SIZE - n,113 n += scnprintf(&buf[n], PAGE_SIZE - n,
114 "num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);114 "num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
115 n += snprintf(&buf[n], PAGE_SIZE - n,115 n += scnprintf(&buf[n], PAGE_SIZE - n,
116 "ber_error_count = %d\n", p->ber_error_count);116 "ber_error_count = %d\n", p->ber_error_count);
117 n += snprintf(&buf[n], PAGE_SIZE - n,117 n += scnprintf(&buf[n], PAGE_SIZE - n,
118 "ber_bit_count = %d\n", p->ber_bit_count);118 "ber_bit_count = %d\n", p->ber_bit_count);
119 n += snprintf(&buf[n], PAGE_SIZE - n,119 n += scnprintf(&buf[n], PAGE_SIZE - n,
120 "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);120 "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
121 n += snprintf(&buf[n], PAGE_SIZE - n,121 n += scnprintf(&buf[n], PAGE_SIZE - n,
122 "pre_ber = %d\n", p->pre_ber);122 "pre_ber = %d\n", p->pre_ber);
123 n += snprintf(&buf[n], PAGE_SIZE - n,123 n += scnprintf(&buf[n], PAGE_SIZE - n,
124 "cell_id = %d\n", p->cell_id);124 "cell_id = %d\n", p->cell_id);
125 n += snprintf(&buf[n], PAGE_SIZE - n,125 n += scnprintf(&buf[n], PAGE_SIZE - n,
126 "dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);126 "dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
127 n += snprintf(&buf[n], PAGE_SIZE - n,127 n += scnprintf(&buf[n], PAGE_SIZE - n,
128 "dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);128 "dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
129 n += snprintf(&buf[n], PAGE_SIZE - n,129 n += scnprintf(&buf[n], PAGE_SIZE - n,
130 "num_mpe_received = %d\n", p->num_mpe_received);130 "num_mpe_received = %d\n", p->num_mpe_received);
131 131
132 debug_data->stats_count = n;132 debug_data->stats_count = n;
@@ -148,42 +148,42 @@ static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data, · 15 unmodified lines
148 148
149 buf = debug_data->stats_data;149 buf = debug_data->stats_data;
150 150
151 n += snprintf(&buf[n], PAGE_SIZE - n,151 n += scnprintf(&buf[n], PAGE_SIZE - n,
152 "statistics_type = %d\t", p->statistics_type);152 "statistics_type = %d\t", p->statistics_type);
153 n += snprintf(&buf[n], PAGE_SIZE - n,153 n += scnprintf(&buf[n], PAGE_SIZE - n,
154 "full_size = %d\n", p->full_size);154 "full_size = %d\n", p->full_size);
155 155
156 n += snprintf(&buf[n], PAGE_SIZE - n,156 n += scnprintf(&buf[n], PAGE_SIZE - n,
157 "is_rf_locked = %d\t\t", p->is_rf_locked);157 "is_rf_locked = %d\t\t", p->is_rf_locked);
158 n += snprintf(&buf[n], PAGE_SIZE - n,158 n += scnprintf(&buf[n], PAGE_SIZE - n,
159 "is_demod_locked = %d\t", p->is_demod_locked);159 "is_demod_locked = %d\t", p->is_demod_locked);
160 n += snprintf(&buf[n], PAGE_SIZE - n,160 n += scnprintf(&buf[n], PAGE_SIZE - n,
161 "is_external_lna_on = %d\n", p->is_external_lna_on);161 "is_external_lna_on = %d\n", p->is_external_lna_on);
162 n += snprintf(&buf[n], PAGE_SIZE - n,162 n += scnprintf(&buf[n], PAGE_SIZE - n,
163 "SNR = %d dB\t\t", p->SNR);163 "SNR = %d dB\t\t", p->SNR);
164 n += snprintf(&buf[n], PAGE_SIZE - n,164 n += scnprintf(&buf[n], PAGE_SIZE - n,
165 "RSSI = %d dBm\t\t", p->RSSI);165 "RSSI = %d dBm\t\t", p->RSSI);
166 n += snprintf(&buf[n], PAGE_SIZE - n,166 n += scnprintf(&buf[n], PAGE_SIZE - n,
167 "in_band_pwr = %d dBm\n", p->in_band_pwr);167 "in_band_pwr = %d dBm\n", p->in_band_pwr);
168 n += snprintf(&buf[n], PAGE_SIZE - n,168 n += scnprintf(&buf[n], PAGE_SIZE - n,
169 "carrier_offset = %d\t", p->carrier_offset);169 "carrier_offset = %d\t", p->carrier_offset);
170 n += snprintf(&buf[n], PAGE_SIZE - n,170 n += scnprintf(&buf[n], PAGE_SIZE - n,
171 "bandwidth = %d\t\t", p->bandwidth);171 "bandwidth = %d\t\t", p->bandwidth);
172 n += snprintf(&buf[n], PAGE_SIZE - n,172 n += scnprintf(&buf[n], PAGE_SIZE - n,
173 "frequency = %d Hz\n", p->frequency);173 "frequency = %d Hz\n", p->frequency);
174 n += snprintf(&buf[n], PAGE_SIZE - n,174 n += scnprintf(&buf[n], PAGE_SIZE - n,
175 "transmission_mode = %d\t", p->transmission_mode);175 "transmission_mode = %d\t", p->transmission_mode);
176 n += snprintf(&buf[n], PAGE_SIZE - n,176 n += scnprintf(&buf[n], PAGE_SIZE - n,
177 "modem_state = %d\t\t", p->modem_state);177 "modem_state = %d\t\t", p->modem_state);
178 n += snprintf(&buf[n], PAGE_SIZE - n,178 n += scnprintf(&buf[n], PAGE_SIZE - n,
179 "guard_interval = %d\n", p->guard_interval);179 "guard_interval = %d\n", p->guard_interval);
180 n += snprintf(&buf[n], PAGE_SIZE - n,180 n += scnprintf(&buf[n], PAGE_SIZE - n,
181 "system_type = %d\t\t", p->system_type);181 "system_type = %d\t\t", p->system_type);
182 n += snprintf(&buf[n], PAGE_SIZE - n,182 n += scnprintf(&buf[n], PAGE_SIZE - n,
183 "partial_reception = %d\t", p->partial_reception);183 "partial_reception = %d\t", p->partial_reception);
184 n += snprintf(&buf[n], PAGE_SIZE - n,184 n += scnprintf(&buf[n], PAGE_SIZE - n,
185 "num_of_layers = %d\n", p->num_of_layers);185 "num_of_layers = %d\n", p->num_of_layers);
186 n += snprintf(&buf[n], PAGE_SIZE - n,186 n += scnprintf(&buf[n], PAGE_SIZE - n,
187 "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);187 "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
188 188
189 for (i = 0; i < 3; i++) {189 for (i = 0; i < 3; i++) {
@@ -191,31 +191,34 @@ static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data, · 1 unmodified line
191 p->layer_info[i].number_of_segments > 13)191 p->layer_info[i].number_of_segments > 13)
192 continue;192 continue;
193 193
194 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);194 n += scnprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
195 n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",195 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
196 p->layer_info[i].code_rate);196 p->layer_info[i].code_rate);
197 n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",197 n += scnprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
198 p->layer_info[i].constellation);198 p->layer_info[i].constellation);
199 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",199 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
200 p->layer_info[i].ber);200 p->layer_info[i].ber);
201 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",201 n += scnprintf(&buf[n], PAGE_SIZE - n,
202 "\tber_error_count = %-5d\t",
202 p->layer_info[i].ber_error_count);203 p->layer_info[i].ber_error_count);
203 n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",204 n += scnprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
204 p->layer_info[i].ber_bit_count);205 p->layer_info[i].ber_bit_count);
205 n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",206 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
206 p->layer_info[i].pre_ber);207 p->layer_info[i].pre_ber);
207 n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",208 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
208 p->layer_info[i].ts_per);209 p->layer_info[i].ts_per);
209 n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",210 n += scnprintf(&buf[n], PAGE_SIZE - n,
211 "\terror_ts_packets = %-5d\t",
210 p->layer_info[i].error_ts_packets);212 p->layer_info[i].error_ts_packets);
211 n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",213 n += scnprintf(&buf[n], PAGE_SIZE - n,
214 "total_ts_packets = %-5d\t",
212 p->layer_info[i].total_ts_packets);215 p->layer_info[i].total_ts_packets);
213 n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",216 n += scnprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
214 p->layer_info[i].ti_ldepth_i);217 p->layer_info[i].ti_ldepth_i);
215 n += snprintf(&buf[n], PAGE_SIZE - n,218 n += scnprintf(&buf[n], PAGE_SIZE - n,
216 "\tnumber_of_segments = %d\t",219 "\tnumber_of_segments = %d\t",
217 p->layer_info[i].number_of_segments);220 p->layer_info[i].number_of_segments);
218 n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",221 n += scnprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
219 p->layer_info[i].tmcc_errors);222 p->layer_info[i].tmcc_errors);
220 }223 }
221 224
@@ -238,44 +241,44 @@ static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data, · 16 unmodified lines
238 241
239 buf = debug_data->stats_data;242 buf = debug_data->stats_data;
240 243
241 n += snprintf(&buf[n], PAGE_SIZE - n,244 n += scnprintf(&buf[n], PAGE_SIZE - n,
242 "statistics_type = %d\t", p->statistics_type);245 "statistics_type = %d\t", p->statistics_type);
243 n += snprintf(&buf[n], PAGE_SIZE - n,246 n += scnprintf(&buf[n], PAGE_SIZE - n,
244 "full_size = %d\n", p->full_size);247 "full_size = %d\n", p->full_size);
245 248
246 n += snprintf(&buf[n], PAGE_SIZE - n,249 n += scnprintf(&buf[n], PAGE_SIZE - n,
247 "is_rf_locked = %d\t\t", p->is_rf_locked);250 "is_rf_locked = %d\t\t", p->is_rf_locked);
248 n += snprintf(&buf[n], PAGE_SIZE - n,251 n += scnprintf(&buf[n], PAGE_SIZE - n,
249 "is_demod_locked = %d\t", p->is_demod_locked);252 "is_demod_locked = %d\t", p->is_demod_locked);
250 n += snprintf(&buf[n], PAGE_SIZE - n,253 n += scnprintf(&buf[n], PAGE_SIZE - n,
251 "is_external_lna_on = %d\n", p->is_external_lna_on);254 "is_external_lna_on = %d\n", p->is_external_lna_on);
252 n += snprintf(&buf[n], PAGE_SIZE - n,255 n += scnprintf(&buf[n], PAGE_SIZE - n,
253 "SNR = %d dB\t\t", p->SNR);256 "SNR = %d dB\t\t", p->SNR);
254 n += snprintf(&buf[n], PAGE_SIZE - n,257 n += scnprintf(&buf[n], PAGE_SIZE - n,
255 "RSSI = %d dBm\t\t", p->RSSI);258 "RSSI = %d dBm\t\t", p->RSSI);
256 n += snprintf(&buf[n], PAGE_SIZE - n,259 n += scnprintf(&buf[n], PAGE_SIZE - n,
257 "in_band_pwr = %d dBm\n", p->in_band_pwr);260 "in_band_pwr = %d dBm\n", p->in_band_pwr);
258 n += snprintf(&buf[n], PAGE_SIZE - n,261 n += scnprintf(&buf[n], PAGE_SIZE - n,
259 "carrier_offset = %d\t", p->carrier_offset);262 "carrier_offset = %d\t", p->carrier_offset);
260 n += snprintf(&buf[n], PAGE_SIZE - n,263 n += scnprintf(&buf[n], PAGE_SIZE - n,
261 "bandwidth = %d\t\t", p->bandwidth);264 "bandwidth = %d\t\t", p->bandwidth);
262 n += snprintf(&buf[n], PAGE_SIZE - n,265 n += scnprintf(&buf[n], PAGE_SIZE - n,
263 "frequency = %d Hz\n", p->frequency);266 "frequency = %d Hz\n", p->frequency);
264 n += snprintf(&buf[n], PAGE_SIZE - n,267 n += scnprintf(&buf[n], PAGE_SIZE - n,
265 "transmission_mode = %d\t", p->transmission_mode);268 "transmission_mode = %d\t", p->transmission_mode);
266 n += snprintf(&buf[n], PAGE_SIZE - n,269 n += scnprintf(&buf[n], PAGE_SIZE - n,
267 "modem_state = %d\t\t", p->modem_state);270 "modem_state = %d\t\t", p->modem_state);
268 n += snprintf(&buf[n], PAGE_SIZE - n,271 n += scnprintf(&buf[n], PAGE_SIZE - n,
269 "guard_interval = %d\n", p->guard_interval);272 "guard_interval = %d\n", p->guard_interval);
270 n += snprintf(&buf[n], PAGE_SIZE - n,273 n += scnprintf(&buf[n], PAGE_SIZE - n,
271 "system_type = %d\t\t", p->system_type);274 "system_type = %d\t\t", p->system_type);
272 n += snprintf(&buf[n], PAGE_SIZE - n,275 n += scnprintf(&buf[n], PAGE_SIZE - n,
273 "partial_reception = %d\t", p->partial_reception);276 "partial_reception = %d\t", p->partial_reception);
274 n += snprintf(&buf[n], PAGE_SIZE - n,277 n += scnprintf(&buf[n], PAGE_SIZE - n,
275 "num_of_layers = %d\n", p->num_of_layers);278 "num_of_layers = %d\n", p->num_of_layers);
276 n += snprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",279 n += scnprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
277 p->segment_number);280 p->segment_number);
278 n += snprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",281 n += scnprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
279 p->tune_bw);282 p->tune_bw);
280 283
281 for (i = 0; i < 3; i++) {284 for (i = 0; i < 3; i++) {
@@ -283,31 +286,34 @@ static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data, · 1 unmodified line
283 p->layer_info[i].number_of_segments > 13)286 p->layer_info[i].number_of_segments > 13)
284 continue;287 continue;
285 288
286 n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);289 n += scnprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
287 n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",290 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
288 p->layer_info[i].code_rate);291 p->layer_info[i].code_rate);
289 n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",292 n += scnprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
290 p->layer_info[i].constellation);293 p->layer_info[i].constellation);
291 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",294 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
292 p->layer_info[i].ber);295 p->layer_info[i].ber);
293 n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",296 n += scnprintf(&buf[n], PAGE_SIZE - n,
297 "\tber_error_count = %-5d\t",
294 p->layer_info[i].ber_error_count);298 p->layer_info[i].ber_error_count);
295 n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",299 n += scnprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
296 p->layer_info[i].ber_bit_count);300 p->layer_info[i].ber_bit_count);
297 n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",301 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
298 p->layer_info[i].pre_ber);302 p->layer_info[i].pre_ber);
299 n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",303 n += scnprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
300 p->layer_info[i].ts_per);304 p->layer_info[i].ts_per);
301 n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",305 n += scnprintf(&buf[n], PAGE_SIZE - n,
306 "\terror_ts_packets = %-5d\t",
302 p->layer_info[i].error_ts_packets);307 p->layer_info[i].error_ts_packets);
303 n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",308 n += scnprintf(&buf[n], PAGE_SIZE - n,
309 "total_ts_packets = %-5d\t",
304 p->layer_info[i].total_ts_packets);310 p->layer_info[i].total_ts_packets);
305 n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",311 n += scnprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
306 p->layer_info[i].ti_ldepth_i);312 p->layer_info[i].ti_ldepth_i);
307 n += snprintf(&buf[n], PAGE_SIZE - n,313 n += scnprintf(&buf[n], PAGE_SIZE - n,
308 "\tnumber_of_segments = %d\t",314 "\tnumber_of_segments = %d\t",
309 p->layer_info[i].number_of_segments);315 p->layer_info[i].number_of_segments);
310 n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",316 n += scnprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
311 p->layer_info[i].tmcc_errors);317 p->layer_info[i].tmcc_errors);
312 }318 }
313 319
drivers/media/common/videobuf2/videobuf2-core.c+2−2
@@ -393,8 +393,8 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, · 392 unmodified lines
393 }393 }
394 }394 }
395 395
396 dprintk(1, "allocated %d buffers, %d plane(s) each\n",396 dprintk(3, "allocated %d buffers, %d plane(s) each\n",
397 buffer, num_planes);397 buffer, num_planes);
398 398
399 return buffer;399 return buffer;
400}400}
drivers/media/common/videobuf2/videobuf2-dma-contig.c+2−2
@@ -593,8 +593,8 @@ static int vb2_dc_map_dmabuf(void *mem_priv) · 592 unmodified lines
593 /* checking if dmabuf is big enough to store contiguous chunk */593 /* checking if dmabuf is big enough to store contiguous chunk */
594 contig_size = vb2_dc_get_contiguous_size(sgt);594 contig_size = vb2_dc_get_contiguous_size(sgt);
595 if (contig_size < buf->size) {595 if (contig_size < buf->size) {
596 pr_err("contiguous chunk is too small %lu/%lu b\n",596 pr_err("contiguous chunk is too small %lu/%lu\n",
597 contig_size, buf->size);597 contig_size, buf->size);
598 dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);598 dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
599 return -EFAULT;599 return -EFAULT;
600 }600 }
drivers/media/dvb-frontends/drx39xyj/drxj.c+2−2
@@ -2182,7 +2182,7 @@ int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr, · 2181 unmodified lines
2182 u32 *data, u32 flags)2182 u32 *data, u32 flags)
2183{2183{
2184 u8 buf[sizeof(*data)] = { 0 };2184 u8 buf[sizeof(*data)] = { 0 };
2185 int rc = -EIO;2185 int rc;
2186 u32 word = 0;2186 u32 word = 0;
2187 2187
2188 if (!data)2188 if (!data)
@@ -4229,7 +4229,7 @@ int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr, · 2040 unmodified lines
4229 u16 data, u32 flags)4229 u16 data, u32 flags)
4230{4230{
4231 u8 buf[2];4231 u8 buf[2];
4232 int rc = -EIO;4232 int rc;
4233 4233
4234 buf[0] = (u8) (data & 0xff);4234 buf[0] = (u8) (data & 0xff);
4235 buf[1] = (u8) ((data >> 8) & 0xff);4235 buf[1] = (u8) ((data >> 8) & 0xff);
drivers/media/dvb-frontends/m88ds3103.c+455−11
@@ -64,6 +64,92 @@ err: · 63 unmodified lines
64 return ret;64 return ret;
65}65}
66 66
67/*
68 * m88ds3103b demod has an internal device related to clocking. First the i2c
69 * gate must be opened, for one transaction, then writes will be allowed.
70 */
71static int m88ds3103b_dt_write(struct m88ds3103_dev *dev, int reg, int data)
72{
73 struct i2c_client *client = dev->client;
74 u8 buf[] = {reg, data};
75 u8 val;
76 int ret;
77 struct i2c_msg msg = {
78 .addr = dev->dt_addr, .flags = 0, .buf = buf, .len = 2
79 };
80
81 m88ds3103_update_bits(dev, 0x11, 0x01, 0x00);
82
83 val = 0x11;
84 ret = regmap_write(dev->regmap, 0x03, val);
85 if (ret)
86 dev_dbg(&client->dev, "fail=%d\n", ret);
87
88 ret = i2c_transfer(dev->dt_client->adapter, &msg, 1);
89 if (ret != 1) {
90 dev_err(&client->dev, "0x%02x (ret=%i, reg=0x%02x, value=0x%02x)\n",
91 dev->dt_addr, ret, reg, data);
92
93 m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
94 return -EREMOTEIO;
95 }
96 m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
97
98 dev_dbg(&client->dev, "0x%02x reg 0x%02x, value 0x%02x\n",
99 dev->dt_addr, reg, data);
100
101 return 0;
102}
103
104/*
105 * m88ds3103b demod has an internal device related to clocking. First the i2c
106 * gate must be opened, for two transactions, then reads will be allowed.
107 */
108static int m88ds3103b_dt_read(struct m88ds3103_dev *dev, u8 reg)
109{
110 struct i2c_client *client = dev->client;
111 int ret;
112 u8 val;
113 u8 b0[] = { reg };
114 u8 b1[] = { 0 };
115 struct i2c_msg msg[] = {
116 {
117 .addr = dev->dt_addr,
118 .flags = 0,
119 .buf = b0,
120 .len = 1
121 },
122 {
123 .addr = dev->dt_addr,
124 .flags = I2C_M_RD,
125 .buf = b1,
126 .len = 1
127 }
128 };
129
130 m88ds3103_update_bits(dev, 0x11, 0x01, 0x00);
131
132 val = 0x12;
133 ret = regmap_write(dev->regmap, 0x03, val);
134 if (ret)
135 dev_dbg(&client->dev, "fail=%d\n", ret);
136
137 ret = i2c_transfer(dev->dt_client->adapter, msg, 2);
138 if (ret != 2) {
139 dev_err(&client->dev, "0x%02x (ret=%d, reg=0x%02x)\n",
140 dev->dt_addr, ret, reg);
141
142 m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
143 return -EREMOTEIO;
144 }
145 m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
146
147 dev_dbg(&client->dev, "0x%02x reg 0x%02x, value 0x%02x\n",
148 dev->dt_addr, reg, b1[0]);
149
150 return b1[0];
151}
152
67/*153/*
68 * Get the demodulator AGC PWM voltage setting supplied to the tuner.154 * Get the demodulator AGC PWM voltage setting supplied to the tuner.
69 */155 */
@@ -288,6 +374,251 @@ err: · 218 unmodified lines
288 return ret;374 return ret;
289}375}
290 376
377static int m88ds3103b_select_mclk(struct m88ds3103_dev *dev)
378{
379 struct i2c_client *client = dev->client;
380 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
381 u32 adc_Freq_MHz[3] = {96, 93, 99};
382 u8 reg16_list[3] = {96, 92, 100}, reg16, reg15;
383 u32 offset_MHz[3];
384 u32 max_offset = 0;
385 u32 old_setting = dev->mclk;
386 u32 tuner_freq_MHz = c->frequency / 1000;
387 u8 i;
388 char big_symbol = 0;
389
390 big_symbol = (c->symbol_rate > 45010000) ? 1 : 0;
391
392 if (big_symbol) {
393 reg16 = 115;
394 } else {
395 reg16 = 96;
396
397 /* TODO: IS THIS NECESSARY ? */
398 for (i = 0; i < 3; i++) {
399 offset_MHz[i] = tuner_freq_MHz % adc_Freq_MHz[i];
400
401 if (offset_MHz[i] > (adc_Freq_MHz[i] / 2))
402 offset_MHz[i] = adc_Freq_MHz[i] - offset_MHz[i];
403
404 if (offset_MHz[i] > max_offset) {
405 max_offset = offset_MHz[i];
406 reg16 = reg16_list[i];
407 dev->mclk = adc_Freq_MHz[i] * 1000 * 1000;
408
409 if (big_symbol)
410 dev->mclk /= 2;
411
412 dev_dbg(&client->dev, "modifying mclk %u -> %u\n",
413 old_setting, dev->mclk);
414 }
415 }
416 }
417
418 if (dev->mclk == 93000000)
419 regmap_write(dev->regmap, 0xA0, 0x42);
420 else if (dev->mclk == 96000000)
421 regmap_write(dev->regmap, 0xA0, 0x44);
422 else if (dev->mclk == 99000000)
423 regmap_write(dev->regmap, 0xA0, 0x46);
424 else if (dev->mclk == 110250000)
425 regmap_write(dev->regmap, 0xA0, 0x4E);
426 else
427 regmap_write(dev->regmap, 0xA0, 0x44);
428
429 reg15 = m88ds3103b_dt_read(dev, 0x15);
430
431 m88ds3103b_dt_write(dev, 0x05, 0x40);
432 m88ds3103b_dt_write(dev, 0x11, 0x08);
433
434 if (big_symbol)
435 reg15 |= 0x02;
436 else
437 reg15 &= ~0x02;
438
439 m88ds3103b_dt_write(dev, 0x15, reg15);
440 m88ds3103b_dt_write(dev, 0x16, reg16);
441
442 usleep_range(5000, 5500);
443
444 m88ds3103b_dt_write(dev, 0x05, 0x00);
445 m88ds3103b_dt_write(dev, 0x11, (u8)(big_symbol ? 0x0E : 0x0A));
446
447 usleep_range(5000, 5500);
448
449 return 0;
450}
451
452static int m88ds3103b_set_mclk(struct m88ds3103_dev *dev, u32 mclk_khz)
453{
454 u8 reg11 = 0x0A, reg15, reg16, reg1D, reg1E, reg1F, tmp;
455 u8 sm, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
456 u16 pll_div_fb, N;
457 u32 div;
458
459 reg15 = m88ds3103b_dt_read(dev, 0x15);
460 reg16 = m88ds3103b_dt_read(dev, 0x16);
461 reg1D = m88ds3103b_dt_read(dev, 0x1D);
462
463 if (dev->cfg->ts_mode != M88DS3103_TS_SERIAL) {
464 if (reg16 == 92)
465 tmp = 93;
466 else if (reg16 == 100)
467 tmp = 99;
468 else
469 tmp = 96;
470
471 mclk_khz *= tmp;
472 mclk_khz /= 96;
473 }
474
475 pll_div_fb = (reg15 & 0x01) << 8;
476 pll_div_fb += reg16;
477 pll_div_fb += 32;
478
479 div = 9000 * pll_div_fb * 4;
480 div /= mclk_khz;
481
482 if (dev->cfg->ts_mode == M88DS3103_TS_SERIAL) {
483 reg11 |= 0x02;
484
485 if (div <= 32) {
486 N = 2;
487
488 f0 = 0;
489 f1 = div / N;
490 f2 = div - f1;
491 f3 = 0;
492 } else if (div <= 34) {
493 N = 3;
494
495 f0 = div / N;
496 f1 = (div - f0) / (N - 1);
497 f2 = div - f0 - f1;
498 f3 = 0;
499 } else if (div <= 64) {
500 N = 4;
501
502 f0 = div / N;
503 f1 = (div - f0) / (N - 1);
504 f2 = (div - f0 - f1) / (N - 2);
505 f3 = div - f0 - f1 - f2;
506 } else {
507 N = 4;
508
509 f0 = 16;
510 f1 = 16;
511 f2 = 16;
512 f3 = 16;
513 }
514
515 if (f0 == 16)
516 f0 = 0;
517 else if ((f0 < 8) && (f0 != 0))
518 f0 = 8;
519
520 if (f1 == 16)
521 f1 = 0;
522 else if ((f1 < 8) && (f1 != 0))
523 f1 = 8;
524
525 if (f2 == 16)
526 f2 = 0;
527 else if ((f2 < 8) && (f2 != 0))
528 f2 = 8;
529
530 if (f3 == 16)
531 f3 = 0;
532 else if ((f3 < 8) && (f3 != 0))
533 f3 = 8;
534 } else {
535 reg11 &= ~0x02;
536
537 if (div <= 32) {
538 N = 2;
539
540 f0 = 0;
541 f1 = div / N;
542 f2 = div - f1;
543 f3 = 0;
544 } else if (div <= 48) {
545 N = 3;
546
547 f0 = div / N;
548 f1 = (div - f0) / (N - 1);
549 f2 = div - f0 - f1;
550 f3 = 0;
551 } else if (div <= 64) {
552 N = 4;
553
554 f0 = div / N;
555 f1 = (div - f0) / (N - 1);
556 f2 = (div - f0 - f1) / (N - 2);
557 f3 = div - f0 - f1 - f2;
558 } else {
559 N = 4;
560
561 f0 = 16;
562 f1 = 16;
563 f2 = 16;
564 f3 = 16;
565 }
566
567 if (f0 == 16)
568 f0 = 0;
569 else if ((f0 < 9) && (f0 != 0))
570 f0 = 9;
571
572 if (f1 == 16)
573 f1 = 0;
574 else if ((f1 < 9) && (f1 != 0))
575 f1 = 9;
576
577 if (f2 == 16)
578 f2 = 0;
579 else if ((f2 < 9) && (f2 != 0))
580 f2 = 9;
581
582 if (f3 == 16)
583 f3 = 0;
584 else if ((f3 < 9) && (f3 != 0))
585 f3 = 9;
586 }
587
588 sm = N - 1;
589
590 /* Write to registers */
591 //reg15 &= 0x01;
592 //reg15 |= (pll_div_fb >> 8) & 0x01;
593
594 //reg16 = pll_div_fb & 0xFF;
595
596 reg1D &= ~0x03;
597 reg1D |= sm;
598 reg1D |= 0x80;
599
600 reg1E = ((f3 << 4) + f2) & 0xFF;
601 reg1F = ((f1 << 4) + f0) & 0xFF;
602
603 m88ds3103b_dt_write(dev, 0x05, 0x40);
604 m88ds3103b_dt_write(dev, 0x11, 0x08);
605 m88ds3103b_dt_write(dev, 0x1D, reg1D);
606 m88ds3103b_dt_write(dev, 0x1E, reg1E);
607 m88ds3103b_dt_write(dev, 0x1F, reg1F);
608
609 m88ds3103b_dt_write(dev, 0x17, 0xc1);
610 m88ds3103b_dt_write(dev, 0x17, 0x81);
611
612 usleep_range(5000, 5500);
613
614 m88ds3103b_dt_write(dev, 0x05, 0x00);
615 m88ds3103b_dt_write(dev, 0x11, 0x0A);
616
617 usleep_range(5000, 5500);
618
619 return 0;
620}
621
291static int m88ds3103_set_frontend(struct dvb_frontend *fe)622static int m88ds3103_set_frontend(struct dvb_frontend *fe)
292{623{
293 struct m88ds3103_dev *dev = fe->demodulator_priv;624 struct m88ds3103_dev *dev = fe->demodulator_priv;
@@ -298,7 +629,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 4 unmodified lines
298 u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */629 u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */
299 u8 buf[3];630 u8 buf[3];
300 u16 u16tmp;631 u16 u16tmp;
301 u32 tuner_frequency_khz, target_mclk;632 u32 tuner_frequency_khz, target_mclk, u32tmp;
302 s32 s32tmp;633 s32 s32tmp;
303 static const struct reg_sequence reset_buf[] = {634 static const struct reg_sequence reset_buf[] = {
304 {0x07, 0x80}, {0x07, 0x00}635 {0x07, 0x80}, {0x07, 0x00}
@@ -321,6 +652,20 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 16 unmodified lines
321 652
322 /* Disable demod clock path */653 /* Disable demod clock path */
323 if (dev->chip_id == M88RS6000_CHIP_ID) {654 if (dev->chip_id == M88RS6000_CHIP_ID) {
655 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
656 ret = regmap_read(dev->regmap, 0xb2, &u32tmp);
657 if (ret)
658 goto err;
659 if (u32tmp == 0x01) {
660 ret = regmap_write(dev->regmap, 0x00, 0x00);
661 if (ret)
662 goto err;
663 ret = regmap_write(dev->regmap, 0xb2, 0x00);
664 if (ret)
665 goto err;
666 }
667 }
668
324 ret = regmap_write(dev->regmap, 0x06, 0xe0);669 ret = regmap_write(dev->regmap, 0x06, 0xe0);
325 if (ret)670 if (ret)
326 goto err;671 goto err;
@@ -346,7 +691,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 19 unmodified lines
346 tuner_frequency_khz = c->frequency;691 tuner_frequency_khz = c->frequency;
347 }692 }
348 693
349 /* select M88RS6000 demod main mclk and ts mclk from tuner die. */694 /* set M88RS6000/DS3103B demod main mclk and ts mclk from tuner die */
350 if (dev->chip_id == M88RS6000_CHIP_ID) {695 if (dev->chip_id == M88RS6000_CHIP_ID) {
351 if (c->symbol_rate > 45010000)696 if (c->symbol_rate > 45010000)
352 dev->mclk = 110250000;697 dev->mclk = 110250000;
@@ -358,6 +703,11 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 5 unmodified lines
358 else703 else
359 target_mclk = 144000000;704 target_mclk = 144000000;
360 705
706 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
707 m88ds3103b_select_mclk(dev);
708 m88ds3103b_set_mclk(dev, target_mclk / 1000);
709 }
710
361 /* Enable demod clock path */711 /* Enable demod clock path */
362 ret = regmap_write(dev->regmap, 0x06, 0x00);712 ret = regmap_write(dev->regmap, 0x06, 0x00);
363 if (ret)713 if (ret)
@@ -469,12 +819,42 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 105 unmodified lines
469 ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);819 ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);
470 if (ret)820 if (ret)
471 goto err;821 goto err;
822
823 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
824 buf[0] = m88ds3103b_dt_read(dev, 0x15);
825 buf[1] = m88ds3103b_dt_read(dev, 0x16);
826
827 if (c->symbol_rate > 45010000) {
828 buf[0] &= ~0x03;
829 buf[0] |= 0x02;
830 buf[0] |= ((147 - 32) >> 8) & 0x01;
831 buf[1] = (147 - 32) & 0xFF;
832
833 dev->mclk = 110250 * 1000;
834 } else {
835 buf[0] &= ~0x03;
836 buf[0] |= ((128 - 32) >> 8) & 0x01;
837 buf[1] = (128 - 32) & 0xFF;
838
839 dev->mclk = 96000 * 1000;
840 }
841 m88ds3103b_dt_write(dev, 0x15, buf[0]);
842 m88ds3103b_dt_write(dev, 0x16, buf[1]);
843
844 regmap_read(dev->regmap, 0x30, &u32tmp);
845 u32tmp &= ~0x80;
846 regmap_write(dev->regmap, 0x30, u32tmp & 0xff);
847 }
848
472 ret = regmap_write(dev->regmap, 0xf1, 0x01);849 ret = regmap_write(dev->regmap, 0xf1, 0x01);
473 if (ret)850 if (ret)
474 goto err;851 goto err;
475 ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);852
476 if (ret)853 if (dev->chiptype != M88DS3103_CHIPTYPE_3103B) {
477 goto err;854 ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
855 if (ret)
856 goto err;
857 }
478 }858 }
479 859
480 switch (dev->cfg->ts_mode) {860 switch (dev->cfg->ts_mode) {
@@ -488,6 +868,10 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 7 unmodified lines
488 break;868 break;
489 case M88DS3103_TS_PARALLEL:869 case M88DS3103_TS_PARALLEL:
490 u8tmp = 0x02;870 u8tmp = 0x02;
871 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
872 u8tmp = 0x01;
873 u8tmp1 = 0x01;
874 }
491 break;875 break;
492 case M88DS3103_TS_CI:876 case M88DS3103_TS_CI:
493 u8tmp = 0x03;877 u8tmp = 0x03;
@@ -516,6 +900,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 22 unmodified lines
516 u8tmp1 = 0x3f;900 u8tmp1 = 0x3f;
517 u8tmp2 = 0x3f;901 u8tmp2 = 0x3f;
518 break;902 break;
903 case M88DS3103_TS_PARALLEL:
904 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
905 ret = m88ds3103_update_bits(dev, 0x29, 0x01, u8tmp1);
906 if (ret)
907 goto err;
908 }
909 /* fall through */
519 default:910 default:
520 u16tmp = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk);911 u16tmp = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk);
521 u8tmp1 = u16tmp / 2 - 1;912 u8tmp1 = u16tmp / 2 - 1;
@@ -543,6 +934,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 21 unmodified lines
543 else934 else
544 u8tmp = 0x06;935 u8tmp = 0x06;
545 936
937 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
938 m88ds3103b_set_mclk(dev, target_mclk / 1000);
939
546 ret = regmap_write(dev->regmap, 0xc3, 0x08);940 ret = regmap_write(dev->regmap, 0xc3, 0x08);
547 if (ret)941 if (ret)
548 goto err;942 goto err;
@@ -578,6 +972,16 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) · 29 unmodified lines
578 if (ret)972 if (ret)
579 goto err;973 goto err;
580 974
975 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
976 /* enable/disable 192M LDPC clock */
977 ret = m88ds3103_update_bits(dev, 0x29, 0x10,
978 (c->delivery_system == SYS_DVBS) ? 0x10 : 0x0);
979 if (ret)
980 goto err;
981
982 ret = m88ds3103_update_bits(dev, 0xc9, 0x08, 0x08);
983 }
984
581 dev_dbg(&client->dev, "carrier offset=%d\n",985 dev_dbg(&client->dev, "carrier offset=%d\n",
582 (tuner_frequency_khz - c->frequency));986 (tuner_frequency_khz - c->frequency));
583 987
@@ -642,7 +1046,7 @@ static int m88ds3103_init(struct dvb_frontend *fe) · 58 unmodified lines
642 if (utmp)1046 if (utmp)
643 goto warm;1047 goto warm;
644 1048
645 /* global reset, global diseqc reset, golbal fec reset */1049 /* global reset, global diseqc reset, global fec reset */
646 ret = regmap_write(dev->regmap, 0x07, 0xe0);1050 ret = regmap_write(dev->regmap, 0x07, 0xe0);
647 if (ret)1051 if (ret)
648 goto err;1052 goto err;
@@ -652,12 +1056,15 @@ static int m88ds3103_init(struct dvb_frontend *fe) · 3 unmodified lines
652 1056
653 /* cold state - try to download firmware */1057 /* cold state - try to download firmware */
654 dev_info(&client->dev, "found a '%s' in cold state\n",1058 dev_info(&client->dev, "found a '%s' in cold state\n",
655 m88ds3103_ops.info.name);1059 dev->fe.ops.info.name);
656 1060
657 if (dev->chip_id == M88RS6000_CHIP_ID)1061 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
1062 name = M88DS3103B_FIRMWARE;
1063 else if (dev->chip_id == M88RS6000_CHIP_ID)
658 name = M88RS6000_FIRMWARE;1064 name = M88RS6000_FIRMWARE;
659 else1065 else
660 name = M88DS3103_FIRMWARE;1066 name = M88DS3103_FIRMWARE;
1067
661 /* request the firmware, this will block and timeout */1068 /* request the firmware, this will block and timeout */
662 ret = request_firmware(&firmware, name, &client->dev);1069 ret = request_firmware(&firmware, name, &client->dev);
663 if (ret) {1070 if (ret) {
@@ -700,10 +1107,16 @@ static int m88ds3103_init(struct dvb_frontend *fe) · 36 unmodified lines
700 }1107 }
701 1108
702 dev_info(&client->dev, "found a '%s' in warm state\n",1109 dev_info(&client->dev, "found a '%s' in warm state\n",
703 m88ds3103_ops.info.name);1110 dev->fe.ops.info.name);
704 dev_info(&client->dev, "firmware version: %X.%X\n",1111 dev_info(&client->dev, "firmware version: %X.%X\n",
705 (utmp >> 4) & 0xf, (utmp >> 0 & 0xf));1112 (utmp >> 4) & 0xf, (utmp >> 0 & 0xf));
706 1113
1114 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
1115 m88ds3103b_dt_write(dev, 0x21, 0x92);
1116 m88ds3103b_dt_write(dev, 0x15, 0x6C);
1117 m88ds3103b_dt_write(dev, 0x17, 0xC1);
1118 m88ds3103b_dt_write(dev, 0x17, 0x81);
1119 }
707warm:1120warm:
708 /* warm state */1121 /* warm state */
709 dev->warm = true;1122 dev->warm = true;
@@ -1393,6 +1806,8 @@ static int m88ds3103_probe(struct i2c_client *client, · 683 unmodified lines
1393 goto err_kfree;1806 goto err_kfree;
1394 1807
1395 dev->chip_id = utmp >> 1;1808 dev->chip_id = utmp >> 1;
1809 dev->chiptype = (u8)id->driver_data;
1810
1396 dev_dbg(&client->dev, "chip_id=%02x\n", dev->chip_id);1811 dev_dbg(&client->dev, "chip_id=%02x\n", dev->chip_id);
1397 1812
1398 switch (dev->chip_id) {1813 switch (dev->chip_id) {
@@ -1459,7 +1874,10 @@ static int m88ds3103_probe(struct i2c_client *client, · 60 unmodified lines
1459 1874
1460 /* create dvb_frontend */1875 /* create dvb_frontend */
1461 memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));1876 memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
1462 if (dev->chip_id == M88RS6000_CHIP_ID)1877 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
1878 strscpy(dev->fe.ops.info.name, "Montage Technology M88DS3103B",
1879 sizeof(dev->fe.ops.info.name));
1880 else if (dev->chip_id == M88RS6000_CHIP_ID)
1463 strscpy(dev->fe.ops.info.name, "Montage Technology M88RS6000",1881 strscpy(dev->fe.ops.info.name, "Montage Technology M88RS6000",
1464 sizeof(dev->fe.ops.info.name));1882 sizeof(dev->fe.ops.info.name));
1465 if (!pdata->attach_in_use)1883 if (!pdata->attach_in_use)
@@ -1470,6 +1888,26 @@ static int m88ds3103_probe(struct i2c_client *client, · 4 unmodified lines
1470 /* setup callbacks */1888 /* setup callbacks */
1471 pdata->get_dvb_frontend = m88ds3103_get_dvb_frontend;1889 pdata->get_dvb_frontend = m88ds3103_get_dvb_frontend;
1472 pdata->get_i2c_adapter = m88ds3103_get_i2c_adapter;1890 pdata->get_i2c_adapter = m88ds3103_get_i2c_adapter;
1891
1892 if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
1893 /* enable i2c repeater for tuner */
1894 m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
1895
1896 /* get frontend address */
1897 ret = regmap_read(dev->regmap, 0x29, &utmp);
1898 if (ret)
1899 goto err_kfree;
1900 dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1;
1901 dev_err(&client->dev, "dt addr is 0x%02x", dev->dt_addr);
1902
1903 dev->dt_client = i2c_new_dummy_device(client->adapter,
1904 dev->dt_addr);
1905 if (!dev->dt_client) {
1906 ret = -ENODEV;
1907 goto err_kfree;
1908 }
1909 }
1910
1473 return 0;1911 return 0;
1474err_kfree:1912err_kfree:
1475 kfree(dev);1913 kfree(dev);
@@ -1484,6 +1922,9 @@ static int m88ds3103_remove(struct i2c_client *client) · 8 unmodified lines
1484 1922
1485 dev_dbg(&client->dev, "\n");1923 dev_dbg(&client->dev, "\n");
1486 1924
1925 if (dev->dt_client)
1926 i2c_unregister_device(dev->dt_client);
1927
1487 i2c_mux_del_adapters(dev->muxc);1928 i2c_mux_del_adapters(dev->muxc);
1488 1929
1489 kfree(dev);1930 kfree(dev);
@@ -1491,7 +1932,9 @@ static int m88ds3103_remove(struct i2c_client *client) · 1 unmodified line
1491}1932}
1492 1933
1493static const struct i2c_device_id m88ds3103_id_table[] = {1934static const struct i2c_device_id m88ds3103_id_table[] = {
1494 {"m88ds3103", 0},1935 {"m88ds3103", M88DS3103_CHIPTYPE_3103},
1936 {"m88rs6000", M88DS3103_CHIPTYPE_RS6000},
1937 {"m88ds3103b", M88DS3103_CHIPTYPE_3103B},
1495 {}1938 {}
1496};1939};
1497MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);1940MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);
@@ -1513,3 +1956,4 @@ MODULE_DESCRIPTION("Montage Technology M88DS3103 DVB-S/S2 demodulator driver"); · 15 unmodified lines
1513MODULE_LICENSE("GPL");1956MODULE_LICENSE("GPL");
1514MODULE_FIRMWARE(M88DS3103_FIRMWARE);1957MODULE_FIRMWARE(M88DS3103_FIRMWARE);
1515MODULE_FIRMWARE(M88RS6000_FIRMWARE);1958MODULE_FIRMWARE(M88RS6000_FIRMWARE);
1959MODULE_FIRMWARE(M88DS3103B_FIRMWARE);
drivers/media/dvb-frontends/m88ds3103_priv.h+12−2
@@ -16,13 +16,20 @@ · 15 unmodified lines
16#include <linux/regmap.h>16#include <linux/regmap.h>
17#include <linux/math64.h>17#include <linux/math64.h>
18 18
19#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"19#define M88DS3103B_FIRMWARE "dvb-demod-m88ds3103b.fw"
20#define M88RS6000_FIRMWARE "dvb-demod-m88rs6000.fw"20#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"
21#define M88RS6000_FIRMWARE "dvb-demod-m88rs6000.fw"
22
21#define M88RS6000_CHIP_ID 0x7423#define M88RS6000_CHIP_ID 0x74
22#define M88DS3103_CHIP_ID 0x7024#define M88DS3103_CHIP_ID 0x70
23 25
26#define M88DS3103_CHIPTYPE_3103 0
27#define M88DS3103_CHIPTYPE_RS6000 1
28#define M88DS3103_CHIPTYPE_3103B 2
29
24struct m88ds3103_dev {30struct m88ds3103_dev {
25 struct i2c_client *client;31 struct i2c_client *client;
32 struct i2c_client *dt_client;
26 struct regmap_config regmap_config;33 struct regmap_config regmap_config;
27 struct regmap *regmap;34 struct regmap *regmap;
28 struct m88ds3103_config config;35 struct m88ds3103_config config;
@@ -35,10 +42,13 @@ struct m88ds3103_dev { · 6 unmodified lines
35 struct i2c_mux_core *muxc;42 struct i2c_mux_core *muxc;
36 /* auto detect chip id to do different config */43 /* auto detect chip id to do different config */
37 u8 chip_id;44 u8 chip_id;
45 /* chip type to differentiate m88rs6000 from m88ds3103b */
46 u8 chiptype;
38 /* main mclk is calculated for M88RS6000 dynamically */47 /* main mclk is calculated for M88RS6000 dynamically */
39 s32 mclk;48 s32 mclk;
40 u64 post_bit_error;49 u64 post_bit_error;
41 u64 post_bit_count;50 u64 post_bit_count;
51 u8 dt_addr;
42};52};
43 53
44struct m88ds3103_reg_val {54struct m88ds3103_reg_val {
drivers/media/dvb-frontends/tda10071.c+5−4
@@ -470,10 +470,11 @@ static int tda10071_read_status(struct dvb_frontend *fe, enum fe_status *status) · 469 unmodified lines
470 goto error;470 goto error;
471 471
472 if (dev->delivery_system == SYS_DVBS) {472 if (dev->delivery_system == SYS_DVBS) {
473 dev->dvbv3_ber = buf[0] << 24 | buf[1] << 16 |473 u32 bit_error = buf[0] << 24 | buf[1] << 16 |
474 buf[2] << 8 | buf[3] << 0;474 buf[2] << 8 | buf[3] << 0;
475 dev->post_bit_error += buf[0] << 24 | buf[1] << 16 |475
476 buf[2] << 8 | buf[3] << 0;476 dev->dvbv3_ber = bit_error;
477 dev->post_bit_error += bit_error;
477 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;478 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
478 c->post_bit_error.stat[0].uvalue = dev->post_bit_error;479 c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
479 dev->block_error += buf[4] << 8 | buf[5] << 0;480 dev->block_error += buf[4] << 8 | buf[5] << 0;
drivers/media/i2c/Kconfig+16−0
@@ -238,6 +238,7 @@ config VIDEO_ADV7604 · 237 unmodified lines
238 tristate "Analog Devices ADV7604 decoder"238 tristate "Analog Devices ADV7604 decoder"
239 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API239 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
240 depends on GPIOLIB || COMPILE_TEST240 depends on GPIOLIB || COMPILE_TEST
241 select REGMAP_I2C
241 select HDMI242 select HDMI
242 select V4L2_FWNODE243 select V4L2_FWNODE
243 help244 help
@@ -379,6 +380,7 @@ config VIDEO_TVP5150 · 135 unmodified lines
379 tristate "Texas Instruments TVP5150 video decoder"380 tristate "Texas Instruments TVP5150 video decoder"
380 depends on VIDEO_V4L2 && I2C381 depends on VIDEO_V4L2 && I2C
381 select V4L2_FWNODE382 select V4L2_FWNODE
383 select REGMAP_I2C
382 help384 help
383 Support for the Texas Instruments TVP5150 video decoder.385 Support for the Texas Instruments TVP5150 video decoder.
384 386
@@ -584,6 +586,7 @@ config VIDEO_IMX214 · 199 unmodified lines
584 tristate "Sony IMX214 sensor support"586 tristate "Sony IMX214 sensor support"
585 depends on GPIOLIB && I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API587 depends on GPIOLIB && I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
586 depends on V4L2_FWNODE588 depends on V4L2_FWNODE
589 select REGMAP_I2C
587 help590 help
588 This is a Video4Linux2 sensor driver for the Sony591 This is a Video4Linux2 sensor driver for the Sony
589 IMX214 camera.592 IMX214 camera.
@@ -591,6 +594,17 @@ config VIDEO_IMX214 · 1 unmodified line
591 To compile this driver as a module, choose M here: the594 To compile this driver as a module, choose M here: the
592 module will be called imx214.595 module will be called imx214.
593 596
597config VIDEO_IMX219
598 tristate "Sony IMX219 sensor support"
599 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
600 select V4L2_FWNODE
601 help
602 This is a Video4Linux2 sensor driver for the Sony
603 IMX219 camera.
604
605 To compile this driver as a module, choose M here: the
606 module will be called imx219.
607
594config VIDEO_IMX258608config VIDEO_IMX258
595 tristate "Sony IMX258 sensor support"609 tristate "Sony IMX258 sensor support"
596 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API610 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
@@ -612,6 +626,7 @@ config VIDEO_IMX274 · 15 unmodified lines
612config VIDEO_IMX290626config VIDEO_IMX290
613 tristate "Sony IMX290 sensor support"627 tristate "Sony IMX290 sensor support"
614 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API628 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
629 select REGMAP_I2C
615 select V4L2_FWNODE630 select V4L2_FWNODE
616 help631 help
617 This is a Video4Linux2 sensor driver for the Sony632 This is a Video4Linux2 sensor driver for the Sony
@@ -804,6 +819,7 @@ config VIDEO_OV7670 · 186 unmodified lines
804config VIDEO_OV7740819config VIDEO_OV7740
805 tristate "OmniVision OV7740 sensor support"820 tristate "OmniVision OV7740 sensor support"
806 depends on I2C && VIDEO_V4L2821 depends on I2C && VIDEO_V4L2
822 select REGMAP_I2C
807 help823 help
808 This is a Video4Linux2 sensor driver for the OmniVision824 This is a Video4Linux2 sensor driver for the OmniVision
809 OV7740 VGA camera sensor.825 OV7740 VGA camera sensor.
drivers/media/i2c/Makefile+1−0
@@ -111,6 +111,7 @@ obj-$(CONFIG_VIDEO_OV2659) += ov2659.o · 110 unmodified lines
111obj-$(CONFIG_VIDEO_TC358743) += tc358743.o111obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
112obj-$(CONFIG_VIDEO_HI556) += hi556.o112obj-$(CONFIG_VIDEO_HI556) += hi556.o
113obj-$(CONFIG_VIDEO_IMX214) += imx214.o113obj-$(CONFIG_VIDEO_IMX214) += imx214.o
114obj-$(CONFIG_VIDEO_IMX219) += imx219.o
114obj-$(CONFIG_VIDEO_IMX258) += imx258.o115obj-$(CONFIG_VIDEO_IMX258) += imx258.o
115obj-$(CONFIG_VIDEO_IMX274) += imx274.o116obj-$(CONFIG_VIDEO_IMX274) += imx274.o
116obj-$(CONFIG_VIDEO_IMX290) += imx290.o117obj-$(CONFIG_VIDEO_IMX290) += imx290.o
drivers/media/i2c/adv7180.c+12−0
@@ -749,6 +749,17 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd, · 748 unmodified lines
749 return ret;749 return ret;
750}750}
751 751
752static int adv7180_init_cfg(struct v4l2_subdev *sd,
753 struct v4l2_subdev_pad_config *cfg)
754{
755 struct v4l2_subdev_format fmt = {
756 .which = cfg ? V4L2_SUBDEV_FORMAT_TRY
757 : V4L2_SUBDEV_FORMAT_ACTIVE,
758 };
759
760 return adv7180_set_pad_format(sd, cfg, &fmt);
761}
762
752static int adv7180_g_mbus_config(struct v4l2_subdev *sd,763static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
753 struct v4l2_mbus_config *cfg)764 struct v4l2_mbus_config *cfg)
754{765{
@@ -854,6 +865,7 @@ static const struct v4l2_subdev_core_ops adv7180_core_ops = { · 99 unmodified lines
854};865};
855 866
856static const struct v4l2_subdev_pad_ops adv7180_pad_ops = {867static const struct v4l2_subdev_pad_ops adv7180_pad_ops = {
868 .init_cfg = adv7180_init_cfg,
857 .enum_mbus_code = adv7180_enum_mbus_code,869 .enum_mbus_code = adv7180_enum_mbus_code,
858 .set_fmt = adv7180_set_pad_format,870 .set_fmt = adv7180_set_pad_format,
859 .get_fmt = adv7180_get_pad_format,871 .get_fmt = adv7180_get_pad_format,
drivers/media/i2c/imx214.c+0−1
@@ -803,7 +803,6 @@ err_rpm_put: · 802 unmodified lines
803static int imx214_g_frame_interval(struct v4l2_subdev *subdev,803static int imx214_g_frame_interval(struct v4l2_subdev *subdev,
804 struct v4l2_subdev_frame_interval *fival)804 struct v4l2_subdev_frame_interval *fival)
805{805{
806 fival->pad = 0;
807 fival->interval.numerator = 1;806 fival->interval.numerator = 1;
808 fival->interval.denominator = IMX214_FPS;807 fival->interval.denominator = IMX214_FPS;
809 808
drivers/media/i2c/imx219.c+1481−0
@@ -0,0 +1,1481 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * A V4L2 driver for Sony IMX219 cameras.
4 * Copyright (C) 2019, Raspberry Pi (Trading) Ltd
5 *
6 * Based on Sony imx258 camera driver
7 * Copyright (C) 2018 Intel Corporation
8 *
9 * DT / fwnode changes, and regulator / GPIO control taken from imx214 driver
10 * Copyright 2018 Qtechnology A/S
11 *
12 * Flip handling taken from the Sony IMX319 driver.
13 * Copyright (C) 2018 Intel Corporation
14 *
15 */
16
17#include <linux/clk.h>
18#include <linux/clk-provider.h>
19#include <linux/clkdev.h>
20#include <linux/delay.h>
21#include <linux/gpio/consumer.h>
22#include <linux/i2c.h>
23#include <linux/module.h>
24#include <linux/pm_runtime.h>
25#include <linux/regulator/consumer.h>
26#include <media/v4l2-ctrls.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-event.h>
29#include <media/v4l2-fwnode.h>
30#include <media/v4l2-mediabus.h>
31#include <asm/unaligned.h>
32
33#define IMX219_REG_VALUE_08BIT 1
34#define IMX219_REG_VALUE_16BIT 2
35
36#define IMX219_REG_MODE_SELECT 0x0100
37#define IMX219_MODE_STANDBY 0x00
38#define IMX219_MODE_STREAMING 0x01
39
40/* Chip ID */
41#define IMX219_REG_CHIP_ID 0x0000
42#define IMX219_CHIP_ID 0x0219
43
44/* External clock frequency is 24.0M */
45#define IMX219_XCLK_FREQ 24000000
46
47/* Pixel rate is fixed at 182.4M for all the modes */
48#define IMX219_PIXEL_RATE 182400000
49
50#define IMX219_DEFAULT_LINK_FREQ 456000000
51
52/* V_TIMING internal */
53#define IMX219_REG_VTS 0x0160
54#define IMX219_VTS_15FPS 0x0dc6
55#define IMX219_VTS_30FPS_1080P 0x06e3
56#define IMX219_VTS_30FPS_BINNED 0x06e3
57#define IMX219_VTS_30FPS_640x480 0x06e3
58#define IMX219_VTS_MAX 0xffff
59
60#define IMX219_VBLANK_MIN 4
61
62/*Frame Length Line*/
63#define IMX219_FLL_MIN 0x08a6
64#define IMX219_FLL_MAX 0xffff
65#define IMX219_FLL_STEP 1
66#define IMX219_FLL_DEFAULT 0x0c98
67
68/* HBLANK control - read only */
69#define IMX219_PPL_DEFAULT 3448
70
71/* Exposure control */
72#define IMX219_REG_EXPOSURE 0x015a
73#define IMX219_EXPOSURE_MIN 4
74#define IMX219_EXPOSURE_STEP 1
75#define IMX219_EXPOSURE_DEFAULT 0x640
76#define IMX219_EXPOSURE_MAX 65535
77
78/* Analog gain control */
79#define IMX219_REG_ANALOG_GAIN 0x0157
80#define IMX219_ANA_GAIN_MIN 0
81#define IMX219_ANA_GAIN_MAX 232
82#define IMX219_ANA_GAIN_STEP 1
83#define IMX219_ANA_GAIN_DEFAULT 0x0
84
85/* Digital gain control */
86#define IMX219_REG_DIGITAL_GAIN 0x0158
87#define IMX219_DGTL_GAIN_MIN 0x0100
88#define IMX219_DGTL_GAIN_MAX 0x0fff
89#define IMX219_DGTL_GAIN_DEFAULT 0x0100
90#define IMX219_DGTL_GAIN_STEP 1
91
92#define IMX219_REG_ORIENTATION 0x0172
93
94/* Test Pattern Control */
95#define IMX219_REG_TEST_PATTERN 0x0600
96#define IMX219_TEST_PATTERN_DISABLE 0
97#define IMX219_TEST_PATTERN_SOLID_COLOR 1
98#define IMX219_TEST_PATTERN_COLOR_BARS 2
99#define IMX219_TEST_PATTERN_GREY_COLOR 3
100#define IMX219_TEST_PATTERN_PN9 4
101
102/* Test pattern colour components */
103#define IMX219_REG_TESTP_RED 0x0602
104#define IMX219_REG_TESTP_GREENR 0x0604
105#define IMX219_REG_TESTP_BLUE 0x0606
106#define IMX219_REG_TESTP_GREENB 0x0608
107#define IMX219_TESTP_COLOUR_MIN 0
108#define IMX219_TESTP_COLOUR_MAX 0x03ff
109#define IMX219_TESTP_COLOUR_STEP 1
110#define IMX219_TESTP_RED_DEFAULT IMX219_TESTP_COLOUR_MAX
111#define IMX219_TESTP_GREENR_DEFAULT 0
112#define IMX219_TESTP_BLUE_DEFAULT 0
113#define IMX219_TESTP_GREENB_DEFAULT 0
114
115struct imx219_reg {
116 u16 address;
117 u8 val;
118};
119
120struct imx219_reg_list {
121 unsigned int num_of_regs;
122 const struct imx219_reg *regs;
123};
124
125/* Mode : resolution and related config&values */
126struct imx219_mode {
127 /* Frame width */
128 unsigned int width;
129 /* Frame height */
130 unsigned int height;
131
132 /* V-timing */
133 unsigned int vts_def;
134
135 /* Default register values */
136 struct imx219_reg_list reg_list;
137};
138
139/*
140 * Register sets lifted off the i2C interface from the Raspberry Pi firmware
141 * driver.
142 * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
143 */
144static const struct imx219_reg mode_3280x2464_regs[] = {
145 {0x0100, 0x00},
146 {0x30eb, 0x0c},
147 {0x30eb, 0x05},
148 {0x300a, 0xff},
149 {0x300b, 0xff},
150 {0x30eb, 0x05},
151 {0x30eb, 0x09},
152 {0x0114, 0x01},
153 {0x0128, 0x00},
154 {0x012a, 0x18},
155 {0x012b, 0x00},
156 {0x0164, 0x00},
157 {0x0165, 0x00},
158 {0x0166, 0x0c},
159 {0x0167, 0xcf},
160 {0x0168, 0x00},
161 {0x0169, 0x00},
162 {0x016a, 0x09},
163 {0x016b, 0x9f},
164 {0x016c, 0x0c},
165 {0x016d, 0xd0},
166 {0x016e, 0x09},
167 {0x016f, 0xa0},
168 {0x0170, 0x01},
169 {0x0171, 0x01},
170 {0x0174, 0x00},
171 {0x0175, 0x00},
172 {0x0301, 0x05},
173 {0x0303, 0x01},
174 {0x0304, 0x03},
175 {0x0305, 0x03},
176 {0x0306, 0x00},
177 {0x0307, 0x39},
178 {0x030b, 0x01},
179 {0x030c, 0x00},
180 {0x030d, 0x72},
181 {0x0624, 0x0c},
182 {0x0625, 0xd0},
183 {0x0626, 0x09},
184 {0x0627, 0xa0},
185 {0x455e, 0x00},
186 {0x471e, 0x4b},
187 {0x4767, 0x0f},
188 {0x4750, 0x14},
189 {0x4540, 0x00},
190 {0x47b4, 0x14},
191 {0x4713, 0x30},
192 {0x478b, 0x10},
193 {0x478f, 0x10},
194 {0x4793, 0x10},
195 {0x4797, 0x0e},
196 {0x479b, 0x0e},
197 {0x0162, 0x0d},
198 {0x0163, 0x78},
199};
200
201static const struct imx219_reg mode_1920_1080_regs[] = {
202 {0x0100, 0x00},
203 {0x30eb, 0x05},
204 {0x30eb, 0x0c},
205 {0x300a, 0xff},
206 {0x300b, 0xff},
207 {0x30eb, 0x05},
208 {0x30eb, 0x09},
209 {0x0114, 0x01},
210 {0x0128, 0x00},
211 {0x012a, 0x18},
212 {0x012b, 0x00},
213 {0x0162, 0x0d},
214 {0x0163, 0x78},
215 {0x0164, 0x02},
216 {0x0165, 0xa8},
217 {0x0166, 0x0a},
218 {0x0167, 0x27},
219 {0x0168, 0x02},
220 {0x0169, 0xb4},
221 {0x016a, 0x06},
222 {0x016b, 0xeb},
223 {0x016c, 0x07},
224 {0x016d, 0x80},
225 {0x016e, 0x04},
226 {0x016f, 0x38},
227 {0x0170, 0x01},
228 {0x0171, 0x01},
229 {0x0174, 0x00},
230 {0x0175, 0x00},
231 {0x0301, 0x05},
232 {0x0303, 0x01},
233 {0x0304, 0x03},
234 {0x0305, 0x03},
235 {0x0306, 0x00},
236 {0x0307, 0x39},
237 {0x030b, 0x01},
238 {0x030c, 0x00},
239 {0x030d, 0x72},
240 {0x0624, 0x07},
241 {0x0625, 0x80},
242 {0x0626, 0x04},
243 {0x0627, 0x38},
244 {0x455e, 0x00},
245 {0x471e, 0x4b},
246 {0x4767, 0x0f},
247 {0x4750, 0x14},
248 {0x4540, 0x00},
249 {0x47b4, 0x14},
250 {0x4713, 0x30},
251 {0x478b, 0x10},
252 {0x478f, 0x10},
253 {0x4793, 0x10},
254 {0x4797, 0x0e},
255 {0x479b, 0x0e},
256 {0x0162, 0x0d},
257 {0x0163, 0x78},
258};
259
260static const struct imx219_reg mode_1640_1232_regs[] = {
261 {0x0100, 0x00},
262 {0x30eb, 0x0c},
263 {0x30eb, 0x05},
264 {0x300a, 0xff},
265 {0x300b, 0xff},
266 {0x30eb, 0x05},
267 {0x30eb, 0x09},
268 {0x0114, 0x01},
269 {0x0128, 0x00},
270 {0x012a, 0x18},
271 {0x012b, 0x00},
272 {0x0164, 0x00},
273 {0x0165, 0x00},
274 {0x0166, 0x0c},
275 {0x0167, 0xcf},
276 {0x0168, 0x00},
277 {0x0169, 0x00},
278 {0x016a, 0x09},
279 {0x016b, 0x9f},
280 {0x016c, 0x06},
281 {0x016d, 0x68},
282 {0x016e, 0x04},
283 {0x016f, 0xd0},
284 {0x0170, 0x01},
285 {0x0171, 0x01},
286 {0x0174, 0x01},
287 {0x0175, 0x01},
288 {0x0301, 0x05},
289 {0x0303, 0x01},
290 {0x0304, 0x03},
291 {0x0305, 0x03},
292 {0x0306, 0x00},
293 {0x0307, 0x39},
294 {0x030b, 0x01},
295 {0x030c, 0x00},
296 {0x030d, 0x72},
297 {0x0624, 0x06},
298 {0x0625, 0x68},
299 {0x0626, 0x04},
300 {0x0627, 0xd0},
301 {0x455e, 0x00},
302 {0x471e, 0x4b},
303 {0x4767, 0x0f},
304 {0x4750, 0x14},
305 {0x4540, 0x00},
306 {0x47b4, 0x14},
307 {0x4713, 0x30},
308 {0x478b, 0x10},
309 {0x478f, 0x10},
310 {0x4793, 0x10},
311 {0x4797, 0x0e},
312 {0x479b, 0x0e},
313 {0x0162, 0x0d},
314 {0x0163, 0x78},
315};
316
317static const struct imx219_reg mode_640_480_regs[] = {
318 {0x0100, 0x00},
319 {0x30eb, 0x05},
320 {0x30eb, 0x0c},
321 {0x300a, 0xff},
322 {0x300b, 0xff},
323 {0x30eb, 0x05},
324 {0x30eb, 0x09},
325 {0x0114, 0x01},
326 {0x0128, 0x00},
327 {0x012a, 0x18},
328 {0x012b, 0x00},
329 {0x0162, 0x0d},
330 {0x0163, 0x78},
331 {0x0164, 0x03},
332 {0x0165, 0xe8},
333 {0x0166, 0x08},
334 {0x0167, 0xe7},
335 {0x0168, 0x02},
336 {0x0169, 0xf0},
337 {0x016a, 0x06},
338 {0x016b, 0xaf},
339 {0x016c, 0x02},
340 {0x016d, 0x80},
341 {0x016e, 0x01},
342 {0x016f, 0xe0},
343 {0x0170, 0x01},
344 {0x0171, 0x01},
345 {0x0174, 0x03},
346 {0x0175, 0x03},
347 {0x0301, 0x05},
348 {0x0303, 0x01},
349 {0x0304, 0x03},
350 {0x0305, 0x03},
351 {0x0306, 0x00},
352 {0x0307, 0x39},
353 {0x030b, 0x01},
354 {0x030c, 0x00},
355 {0x030d, 0x72},
356 {0x0624, 0x06},
357 {0x0625, 0x68},
358 {0x0626, 0x04},
359 {0x0627, 0xd0},
360 {0x455e, 0x00},
361 {0x471e, 0x4b},
362 {0x4767, 0x0f},
363 {0x4750, 0x14},
364 {0x4540, 0x00},
365 {0x47b4, 0x14},
366 {0x4713, 0x30},
367 {0x478b, 0x10},
368 {0x478f, 0x10},
369 {0x4793, 0x10},
370 {0x4797, 0x0e},
371 {0x479b, 0x0e},
372};
373
374static const struct imx219_reg raw8_framefmt_regs[] = {
375 {0x018c, 0x08},
376 {0x018d, 0x08},
377 {0x0309, 0x08},
378};
379
380static const struct imx219_reg raw10_framefmt_regs[] = {
381 {0x018c, 0x0a},
382 {0x018d, 0x0a},
383 {0x0309, 0x0a},
384};
385
386static const char * const imx219_test_pattern_menu[] = {
387 "Disabled",
388 "Color Bars",
389 "Solid Color",
390 "Grey Color Bars",
391 "PN9"
392};
393
394static const int imx219_test_pattern_val[] = {
395 IMX219_TEST_PATTERN_DISABLE,
396 IMX219_TEST_PATTERN_COLOR_BARS,
397 IMX219_TEST_PATTERN_SOLID_COLOR,
398 IMX219_TEST_PATTERN_GREY_COLOR,
399 IMX219_TEST_PATTERN_PN9,
400};
401
402/* regulator supplies */
403static const char * const imx219_supply_name[] = {
404 /* Supplies can be enabled in any order */
405 "VANA", /* Analog (2.8V) supply */
406 "VDIG", /* Digital Core (1.8V) supply */
407 "VDDL", /* IF (1.2V) supply */
408};
409
410#define IMX219_NUM_SUPPLIES ARRAY_SIZE(imx219_supply_name)
411
412/*
413 * The supported formats.
414 * This table MUST contain 4 entries per format, to cover the various flip
415 * combinations in the order
416 * - no flip
417 * - h flip
418 * - v flip
419 * - h&v flips
420 */
421static const u32 codes[] = {
422 MEDIA_BUS_FMT_SRGGB10_1X10,
423 MEDIA_BUS_FMT_SGRBG10_1X10,
424 MEDIA_BUS_FMT_SGBRG10_1X10,
425 MEDIA_BUS_FMT_SBGGR10_1X10,
426
427 MEDIA_BUS_FMT_SRGGB8_1X8,
428 MEDIA_BUS_FMT_SGRBG8_1X8,
429 MEDIA_BUS_FMT_SGBRG8_1X8,
430 MEDIA_BUS_FMT_SBGGR8_1X8,
431};
432
433/*
434 * Initialisation delay between XCLR low->high and the moment when the sensor
435 * can start capture (i.e. can leave software stanby) must be not less than:
436 * t4 + max(t5, t6 + <time to initialize the sensor register over I2C>)
437 * where
438 * t4 is fixed, and is max 200uS,
439 * t5 is fixed, and is 6000uS,
440 * t6 depends on the sensor external clock, and is max 32000 clock periods.
441 * As per sensor datasheet, the external clock must be from 6MHz to 27MHz.
442 * So for any acceptable external clock t6 is always within the range of
443 * 1185 to 5333 uS, and is always less than t5.
444 * For this reason this is always safe to wait (t4 + t5) = 6200 uS, then
445 * initialize the sensor over I2C, and then exit the software standby.
446 *
447 * This start-up time can be optimized a bit more, if we start the writes
448 * over I2C after (t4+t6), but before (t4+t5) expires. But then sensor
449 * initialization over I2C may complete before (t4+t5) expires, and we must
450 * ensure that capture is not started before (t4+t5).
451 *
452 * This delay doesn't account for the power supply startup time. If needed,
453 * this should be taken care of via the regulator framework. E.g. in the
454 * case of DT for regulator-fixed one should define the startup-delay-us
455 * property.
456 */
457#define IMX219_XCLR_MIN_DELAY_US 6200
458#define IMX219_XCLR_DELAY_RANGE_US 1000
459
460/* Mode configs */
461static const struct imx219_mode supported_modes[] = {
462 {
463 /* 8MPix 15fps mode */
464 .width = 3280,
465 .height = 2464,
466 .vts_def = IMX219_VTS_15FPS,
467 .reg_list = {
468 .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
469 .regs = mode_3280x2464_regs,
470 },
471 },
472 {
473 /* 1080P 30fps cropped */
474 .width = 1920,
475 .height = 1080,
476 .vts_def = IMX219_VTS_30FPS_1080P,
477 .reg_list = {
478 .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
479 .regs = mode_1920_1080_regs,
480 },
481 },
482 {
483 /* 2x2 binned 30fps mode */
484 .width = 1640,
485 .height = 1232,
486 .vts_def = IMX219_VTS_30FPS_BINNED,
487 .reg_list = {
488 .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
489 .regs = mode_1640_1232_regs,
490 },
491 },
492 {
493 /* 640x480 30fps mode */
494 .width = 640,
495 .height = 480,
496 .vts_def = IMX219_VTS_30FPS_640x480,
497 .reg_list = {
498 .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
499 .regs = mode_640_480_regs,
500 },
501 },
502};
503
504struct imx219 {
505 struct v4l2_subdev sd;
506 struct media_pad pad;
507
508 struct v4l2_mbus_framefmt fmt;
509
510 struct clk *xclk; /* system clock to IMX219 */
511 u32 xclk_freq;
512
513 struct gpio_desc *reset_gpio;
514 struct regulator_bulk_data supplies[IMX219_NUM_SUPPLIES];
515
516 struct v4l2_ctrl_handler ctrl_handler;
517 /* V4L2 Controls */
518 struct v4l2_ctrl *pixel_rate;
519 struct v4l2_ctrl *exposure;
520 struct v4l2_ctrl *vflip;
521 struct v4l2_ctrl *hflip;
522 struct v4l2_ctrl *vblank;
523 struct v4l2_ctrl *hblank;
524
525 /* Current mode */
526 const struct imx219_mode *mode;
527
528 /*
529 * Mutex for serialized access:
530 * Protect sensor module set pad format and start/stop streaming safely.
531 */
532 struct mutex mutex;
533
534 /* Streaming on/off */
535 bool streaming;
536};
537
538static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd)
539{
540 return container_of(_sd, struct imx219, sd);
541}
542
543/* Read registers up to 2 at a time */
544static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val)
545{
546 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
547 struct i2c_msg msgs[2];
548 u8 addr_buf[2] = { reg >> 8, reg & 0xff };
549 u8 data_buf[4] = { 0, };
550 int ret;
551
552 if (len > 4)
553 return -EINVAL;
554
555 /* Write register address */
556 msgs[0].addr = client->addr;
557 msgs[0].flags = 0;
558 msgs[0].len = ARRAY_SIZE(addr_buf);
559 msgs[0].buf = addr_buf;
560
561 /* Read data from register */
562 msgs[1].addr = client->addr;
563 msgs[1].flags = I2C_M_RD;
564 msgs[1].len = len;
565 msgs[1].buf = &data_buf[4 - len];
566
567 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
568 if (ret != ARRAY_SIZE(msgs))
569 return -EIO;
570
571 *val = get_unaligned_be32(data_buf);
572
573 return 0;
574}
575
576/* Write registers up to 2 at a time */
577static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val)
578{
579 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
580 u8 buf[6];
581
582 if (len > 4)
583 return -EINVAL;
584
585 put_unaligned_be16(reg, buf);
586 put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
587 if (i2c_master_send(client, buf, len + 2) != len + 2)
588 return -EIO;
589
590 return 0;
591}
592
593/* Write a list of registers */
594static int imx219_write_regs(struct imx219 *imx219,
595 const struct imx219_reg *regs, u32 len)
596{
597 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
598 unsigned int i;
599 int ret;
600
601 for (i = 0; i < len; i++) {
602 ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val);
603 if (ret) {
604 dev_err_ratelimited(&client->dev,
605 "Failed to write reg 0x%4.4x. error = %d\n",
606 regs[i].address, ret);
607
608 return ret;
609 }
610 }
611
612 return 0;
613}
614
615/* Get bayer order based on flip setting. */
616static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
617{
618 unsigned int i;
619
620 lockdep_assert_held(&imx219->mutex);
621
622 for (i = 0; i < ARRAY_SIZE(codes); i++)
623 if (codes[i] == code)
624 break;
625
626 if (i >= ARRAY_SIZE(codes))
627 i = 0;
628
629 i = (i & ~3) | (imx219->vflip->val ? 2 : 0) |
630 (imx219->hflip->val ? 1 : 0);
631
632 return codes[i];
633}
634
635static void imx219_set_default_format(struct imx219 *imx219)
636{
637 struct v4l2_mbus_framefmt *fmt;
638
639 fmt = &imx219->fmt;
640 fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
641 fmt->colorspace = V4L2_COLORSPACE_SRGB;
642 fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
643 fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
644 fmt->colorspace,
645 fmt->ycbcr_enc);
646 fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
647 fmt->width = supported_modes[0].width;
648 fmt->height = supported_modes[0].height;
649 fmt->field = V4L2_FIELD_NONE;
650}
651
652static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
653{
654 struct imx219 *imx219 = to_imx219(sd);
655 struct v4l2_mbus_framefmt *try_fmt =
656 v4l2_subdev_get_try_format(sd, fh->pad, 0);
657
658 mutex_lock(&imx219->mutex);
659
660 /* Initialize try_fmt */
661 try_fmt->width = supported_modes[0].width;
662 try_fmt->height = supported_modes[0].height;
663 try_fmt->code = imx219_get_format_code(imx219,
664 MEDIA_BUS_FMT_SRGGB10_1X10);
665 try_fmt->field = V4L2_FIELD_NONE;
666
667 mutex_unlock(&imx219->mutex);
668
669 return 0;
670}
671
672static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
673{
674 struct imx219 *imx219 =
675 container_of(ctrl->handler, struct imx219, ctrl_handler);
676 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
677 int ret;
678
679 if (ctrl->id == V4L2_CID_VBLANK) {
680 int exposure_max, exposure_def;
681
682 /* Update max exposure while meeting expected vblanking */
683 exposure_max = imx219->mode->height + ctrl->val - 4;
684 exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
685 exposure_max : IMX219_EXPOSURE_DEFAULT;
686 __v4l2_ctrl_modify_range(imx219->exposure,
687 imx219->exposure->minimum,
688 exposure_max, imx219->exposure->step,
689 exposure_def);
690 }
691
692 /*
693 * Applying V4L2 control value only happens
694 * when power is up for streaming
695 */
696 if (pm_runtime_get_if_in_use(&client->dev) == 0)
697 return 0;
698
699 switch (ctrl->id) {
700 case V4L2_CID_ANALOGUE_GAIN:
701 ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN,
702 IMX219_REG_VALUE_08BIT, ctrl->val);
703 break;
704 case V4L2_CID_EXPOSURE:
705 ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE,
706 IMX219_REG_VALUE_16BIT, ctrl->val);
707 break;
708 case V4L2_CID_DIGITAL_GAIN:
709 ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
710 IMX219_REG_VALUE_16BIT, ctrl->val);
711 break;
712 case V4L2_CID_TEST_PATTERN:
713 ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN,
714 IMX219_REG_VALUE_16BIT,
715 imx219_test_pattern_val[ctrl->val]);
716 break;
717 case V4L2_CID_HFLIP:
718 case V4L2_CID_VFLIP:
719 ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1,
720 imx219->hflip->val |
721 imx219->vflip->val << 1);
722 break;
723 case V4L2_CID_VBLANK:
724 ret = imx219_write_reg(imx219, IMX219_REG_VTS,
725 IMX219_REG_VALUE_16BIT,
726 imx219->mode->height + ctrl->val);
727 break;
728 case V4L2_CID_TEST_PATTERN_RED:
729 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
730 IMX219_REG_VALUE_16BIT, ctrl->val);
731 break;
732 case V4L2_CID_TEST_PATTERN_GREENR:
733 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR,
734 IMX219_REG_VALUE_16BIT, ctrl->val);
735 break;
736 case V4L2_CID_TEST_PATTERN_BLUE:
737 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE,
738 IMX219_REG_VALUE_16BIT, ctrl->val);
739 break;
740 case V4L2_CID_TEST_PATTERN_GREENB:
741 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB,
742 IMX219_REG_VALUE_16BIT, ctrl->val);
743 break;
744 default:
745 dev_info(&client->dev,
746 "ctrl(id:0x%x,val:0x%x) is not handled\n",
747 ctrl->id, ctrl->val);
748 ret = -EINVAL;
749 break;
750 }
751
752 pm_runtime_put(&client->dev);
753
754 return ret;
755}
756
757static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
758 .s_ctrl = imx219_set_ctrl,
759};
760
761static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
762 struct v4l2_subdev_pad_config *cfg,
763 struct v4l2_subdev_mbus_code_enum *code)
764{
765 struct imx219 *imx219 = to_imx219(sd);
766
767 if (code->index >= (ARRAY_SIZE(codes) / 4))
768 return -EINVAL;
769
770 code->code = imx219_get_format_code(imx219, codes[code->index * 4]);
771
772 return 0;
773}
774
775static int imx219_enum_frame_size(struct v4l2_subdev *sd,
776 struct v4l2_subdev_pad_config *cfg,
777 struct v4l2_subdev_frame_size_enum *fse)
778{
779 struct imx219 *imx219 = to_imx219(sd);
780
781 if (fse->index >= ARRAY_SIZE(supported_modes))
782 return -EINVAL;
783
784 if (fse->code != imx219_get_format_code(imx219, imx219->fmt.code))
785 return -EINVAL;
786
787 fse->min_width = supported_modes[fse->index].width;
788 fse->max_width = fse->min_width;
789 fse->min_height = supported_modes[fse->index].height;
790 fse->max_height = fse->min_height;
791
792 return 0;
793}
794
795static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
796{
797 fmt->colorspace = V4L2_COLORSPACE_SRGB;
798 fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
799 fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
800 fmt->colorspace,
801 fmt->ycbcr_enc);
802 fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
803}
804
805static void imx219_update_pad_format(struct imx219 *imx219,
806 const struct imx219_mode *mode,
807 struct v4l2_subdev_format *fmt)
808{
809 fmt->format.width = mode->width;
810 fmt->format.height = mode->height;
811 fmt->format.field = V4L2_FIELD_NONE;
812 imx219_reset_colorspace(&fmt->format);
813}
814
815static int __imx219_get_pad_format(struct imx219 *imx219,
816 struct v4l2_subdev_pad_config *cfg,
817 struct v4l2_subdev_format *fmt)
818{
819 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
820 struct v4l2_mbus_framefmt *try_fmt =
821 v4l2_subdev_get_try_format(&imx219->sd, cfg, fmt->pad);
822 /* update the code which could change due to vflip or hflip: */
823 try_fmt->code = imx219_get_format_code(imx219, try_fmt->code);
824 fmt->format = *try_fmt;
825 } else {
826 imx219_update_pad_format(imx219, imx219->mode, fmt);
827 fmt->format.code = imx219_get_format_code(imx219,
828 imx219->fmt.code);
829 }
830
831 return 0;
832}
833
834static int imx219_get_pad_format(struct v4l2_subdev *sd,
835 struct v4l2_subdev_pad_config *cfg,
836 struct v4l2_subdev_format *fmt)
837{
838 struct imx219 *imx219 = to_imx219(sd);
839 int ret;
840
841 mutex_lock(&imx219->mutex);
842 ret = __imx219_get_pad_format(imx219, cfg, fmt);
843 mutex_unlock(&imx219->mutex);
844
845 return ret;
846}
847
848static int imx219_set_pad_format(struct v4l2_subdev *sd,
849 struct v4l2_subdev_pad_config *cfg,
850 struct v4l2_subdev_format *fmt)
851{
852 struct imx219 *imx219 = to_imx219(sd);
853 const struct imx219_mode *mode;
854 struct v4l2_mbus_framefmt *framefmt;
855 int exposure_max, exposure_def, hblank;
856 unsigned int i;
857
858 mutex_lock(&imx219->mutex);
859
860 for (i = 0; i < ARRAY_SIZE(codes); i++)
861 if (codes[i] == fmt->format.code)
862 break;
863 if (i >= ARRAY_SIZE(codes))
864 i = 0;
865
866 /* Bayer order varies with flips */
867 fmt->format.code = imx219_get_format_code(imx219, codes[i]);
868
869 mode = v4l2_find_nearest_size(supported_modes,
870 ARRAY_SIZE(supported_modes),
871 width, height,
872 fmt->format.width, fmt->format.height);
873 imx219_update_pad_format(imx219, mode, fmt);
874 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
875 framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
876 *framefmt = fmt->format;
877 } else if (imx219->mode != mode ||
878 imx219->fmt.code != fmt->format.code) {
879 imx219->fmt = fmt->format;
880 imx219->mode = mode;
881 /* Update limits and set FPS to default */
882 __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
883 IMX219_VTS_MAX - mode->height, 1,
884 mode->vts_def - mode->height);
885 __v4l2_ctrl_s_ctrl(imx219->vblank,
886 mode->vts_def - mode->height);
887 /* Update max exposure while meeting expected vblanking */
888 exposure_max = mode->vts_def - 4;
889 exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
890 exposure_max : IMX219_EXPOSURE_DEFAULT;
891 __v4l2_ctrl_modify_range(imx219->exposure,
892 imx219->exposure->minimum,
893 exposure_max, imx219->exposure->step,
894 exposure_def);
895 /*
896 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
897 * depends on mode->width only, and is not changeble in any
898 * way other than changing the mode.
899 */
900 hblank = IMX219_PPL_DEFAULT - mode->width;
901 __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
902 hblank);
903 }
904
905 mutex_unlock(&imx219->mutex);
906
907 return 0;
908}
909
910static int imx219_set_framefmt(struct imx219 *imx219)
911{
912 switch (imx219->fmt.code) {
913 case MEDIA_BUS_FMT_SRGGB8_1X8:
914 case MEDIA_BUS_FMT_SGRBG8_1X8:
915 case MEDIA_BUS_FMT_SGBRG8_1X8:
916 case MEDIA_BUS_FMT_SBGGR8_1X8:
917 return imx219_write_regs(imx219, raw8_framefmt_regs,
918 ARRAY_SIZE(raw8_framefmt_regs));
919
920 case MEDIA_BUS_FMT_SRGGB10_1X10:
921 case MEDIA_BUS_FMT_SGRBG10_1X10:
922 case MEDIA_BUS_FMT_SGBRG10_1X10:
923 case MEDIA_BUS_FMT_SBGGR10_1X10:
924 return imx219_write_regs(imx219, raw10_framefmt_regs,
925 ARRAY_SIZE(raw10_framefmt_regs));
926 }
927
928 return -EINVAL;
929}
930
931static int imx219_start_streaming(struct imx219 *imx219)
932{
933 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
934 const struct imx219_reg_list *reg_list;
935 int ret;
936
937 /* Apply default values of current mode */
938 reg_list = &imx219->mode->reg_list;
939 ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
940 if (ret) {
941 dev_err(&client->dev, "%s failed to set mode\n", __func__);
942 return ret;
943 }
944
945 ret = imx219_set_framefmt(imx219);
946 if (ret) {
947 dev_err(&client->dev, "%s failed to set frame format: %d\n",
948 __func__, ret);
949 return ret;
950 }
951
952 /* Apply customized values from user */
953 ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
954 if (ret)
955 return ret;
956
957 /* set stream on register */
958 return imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
959 IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
960}
961
962static void imx219_stop_streaming(struct imx219 *imx219)
963{
964 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
965 int ret;
966
967 /* set stream off register */
968 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
969 IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
970 if (ret)
971 dev_err(&client->dev, "%s failed to set stream\n", __func__);
972}
973
974static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
975{
976 struct imx219 *imx219 = to_imx219(sd);
977 struct i2c_client *client = v4l2_get_subdevdata(sd);
978 int ret = 0;
979
980 mutex_lock(&imx219->mutex);
981 if (imx219->streaming == enable) {
982 mutex_unlock(&imx219->mutex);
983 return 0;
984 }
985
986 if (enable) {
987 ret = pm_runtime_get_sync(&client->dev);
988 if (ret < 0) {
989 pm_runtime_put_noidle(&client->dev);
990 goto err_unlock;
991 }
992
993 /*
994 * Apply default & customized values
995 * and then start streaming.
996 */
997 ret = imx219_start_streaming(imx219);
998 if (ret)
999 goto err_rpm_put;
1000 } else {
1001 imx219_stop_streaming(imx219);
1002 pm_runtime_put(&client->dev);
1003 }
1004
1005 imx219->streaming = enable;
1006
1007 /* vflip and hflip cannot change during streaming */
1008 __v4l2_ctrl_grab(imx219->vflip, enable);
1009 __v4l2_ctrl_grab(imx219->hflip, enable);
1010
1011 mutex_unlock(&imx219->mutex);
1012
1013 return ret;
1014
1015err_rpm_put:
1016 pm_runtime_put(&client->dev);
1017err_unlock:
1018 mutex_unlock(&imx219->mutex);
1019
1020 return ret;
1021}
1022
1023/* Power/clock management functions */
1024static int imx219_power_on(struct device *dev)
1025{
1026 struct i2c_client *client = to_i2c_client(dev);
1027 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1028 struct imx219 *imx219 = to_imx219(sd);
1029 int ret;
1030
1031 ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
1032 imx219->supplies);
1033 if (ret) {
1034 dev_err(&client->dev, "%s: failed to enable regulators\n",
1035 __func__);
1036 return ret;
1037 }
1038
1039 ret = clk_prepare_enable(imx219->xclk);
1040 if (ret) {
1041 dev_err(&client->dev, "%s: failed to enable clock\n",
1042 __func__);
1043 goto reg_off;
1044 }
1045
1046 gpiod_set_value_cansleep(imx219->reset_gpio, 1);
1047 usleep_range(IMX219_XCLR_MIN_DELAY_US,
1048 IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
1049
1050 return 0;
1051
1052reg_off:
1053 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
1054
1055 return ret;
1056}
1057
1058static int imx219_power_off(struct device *dev)
1059{
1060 struct i2c_client *client = to_i2c_client(dev);
1061 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1062 struct imx219 *imx219 = to_imx219(sd);
1063
1064 gpiod_set_value_cansleep(imx219->reset_gpio, 0);
1065 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
1066 clk_disable_unprepare(imx219->xclk);
1067
1068 return 0;
1069}
1070
1071static int __maybe_unused imx219_suspend(struct device *dev)
1072{
1073 struct i2c_client *client = to_i2c_client(dev);
1074 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1075 struct imx219 *imx219 = to_imx219(sd);
1076
1077 if (imx219->streaming)
1078 imx219_stop_streaming(imx219);
1079
1080 return 0;
1081}
1082
1083static int __maybe_unused imx219_resume(struct device *dev)
1084{
1085 struct i2c_client *client = to_i2c_client(dev);
1086 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1087 struct imx219 *imx219 = to_imx219(sd);
1088 int ret;
1089
1090 if (imx219->streaming) {
1091 ret = imx219_start_streaming(imx219);
1092 if (ret)
1093 goto error;
1094 }
1095
1096 return 0;
1097
1098error:
1099 imx219_stop_streaming(imx219);
1100 imx219->streaming = 0;
1101
1102 return ret;
1103}
1104
1105static int imx219_get_regulators(struct imx219 *imx219)
1106{
1107 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
1108 unsigned int i;
1109
1110 for (i = 0; i < IMX219_NUM_SUPPLIES; i++)
1111 imx219->supplies[i].supply = imx219_supply_name[i];
1112
1113 return devm_regulator_bulk_get(&client->dev,
1114 IMX219_NUM_SUPPLIES,
1115 imx219->supplies);
1116}
1117
1118/* Verify chip ID */
1119static int imx219_identify_module(struct imx219 *imx219)
1120{
1121 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
1122 int ret;
1123 u32 val;
1124
1125 ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID,
1126 IMX219_REG_VALUE_16BIT, &val);
1127 if (ret) {
1128 dev_err(&client->dev, "failed to read chip id %x\n",
1129 IMX219_CHIP_ID);
1130 return ret;
1131 }
1132
1133 if (val != IMX219_CHIP_ID) {
1134 dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
1135 IMX219_CHIP_ID, val);
1136 return -EIO;
1137 }
1138
1139 return 0;
1140}
1141
1142static const struct v4l2_subdev_core_ops imx219_core_ops = {
1143 .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1144 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1145};
1146
1147static const struct v4l2_subdev_video_ops imx219_video_ops = {
1148 .s_stream = imx219_set_stream,
1149};
1150
1151static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
1152 .enum_mbus_code = imx219_enum_mbus_code,
1153 .get_fmt = imx219_get_pad_format,
1154 .set_fmt = imx219_set_pad_format,
1155 .enum_frame_size = imx219_enum_frame_size,
1156};
1157
1158static const struct v4l2_subdev_ops imx219_subdev_ops = {
1159 .core = &imx219_core_ops,
1160 .video = &imx219_video_ops,
1161 .pad = &imx219_pad_ops,
1162};
1163
1164static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
1165 .open = imx219_open,
1166};
1167
1168/* Initialize control handlers */
1169static int imx219_init_controls(struct imx219 *imx219)
1170{
1171 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
1172 struct v4l2_ctrl_handler *ctrl_hdlr;
1173 unsigned int height = imx219->mode->height;
1174 int exposure_max, exposure_def, hblank;
1175 int i, ret;
1176
1177 ctrl_hdlr = &imx219->ctrl_handler;
1178 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
1179 if (ret)
1180 return ret;
1181
1182 mutex_init(&imx219->mutex);
1183 ctrl_hdlr->lock = &imx219->mutex;
1184
1185 /* By default, PIXEL_RATE is read only */
1186 imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1187 V4L2_CID_PIXEL_RATE,
1188 IMX219_PIXEL_RATE,
1189 IMX219_PIXEL_RATE, 1,
1190 IMX219_PIXEL_RATE);
1191
1192 /* Initial vblank/hblank/exposure parameters based on current mode */
1193 imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1194 V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
1195 IMX219_VTS_MAX - height, 1,
1196 imx219->mode->vts_def - height);
1197 hblank = IMX219_PPL_DEFAULT - imx219->mode->width;
1198 imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1199 V4L2_CID_HBLANK, hblank, hblank,
1200 1, hblank);
1201 if (imx219->hblank)
1202 imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1203 exposure_max = imx219->mode->vts_def - 4;
1204 exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
1205 exposure_max : IMX219_EXPOSURE_DEFAULT;
1206 imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1207 V4L2_CID_EXPOSURE,
1208 IMX219_EXPOSURE_MIN, exposure_max,
1209 IMX219_EXPOSURE_STEP,
1210 exposure_def);
1211
1212 v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1213 IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX,
1214 IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT);
1215
1216 v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1217 IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX,
1218 IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT);
1219
1220 imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1221 V4L2_CID_HFLIP, 0, 1, 1, 0);
1222 if (imx219->hflip)
1223 imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1224
1225 imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1226 V4L2_CID_VFLIP, 0, 1, 1, 0);
1227 if (imx219->vflip)
1228 imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1229
1230 v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops,
1231 V4L2_CID_TEST_PATTERN,
1232 ARRAY_SIZE(imx219_test_pattern_menu) - 1,
1233 0, 0, imx219_test_pattern_menu);
1234 for (i = 0; i < 4; i++) {
1235 /*
1236 * The assumption is that
1237 * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
1238 * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
1239 * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
1240 */
1241 v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
1242 V4L2_CID_TEST_PATTERN_RED + i,
1243 IMX219_TESTP_COLOUR_MIN,
1244 IMX219_TESTP_COLOUR_MAX,
1245 IMX219_TESTP_COLOUR_STEP,
1246 IMX219_TESTP_COLOUR_MAX);
1247 /* The "Solid color" pattern is white by default */
1248 }
1249
1250 if (ctrl_hdlr->error) {
1251 ret = ctrl_hdlr->error;
1252 dev_err(&client->dev, "%s control init failed (%d)\n",
1253 __func__, ret);
1254 goto error;
1255 }
1256
1257 imx219->sd.ctrl_handler = ctrl_hdlr;
1258
1259 return 0;
1260
1261error:
1262 v4l2_ctrl_handler_free(ctrl_hdlr);
1263 mutex_destroy(&imx219->mutex);
1264
1265 return ret;
1266}
1267
1268static void imx219_free_controls(struct imx219 *imx219)
1269{
1270 v4l2_ctrl_handler_free(imx219->sd.ctrl_handler);
1271 mutex_destroy(&imx219->mutex);
1272}
1273
1274static int imx219_check_hwcfg(struct device *dev)
1275{
1276 struct fwnode_handle *endpoint;
1277 struct v4l2_fwnode_endpoint ep_cfg = {
1278 .bus_type = V4L2_MBUS_CSI2_DPHY
1279 };
1280 int ret = -EINVAL;
1281
1282 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
1283 if (!endpoint) {
1284 dev_err(dev, "endpoint node not found\n");
1285 return -EINVAL;
1286 }
1287
1288 if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
1289 dev_err(dev, "could not parse endpoint\n");
1290 goto error_out;
1291 }
1292
1293 /* Check the number of MIPI CSI2 data lanes */
1294 if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
1295 dev_err(dev, "only 2 data lanes are currently supported\n");
1296 goto error_out;
1297 }
1298
1299 /* Check the link frequency set in device tree */
1300 if (!ep_cfg.nr_of_link_frequencies) {
1301 dev_err(dev, "link-frequency property not found in DT\n");
1302 goto error_out;
1303 }
1304
1305 if (ep_cfg.nr_of_link_frequencies != 1 ||
1306 ep_cfg.link_frequencies[0] != IMX219_DEFAULT_LINK_FREQ) {
1307 dev_err(dev, "Link frequency not supported: %lld\n",
1308 ep_cfg.link_frequencies[0]);
1309 goto error_out;
1310 }
1311
1312 ret = 0;
1313
1314error_out:
1315 v4l2_fwnode_endpoint_free(&ep_cfg);
1316 fwnode_handle_put(endpoint);
1317
1318 return ret;
1319}
1320
1321static int imx219_probe(struct i2c_client *client)
1322{
1323 struct device *dev = &client->dev;
1324 struct imx219 *imx219;
1325 int ret;
1326
1327 imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL);
1328 if (!imx219)
1329 return -ENOMEM;
1330
1331 v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
1332
1333 /* Check the hardware configuration in device tree */
1334 if (imx219_check_hwcfg(dev))
1335 return -EINVAL;
1336
1337 /* Get system clock (xclk) */
1338 imx219->xclk = devm_clk_get(dev, NULL);
1339 if (IS_ERR(imx219->xclk)) {
1340 dev_err(dev, "failed to get xclk\n");
1341 return PTR_ERR(imx219->xclk);
1342 }
1343
1344 imx219->xclk_freq = clk_get_rate(imx219->xclk);
1345 if (imx219->xclk_freq != IMX219_XCLK_FREQ) {
1346 dev_err(dev, "xclk frequency not supported: %d Hz\n",
1347 imx219->xclk_freq);
1348 return -EINVAL;
1349 }
1350
1351 ret = imx219_get_regulators(imx219);
1352 if (ret) {
1353 dev_err(dev, "failed to get regulators\n");
1354 return ret;
1355 }
1356
1357 /* Request optional enable pin */
1358 imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1359 GPIOD_OUT_HIGH);
1360
1361 /*
1362 * The sensor must be powered for imx219_identify_module()
1363 * to be able to read the CHIP_ID register
1364 */
1365 ret = imx219_power_on(dev);
1366 if (ret)
1367 return ret;
1368
1369 ret = imx219_identify_module(imx219);
1370 if (ret)
1371 goto error_power_off;
1372
1373 /* Set default mode to max resolution */
1374 imx219->mode = &supported_modes[0];
1375
1376 /* sensor doesn't enter LP-11 state upon power up until and unless
1377 * streaming is started, so upon power up switch the modes to:
1378 * streaming -> standby
1379 */
1380 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
1381 IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
1382 if (ret < 0)
1383 goto error_power_off;
1384 usleep_range(100, 110);
1385
1386 /* put sensor back to standby mode */
1387 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
1388 IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
1389 if (ret < 0)
1390 goto error_power_off;
1391 usleep_range(100, 110);
1392
1393 ret = imx219_init_controls(imx219);
1394 if (ret)
1395 goto error_power_off;
1396
1397 /* Initialize subdev */
1398 imx219->sd.internal_ops = &imx219_internal_ops;
1399 imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1400 imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1401
1402 /* Initialize source pad */
1403 imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
1404
1405 /* Initialize default format */
1406 imx219_set_default_format(imx219);
1407
1408 ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
1409 if (ret) {
1410 dev_err(dev, "failed to init entity pads: %d\n", ret);
1411 goto error_handler_free;
1412 }
1413
1414 ret = v4l2_async_register_subdev_sensor_common(&imx219->sd);
1415 if (ret < 0) {
1416 dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
1417 goto error_media_entity;
1418 }
1419
1420 /* Enable runtime PM and turn off the device */
1421 pm_runtime_set_active(dev);
1422 pm_runtime_enable(dev);
1423 pm_runtime_idle(dev);
1424
1425 return 0;
1426
1427error_media_entity:
1428 media_entity_cleanup(&imx219->sd.entity);
1429
1430error_handler_free:
1431 imx219_free_controls(imx219);
1432
1433error_power_off:
1434 imx219_power_off(dev);
1435
1436 return ret;
1437}
1438
1439static int imx219_remove(struct i2c_client *client)
1440{
1441 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1442 struct imx219 *imx219 = to_imx219(sd);
1443
1444 v4l2_async_unregister_subdev(sd);
1445 media_entity_cleanup(&sd->entity);
1446 imx219_free_controls(imx219);
1447
1448 pm_runtime_disable(&client->dev);
1449 if (!pm_runtime_status_suspended(&client->dev))
1450 imx219_power_off(&client->dev);
1451 pm_runtime_set_suspended(&client->dev);
1452
1453 return 0;
1454}
1455
1456static const struct of_device_id imx219_dt_ids[] = {
1457 { .compatible = "sony,imx219" },
1458 { /* sentinel */ }
1459};
1460MODULE_DEVICE_TABLE(of, imx219_dt_ids);
1461
1462static const struct dev_pm_ops imx219_pm_ops = {
1463 SET_SYSTEM_SLEEP_PM_OPS(imx219_suspend, imx219_resume)
1464 SET_RUNTIME_PM_OPS(imx219_power_off, imx219_power_on, NULL)
1465};
1466
1467static struct i2c_driver imx219_i2c_driver = {
1468 .driver = {
1469 .name = "imx219",
1470 .of_match_table = imx219_dt_ids,
1471 .pm = &imx219_pm_ops,
1472 },
1473 .probe_new = imx219_probe,
1474 .remove = imx219_remove,
1475};
1476
1477module_i2c_driver(imx219_i2c_driver);
1478
1479MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com");
1480MODULE_DESCRIPTION("Sony IMX219 sensor driver");
1481MODULE_LICENSE("GPL v2");
drivers/media/i2c/ov5675.c+73−9
@@ -63,6 +63,10 @@ · 62 unmodified lines
63#define OV5675_TEST_PATTERN_ENABLE BIT(7)63#define OV5675_TEST_PATTERN_ENABLE BIT(7)
64#define OV5675_TEST_PATTERN_BAR_SHIFT 264#define OV5675_TEST_PATTERN_BAR_SHIFT 2
65 65
66/* Flip Mirror Controls from sensor */
67#define OV5675_REG_FORMAT1 0x3820
68#define OV5675_REG_FORMAT2 0x373d
69
66#define to_ov5675(_sd) container_of(_sd, struct ov5675, sd)70#define to_ov5675(_sd) container_of(_sd, struct ov5675, sd)
67 71
68enum {72enum {
@@ -314,21 +318,21 @@ static const struct ov5675_reg mode_1296x972_regs[] = { · 245 unmodified lines
314 {0x3800, 0x00},318 {0x3800, 0x00},
315 {0x3801, 0x00},319 {0x3801, 0x00},
316 {0x3802, 0x00},320 {0x3802, 0x00},
317 {0x3803, 0xf4},321 {0x3803, 0x00},
318 {0x3804, 0x0a},322 {0x3804, 0x0a},
319 {0x3805, 0x3f},323 {0x3805, 0x3f},
320 {0x3806, 0x06},324 {0x3806, 0x07},
321 {0x3807, 0xb3},325 {0x3807, 0xb7},
322 {0x3808, 0x05},326 {0x3808, 0x05},
323 {0x3809, 0x00},327 {0x3809, 0x10},
324 {0x380a, 0x02},328 {0x380a, 0x03},
325 {0x380b, 0xd0},329 {0x380b, 0xcc},
326 {0x380c, 0x02},330 {0x380c, 0x02},
327 {0x380d, 0xee},331 {0x380d, 0xee},
328 {0x380e, 0x07},332 {0x380e, 0x07},
329 {0x380f, 0xe4},333 {0x380f, 0xd0},
330 {0x3811, 0x10},334 {0x3811, 0x08},
331 {0x3813, 0x09},335 {0x3813, 0x0d},
332 {0x3814, 0x03},336 {0x3814, 0x03},
333 {0x3815, 0x01},337 {0x3815, 0x01},
334 {0x3816, 0x03},338 {0x3816, 0x03},
@@ -604,6 +608,53 @@ static int ov5675_test_pattern(struct ov5675 *ov5675, u32 pattern) · 269 unmodified lines
604 OV5675_REG_VALUE_08BIT, pattern);608 OV5675_REG_VALUE_08BIT, pattern);
605}609}
606 610
611/*
612 * OV5675 supports keeping the pixel order by mirror and flip function
613 * The Bayer order isn't affected by the flip controls
614 */
615static int ov5675_set_ctrl_hflip(struct ov5675 *ov5675, u32 ctrl_val)
616{
617 int ret;
618 u32 val;
619
620 ret = ov5675_read_reg(ov5675, OV5675_REG_FORMAT1,
621 OV5675_REG_VALUE_08BIT, &val);
622 if (ret)
623 return ret;
624
625 return ov5675_write_reg(ov5675, OV5675_REG_FORMAT1,
626 OV5675_REG_VALUE_08BIT,
627 ctrl_val ? val & ~BIT(3) : val);
628}
629
630static int ov5675_set_ctrl_vflip(struct ov5675 *ov5675, u8 ctrl_val)
631{
632 int ret;
633 u32 val;
634
635 ret = ov5675_read_reg(ov5675, OV5675_REG_FORMAT1,
636 OV5675_REG_VALUE_08BIT, &val);
637 if (ret)
638 return ret;
639
640 ret = ov5675_write_reg(ov5675, OV5675_REG_FORMAT1,
641 OV5675_REG_VALUE_08BIT,
642 ctrl_val ? val | BIT(4) | BIT(5) : val);
643
644 if (ret)
645 return ret;
646
647 ret = ov5675_read_reg(ov5675, OV5675_REG_FORMAT2,
648 OV5675_REG_VALUE_08BIT, &val);
649
650 if (ret)
651 return ret;
652
653 return ov5675_write_reg(ov5675, OV5675_REG_FORMAT2,
654 OV5675_REG_VALUE_08BIT,
655 ctrl_val ? val | BIT(1) : val);
656}
657
607static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)658static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
608{659{
609 struct ov5675 *ov5675 = container_of(ctrl->handler,660 struct ov5675 *ov5675 = container_of(ctrl->handler,
@@ -654,6 +705,14 @@ static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl) · 44 unmodified lines
654 ret = ov5675_test_pattern(ov5675, ctrl->val);705 ret = ov5675_test_pattern(ov5675, ctrl->val);
655 break;706 break;
656 707
708 case V4L2_CID_HFLIP:
709 ov5675_set_ctrl_hflip(ov5675, ctrl->val);
710 break;
711
712 case V4L2_CID_VFLIP:
713 ov5675_set_ctrl_vflip(ov5675, ctrl->val);
714 break;
715
657 default:716 default:
658 ret = -EINVAL;717 ret = -EINVAL;
659 break;718 break;
@@ -722,6 +781,11 @@ static int ov5675_init_controls(struct ov5675 *ov5675) · 62 unmodified lines
722 V4L2_CID_TEST_PATTERN,781 V4L2_CID_TEST_PATTERN,
723 ARRAY_SIZE(ov5675_test_pattern_menu) - 1,782 ARRAY_SIZE(ov5675_test_pattern_menu) - 1,
724 0, 0, ov5675_test_pattern_menu);783 0, 0, ov5675_test_pattern_menu);
784 v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
785 V4L2_CID_HFLIP, 0, 1, 1, 0);
786 v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
787 V4L2_CID_VFLIP, 0, 1, 1, 0);
788
725 if (ctrl_hdlr->error)789 if (ctrl_hdlr->error)
726 return ctrl_hdlr->error;790 return ctrl_hdlr->error;
727 791
drivers/media/i2c/ov5695.c+31−18
@@ -971,16 +971,9 @@ unlock_and_return: · 970 unmodified lines
971 return ret;971 return ret;
972}972}
973 973
974/* Calculate the delay in us by clock rate and clock cycles */
975static inline u32 ov5695_cal_delay(u32 cycles)
976{
977 return DIV_ROUND_UP(cycles, OV5695_XVCLK_FREQ / 1000 / 1000);
978}
979
980static int __ov5695_power_on(struct ov5695 *ov5695)974static int __ov5695_power_on(struct ov5695 *ov5695)
981{975{
982 int ret;976 int i, ret;
983 u32 delay_us;
984 struct device *dev = &ov5695->client->dev;977 struct device *dev = &ov5695->client->dev;
985 978
986 ret = clk_prepare_enable(ov5695->xvclk);979 ret = clk_prepare_enable(ov5695->xvclk);
@@ -991,21 +984,28 @@ static int __ov5695_power_on(struct ov5695 *ov5695) · 4 unmodified lines
991 984
992 gpiod_set_value_cansleep(ov5695->reset_gpio, 1);985 gpiod_set_value_cansleep(ov5695->reset_gpio, 1);
993 986
994 ret = regulator_bulk_enable(OV5695_NUM_SUPPLIES, ov5695->supplies);987 /*
995 if (ret < 0) {988 * The hardware requires the regulators to be powered on in order,
996 dev_err(dev, "Failed to enable regulators\n");989 * so enable them one by one.
997 goto disable_clk;990 */
991 for (i = 0; i < OV5695_NUM_SUPPLIES; i++) {
992 ret = regulator_enable(ov5695->supplies[i].consumer);
993 if (ret) {
994 dev_err(dev, "Failed to enable %s: %d\n",
995 ov5695->supplies[i].supply, ret);
996 goto disable_reg_clk;
997 }
998 }998 }
999 999
1000 gpiod_set_value_cansleep(ov5695->reset_gpio, 0);1000 gpiod_set_value_cansleep(ov5695->reset_gpio, 0);
1001 1001
1002 /* 8192 cycles prior to first SCCB transaction */1002 usleep_range(1000, 1200);
1003 delay_us = ov5695_cal_delay(8192);
1004 usleep_range(delay_us, delay_us * 2);
1005 1003
1006 return 0;1004 return 0;
1007 1005
1008disable_clk:1006disable_reg_clk:
1007 for (--i; i >= 0; i--)
1008 regulator_disable(ov5695->supplies[i].consumer);
1009 clk_disable_unprepare(ov5695->xvclk);1009 clk_disable_unprepare(ov5695->xvclk);
1010 1010
1011 return ret;1011 return ret;
@@ -1013,9 +1013,22 @@ disable_clk: · 1 unmodified line
1013 1013
1014static void __ov5695_power_off(struct ov5695 *ov5695)1014static void __ov5695_power_off(struct ov5695 *ov5695)
1015{1015{
1016 struct device *dev = &ov5695->client->dev;
1017 int i, ret;
1018
1016 clk_disable_unprepare(ov5695->xvclk);1019 clk_disable_unprepare(ov5695->xvclk);
1017 gpiod_set_value_cansleep(ov5695->reset_gpio, 1);1020 gpiod_set_value_cansleep(ov5695->reset_gpio, 1);
1018 regulator_bulk_disable(OV5695_NUM_SUPPLIES, ov5695->supplies);1021
1022 /*
1023 * The hardware requires the regulators to be powered off in order,
1024 * so disable them one by one.
1025 */
1026 for (i = OV5695_NUM_SUPPLIES - 1; i >= 0; i--) {
1027 ret = regulator_disable(ov5695->supplies[i].consumer);
1028 if (ret)
1029 dev_err(dev, "Failed to disable %s: %d\n",
1030 ov5695->supplies[i].supply, ret);
1031 }
1019}1032}
1020 1033
1021static int __maybe_unused ov5695_runtime_resume(struct device *dev)1034static int __maybe_unused ov5695_runtime_resume(struct device *dev)
@@ -1285,7 +1298,7 @@ static int ov5695_probe(struct i2c_client *client, · 263 unmodified lines
1285 if (clk_get_rate(ov5695->xvclk) != OV5695_XVCLK_FREQ)1298 if (clk_get_rate(ov5695->xvclk) != OV5695_XVCLK_FREQ)
1286 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");1299 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
1287 1300
1288 ov5695->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);1301 ov5695->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
1289 if (IS_ERR(ov5695->reset_gpio)) {1302 if (IS_ERR(ov5695->reset_gpio)) {
1290 dev_err(dev, "Failed to get reset-gpios\n");1303 dev_err(dev, "Failed to get reset-gpios\n");
1291 return -EINVAL;1304 return -EINVAL;
drivers/media/i2c/s5c73m3/s5c73m3-ctrls.c+1−1
@@ -547,7 +547,7 @@ int s5c73m3_init_controls(struct s5c73m3 *state) · 546 unmodified lines
547 V4L2_CTRL_FLAG_UPDATE;547 V4L2_CTRL_FLAG_UPDATE;
548 v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso, 0, false);548 v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso, 0, false);
549 ctrls->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE;549 ctrls->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE;
550 v4l2_ctrl_cluster(6, &ctrls->focus_auto);550 v4l2_ctrl_cluster(5, &ctrls->focus_auto);
551 551
552 state->sensor_sd.ctrl_handler = hdl;552 state->sensor_sd.ctrl_handler = hdl;
553 553
drivers/media/i2c/smiapp/smiapp-core.c+129−130
@@ -57,6 +57,45 @@ static const struct smiapp_module_ident smiapp_module_idents[] = { · 56 unmodified lines
57 *57 *
58 */58 */
59 59
60static u32 smiapp_get_limit(struct smiapp_sensor *sensor,
61 unsigned int limit)
62{
63 if (WARN_ON(limit >= SMIAPP_LIMIT_LAST))
64 return 1;
65
66 return sensor->limits[limit];
67}
68
69#define SMIA_LIM(sensor, limit) \
70 smiapp_get_limit(sensor, SMIAPP_LIMIT_##limit)
71
72static int smiapp_read_all_smia_limits(struct smiapp_sensor *sensor)
73{
74 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
75 unsigned int i;
76 int rval;
77
78 for (i = 0; i < SMIAPP_LIMIT_LAST; i++) {
79 u32 val;
80
81 rval = smiapp_read(
82 sensor, smiapp_reg_limits[i].addr, &val);
83 if (rval)
84 return rval;
85
86 sensor->limits[i] = val;
87
88 dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
89 smiapp_reg_limits[i].addr,
90 smiapp_reg_limits[i].what, val, val);
91 }
92
93 if (SMIA_LIM(sensor, SCALER_N_MIN) == 0)
94 smiapp_replace_limit(sensor, SMIAPP_LIMIT_SCALER_N_MIN, 16);
95
96 return 0;
97}
98
60static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor)99static int smiapp_read_frame_fmt(struct smiapp_sensor *sensor)
61{100{
62 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);101 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
@@ -240,35 +279,35 @@ static int smiapp_pll_try(struct smiapp_sensor *sensor, · 177 unmodified lines
240{279{
241 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);280 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
242 struct smiapp_pll_limits lim = {281 struct smiapp_pll_limits lim = {
243 .min_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_PRE_PLL_CLK_DIV],282 .min_pre_pll_clk_div = SMIA_LIM(sensor, MIN_PRE_PLL_CLK_DIV),
244 .max_pre_pll_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_PRE_PLL_CLK_DIV],283 .max_pre_pll_clk_div = SMIA_LIM(sensor, MAX_PRE_PLL_CLK_DIV),
245 .min_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_IP_FREQ_HZ],284 .min_pll_ip_freq_hz = SMIA_LIM(sensor, MIN_PLL_IP_FREQ_HZ),
246 .max_pll_ip_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_IP_FREQ_HZ],285 .max_pll_ip_freq_hz = SMIA_LIM(sensor, MAX_PLL_IP_FREQ_HZ),
247 .min_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MIN_PLL_MULTIPLIER],286 .min_pll_multiplier = SMIA_LIM(sensor, MIN_PLL_MULTIPLIER),
248 .max_pll_multiplier = sensor->limits[SMIAPP_LIMIT_MAX_PLL_MULTIPLIER],287 .max_pll_multiplier = SMIA_LIM(sensor, MAX_PLL_MULTIPLIER),
249 .min_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ],288 .min_pll_op_freq_hz = SMIA_LIM(sensor, MIN_PLL_OP_FREQ_HZ),
250 .max_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ],289 .max_pll_op_freq_hz = SMIA_LIM(sensor, MAX_PLL_OP_FREQ_HZ),
251 290
252 .op.min_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV],291 .op.min_sys_clk_div = SMIA_LIM(sensor, MIN_OP_SYS_CLK_DIV),
253 .op.max_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV],292 .op.max_sys_clk_div = SMIA_LIM(sensor, MAX_OP_SYS_CLK_DIV),
254 .op.min_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV],293 .op.min_pix_clk_div = SMIA_LIM(sensor, MIN_OP_PIX_CLK_DIV),
255 .op.max_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV],294 .op.max_pix_clk_div = SMIA_LIM(sensor, MAX_OP_PIX_CLK_DIV),
256 .op.min_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ],295 .op.min_sys_clk_freq_hz = SMIA_LIM(sensor, MIN_OP_SYS_CLK_FREQ_HZ),
257 .op.max_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ],296 .op.max_sys_clk_freq_hz = SMIA_LIM(sensor, MAX_OP_SYS_CLK_FREQ_HZ),
258 .op.min_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ],297 .op.min_pix_clk_freq_hz = SMIA_LIM(sensor, MIN_OP_PIX_CLK_FREQ_HZ),
259 .op.max_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ],298 .op.max_pix_clk_freq_hz = SMIA_LIM(sensor, MAX_OP_PIX_CLK_FREQ_HZ),
260 299
261 .vt.min_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV],300 .vt.min_sys_clk_div = SMIA_LIM(sensor, MIN_VT_SYS_CLK_DIV),
262 .vt.max_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV],301 .vt.max_sys_clk_div = SMIA_LIM(sensor, MAX_VT_SYS_CLK_DIV),
263 .vt.min_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV],302 .vt.min_pix_clk_div = SMIA_LIM(sensor, MIN_VT_PIX_CLK_DIV),
264 .vt.max_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV],303 .vt.max_pix_clk_div = SMIA_LIM(sensor, MAX_VT_PIX_CLK_DIV),
265 .vt.min_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ],304 .vt.min_sys_clk_freq_hz = SMIA_LIM(sensor, MIN_VT_SYS_CLK_FREQ_HZ),
266 .vt.max_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ],305 .vt.max_sys_clk_freq_hz = SMIA_LIM(sensor, MAX_VT_SYS_CLK_FREQ_HZ),
267 .vt.min_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ],306 .vt.min_pix_clk_freq_hz = SMIA_LIM(sensor, MIN_VT_PIX_CLK_FREQ_HZ),
268 .vt.max_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ],307 .vt.max_pix_clk_freq_hz = SMIA_LIM(sensor, MAX_VT_PIX_CLK_FREQ_HZ),
269 308
270 .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN],309 .min_line_length_pck_bin = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK_BIN),
271 .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK],310 .min_line_length_pck = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK),
272 };311 };
273 312
274 return smiapp_pll_calculate(&client->dev, &lim, pll);313 return smiapp_pll_calculate(&client->dev, &lim, pll);
@@ -311,7 +350,7 @@ static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor) · 36 unmodified lines
311 350
312 max = sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height351 max = sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
313 + sensor->vblank->val352 + sensor->vblank->val
314 - sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];353 - SMIA_LIM(sensor, COARSE_INTEGRATION_TIME_MAX_MARGIN);
315 354
316 __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max);355 __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max);
317}356}
@@ -568,10 +607,10 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor) · 250 unmodified lines
568 sensor->analog_gain = v4l2_ctrl_new_std(607 sensor->analog_gain = v4l2_ctrl_new_std(
569 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,608 &sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
570 V4L2_CID_ANALOGUE_GAIN,609 V4L2_CID_ANALOGUE_GAIN,
571 sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN],610 SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_MIN),
572 sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MAX],611 SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_MAX),
573 max(sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_STEP], 1U),612 max(SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_STEP), 1U),
574 sensor->limits[SMIAPP_LIMIT_ANALOGUE_GAIN_CODE_MIN]);613 SMIA_LIM(sensor, ANALOGUE_GAIN_CODE_MIN));
575 614
576 /* Exposure limits will be updated soon, use just something here. */615 /* Exposure limits will be updated soon, use just something here. */
577 sensor->exposure = v4l2_ctrl_new_std(616 sensor->exposure = v4l2_ctrl_new_std(
@@ -677,45 +716,6 @@ static void smiapp_free_controls(struct smiapp_sensor *sensor) · 99 unmodified lines
677 v4l2_ctrl_handler_free(&sensor->ssds[i].ctrl_handler);716 v4l2_ctrl_handler_free(&sensor->ssds[i].ctrl_handler);
678}717}
679 718
680static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit,
681 unsigned int n)
682{
683 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
684 unsigned int i;
685 u32 val;
686 int rval;
687
688 for (i = 0; i < n; i++) {
689 rval = smiapp_read(
690 sensor, smiapp_reg_limits[limit[i]].addr, &val);
691 if (rval)
692 return rval;
693 sensor->limits[limit[i]] = val;
694 dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
695 smiapp_reg_limits[limit[i]].addr,
696 smiapp_reg_limits[limit[i]].what, val, val);
697 }
698
699 return 0;
700}
701
702static int smiapp_get_all_limits(struct smiapp_sensor *sensor)
703{
704 unsigned int i;
705 int rval;
706
707 for (i = 0; i < SMIAPP_LIMIT_LAST; i++) {
708 rval = smiapp_get_limits(sensor, &i, 1);
709 if (rval < 0)
710 return rval;
711 }
712
713 if (sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] == 0)
714 smiapp_replace_limit(sensor, SMIAPP_LIMIT_SCALER_N_MIN, 16);
715
716 return 0;
717}
718
719static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)719static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
720{720{
721 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);721 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
@@ -869,21 +869,21 @@ static void smiapp_update_blanking(struct smiapp_sensor *sensor) · 147 unmodified lines
869 int min, max;869 int min, max;
870 870
871 if (sensor->binning_vertical > 1 || sensor->binning_horizontal > 1) {871 if (sensor->binning_vertical > 1 || sensor->binning_horizontal > 1) {
872 min_fll = sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN];872 min_fll = SMIA_LIM(sensor, MIN_FRAME_LENGTH_LINES_BIN);
873 max_fll = sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN];873 max_fll = SMIA_LIM(sensor, MAX_FRAME_LENGTH_LINES_BIN);
874 min_llp = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN];874 min_llp = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK_BIN);
875 max_llp = sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN];875 max_llp = SMIA_LIM(sensor, MAX_LINE_LENGTH_PCK_BIN);
876 min_lbp = sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN];876 min_lbp = SMIA_LIM(sensor, MIN_LINE_BLANKING_PCK_BIN);
877 } else {877 } else {
878 min_fll = sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES];878 min_fll = SMIA_LIM(sensor, MIN_FRAME_LENGTH_LINES);
879 max_fll = sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES];879 max_fll = SMIA_LIM(sensor, MAX_FRAME_LENGTH_LINES);
880 min_llp = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK];880 min_llp = SMIA_LIM(sensor, MIN_LINE_LENGTH_PCK);
881 max_llp = sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK];881 max_llp = SMIA_LIM(sensor, MAX_LINE_LENGTH_PCK);
882 min_lbp = sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK];882 min_lbp = SMIA_LIM(sensor, MIN_LINE_BLANKING_PCK);
883 }883 }
884 884
885 min = max_t(int,885 min = max_t(int,
886 sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],886 SMIA_LIM(sensor, MIN_FRAME_BLANKING_LINES),
887 min_fll -887 min_fll -
888 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);888 sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
889 max = max_fll - sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;889 max = max_fll - sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
@@ -961,7 +961,7 @@ static int smiapp_read_nvm_page(struct smiapp_sensor *sensor, u32 p, u8 *nvm, · 71 unmodified lines
961 return -ENODATA;961 return -ENODATA;
962 }962 }
963 963
964 if (sensor->limits[SMIAPP_LIMIT_DATA_TRANSFER_IF_CAPABILITY] &964 if (SMIA_LIM(sensor, DATA_TRANSFER_IF_CAPABILITY) &
965 SMIAPP_DATA_TRANSFER_IF_CAPABILITY_POLL) {965 SMIAPP_DATA_TRANSFER_IF_CAPABILITY_POLL) {
966 for (i = 1000; i > 0; i--) {966 for (i = 1000; i > 0; i--) {
967 if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)967 if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)
@@ -1416,7 +1416,7 @@ static int smiapp_start_streaming(struct smiapp_sensor *sensor) · 448 unmodified lines
1416 */1416 */
1417 1417
1418 /* Digital crop */1418 /* Digital crop */
1419 if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]1419 if (SMIA_LIM(sensor, DIGITAL_CROP_CAPABILITY)
1420 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {1420 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
1421 rval = smiapp_write(1421 rval = smiapp_write(
1422 sensor, SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET,1422 sensor, SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET,
@@ -1444,7 +1444,7 @@ static int smiapp_start_streaming(struct smiapp_sensor *sensor) · 21 unmodified lines
1444 }1444 }
1445 1445
1446 /* Scaling */1446 /* Scaling */
1447 if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]1447 if (SMIA_LIM(sensor, SCALING_CAPABILITY)
1448 != SMIAPP_SCALING_CAPABILITY_NONE) {1448 != SMIAPP_SCALING_CAPABILITY_NONE) {
1449 rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALING_MODE,1449 rval = smiapp_write(sensor, SMIAPP_REG_U16_SCALING_MODE,
1450 sensor->scaling_mode);1450 sensor->scaling_mode);
@@ -1467,7 +1467,7 @@ static int smiapp_start_streaming(struct smiapp_sensor *sensor) · 16 unmodified lines
1467 if (rval < 0)1467 if (rval < 0)
1468 goto out;1468 goto out;
1469 1469
1470 if ((sensor->limits[SMIAPP_LIMIT_FLASH_MODE_CAPABILITY] &1470 if ((SMIA_LIM(sensor, FLASH_MODE_CAPABILITY) &
1471 (SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE |1471 (SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE |
1472 SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE)) &&1472 SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE)) &&
1473 sensor->hwcfg->strobe_setup != NULL &&1473 sensor->hwcfg->strobe_setup != NULL &&
@@ -1715,8 +1715,7 @@ static void smiapp_propagate(struct v4l2_subdev *subdev, · 241 unmodified lines
1715 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {1715 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1716 if (ssd == sensor->scaler) {1716 if (ssd == sensor->scaler) {
1717 sensor->scale_m =1717 sensor->scale_m =
1718 sensor->limits[1718 SMIA_LIM(sensor, SCALER_N_MIN);
1719 SMIAPP_LIMIT_SCALER_N_MIN];
1720 sensor->scaling_mode =1719 sensor->scaling_mode =
1721 SMIAPP_SCALING_MODE_NONE;1720 SMIAPP_SCALING_MODE_NONE;
1722 } else if (ssd == sensor->binner) {1721 } else if (ssd == sensor->binner) {
@@ -1828,12 +1827,12 @@ static int smiapp_set_format(struct v4l2_subdev *subdev, · 105 unmodified lines
1828 1827
1829 fmt->format.width =1828 fmt->format.width =
1830 clamp(fmt->format.width,1829 clamp(fmt->format.width,
1831 sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],1830 SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE),
1832 sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);1831 SMIA_LIM(sensor, MAX_X_OUTPUT_SIZE));
1833 fmt->format.height =1832 fmt->format.height =
1834 clamp(fmt->format.height,1833 clamp(fmt->format.height,
1835 sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],1834 SMIA_LIM(sensor, MIN_Y_OUTPUT_SIZE),
1836 sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);1835 SMIA_LIM(sensor, MAX_Y_OUTPUT_SIZE));
1837 1836
1838 smiapp_get_crop_compose(subdev, cfg, crops, NULL, fmt->which);1837 smiapp_get_crop_compose(subdev, cfg, crops, NULL, fmt->which);
1839 1838
@@ -1886,7 +1885,7 @@ static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w, · 46 unmodified lines
1886 val -= abs(w - ask_w);1885 val -= abs(w - ask_w);
1887 val -= abs(h - ask_h);1886 val -= abs(h - ask_h);
1888 1887
1889 if (w < sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])1888 if (w < SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE))
1890 val -= SCALING_GOODNESS_EXTREME;1889 val -= SCALING_GOODNESS_EXTREME;
1891 1890
1892 dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",1891 dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",
@@ -1952,7 +1951,7 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, · 59 unmodified lines
1952 struct i2c_client *client = v4l2_get_subdevdata(subdev);1951 struct i2c_client *client = v4l2_get_subdevdata(subdev);
1953 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);1952 struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
1954 u32 min, max, a, b, max_m;1953 u32 min, max, a, b, max_m;
1955 u32 scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];1954 u32 scale_m = SMIA_LIM(sensor, SCALER_N_MIN);
1956 int mode = SMIAPP_SCALING_MODE_HORIZONTAL;1955 int mode = SMIAPP_SCALING_MODE_HORIZONTAL;
1957 u32 try[4];1956 u32 try[4];
1958 u32 ntry = 0;1957 u32 ntry = 0;
@@ -1965,19 +1964,19 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, · 6 unmodified lines
1965 crops[SMIAPP_PAD_SINK]->height);1964 crops[SMIAPP_PAD_SINK]->height);
1966 1965
1967 a = crops[SMIAPP_PAD_SINK]->width1966 a = crops[SMIAPP_PAD_SINK]->width
1968 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.width;1967 * SMIA_LIM(sensor, SCALER_N_MIN) / sel->r.width;
1969 b = crops[SMIAPP_PAD_SINK]->height1968 b = crops[SMIAPP_PAD_SINK]->height
1970 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN] / sel->r.height;1969 * SMIA_LIM(sensor, SCALER_N_MIN) / sel->r.height;
1971 max_m = crops[SMIAPP_PAD_SINK]->width1970 max_m = crops[SMIAPP_PAD_SINK]->width
1972 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]1971 * SMIA_LIM(sensor, SCALER_N_MIN)
1973 / sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE];1972 / SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE);
1974 1973
1975 a = clamp(a, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],1974 a = clamp(a, SMIA_LIM(sensor, SCALER_M_MIN),
1976 sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);1975 SMIA_LIM(sensor, SCALER_M_MAX));
1977 b = clamp(b, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],1976 b = clamp(b, SMIA_LIM(sensor, SCALER_M_MIN),
1978 sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);1977 SMIA_LIM(sensor, SCALER_M_MAX));
1979 max_m = clamp(max_m, sensor->limits[SMIAPP_LIMIT_SCALER_M_MIN],1978 max_m = clamp(max_m, SMIA_LIM(sensor, SCALER_M_MIN),
1980 sensor->limits[SMIAPP_LIMIT_SCALER_M_MAX]);1979 SMIA_LIM(sensor, SCALER_M_MAX));
1981 1980
1982 dev_dbg(&client->dev, "scaling: a %d b %d max_m %d\n", a, b, max_m);1981 dev_dbg(&client->dev, "scaling: a %d b %d max_m %d\n", a, b, max_m);
1983 1982
@@ -2004,7 +2003,7 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, · 20 unmodified lines
2004 subdev,2003 subdev,
2005 crops[SMIAPP_PAD_SINK]->width2004 crops[SMIAPP_PAD_SINK]->width
2006 / try[i]2005 / try[i]
2007 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],2006 * SMIA_LIM(sensor, SCALER_N_MIN),
2008 sel->r.width,2007 sel->r.width,
2009 crops[SMIAPP_PAD_SINK]->height,2008 crops[SMIAPP_PAD_SINK]->height,
2010 sel->r.height,2009 sel->r.height,
@@ -2018,18 +2017,18 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, · 7 unmodified lines
2018 best = this;2017 best = this;
2019 }2018 }
2020 2019
2021 if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]2020 if (SMIA_LIM(sensor, SCALING_CAPABILITY)
2022 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)2021 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
2023 continue;2022 continue;
2024 2023
2025 this = scaling_goodness(2024 this = scaling_goodness(
2026 subdev, crops[SMIAPP_PAD_SINK]->width2025 subdev, crops[SMIAPP_PAD_SINK]->width
2027 / try[i]2026 / try[i]
2028 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],2027 * SMIA_LIM(sensor, SCALER_N_MIN),
2029 sel->r.width,2028 sel->r.width,
2030 crops[SMIAPP_PAD_SINK]->height2029 crops[SMIAPP_PAD_SINK]->height
2031 / try[i]2030 / try[i]
2032 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN],2031 * SMIA_LIM(sensor, SCALER_N_MIN),
2033 sel->r.height,2032 sel->r.height,
2034 sel->flags);2033 sel->flags);
2035 2034
@@ -2043,12 +2042,12 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, · 7 unmodified lines
2043 sel->r.width =2042 sel->r.width =
2044 (crops[SMIAPP_PAD_SINK]->width2043 (crops[SMIAPP_PAD_SINK]->width
2045 / scale_m2044 / scale_m
2046 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]) & ~1;2045 * SMIA_LIM(sensor, SCALER_N_MIN)) & ~1;
2047 if (mode == SMIAPP_SCALING_MODE_BOTH)2046 if (mode == SMIAPP_SCALING_MODE_BOTH)
2048 sel->r.height =2047 sel->r.height =
2049 (crops[SMIAPP_PAD_SINK]->height2048 (crops[SMIAPP_PAD_SINK]->height
2050 / scale_m2049 / scale_m
2051 * sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN])2050 * SMIA_LIM(sensor, SCALER_N_MIN))
2052 & ~1;2051 & ~1;
2053 else2052 else
2054 sel->r.height = crops[SMIAPP_PAD_SINK]->height;2053 sel->r.height = crops[SMIAPP_PAD_SINK]->height;
@@ -2104,7 +2103,7 @@ static int __smiapp_sel_supported(struct v4l2_subdev *subdev, · 49 unmodified lines
2104 return 0;2103 return 0;
2105 if (ssd == sensor->scaler2104 if (ssd == sensor->scaler
2106 && sel->pad == SMIAPP_PAD_SINK2105 && sel->pad == SMIAPP_PAD_SINK
2107 && sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]2106 && SMIA_LIM(sensor, DIGITAL_CROP_CAPABILITY)
2108 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP)2107 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP)
2109 return 0;2108 return 0;
2110 return -EINVAL;2109 return -EINVAL;
@@ -2120,7 +2119,7 @@ static int __smiapp_sel_supported(struct v4l2_subdev *subdev, · 9 unmodified lines
2120 if (ssd == sensor->binner)2119 if (ssd == sensor->binner)
2121 return 0;2120 return 0;
2122 if (ssd == sensor->scaler2121 if (ssd == sensor->scaler
2123 && sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]2122 && SMIA_LIM(sensor, SCALING_CAPABILITY)
2124 != SMIAPP_SCALING_CAPABILITY_NONE)2123 != SMIAPP_SCALING_CAPABILITY_NONE)
2125 return 0;2124 return 0;
2126 /* Fall through */2125 /* Fall through */
@@ -2185,8 +2184,8 @@ static void smiapp_get_native_size(struct smiapp_subdev *ssd, · 58 unmodified lines
2185{2184{
2186 r->top = 0;2185 r->top = 0;
2187 r->left = 0;2186 r->left = 0;
2188 r->width = ssd->sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;2187 r->width = SMIA_LIM(ssd->sensor, X_ADDR_MAX) + 1;
2189 r->height = ssd->sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;2188 r->height = SMIA_LIM(ssd->sensor, Y_ADDR_MAX) + 1;
2190}2189}
2191 2190
2192static int __smiapp_get_selection(struct v4l2_subdev *subdev,2191static int __smiapp_get_selection(struct v4l2_subdev *subdev,
@@ -2271,10 +2270,10 @@ static int smiapp_set_selection(struct v4l2_subdev *subdev, · 78 unmodified lines
2271 sel->r.height = SMIAPP_ALIGN_DIM(sel->r.height, sel->flags);2270 sel->r.height = SMIAPP_ALIGN_DIM(sel->r.height, sel->flags);
2272 2271
2273 sel->r.width = max_t(unsigned int,2272 sel->r.width = max_t(unsigned int,
2274 sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],2273 SMIA_LIM(sensor, MIN_X_OUTPUT_SIZE),
2275 sel->r.width);2274 sel->r.width);
2276 sel->r.height = max_t(unsigned int,2275 sel->r.height = max_t(unsigned int,
2277 sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],2276 SMIA_LIM(sensor, MIN_Y_OUTPUT_SIZE),
2278 sel->r.height);2277 sel->r.height);
2279 2278
2280 switch (sel->target) {2279 switch (sel->target) {
@@ -2927,7 +2926,7 @@ static int smiapp_probe(struct i2c_client *client) · 646 unmodified lines
2927 goto out_power_off;2926 goto out_power_off;
2928 }2927 }
2929 2928
2930 rval = smiapp_get_all_limits(sensor);2929 rval = smiapp_read_all_smia_limits(sensor);
2931 if (rval) {2930 if (rval) {
2932 rval = -ENODEV;2931 rval = -ENODEV;
2933 goto out_power_off;2932 goto out_power_off;
@@ -2963,7 +2962,7 @@ static int smiapp_probe(struct i2c_client *client) · 29 unmodified lines
2963 goto out_power_off;2962 goto out_power_off;
2964 }2963 }
2965 2964
2966 if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {2965 if (SMIA_LIM(sensor, BINNING_CAPABILITY)) {
2967 u32 val;2966 u32 val;
2968 2967
2969 rval = smiapp_read(sensor,2968 rval = smiapp_read(sensor,
@@ -3000,7 +2999,7 @@ static int smiapp_probe(struct i2c_client *client) · 30 unmodified lines
3000 }2999 }
3001 3000
3002 if (sensor->minfo.smiapp_version &&3001 if (sensor->minfo.smiapp_version &&
3003 sensor->limits[SMIAPP_LIMIT_DATA_TRANSFER_IF_CAPABILITY] &3002 SMIA_LIM(sensor, DATA_TRANSFER_IF_CAPABILITY) &
3004 SMIAPP_DATA_TRANSFER_IF_CAPABILITY_SUPPORTED) {3003 SMIAPP_DATA_TRANSFER_IF_CAPABILITY_SUPPORTED) {
3005 if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {3004 if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
3006 dev_err(&client->dev, "sysfs nvm entry failed\n");3005 dev_err(&client->dev, "sysfs nvm entry failed\n");
@@ -3010,21 +3009,21 @@ static int smiapp_probe(struct i2c_client *client) · 3 unmodified lines
3010 }3009 }
3011 3010
3012 /* We consider this as profile 0 sensor if any of these are zero. */3011 /* We consider this as profile 0 sensor if any of these are zero. */
3013 if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||3012 if (!SMIA_LIM(sensor, MIN_OP_SYS_CLK_DIV) ||
3014 !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||3013 !SMIA_LIM(sensor, MAX_OP_SYS_CLK_DIV) ||
3015 !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] ||3014 !SMIA_LIM(sensor, MIN_OP_PIX_CLK_DIV) ||
3016 !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) {3015 !SMIA_LIM(sensor, MAX_OP_PIX_CLK_DIV)) {
3017 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;3016 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;
3018 } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]3017 } else if (SMIA_LIM(sensor, SCALING_CAPABILITY)
3019 != SMIAPP_SCALING_CAPABILITY_NONE) {3018 != SMIAPP_SCALING_CAPABILITY_NONE) {
3020 if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]3019 if (SMIA_LIM(sensor, SCALING_CAPABILITY)
3021 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)3020 == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
3022 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;3021 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;
3023 else3022 else
3024 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;3023 sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;
3025 sensor->scaler = &sensor->ssds[sensor->ssds_used];3024 sensor->scaler = &sensor->ssds[sensor->ssds_used];
3026 sensor->ssds_used++;3025 sensor->ssds_used++;
3027 } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]3026 } else if (SMIA_LIM(sensor, DIGITAL_CROP_CAPABILITY)
3028 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {3027 == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
3029 sensor->scaler = &sensor->ssds[sensor->ssds_used];3028 sensor->scaler = &sensor->ssds[sensor->ssds_used];
3030 sensor->ssds_used++;3029 sensor->ssds_used++;
@@ -3034,13 +3033,13 @@ static int smiapp_probe(struct i2c_client *client) · 3 unmodified lines
3034 sensor->pixel_array = &sensor->ssds[sensor->ssds_used];3033 sensor->pixel_array = &sensor->ssds[sensor->ssds_used];
3035 sensor->ssds_used++;3034 sensor->ssds_used++;
3036 3035
3037 sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];3036 sensor->scale_m = SMIA_LIM(sensor, SCALER_N_MIN);
3038 3037
3039 /* prepare PLL configuration input values */3038 /* prepare PLL configuration input values */
3040 sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;3039 sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
3041 sensor->pll.csi2.lanes = sensor->hwcfg->lanes;3040 sensor->pll.csi2.lanes = sensor->hwcfg->lanes;
3042 sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk;3041 sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk;
3043 sensor->pll.scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];3042 sensor->pll.scale_n = SMIA_LIM(sensor, SCALER_N_MIN);
3044 /* Profile 0 sensors have no separate OP clock branch. */3043 /* Profile 0 sensors have no separate OP clock branch. */
3045 if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)3044 if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
3046 sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;3045 sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
drivers/media/i2c/smiapp/smiapp-reg.h+4−0
@@ -35,6 +35,10 @@ · 34 unmodified lines
35#define SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE BIT(0)35#define SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE BIT(0)
36#define SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE BIT(1)36#define SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE BIT(1)
37 37
38#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK 0
39#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE 1
40#define SMIAPP_CSI_SIGNALLING_MODE_CSI2 2
41
38#define SMIAPP_DPHY_CTRL_AUTOMATIC 042#define SMIAPP_DPHY_CTRL_AUTOMATIC 0
39/* DPHY control based on REQUESTED_LINK_BIT_RATE_MBPS */43/* DPHY control based on REQUESTED_LINK_BIT_RATE_MBPS */
40#define SMIAPP_DPHY_CTRL_UI 144#define SMIAPP_DPHY_CTRL_UI 1
drivers/media/i2c/smiapp/smiapp-regs.c+20−51
@@ -8,6 +8,8 @@ · 7 unmodified lines
8 * Contact: Sakari Ailus <sakari.ailus@iki.fi>8 * Contact: Sakari Ailus <sakari.ailus@iki.fi>
9 */9 */
10 10
11#include <asm/unaligned.h>
12
11#include <linux/delay.h>13#include <linux/delay.h>
12#include <linux/i2c.h>14#include <linux/i2c.h>
13 15
@@ -69,18 +71,19 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg, · 55 unmodified lines
69{71{
70 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);72 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
71 struct i2c_msg msg;73 struct i2c_msg msg;
72 unsigned char data[4];74 unsigned char data_buf[sizeof(u32)] = { 0 };
73 u16 offset = reg;75 unsigned char offset_buf[sizeof(u16)];
74 int r;76 int r;
75 77
78 if (len > sizeof(data_buf))
79 return -EINVAL;
80
76 msg.addr = client->addr;81 msg.addr = client->addr;
77 msg.flags = 0;82 msg.flags = 0;
78 msg.len = 2;83 msg.len = sizeof(offset_buf);
79 msg.buf = data;84 msg.buf = offset_buf;
85 put_unaligned_be16(reg, offset_buf);
80 86
81 /* high byte goes out first */
82 data[0] = (u8) (offset >> 8);
83 data[1] = (u8) offset;
84 r = i2c_transfer(client->adapter, &msg, 1);87 r = i2c_transfer(client->adapter, &msg, 1);
85 if (r != 1) {88 if (r != 1) {
86 if (r >= 0)89 if (r >= 0)
@@ -90,6 +93,8 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg, · 3 unmodified lines
90 93
91 msg.len = len;94 msg.len = len;
92 msg.flags = I2C_M_RD;95 msg.flags = I2C_M_RD;
96 msg.buf = &data_buf[sizeof(data_buf) - len];
97
93 r = i2c_transfer(client->adapter, &msg, 1);98 r = i2c_transfer(client->adapter, &msg, 1);
94 if (r != 1) {99 if (r != 1) {
95 if (r >= 0)100 if (r >= 0)
@@ -97,27 +102,12 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg, · 1 unmodified line
97 goto err;102 goto err;
98 }103 }
99 104
100 *val = 0;105 *val = get_unaligned_be32(data_buf);
101 /* high byte comes first */
102 switch (len) {
103 case SMIAPP_REG_32BIT:
104 *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
105 data[3];
106 break;
107 case SMIAPP_REG_16BIT:
108 *val = (data[0] << 8) + data[1];
109 break;
110 case SMIAPP_REG_8BIT:
111 *val = data[0];
112 break;
113 default:
114 BUG();
115 }
116 106
117 return 0;107 return 0;
118 108
119err:109err:
120 dev_err(&client->dev, "read from offset 0x%x error %d\n", offset, r);110 dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r);
121 111
122 return r;112 return r;
123}113}
@@ -158,7 +148,7 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val, · 34 unmodified lines
158 && len != SMIAPP_REG_32BIT)148 && len != SMIAPP_REG_32BIT)
159 return -EINVAL;149 return -EINVAL;
160 150
161 if (len == SMIAPP_REG_8BIT || !only8)151 if (!only8)
162 rval = ____smiapp_read(sensor, SMIAPP_REG_ADDR(reg), len, val);152 rval = ____smiapp_read(sensor, SMIAPP_REG_ADDR(reg), len, val);
163 else153 else
164 rval = ____smiapp_read_8only(sensor, SMIAPP_REG_ADDR(reg), len,154 rval = ____smiapp_read_8only(sensor, SMIAPP_REG_ADDR(reg), len,
@@ -214,13 +204,10 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) · 49 unmodified lines
214 struct i2c_msg msg;204 struct i2c_msg msg;
215 unsigned char data[6];205 unsigned char data[6];
216 unsigned int retries;206 unsigned int retries;
217 u8 flags = SMIAPP_REG_FLAGS(reg);
218 u8 len = SMIAPP_REG_WIDTH(reg);207 u8 len = SMIAPP_REG_WIDTH(reg);
219 u16 offset = SMIAPP_REG_ADDR(reg);
220 int r;208 int r;
221 209
222 if ((len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT &&210 if (len > sizeof(data) - 2)
223 len != SMIAPP_REG_32BIT) || flags)
224 return -EINVAL;211 return -EINVAL;
225 212
226 msg.addr = client->addr;213 msg.addr = client->addr;
@@ -228,27 +215,8 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) · 1 unmodified line
228 msg.len = 2 + len;215 msg.len = 2 + len;
229 msg.buf = data;216 msg.buf = data;
230 217
231 /* high byte goes out first */218 put_unaligned_be16(SMIAPP_REG_ADDR(reg), data);
232 data[0] = (u8) (reg >> 8);219 put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2);
233 data[1] = (u8) (reg & 0xff);
234
235 switch (len) {
236 case SMIAPP_REG_8BIT:
237 data[2] = val;
238 break;
239 case SMIAPP_REG_16BIT:
240 data[2] = val >> 8;
241 data[3] = val;
242 break;
243 case SMIAPP_REG_32BIT:
244 data[2] = val >> 24;
245 data[3] = val >> 16;
246 data[4] = val >> 8;
247 data[5] = val;
248 break;
249 default:
250 BUG();
251 }
252 220
253 for (retries = 0; retries < 5; retries++) {221 for (retries = 0; retries < 5; retries++) {
254 /*222 /*
@@ -269,7 +237,8 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) · 14 unmodified lines
269 }237 }
270 238
271 dev_err(&client->dev,239 dev_err(&client->dev,
272 "wrote 0x%x to offset 0x%x error %d\n", val, offset, r);240 "wrote 0x%x to offset 0x%x error %d\n", val,
241 SMIAPP_REG_ADDR(reg), r);
273 242
274 return r;243 return r;
275}244}
drivers/media/i2c/smiapp/smiapp.h+43−1
@@ -14,7 +14,6 @@ · 13 unmodified lines
14#include <linux/mutex.h>14#include <linux/mutex.h>
15#include <media/v4l2-ctrls.h>15#include <media/v4l2-ctrls.h>
16#include <media/v4l2-subdev.h>16#include <media/v4l2-subdev.h>
17#include <media/i2c/smiapp.h>
18 17
19#include "smiapp-pll.h"18#include "smiapp-pll.h"
20#include "smiapp-reg.h"19#include "smiapp-reg.h"
@@ -42,6 +41,49 @@ · 21 unmodified lines
42 41
43#define SMIAPP_COLOUR_COMPONENTS 442#define SMIAPP_COLOUR_COMPONENTS 4
44 43
44#define SMIAPP_NAME "smiapp"
45
46#define SMIAPP_DFL_I2C_ADDR (0x20 >> 1) /* Default I2C Address */
47#define SMIAPP_ALT_I2C_ADDR (0x6e >> 1) /* Alternate I2C Address */
48
49/*
50 * Sometimes due to board layout considerations the camera module can be
51 * mounted rotated. The typical rotation used is 180 degrees which can be
52 * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
53 * FIXME: rotation also changes the bayer pattern.
54 */
55enum smiapp_module_board_orient {
56 SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
57 SMIAPP_MODULE_BOARD_ORIENT_180,
58};
59
60struct smiapp_flash_strobe_parms {
61 u8 mode;
62 u32 strobe_width_high_us;
63 u16 strobe_delay;
64 u16 stobe_start_point;
65 u8 trigger;
66};
67
68struct smiapp_hwconfig {
69 /*
70 * Change the cci address if i2c_addr_alt is set.
71 * Both default and alternate cci addr need to be present
72 */
73 unsigned short i2c_addr_dfl; /* Default i2c addr */
74 unsigned short i2c_addr_alt; /* Alternate i2c addr */
75
76 uint32_t ext_clk; /* sensor external clk */
77
78 unsigned int lanes; /* Number of CSI-2 lanes */
79 uint32_t csi_signalling_mode; /* SMIAPP_CSI_SIGNALLING_MODE_* */
80 uint64_t *op_sys_clock;
81
82 enum smiapp_module_board_orient module_board_orient;
83
84 struct smiapp_flash_strobe_parms *strobe_setup;
85};
86
45#include "smiapp-limits.h"87#include "smiapp-limits.h"
46 88
47struct smiapp_quirk;89struct smiapp_quirk;
drivers/media/i2c/tvp5150.c+622−180
@@ -13,12 +13,15 @@ · 12 unmodified lines
13#include <linux/interrupt.h>13#include <linux/interrupt.h>
14#include <linux/module.h>14#include <linux/module.h>
15#include <linux/of_graph.h>15#include <linux/of_graph.h>
16#include <linux/pm_runtime.h>
16#include <linux/regmap.h>17#include <linux/regmap.h>
17#include <media/v4l2-async.h>18#include <media/v4l2-async.h>
18#include <media/v4l2-device.h>19#include <media/v4l2-device.h>
20#include <media/v4l2-event.h>
19#include <media/v4l2-ctrls.h>21#include <media/v4l2-ctrls.h>
20#include <media/v4l2-fwnode.h>22#include <media/v4l2-fwnode.h>
21#include <media/v4l2-mc.h>23#include <media/v4l2-mc.h>
24#include <media/v4l2-rect.h>
22 25
23#include "tvp5150_reg.h"26#include "tvp5150_reg.h"
24 27
@@ -31,6 +34,15 @@ · 6 unmodified lines
31#define TVP5150_MBUS_FMT MEDIA_BUS_FMT_UYVY8_2X834#define TVP5150_MBUS_FMT MEDIA_BUS_FMT_UYVY8_2X8
32#define TVP5150_FIELD V4L2_FIELD_ALTERNATE35#define TVP5150_FIELD V4L2_FIELD_ALTERNATE
33#define TVP5150_COLORSPACE V4L2_COLORSPACE_SMPTE170M36#define TVP5150_COLORSPACE V4L2_COLORSPACE_SMPTE170M
37#define TVP5150_STD_MASK (V4L2_STD_NTSC | \
38 V4L2_STD_NTSC_443 | \
39 V4L2_STD_PAL | \
40 V4L2_STD_PAL_M | \
41 V4L2_STD_PAL_N | \
42 V4L2_STD_PAL_Nc | \
43 V4L2_STD_SECAM)
44
45#define TVP5150_MAX_CONNECTORS 3 /* Check dt-bindings for more information */
34 46
35MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video decoder driver");47MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video decoder driver");
36MODULE_AUTHOR("Mauro Carvalho Chehab");48MODULE_AUTHOR("Mauro Carvalho Chehab");
@@ -44,18 +56,26 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); · 7 unmodified lines
44#define dprintk0(__dev, __arg...) dev_dbg_lvl(__dev, 0, 0, __arg)56#define dprintk0(__dev, __arg...) dev_dbg_lvl(__dev, 0, 0, __arg)
45 57
46enum tvp5150_pads {58enum tvp5150_pads {
47 TVP5150_PAD_IF_INPUT,59 TVP5150_PAD_AIP1A,
60 TVP5150_PAD_AIP1B,
48 TVP5150_PAD_VID_OUT,61 TVP5150_PAD_VID_OUT,
49 TVP5150_NUM_PADS62 TVP5150_NUM_PADS
50};63};
51 64
65struct tvp5150_connector {
66 struct v4l2_fwnode_connector base;
67 struct media_entity ent;
68 struct media_pad pad;
69};
70
52struct tvp5150 {71struct tvp5150 {
53 struct v4l2_subdev sd;72 struct v4l2_subdev sd;
54#ifdef CONFIG_MEDIA_CONTROLLER73
55 struct media_pad pads[TVP5150_NUM_PADS];74 struct media_pad pads[TVP5150_NUM_PADS];
56 struct media_entity input_ent[TVP5150_INPUT_NUM];75 struct tvp5150_connector connectors[TVP5150_MAX_CONNECTORS];
57 struct media_pad input_pad[TVP5150_INPUT_NUM];76 struct tvp5150_connector *cur_connector;
58#endif77 unsigned int connectors_num;
78
59 struct v4l2_ctrl_handler hdl;79 struct v4l2_ctrl_handler hdl;
60 struct v4l2_rect rect;80 struct v4l2_rect rect;
61 struct regmap *regmap;81 struct regmap *regmap;
@@ -282,9 +302,12 @@ static void tvp5150_selmux(struct v4l2_subdev *sd) · 220 unmodified lines
282 break;302 break;
283 }303 }
284 304
285 dev_dbg_lvl(sd->dev, 1, debug, "Selecting video route: route input=%i, output=%i => tvp5150 input=%i, opmode=%i\n",305 dev_dbg_lvl(sd->dev, 1, debug,
286 decoder->input, decoder->output,306 "Selecting video route: route input=%s, output=%s => tvp5150 input=0x%02x, opmode=0x%02x\n",
287 input, opmode);307 decoder->input == 0 ? "aip1a" :
308 decoder->input == 2 ? "aip1b" : "svideo",
309 decoder->output == 0 ? "normal" : "black-frame-gen",
310 input, opmode);
288 311
289 regmap_write(decoder->regmap, TVP5150_OP_MODE_CTL, opmode);312 regmap_write(decoder->regmap, TVP5150_OP_MODE_CTL, opmode);
290 regmap_write(decoder->regmap, TVP5150_VD_IN_SRC_SEL_1, input);313 regmap_write(decoder->regmap, TVP5150_VD_IN_SRC_SEL_1, input);
@@ -773,17 +796,33 @@ static int tvp5150_g_std(struct v4l2_subdev *sd, v4l2_std_id *std) · 482 unmodified lines
773static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)796static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
774{797{
775 struct tvp5150 *decoder = to_tvp5150(sd);798 struct tvp5150 *decoder = to_tvp5150(sd);
799 struct tvp5150_connector *cur_con = decoder->cur_connector;
800 v4l2_std_id supported_stds;
776 801
777 if (decoder->norm == std)802 if (decoder->norm == std)
778 return 0;803 return 0;
779 804
805 /* In case of no of-connectors are available no limitations are made */
806 if (!decoder->connectors_num)
807 supported_stds = V4L2_STD_ALL;
808 else
809 supported_stds = cur_con->base.connector.analog.sdtv_stds;
810
811 /*
812 * Check if requested std or group of std's is/are supported by the
813 * connector.
814 */
815 if ((supported_stds & std) == 0)
816 return -EINVAL;
817
780 /* Change cropping height limits */818 /* Change cropping height limits */
781 if (std & V4L2_STD_525_60)819 if (std & V4L2_STD_525_60)
782 decoder->rect.height = TVP5150_V_MAX_525_60;820 decoder->rect.height = TVP5150_V_MAX_525_60;
783 else821 else
784 decoder->rect.height = TVP5150_V_MAX_OTHERS;822 decoder->rect.height = TVP5150_V_MAX_OTHERS;
785 823
786 decoder->norm = std;824 /* Set only the specific supported std in case of group of std's. */
825 decoder->norm = supported_stds & std;
787 826
788 return tvp5150_set_std(sd, std);827 return tvp5150_set_std(sd, std);
789}828}
@@ -986,6 +1025,25 @@ static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop) · 196 unmodified lines
986 crop->height = TVP5150_V_MAX_OTHERS;1025 crop->height = TVP5150_V_MAX_OTHERS;
987}1026}
988 1027
1028static struct v4l2_rect *
1029tvp5150_get_pad_crop(struct tvp5150 *decoder,
1030 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
1031 enum v4l2_subdev_format_whence which)
1032{
1033 switch (which) {
1034 case V4L2_SUBDEV_FORMAT_ACTIVE:
1035 return &decoder->rect;
1036 case V4L2_SUBDEV_FORMAT_TRY:
1037#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
1038 return v4l2_subdev_get_try_crop(&decoder->sd, cfg, pad);
1039#else
1040 return ERR_PTR(-EINVAL);
1041#endif
1042 default:
1043 return ERR_PTR(-EINVAL);
1044 }
1045}
1046
989static int tvp5150_fill_fmt(struct v4l2_subdev *sd,1047static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
990 struct v4l2_subdev_pad_config *cfg,1048 struct v4l2_subdev_pad_config *cfg,
991 struct v4l2_subdev_format *format)1049 struct v4l2_subdev_format *format)
@@ -1010,25 +1068,10 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd, · 18 unmodified lines
1010 return 0;1068 return 0;
1011}1069}
1012 1070
1013static int tvp5150_set_selection(struct v4l2_subdev *sd,1071static unsigned int tvp5150_get_hmax(struct v4l2_subdev *sd)
1014 struct v4l2_subdev_pad_config *cfg,
1015 struct v4l2_subdev_selection *sel)
1016{1072{
1017 struct tvp5150 *decoder = to_tvp5150(sd);1073 struct tvp5150 *decoder = to_tvp5150(sd);
1018 struct v4l2_rect rect = sel->r;
1019 v4l2_std_id std;1074 v4l2_std_id std;
1020 int hmax;
1021
1022 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
1023 sel->target != V4L2_SEL_TGT_CROP)
1024 return -EINVAL;
1025
1026 dev_dbg_lvl(sd->dev, 1, debug, "%s left=%d, top=%d, width=%d, height=%d\n",
1027 __func__, rect.left, rect.top, rect.width, rect.height);
1028
1029 /* tvp5150 has some special limits */
1030 rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
1031 rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP);
1032 1075
1033 /* Calculate height based on current standard */1076 /* Calculate height based on current standard */
1034 if (decoder->norm == V4L2_STD_ALL)1077 if (decoder->norm == V4L2_STD_ALL)
@@ -1036,36 +1079,78 @@ static int tvp5150_set_selection(struct v4l2_subdev *sd, · 1 unmodified line
1036 else1079 else
1037 std = decoder->norm;1080 std = decoder->norm;
1038 1081
1039 if (std & V4L2_STD_525_60)1082 return (std & V4L2_STD_525_60) ?
1040 hmax = TVP5150_V_MAX_525_60;1083 TVP5150_V_MAX_525_60 : TVP5150_V_MAX_OTHERS;
1041 else1084}
1042 hmax = TVP5150_V_MAX_OTHERS;
1043 1085
1044 /*1086static void tvp5150_set_hw_selection(struct v4l2_subdev *sd,
1045 * alignments:1087 struct v4l2_rect *rect)
1046 * - width = 2 due to UYVY colorspace1088{
1047 * - height, image = no special alignment1089 struct tvp5150 *decoder = to_tvp5150(sd);
1048 */1090 unsigned int hmax = tvp5150_get_hmax(sd);
1049 v4l_bound_align_image(&rect.width,
1050 TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
1051 TVP5150_H_MAX - rect.left, 1, &rect.height,
1052 hmax - TVP5150_MAX_CROP_TOP - rect.top,
1053 hmax - rect.top, 0, 0);
1054 1091
1055 regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, rect.top);1092 regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, rect->top);
1056 regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP,1093 regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP,
1057 rect.top + rect.height - hmax);1094 rect->top + rect->height - hmax);
1058 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_MSB,1095 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_MSB,
1059 rect.left >> TVP5150_CROP_SHIFT);1096 rect->left >> TVP5150_CROP_SHIFT);
1060 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_LSB,1097 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_LSB,
1061 rect.left | (1 << TVP5150_CROP_SHIFT));1098 rect->left | (1 << TVP5150_CROP_SHIFT));
1062 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_MSB,1099 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_MSB,
1063 (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>1100 (rect->left + rect->width - TVP5150_MAX_CROP_LEFT) >>
1064 TVP5150_CROP_SHIFT);1101 TVP5150_CROP_SHIFT);
1065 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_LSB,1102 regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_LSB,
1066 rect.left + rect.width - TVP5150_MAX_CROP_LEFT);1103 rect->left + rect->width - TVP5150_MAX_CROP_LEFT);
1104}
1105
1106static int tvp5150_set_selection(struct v4l2_subdev *sd,
1107 struct v4l2_subdev_pad_config *cfg,
1108 struct v4l2_subdev_selection *sel)
1109{
1110 struct tvp5150 *decoder = to_tvp5150(sd);
1111 struct v4l2_rect *rect = &sel->r;
1112 struct v4l2_rect *crop;
1113 unsigned int hmax;
1114
1115 if (sel->target != V4L2_SEL_TGT_CROP)
1116 return -EINVAL;
1117
1118 dev_dbg_lvl(sd->dev, 1, debug, "%s left=%d, top=%d, width=%d, height=%d\n",
1119 __func__, rect->left, rect->top, rect->width, rect->height);
1120
1121 /* tvp5150 has some special limits */
1122 rect->left = clamp(rect->left, 0, TVP5150_MAX_CROP_LEFT);
1123 rect->top = clamp(rect->top, 0, TVP5150_MAX_CROP_TOP);
1124 hmax = tvp5150_get_hmax(sd);
1125
1126 /*
1127 * alignments:
1128 * - width = 2 due to UYVY colorspace
1129 * - height, image = no special alignment
1130 */
1131 v4l_bound_align_image(&rect->width,
1132 TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect->left,
1133 TVP5150_H_MAX - rect->left, 1, &rect->height,
1134 hmax - TVP5150_MAX_CROP_TOP - rect->top,
1135 hmax - rect->top, 0, 0);
1136
1137 if (!IS_ENABLED(CONFIG_VIDEO_V4L2_SUBDEV_API) &&
1138 sel->which == V4L2_SUBDEV_FORMAT_TRY)
1139 return 0;
1140
1141 crop = tvp5150_get_pad_crop(decoder, cfg, sel->pad, sel->which);
1142 if (IS_ERR(crop))
1143 return PTR_ERR(crop);
1144
1145 /*
1146 * Update output image size if the selection (crop) rectangle size or
1147 * position has been modified.
1148 */
1149 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
1150 !v4l2_rect_equal(rect, crop))
1151 tvp5150_set_hw_selection(sd, rect);
1067 1152
1068 decoder->rect = rect;1153 *crop = *rect;
1069 1154
1070 return 0;1155 return 0;
1071}1156}
@@ -1075,11 +1160,9 @@ static int tvp5150_get_selection(struct v4l2_subdev *sd, · 3 unmodified lines
1075 struct v4l2_subdev_selection *sel)1160 struct v4l2_subdev_selection *sel)
1076{1161{
1077 struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);1162 struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
1163 struct v4l2_rect *crop;
1078 v4l2_std_id std;1164 v4l2_std_id std;
1079 1165
1080 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
1081 return -EINVAL;
1082
1083 switch (sel->target) {1166 switch (sel->target) {
1084 case V4L2_SEL_TGT_CROP_BOUNDS:1167 case V4L2_SEL_TGT_CROP_BOUNDS:
1085 sel->r.left = 0;1168 sel->r.left = 0;
@@ -1097,7 +1180,11 @@ static int tvp5150_get_selection(struct v4l2_subdev *sd, · 11 unmodified lines
1097 sel->r.height = TVP5150_V_MAX_OTHERS;1180 sel->r.height = TVP5150_V_MAX_OTHERS;
1098 return 0;1181 return 0;
1099 case V4L2_SEL_TGT_CROP:1182 case V4L2_SEL_TGT_CROP:
1100 sel->r = decoder->rect;1183 crop = tvp5150_get_pad_crop(decoder, cfg, sel->pad,
1184 sel->which);
1185 if (IS_ERR(crop))
1186 return PTR_ERR(crop);
1187 sel->r = *crop;
1101 return 0;1188 return 0;
1102 default:1189 default:
1103 return -EINVAL;1190 return -EINVAL;
@@ -1170,30 +1257,148 @@ static int tvp5150_enum_frame_size(struct v4l2_subdev *sd, · 66 unmodified lines
1170}1257}
1171 1258
1172/****************************************************************************1259/****************************************************************************
1173 Media entity ops1260 * Media entity ops
1174 ****************************************************************************/1261 ****************************************************************************/
1262#if defined(CONFIG_MEDIA_CONTROLLER)
1263static int tvp5150_set_link(struct media_pad *connector_pad,
1264 struct media_pad *tvp5150_pad, u32 flags)
1265{
1266 struct media_link *link;
1267
1268 link = media_entity_find_link(connector_pad, tvp5150_pad);
1269 if (!link)
1270 return -EINVAL;
1271
1272 link->flags = flags;
1273 link->reverse->flags = link->flags;
1274
1275 return 0;
1276}
1277
1278static int tvp5150_disable_all_input_links(struct tvp5150 *decoder)
1279{
1280 struct media_pad *connector_pad;
1281 unsigned int i;
1282 int err;
1283
1284 for (i = 0; i < TVP5150_NUM_PADS - 1; i++) {
1285 connector_pad = media_entity_remote_pad(&decoder->pads[i]);
1286 if (!connector_pad)
1287 continue;
1288
1289 err = tvp5150_set_link(connector_pad, &decoder->pads[i], 0);
1290 if (err)
1291 return err;
1292 }
1293
1294 return 0;
1295}
1296
1297static int tvp5150_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
1298 u32 config);
1175 1299
1176#ifdef CONFIG_MEDIA_CONTROLLER
1177static int tvp5150_link_setup(struct media_entity *entity,1300static int tvp5150_link_setup(struct media_entity *entity,
1178 const struct media_pad *local,1301 const struct media_pad *tvp5150_pad,
1179 const struct media_pad *remote, u32 flags)1302 const struct media_pad *remote, u32 flags)
1180{1303{
1181 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);1304 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1182 struct tvp5150 *decoder = to_tvp5150(sd);1305 struct tvp5150 *decoder = to_tvp5150(sd);
1183 int i;1306 struct media_pad *other_tvp5150_pad =
1307 &decoder->pads[tvp5150_pad->index ^ 1];
1308 struct v4l2_fwnode_connector *v4l2c;
1309 bool is_svideo = false;
1310 unsigned int i;
1311 int err;
1312
1313 /*
1314 * The TVP5150 state is determined by the enabled sink pad link(s).
1315 * Enabling or disabling the source pad link has no effect.
1316 */
1317 if (tvp5150_pad->flags & MEDIA_PAD_FL_SOURCE)
1318 return 0;
1184 1319
1185 for (i = 0; i < TVP5150_INPUT_NUM; i++) {1320 /* Check if the svideo connector should be enabled */
1186 if (remote->entity == &decoder->input_ent[i])1321 for (i = 0; i < decoder->connectors_num; i++) {
1322 if (remote->entity == &decoder->connectors[i].ent) {
1323 v4l2c = &decoder->connectors[i].base;
1324 is_svideo = v4l2c->type == V4L2_CONN_SVIDEO;
1187 break;1325 break;
1326 }
1188 }1327 }
1189 1328
1190 /* Do nothing for entities that are not input connectors */1329 dev_dbg_lvl(sd->dev, 1, debug, "link setup '%s':%d->'%s':%d[%d]",
1191 if (i == TVP5150_INPUT_NUM)1330 remote->entity->name, remote->index,
1192 return 0;1331 tvp5150_pad->entity->name, tvp5150_pad->index,
1332 flags & MEDIA_LNK_FL_ENABLED);
1333 if (is_svideo)
1334 dev_dbg_lvl(sd->dev, 1, debug,
1335 "link setup '%s':%d->'%s':%d[%d]",
1336 remote->entity->name, remote->index,
1337 other_tvp5150_pad->entity->name,
1338 other_tvp5150_pad->index,
1339 flags & MEDIA_LNK_FL_ENABLED);
1193 1340
1194 decoder->input = i;1341 /*
1342 * The TVP5150 has an internal mux which allows the following setup:
1343 *
1344 * comp-connector1 --\
1345 * |---> AIP1A
1346 * /
1347 * svideo-connector -|
1348 * \
1349 * |---> AIP1B
1350 * comp-connector2 --/
1351 *
1352 * We can't rely on user space that the current connector gets disabled
1353 * first before enabling the new connector. Disable all active
1354 * connector links to be on the safe side.
1355 */
1356 err = tvp5150_disable_all_input_links(decoder);
1357 if (err)
1358 return err;
1359
1360 tvp5150_s_routing(sd, is_svideo ? TVP5150_SVIDEO : tvp5150_pad->index,
1361 flags & MEDIA_LNK_FL_ENABLED ? TVP5150_NORMAL :
1362 TVP5150_BLACK_SCREEN, 0);
1363
1364 if (flags & MEDIA_LNK_FL_ENABLED) {
1365 struct v4l2_fwnode_connector_analog *v4l2ca;
1366 u32 new_norm;
1367
1368 /*
1369 * S-Video connector is conneted to both ports AIP1A and AIP1B.
1370 * Both links must be enabled in one-shot regardless which link
1371 * the user requests.
1372 */
1373 if (is_svideo) {
1374 err = tvp5150_set_link((struct media_pad *)remote,
1375 other_tvp5150_pad, flags);
1376 if (err)
1377 return err;
1378 }
1195 1379
1196 tvp5150_selmux(sd);1380 if (!decoder->connectors_num)
1381 return 0;
1382
1383 /* Update the current connector */
1384 decoder->cur_connector =
1385 container_of(remote, struct tvp5150_connector, pad);
1386
1387 /*
1388 * Do nothing if the new connector supports the same tv-norms as
1389 * the old one.
1390 */
1391 v4l2ca = &decoder->cur_connector->base.connector.analog;
1392 new_norm = decoder->norm & v4l2ca->sdtv_stds;
1393 if (decoder->norm == new_norm)
1394 return 0;
1395
1396 /*
1397 * Fallback to the new connector tv-norms if we can't find any
1398 * common between the current tv-norm and the new one.
1399 */
1400 tvp5150_s_std(sd, new_norm ? new_norm : v4l2ca->sdtv_stds);
1401 }
1197 1402
1198 return 0;1403 return 0;
1199}1404}
@@ -1202,20 +1407,54 @@ static const struct media_entity_operations tvp5150_sd_media_ops = { · 2 unmodified lines
1202 .link_setup = tvp5150_link_setup,1407 .link_setup = tvp5150_link_setup,
1203};1408};
1204#endif1409#endif
1205
1206/****************************************************************************1410/****************************************************************************
1207 I2C Command1411 I2C Command
1208 ****************************************************************************/1412 ****************************************************************************/
1413static int __maybe_unused tvp5150_runtime_suspend(struct device *dev)
1414{
1415 struct i2c_client *client = to_i2c_client(dev);
1416 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1417 struct tvp5150 *decoder = to_tvp5150(sd);
1418
1419 if (decoder->irq)
1420 /* Disable lock interrupt */
1421 return regmap_update_bits(decoder->regmap,
1422 TVP5150_INT_ENABLE_REG_A,
1423 TVP5150_INT_A_LOCK, 0);
1424 return 0;
1425}
1426
1427static int __maybe_unused tvp5150_runtime_resume(struct device *dev)
1428{
1429 struct i2c_client *client = to_i2c_client(dev);
1430 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1431 struct tvp5150 *decoder = to_tvp5150(sd);
1432
1433 if (decoder->irq)
1434 /* Enable lock interrupt */
1435 return regmap_update_bits(decoder->regmap,
1436 TVP5150_INT_ENABLE_REG_A,
1437 TVP5150_INT_A_LOCK,
1438 TVP5150_INT_A_LOCK);
1439 return 0;
1440}
1209 1441
1210static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)1442static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
1211{1443{
1212 struct tvp5150 *decoder = to_tvp5150(sd);1444 struct tvp5150 *decoder = to_tvp5150(sd);
1213 unsigned int mask, val = 0, int_val = 0;1445 unsigned int mask, val = 0;
1446 int ret;
1214 1447
1215 mask = TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |1448 mask = TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |
1216 TVP5150_MISC_CTL_CLOCK_OE;1449 TVP5150_MISC_CTL_CLOCK_OE;
1217 1450
1218 if (enable) {1451 if (enable) {
1452 ret = pm_runtime_get_sync(sd->dev);
1453 if (ret < 0) {
1454 pm_runtime_put_noidle(sd->dev);
1455 return ret;
1456 }
1457
1219 tvp5150_enable(sd);1458 tvp5150_enable(sd);
1220 1459
1221 /* Enable outputs if decoder is locked */1460 /* Enable outputs if decoder is locked */
@@ -1223,15 +1462,13 @@ static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable) · 1 unmodified line
1223 val = decoder->lock ? decoder->oe : 0;1462 val = decoder->lock ? decoder->oe : 0;
1224 else1463 else
1225 val = decoder->oe;1464 val = decoder->oe;
1226 int_val = TVP5150_INT_A_LOCK;1465
1227 v4l2_subdev_notify_event(&decoder->sd, &tvp5150_ev_fmt);1466 v4l2_subdev_notify_event(&decoder->sd, &tvp5150_ev_fmt);
1467 } else {
1468 pm_runtime_put(sd->dev);
1228 }1469 }
1229 1470
1230 regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val);1471 regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val);
1231 if (decoder->irq)
1232 /* Enable / Disable lock interrupt */
1233 regmap_update_bits(decoder->regmap, TVP5150_INT_ENABLE_REG_A,
1234 TVP5150_INT_A_LOCK, int_val);
1235 1472
1236 return 0;1473 return 0;
1237}1474}
@@ -1342,6 +1579,19 @@ static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regi · 104 unmodified lines
1342}1579}
1343#endif1580#endif
1344 1581
1582static int tvp5150_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1583 struct v4l2_event_subscription *sub)
1584{
1585 switch (sub->type) {
1586 case V4L2_EVENT_SOURCE_CHANGE:
1587 return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
1588 case V4L2_EVENT_CTRL:
1589 return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
1590 default:
1591 return -EINVAL;
1592 }
1593}
1594
1345static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)1595static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1346{1596{
1347 int status = tvp5150_read(sd, 0x88);1597 int status = tvp5150_read(sd, 0x88);
@@ -1352,40 +1602,96 @@ static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) · 4 unmodified lines
1352 1602
1353static int tvp5150_registered(struct v4l2_subdev *sd)1603static int tvp5150_registered(struct v4l2_subdev *sd)
1354{1604{
1355#ifdef CONFIG_MEDIA_CONTROLLER1605#if defined(CONFIG_MEDIA_CONTROLLER)
1356 struct tvp5150 *decoder = to_tvp5150(sd);1606 struct tvp5150 *decoder = to_tvp5150(sd);
1357 int ret = 0;1607 unsigned int i;
1358 int i;1608 int ret;
1359
1360 for (i = 0; i < TVP5150_INPUT_NUM; i++) {
1361 struct media_entity *input = &decoder->input_ent[i];
1362 struct media_pad *pad = &decoder->input_pad[i];
1363
1364 if (!input->name)
1365 continue;
1366 1609
1367 decoder->input_pad[i].flags = MEDIA_PAD_FL_SOURCE;1610 /*
1611 * Setup connector pads and links. Enable the link to the first
1612 * available connector per default.
1613 */
1614 for (i = 0; i < decoder->connectors_num; i++) {
1615 struct media_entity *con = &decoder->connectors[i].ent;
1616 struct media_pad *pad = &decoder->connectors[i].pad;
1617 struct v4l2_fwnode_connector *v4l2c =
1618 &decoder->connectors[i].base;
1619 struct v4l2_connector_link *link =
1620 v4l2_connector_first_link(v4l2c);
1621 unsigned int port = link->fwnode_link.remote_port;
1622 unsigned int flags = i ? 0 : MEDIA_LNK_FL_ENABLED;
1623 bool is_svideo = v4l2c->type == V4L2_CONN_SVIDEO;
1624
1625 pad->flags = MEDIA_PAD_FL_SOURCE;
1626 ret = media_entity_pads_init(con, 1, pad);
1627 if (ret < 0)
1628 goto err;
1368 1629
1369 ret = media_entity_pads_init(input, 1, pad);1630 ret = media_device_register_entity(sd->v4l2_dev->mdev, con);
1370 if (ret < 0)1631 if (ret < 0)
1371 return ret;1632 goto err;
1372 1633
1373 ret = media_device_register_entity(sd->v4l2_dev->mdev, input);1634 ret = media_create_pad_link(con, 0, &sd->entity, port, flags);
1374 if (ret < 0)1635 if (ret < 0)
1375 return ret;1636 goto err;
1376 1637
1377 ret = media_create_pad_link(input, 0, &sd->entity,1638 if (is_svideo) {
1378 TVP5150_PAD_IF_INPUT, 0);1639 /*
1379 if (ret < 0) {1640 * Check tvp5150_link_setup() comments for more
1380 media_device_unregister_entity(input);1641 * information.
1381 return ret;1642 */
1643 link = v4l2_connector_last_link(v4l2c);
1644 port = link->fwnode_link.remote_port;
1645 ret = media_create_pad_link(con, 0, &sd->entity, port,
1646 flags);
1647 if (ret < 0)
1648 goto err;
1649 }
1650
1651 /* Enable default input. */
1652 if (flags == MEDIA_LNK_FL_ENABLED) {
1653 decoder->input =
1654 is_svideo ? TVP5150_SVIDEO :
1655 port == 0 ? TVP5150_COMPOSITE0 :
1656 TVP5150_COMPOSITE1;
1657
1658 tvp5150_selmux(sd);
1659 decoder->cur_connector = &decoder->connectors[i];
1660 tvp5150_s_std(sd, v4l2c->connector.analog.sdtv_stds);
1382 }1661 }
1383 }1662 }
1663
1664 return 0;
1665
1666err:
1667 for (i = 0; i < decoder->connectors_num; i++)
1668 media_device_unregister_entity(&decoder->connectors[i].ent);
1669 return ret;
1384#endif1670#endif
1385 1671
1386 return 0;1672 return 0;
1387}1673}
1388 1674
1675static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1676{
1677 int ret;
1678
1679 ret = pm_runtime_get_sync(sd->dev);
1680 if (ret < 0) {
1681 pm_runtime_put_noidle(sd->dev);
1682 return ret;
1683 }
1684
1685 return 0;
1686}
1687
1688static int tvp5150_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1689{
1690 pm_runtime_put(sd->dev);
1691
1692 return 0;
1693}
1694
1389/* ----------------------------------------------------------------------- */1695/* ----------------------------------------------------------------------- */
1390 1696
1391static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {1697static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
@@ -1399,6 +1705,8 @@ static const struct v4l2_subdev_core_ops tvp5150_core_ops = { · 7 unmodified lines
1399 .g_register = tvp5150_g_register,1705 .g_register = tvp5150_g_register,
1400 .s_register = tvp5150_s_register,1706 .s_register = tvp5150_s_register,
1401#endif1707#endif
1708 .subscribe_event = tvp5150_subscribe_event,
1709 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1402};1710};
1403 1711
1404static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {1712static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
@@ -1441,6 +1749,8 @@ static const struct v4l2_subdev_ops tvp5150_ops = { · 36 unmodified lines
1441 1749
1442static const struct v4l2_subdev_internal_ops tvp5150_internal_ops = {1750static const struct v4l2_subdev_internal_ops tvp5150_internal_ops = {
1443 .registered = tvp5150_registered,1751 .registered = tvp5150_registered,
1752 .open = tvp5150_open,
1753 .close = tvp5150_close,
1444};1754};
1445 1755
1446/****************************************************************************1756/****************************************************************************
@@ -1591,102 +1901,211 @@ static int tvp5150_init(struct i2c_client *c) · 144 unmodified lines
1591 return 0;1901 return 0;
1592}1902}
1593 1903
1594static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)1904#if defined(CONFIG_MEDIA_CONTROLLER)
1905static int tvp5150_mc_init(struct tvp5150 *decoder)
1595{1906{
1596 struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };1907 struct v4l2_subdev *sd = &decoder->sd;
1597 struct device_node *ep;1908 unsigned int i;
1598#ifdef CONFIG_MEDIA_CONTROLLER
1599 struct device_node *connectors, *child;
1600 struct media_entity *input;
1601 const char *name;
1602 u32 input_type;
1603#endif
1604 unsigned int flags;
1605 int ret = 0;
1606 1909
1607 ep = of_graph_get_next_endpoint(np, NULL);1910 sd->entity.ops = &tvp5150_sd_media_ops;
1608 if (!ep)1911 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
1609 return -EINVAL;
1610 1912
1611 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);1913 for (i = 0; i < TVP5150_NUM_PADS - 1; i++) {
1612 if (ret)1914 decoder->pads[i].flags = MEDIA_PAD_FL_SINK;
1613 goto err;1915 decoder->pads[i].sig_type = PAD_SIGNAL_ANALOG;
1916 }
1614 1917
1615 flags = bus_cfg.bus.parallel.flags;1918 decoder->pads[i].flags = MEDIA_PAD_FL_SOURCE;
1919 decoder->pads[i].sig_type = PAD_SIGNAL_DV;
1616 1920
1617 if (bus_cfg.bus_type == V4L2_MBUS_PARALLEL &&1921 return media_entity_pads_init(&sd->entity, TVP5150_NUM_PADS,
1618 !(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH &&1922 decoder->pads);
1619 flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH &&1923}
1620 flags & V4L2_MBUS_FIELD_EVEN_LOW)) {
1621 ret = -EINVAL;
1622 goto err;
1623 }
1624 1924
1625 decoder->mbus_type = bus_cfg.bus_type;1925#else /* !defined(CONFIG_MEDIA_CONTROLLER) */
1626 1926
1627#ifdef CONFIG_MEDIA_CONTROLLER1927static inline int tvp5150_mc_init(struct tvp5150 *decoder)
1628 connectors = of_get_child_by_name(np, "connectors");1928{
1929 return 0;
1930}
1931#endif /* defined(CONFIG_MEDIA_CONTROLLER) */
1629 1932
1630 if (!connectors)1933static int tvp5150_validate_connectors(struct tvp5150 *decoder)
1631 goto err;1934{
1935 struct device *dev = decoder->sd.dev;
1936 struct tvp5150_connector *tvpc;
1937 struct v4l2_fwnode_connector *v4l2c;
1938 unsigned int i;
1939
1940 if (!decoder->connectors_num) {
1941 dev_err(dev, "No valid connector found\n");
1942 return -ENODEV;
1943 }
1632 1944
1633 for_each_available_child_of_node(connectors, child) {1945 for (i = 0; i < decoder->connectors_num; i++) {
1634 ret = of_property_read_u32(child, "input", &input_type);1946 struct v4l2_connector_link *link0 = NULL;
1635 if (ret) {1947 struct v4l2_connector_link *link1;
1636 dev_err(decoder->sd.dev,1948
1637 "missing type property in node %pOFn\n",1949 tvpc = &decoder->connectors[i];
1638 child);1950 v4l2c = &tvpc->base;
1639 of_node_put(child);1951
1640 goto err_connector;1952 if (v4l2c->type == V4L2_CONN_COMPOSITE) {
1953 if (v4l2c->nr_of_links != 1) {
1954 dev_err(dev, "Composite: connector needs 1 link\n");
1955 return -EINVAL;
1956 }
1957 link0 = v4l2_connector_first_link(v4l2c);
1958 if (!link0) {
1959 dev_err(dev, "Composite: invalid first link\n");
1960 return -EINVAL;
1961 }
1962 if (link0->fwnode_link.remote_id == 1) {
1963 dev_err(dev, "Composite: invalid endpoint id\n");
1964 return -EINVAL;
1965 }
1641 }1966 }
1642 1967
1643 if (input_type >= TVP5150_INPUT_NUM) {1968 if (v4l2c->type == V4L2_CONN_SVIDEO) {
1644 ret = -EINVAL;1969 if (v4l2c->nr_of_links != 2) {
1645 of_node_put(child);1970 dev_err(dev, "SVideo: connector needs 2 links\n");
1646 goto err_connector;1971 return -EINVAL;
1972 }
1973 link0 = v4l2_connector_first_link(v4l2c);
1974 if (!link0) {
1975 dev_err(dev, "SVideo: invalid first link\n");
1976 return -EINVAL;
1977 }
1978 link1 = v4l2_connector_last_link(v4l2c);
1979 if (link0->fwnode_link.remote_port ==
1980 link1->fwnode_link.remote_port) {
1981 dev_err(dev, "SVideo: invalid link setup\n");
1982 return -EINVAL;
1983 }
1647 }1984 }
1648 1985
1649 input = &decoder->input_ent[input_type];1986 if (!(v4l2c->connector.analog.sdtv_stds & TVP5150_STD_MASK)) {
1987 dev_err(dev, "Unsupported tv-norm on connector %s\n",
1988 v4l2c->name);
1989 return -EINVAL;
1990 }
1991 }
1992
1993 return 0;
1994}
1995
1996static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
1997{
1998 struct device *dev = decoder->sd.dev;
1999 struct v4l2_fwnode_endpoint bus_cfg = {
2000 .bus_type = V4L2_MBUS_UNKNOWN
2001 };
2002 struct device_node *ep_np;
2003 struct tvp5150_connector *tvpc;
2004 struct v4l2_fwnode_connector *v4l2c;
2005 unsigned int flags, ep_num;
2006 unsigned int i;
2007 int ret;
2008
2009 /* At least 1 output and 1 input */
2010 ep_num = of_graph_get_endpoint_count(np);
2011 if (ep_num < 2 || ep_num > 5) {
2012 dev_err(dev, "At least 1 input and 1 output must be connected to the device.\n");
2013 return -EINVAL;
2014 }
1650 2015
1651 /* Each input connector can only be defined once */2016 /* Layout if all connectors are used:
1652 if (input->name) {2017 *
1653 dev_err(decoder->sd.dev,2018 * tvp-5150 port@0 (AIP1A)
1654 "input %s with same type already exists\n",2019 * endpoint@0 -----------> Comp0-Con port
1655 input->name);2020 * endpoint@1 --------+--> Svideo-Con port
1656 of_node_put(child);2021 * tvp-5150 port@1 (AIP1B) |
1657 ret = -EINVAL;2022 * endpoint@1 --------+
1658 goto err_connector;2023 * endpoint@0 -----------> Comp1-Con port
2024 * tvp-5150 port@2
2025 * endpoint (video bitstream output at YOUT[0-7] parallel bus)
2026 */
2027 for_each_endpoint_of_node(np, ep_np) {
2028 struct fwnode_handle *ep_fwnode = of_fwnode_handle(ep_np);
2029 unsigned int next_connector = decoder->connectors_num;
2030 struct of_endpoint ep;
2031
2032 of_graph_parse_endpoint(ep_np, &ep);
2033 if (ep.port > 1 || ep.id > 1) {
2034 dev_dbg(dev, "Ignore connector on port@%u/ep@%u\n",
2035 ep.port, ep.id);
2036 continue;
1659 }2037 }
1660 2038
1661 switch (input_type) {2039 tvpc = &decoder->connectors[next_connector];
1662 case TVP5150_COMPOSITE0:2040 v4l2c = &tvpc->base;
1663 case TVP5150_COMPOSITE1:2041
1664 input->function = MEDIA_ENT_F_CONN_COMPOSITE;2042 if (ep.port == 0 || (ep.port == 1 && ep.id == 0)) {
1665 break;2043 ret = v4l2_fwnode_connector_parse(ep_fwnode, v4l2c);
1666 case TVP5150_SVIDEO:2044 if (ret)
1667 input->function = MEDIA_ENT_F_CONN_SVIDEO;2045 goto err_put;
1668 break;2046 ret = v4l2_fwnode_connector_add_link(ep_fwnode, v4l2c);
2047 if (ret)
2048 goto err_put;
2049 decoder->connectors_num++;
2050 } else {
2051 /* Adding the 2nd svideo link */
2052 for (i = 0; i < TVP5150_MAX_CONNECTORS; i++) {
2053 tvpc = &decoder->connectors[i];
2054 v4l2c = &tvpc->base;
2055 if (v4l2c->type == V4L2_CONN_SVIDEO)
2056 break;
2057 }
2058
2059 ret = v4l2_fwnode_connector_add_link(ep_fwnode, v4l2c);
2060 if (ret)
2061 goto err_put;
1669 }2062 }
2063 }
1670 2064
1671 input->flags = MEDIA_ENT_FL_CONNECTOR;2065 ret = tvp5150_validate_connectors(decoder);
2066 if (ret)
2067 goto err_free;
2068
2069 for (i = 0; i < decoder->connectors_num; i++) {
2070 tvpc = &decoder->connectors[i];
2071 v4l2c = &tvpc->base;
2072 tvpc->ent.flags = MEDIA_ENT_FL_CONNECTOR;
2073 tvpc->ent.function = v4l2c->type == V4L2_CONN_SVIDEO ?
2074 MEDIA_ENT_F_CONN_SVIDEO : MEDIA_ENT_F_CONN_COMPOSITE;
2075 tvpc->ent.name = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
2076 v4l2c->name, v4l2c->label ?
2077 v4l2c->label : "");
2078 }
1672 2079
1673 ret = of_property_read_string(child, "label", &name);2080 ep_np = of_graph_get_endpoint_by_regs(np, TVP5150_PAD_VID_OUT, 0);
1674 if (ret < 0) {2081 if (!ep_np) {
1675 dev_err(decoder->sd.dev,2082 dev_err(dev, "Error no output endpoint available\n");
1676 "missing label property in node %pOFn\n",2083 goto err_free;
1677 child);2084 }
1678 of_node_put(child);2085 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_np), &bus_cfg);
1679 goto err_connector;2086 of_node_put(ep_np);
1680 }2087 if (ret)
2088 goto err_free;
1681 2089
1682 input->name = name;2090 flags = bus_cfg.bus.parallel.flags;
2091 if (bus_cfg.bus_type == V4L2_MBUS_PARALLEL &&
2092 !(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH &&
2093 flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH &&
2094 flags & V4L2_MBUS_FIELD_EVEN_LOW)) {
2095 ret = -EINVAL;
2096 goto err_free;
1683 }2097 }
1684 2098
1685err_connector:2099 decoder->mbus_type = bus_cfg.bus_type;
1686 of_node_put(connectors);2100
1687#endif2101 return 0;
1688err:2102
1689 of_node_put(ep);2103err_put:
2104 of_node_put(ep_np);
2105err_free:
2106 for (i = 0; i < TVP5150_MAX_CONNECTORS; i++)
2107 v4l2_fwnode_connector_free(&decoder->connectors[i].base);
2108
1690 return ret;2109 return ret;
1691}2110}
1692 2111
@@ -1701,6 +2120,7 @@ static int tvp5150_probe(struct i2c_client *c) · 8 unmodified lines
1701 struct v4l2_subdev *sd;2120 struct v4l2_subdev *sd;
1702 struct device_node *np = c->dev.of_node;2121 struct device_node *np = c->dev.of_node;
1703 struct regmap *map;2122 struct regmap *map;
2123 unsigned int i;
1704 int res;2124 int res;
1705 2125
1706 /* Check if the adapter supports the needed features */2126 /* Check if the adapter supports the needed features */
@@ -1722,6 +2142,9 @@ static int tvp5150_probe(struct i2c_client *c) · 15 unmodified lines
1722 2142
1723 core->regmap = map;2143 core->regmap = map;
1724 sd = &core->sd;2144 sd = &core->sd;
2145 v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
2146 sd->internal_ops = &tvp5150_internal_ops;
2147 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
1725 2148
1726 if (IS_ENABLED(CONFIG_OF) && np) {2149 if (IS_ENABLED(CONFIG_OF) && np) {
1727 res = tvp5150_parse_dt(core, np);2150 res = tvp5150_parse_dt(core, np);
@@ -1734,30 +2157,29 @@ static int tvp5150_probe(struct i2c_client *c) · 6 unmodified lines
1734 core->mbus_type = V4L2_MBUS_BT656;2157 core->mbus_type = V4L2_MBUS_BT656;
1735 }2158 }
1736 2159
1737 v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);2160 res = tvp5150_mc_init(core);
1738 sd->internal_ops = &tvp5150_internal_ops;2161 if (res)
1739 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1740
1741#if defined(CONFIG_MEDIA_CONTROLLER)
1742 core->pads[TVP5150_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
1743 core->pads[TVP5150_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
1744 core->pads[TVP5150_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
1745 core->pads[TVP5150_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
1746
1747 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
1748
1749 res = media_entity_pads_init(&sd->entity, TVP5150_NUM_PADS, core->pads);
1750 if (res < 0)
1751 return res;2162 return res;
1752 2163
1753 sd->entity.ops = &tvp5150_sd_media_ops;
1754#endif
1755
1756 res = tvp5150_detect_version(core);2164 res = tvp5150_detect_version(core);
1757 if (res < 0)2165 if (res < 0)
1758 return res;2166 return res;
1759 2167
1760 core->norm = V4L2_STD_ALL; /* Default is autodetect */2168 /*
2169 * Iterate over all available connectors in case they are supported and
2170 * successfully parsed. Fallback to default autodetect in case they
2171 * aren't supported.
2172 */
2173 for (i = 0; i < core->connectors_num; i++) {
2174 struct v4l2_fwnode_connector *v4l2c;
2175
2176 v4l2c = &core->connectors[i].base;
2177 core->norm |= v4l2c->connector.analog.sdtv_stds;
2178 }
2179
2180 if (!core->connectors_num)
2181 core->norm = V4L2_STD_ALL;
2182
1761 core->detected_norm = V4L2_STD_UNKNOWN;2183 core->detected_norm = V4L2_STD_UNKNOWN;
1762 core->input = TVP5150_COMPOSITE1;2184 core->input = TVP5150_COMPOSITE1;
1763 core->enable = true;2185 core->enable = true;
@@ -1802,6 +2224,11 @@ static int tvp5150_probe(struct i2c_client *c) · 38 unmodified lines
1802 2224
1803 if (debug > 1)2225 if (debug > 1)
1804 tvp5150_log_status(sd);2226 tvp5150_log_status(sd);
2227
2228 pm_runtime_set_active(&c->dev);
2229 pm_runtime_enable(&c->dev);
2230 pm_runtime_idle(&c->dev);
2231
1805 return 0;2232 return 0;
1806 2233
1807err:2234err:
@@ -1813,18 +2240,32 @@ static int tvp5150_remove(struct i2c_client *c) · 5 unmodified lines
1813{2240{
1814 struct v4l2_subdev *sd = i2c_get_clientdata(c);2241 struct v4l2_subdev *sd = i2c_get_clientdata(c);
1815 struct tvp5150 *decoder = to_tvp5150(sd);2242 struct tvp5150 *decoder = to_tvp5150(sd);
2243 unsigned int i;
1816 2244
1817 dev_dbg_lvl(sd->dev, 1, debug,2245 dev_dbg_lvl(sd->dev, 1, debug,
1818 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",2246 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
1819 c->addr << 1);2247 c->addr << 1);
1820 2248
2249 for (i = 0; i < decoder->connectors_num; i++)
2250 v4l2_fwnode_connector_free(&decoder->connectors[i].base);
2251 for (i = 0; i < decoder->connectors_num; i++)
2252 media_device_unregister_entity(&decoder->connectors[i].ent);
1821 v4l2_async_unregister_subdev(sd);2253 v4l2_async_unregister_subdev(sd);
1822 v4l2_ctrl_handler_free(&decoder->hdl);2254 v4l2_ctrl_handler_free(&decoder->hdl);
2255 pm_runtime_disable(&c->dev);
2256 pm_runtime_set_suspended(&c->dev);
2257
1823 return 0;2258 return 0;
1824}2259}
1825 2260
1826/* ----------------------------------------------------------------------- */2261/* ----------------------------------------------------------------------- */
1827 2262
2263static const struct dev_pm_ops tvp5150_pm_ops = {
2264 SET_RUNTIME_PM_OPS(tvp5150_runtime_suspend,
2265 tvp5150_runtime_resume,
2266 NULL)
2267};
2268
1828static const struct i2c_device_id tvp5150_id[] = {2269static const struct i2c_device_id tvp5150_id[] = {
1829 { "tvp5150", 0 },2270 { "tvp5150", 0 },
1830 { }2271 { }
@@ -1843,6 +2284,7 @@ static struct i2c_driver tvp5150_driver = { · 12 unmodified lines
1843 .driver = {2284 .driver = {
1844 .of_match_table = of_match_ptr(tvp5150_of_match),2285 .of_match_table = of_match_ptr(tvp5150_of_match),
1845 .name = "tvp5150",2286 .name = "tvp5150",
2287 .pm = &tvp5150_pm_ops,
1846 },2288 },
1847 .probe_new = tvp5150_probe,2289 .probe_new = tvp5150_probe,
1848 .remove = tvp5150_remove,2290 .remove = tvp5150_remove,
drivers/media/i2c/video-i2c.c+2−2
@@ -255,7 +255,7 @@ static int amg88xx_set_power(struct video_i2c_data *data, bool on) · 254 unmodified lines
255 return amg88xx_set_power_off(data);255 return amg88xx_set_power_off(data);
256}256}
257 257
258#if IS_ENABLED(CONFIG_HWMON)258#if IS_REACHABLE(CONFIG_HWMON)
259 259
260static const u32 amg88xx_temp_config[] = {260static const u32 amg88xx_temp_config[] = {
261 HWMON_T_INPUT,261 HWMON_T_INPUT,
@@ -858,7 +858,7 @@ static int video_i2c_probe(struct i2c_client *client, · 596 unmodified lines
858 }858 }
859 }859 }
860 860
861 ret = video_register_device(&data->vdev, VFL_TYPE_GRABBER, -1);861 ret = video_register_device(&data->vdev, VFL_TYPE_VIDEO, -1);
862 if (ret < 0)862 if (ret < 0)
863 goto error_pm_disable;863 goto error_pm_disable;
864 864
drivers/media/mc/mc-entity.c+8−3
@@ -662,9 +662,14 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, · 661 unmodified lines
662 struct media_link *link;662 struct media_link *link;
663 struct media_link *backlink;663 struct media_link *backlink;
664 664
665 BUG_ON(source == NULL || sink == NULL);665 if (WARN_ON(!source || !sink) ||
666 BUG_ON(source_pad >= source->num_pads);666 WARN_ON(source_pad >= source->num_pads) ||
667 BUG_ON(sink_pad >= sink->num_pads);667 WARN_ON(sink_pad >= sink->num_pads))
668 return -EINVAL;
669 if (WARN_ON(!(source->pads[source_pad].flags & MEDIA_PAD_FL_SOURCE)))
670 return -EINVAL;
671 if (WARN_ON(!(sink->pads[sink_pad].flags & MEDIA_PAD_FL_SINK)))
672 return -EINVAL;
668 673
669 link = media_add_link(&source->links);674 link = media_add_link(&source->links);
670 if (link == NULL)675 if (link == NULL)
drivers/media/pci/bt8xx/bttv-driver.c+2−2
@@ -2964,7 +2964,7 @@ static int bttv_open(struct file *file) · 2963 unmodified lines
2964 2964
2965 dprintk("open dev=%s\n", video_device_node_name(vdev));2965 dprintk("open dev=%s\n", video_device_node_name(vdev));
2966 2966
2967 if (vdev->vfl_type == VFL_TYPE_GRABBER) {2967 if (vdev->vfl_type == VFL_TYPE_VIDEO) {
2968 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;2968 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2969 } else if (vdev->vfl_type == VFL_TYPE_VBI) {2969 } else if (vdev->vfl_type == VFL_TYPE_VBI) {
2970 type = V4L2_BUF_TYPE_VBI_CAPTURE;2970 type = V4L2_BUF_TYPE_VBI_CAPTURE;
@@ -3905,7 +3905,7 @@ static int bttv_register_video(struct bttv *btv) · 934 unmodified lines
3905 if (no_overlay <= 0)3905 if (no_overlay <= 0)
3906 btv->video_dev.device_caps |= V4L2_CAP_VIDEO_OVERLAY;3906 btv->video_dev.device_caps |= V4L2_CAP_VIDEO_OVERLAY;
3907 3907
3908 if (video_register_device(&btv->video_dev, VFL_TYPE_GRABBER,3908 if (video_register_device(&btv->video_dev, VFL_TYPE_VIDEO,
3909 video_nr[btv->c.nr]) < 0)3909 video_nr[btv->c.nr]) < 0)
3910 goto err;3910 goto err;
3911 pr_info("%d: registered device %s\n",3911 pr_info("%d: registered device %s\n",
drivers/media/pci/cobalt/cobalt-v4l2.c+1−1
@@ -1272,7 +1272,7 @@ static int cobalt_node_register(struct cobalt *cobalt, int node) · 1271 unmodified lines
1272 video_set_drvdata(vdev, s);1272 video_set_drvdata(vdev, s);
1273 ret = vb2_queue_init(q);1273 ret = vb2_queue_init(q);
1274 if (!s->is_audio && ret == 0)1274 if (!s->is_audio && ret == 0)
1275 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1275 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1276 else if (!s->is_dummy)1276 else if (!s->is_dummy)
1277 ret = cobalt_alsa_init(s);1277 ret = cobalt_alsa_init(s);
1278 1278
drivers/media/pci/cx18/cx18-streams.c+6−6
@@ -48,19 +48,19 @@ static struct { · 47 unmodified lines
48} cx18_stream_info[] = {48} cx18_stream_info[] = {
49 { /* CX18_ENC_STREAM_TYPE_MPG */49 { /* CX18_ENC_STREAM_TYPE_MPG */
50 "encoder MPEG",50 "encoder MPEG",
51 VFL_TYPE_GRABBER, 0,51 VFL_TYPE_VIDEO, 0,
52 PCI_DMA_FROMDEVICE,52 PCI_DMA_FROMDEVICE,
53 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |53 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
54 V4L2_CAP_AUDIO | V4L2_CAP_TUNER54 V4L2_CAP_AUDIO | V4L2_CAP_TUNER
55 },55 },
56 { /* CX18_ENC_STREAM_TYPE_TS */56 { /* CX18_ENC_STREAM_TYPE_TS */
57 "TS",57 "TS",
58 VFL_TYPE_GRABBER, -1,58 VFL_TYPE_VIDEO, -1,
59 PCI_DMA_FROMDEVICE,59 PCI_DMA_FROMDEVICE,
60 },60 },
61 { /* CX18_ENC_STREAM_TYPE_YUV */61 { /* CX18_ENC_STREAM_TYPE_YUV */
62 "encoder YUV",62 "encoder YUV",
63 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,63 VFL_TYPE_VIDEO, CX18_V4L2_ENC_YUV_OFFSET,
64 PCI_DMA_FROMDEVICE,64 PCI_DMA_FROMDEVICE,
65 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |65 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
66 V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_TUNER66 V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_TUNER
@@ -74,13 +74,13 @@ static struct { · 7 unmodified lines
74 },74 },
75 { /* CX18_ENC_STREAM_TYPE_PCM */75 { /* CX18_ENC_STREAM_TYPE_PCM */
76 "encoder PCM audio",76 "encoder PCM audio",
77 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,77 VFL_TYPE_VIDEO, CX18_V4L2_ENC_PCM_OFFSET,
78 PCI_DMA_FROMDEVICE,78 PCI_DMA_FROMDEVICE,
79 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,79 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
80 },80 },
81 { /* CX18_ENC_STREAM_TYPE_IDX */81 { /* CX18_ENC_STREAM_TYPE_IDX */
82 "encoder IDX",82 "encoder IDX",
83 VFL_TYPE_GRABBER, -1,83 VFL_TYPE_VIDEO, -1,
84 PCI_DMA_FROMDEVICE,84 PCI_DMA_FROMDEVICE,
85 },85 },
86 { /* CX18_ENC_STREAM_TYPE_RAD */86 { /* CX18_ENC_STREAM_TYPE_RAD */
@@ -434,7 +434,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) · 347 unmodified lines
434 name = video_device_node_name(&s->video_dev);434 name = video_device_node_name(&s->video_dev);
435 435
436 switch (vfl_type) {436 switch (vfl_type) {
437 case VFL_TYPE_GRABBER:437 case VFL_TYPE_VIDEO:
438 CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",438 CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
439 name, s->name, cx->stream_buffers[type],439 name, s->name, cx->stream_buffers[type],
440 cx->stream_buf_size[type] / 1024,440 cx->stream_buf_size[type] / 1024,
drivers/media/pci/cx23885/cx23885-417.c+1−1
@@ -1545,7 +1545,7 @@ int cx23885_417_register(struct cx23885_dev *dev) · 1544 unmodified lines
1545 if (dev->tuner_type != TUNER_ABSENT)1545 if (dev->tuner_type != TUNER_ABSENT)
1546 dev->v4l_device->device_caps |= V4L2_CAP_TUNER;1546 dev->v4l_device->device_caps |= V4L2_CAP_TUNER;
1547 err = video_register_device(dev->v4l_device,1547 err = video_register_device(dev->v4l_device,
1548 VFL_TYPE_GRABBER, -1);1548 VFL_TYPE_VIDEO, -1);
1549 if (err < 0) {1549 if (err < 0) {
1550 pr_info("%s: can't register mpeg device\n", dev->name);1550 pr_info("%s: can't register mpeg device\n", dev->name);
1551 return err;1551 return err;
drivers/media/pci/cx23885/cx23885-video.c+1−1
@@ -1304,7 +1304,7 @@ int cx23885_video_register(struct cx23885_dev *dev) · 1303 unmodified lines
1304 V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE;1304 V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE;
1305 if (dev->tuner_type != TUNER_ABSENT)1305 if (dev->tuner_type != TUNER_ABSENT)
1306 dev->video_dev->device_caps |= V4L2_CAP_TUNER;1306 dev->video_dev->device_caps |= V4L2_CAP_TUNER;
1307 err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,1307 err = video_register_device(dev->video_dev, VFL_TYPE_VIDEO,
1308 video_nr[dev->nr]);1308 video_nr[dev->nr]);
1309 if (err < 0) {1309 if (err < 0) {
1310 pr_info("%s: can't register video device\n",1310 pr_info("%s: can't register video device\n",
drivers/media/pci/cx25821/cx25821-video.c+1−1
@@ -757,7 +757,7 @@ int cx25821_video_register(struct cx25821_dev *dev) · 756 unmodified lines
757 snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);757 snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);
758 video_set_drvdata(vdev, chan);758 video_set_drvdata(vdev, chan);
759 759
760 err = video_register_device(vdev, VFL_TYPE_GRABBER,760 err = video_register_device(vdev, VFL_TYPE_VIDEO,
761 video_nr[dev->nr]);761 video_nr[dev->nr]);
762 762
763 if (err < 0)763 if (err < 0)
drivers/media/pci/cx88/cx88-blackbird.c+1−1
@@ -1138,7 +1138,7 @@ static int blackbird_register_video(struct cx8802_dev *dev) · 1137 unmodified lines
1138 V4L2_CAP_VIDEO_CAPTURE;1138 V4L2_CAP_VIDEO_CAPTURE;
1139 if (dev->core->board.tuner_type != UNSET)1139 if (dev->core->board.tuner_type != UNSET)
1140 dev->mpeg_dev.device_caps |= V4L2_CAP_TUNER;1140 dev->mpeg_dev.device_caps |= V4L2_CAP_TUNER;
1141 err = video_register_device(&dev->mpeg_dev, VFL_TYPE_GRABBER, -1);1141 err = video_register_device(&dev->mpeg_dev, VFL_TYPE_VIDEO, -1);
1142 if (err < 0) {1142 if (err < 0) {
1143 pr_info("can't register mpeg device\n");1143 pr_info("can't register mpeg device\n");
1144 return err;1144 return err;
drivers/media/pci/cx88/cx88-video.c+1−1
@@ -1451,7 +1451,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, · 1450 unmodified lines
1451 V4L2_CAP_VIDEO_CAPTURE;1451 V4L2_CAP_VIDEO_CAPTURE;
1452 if (core->board.tuner_type != UNSET)1452 if (core->board.tuner_type != UNSET)
1453 dev->video_dev.device_caps |= V4L2_CAP_TUNER;1453 dev->video_dev.device_caps |= V4L2_CAP_TUNER;
1454 err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER,1454 err = video_register_device(&dev->video_dev, VFL_TYPE_VIDEO,
1455 video_nr[core->nr]);1455 video_nr[core->nr]);
1456 if (err < 0) {1456 if (err < 0) {
1457 pr_err("can't register video device\n");1457 pr_err("can't register video device\n");
drivers/media/pci/dt3155/dt3155.c+1−1
@@ -550,7 +550,7 @@ static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 549 unmodified lines
550 IRQF_SHARED, DT3155_NAME, pd);550 IRQF_SHARED, DT3155_NAME, pd);
551 if (err)551 if (err)
552 goto err_iounmap;552 goto err_iounmap;
553 err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1);553 err = video_register_device(&pd->vdev, VFL_TYPE_VIDEO, -1);
554 if (err)554 if (err)
555 goto err_free_irq;555 goto err_free_irq;
556 dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor);556 dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor);
drivers/media/pci/intel/ipu3/ipu3-cio2.c+1−1
@@ -1647,7 +1647,7 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) · 1646 unmodified lines
1647 vdev->queue = &q->vbq;1647 vdev->queue = &q->vbq;
1648 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;1648 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;
1649 video_set_drvdata(vdev, cio2);1649 video_set_drvdata(vdev, cio2);
1650 r = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1650 r = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1651 if (r) {1651 if (r) {
1652 dev_err(&cio2->pci_dev->dev,1652 dev_err(&cio2->pci_dev->dev,
1653 "failed to register video device (%d)\n", r);1653 "failed to register video device (%d)\n", r);
drivers/media/pci/ivtv/ivtv-streams.c+6−6
@@ -99,7 +99,7 @@ static struct { · 98 unmodified lines
99} ivtv_stream_info[] = {99} ivtv_stream_info[] = {
100 { /* IVTV_ENC_STREAM_TYPE_MPG */100 { /* IVTV_ENC_STREAM_TYPE_MPG */
101 "encoder MPG",101 "encoder MPG",
102 VFL_TYPE_GRABBER, 0,102 VFL_TYPE_VIDEO, 0,
103 PCI_DMA_FROMDEVICE, 0,103 PCI_DMA_FROMDEVICE, 0,
104 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |104 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
105 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,105 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
@@ -107,7 +107,7 @@ static struct { · 1 unmodified line
107 },107 },
108 { /* IVTV_ENC_STREAM_TYPE_YUV */108 { /* IVTV_ENC_STREAM_TYPE_YUV */
109 "encoder YUV",109 "encoder YUV",
110 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,110 VFL_TYPE_VIDEO, IVTV_V4L2_ENC_YUV_OFFSET,
111 PCI_DMA_FROMDEVICE, 0,111 PCI_DMA_FROMDEVICE, 0,
112 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |112 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
113 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,113 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
@@ -123,7 +123,7 @@ static struct { · 9 unmodified lines
123 },123 },
124 { /* IVTV_ENC_STREAM_TYPE_PCM */124 { /* IVTV_ENC_STREAM_TYPE_PCM */
125 "encoder PCM",125 "encoder PCM",
126 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,126 VFL_TYPE_VIDEO, IVTV_V4L2_ENC_PCM_OFFSET,
127 PCI_DMA_FROMDEVICE, 0,127 PCI_DMA_FROMDEVICE, 0,
128 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,128 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
129 &ivtv_v4l2_enc_fops129 &ivtv_v4l2_enc_fops
@@ -137,7 +137,7 @@ static struct { · 7 unmodified lines
137 },137 },
138 { /* IVTV_DEC_STREAM_TYPE_MPG */138 { /* IVTV_DEC_STREAM_TYPE_MPG */
139 "decoder MPG",139 "decoder MPG",
140 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,140 VFL_TYPE_VIDEO, IVTV_V4L2_DEC_MPG_OFFSET,
141 PCI_DMA_TODEVICE, 0,141 PCI_DMA_TODEVICE, 0,
142 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,142 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
143 &ivtv_v4l2_dec_fops143 &ivtv_v4l2_dec_fops
@@ -158,7 +158,7 @@ static struct { · 14 unmodified lines
158 },158 },
159 { /* IVTV_DEC_STREAM_TYPE_YUV */159 { /* IVTV_DEC_STREAM_TYPE_YUV */
160 "decoder YUV",160 "decoder YUV",
161 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,161 VFL_TYPE_VIDEO, IVTV_V4L2_DEC_YUV_OFFSET,
162 PCI_DMA_TODEVICE, 0,162 PCI_DMA_TODEVICE, 0,
163 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,163 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
164 &ivtv_v4l2_dec_fops164 &ivtv_v4l2_dec_fops
@@ -318,7 +318,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) · 153 unmodified lines
318 name = video_device_node_name(&s->vdev);318 name = video_device_node_name(&s->vdev);
319 319
320 switch (vfl_type) {320 switch (vfl_type) {
321 case VFL_TYPE_GRABBER:321 case VFL_TYPE_VIDEO:
322 IVTV_INFO("Registered device %s for %s (%d kB)\n",322 IVTV_INFO("Registered device %s for %s (%d kB)\n",
323 name, s->name, itv->options.kilobytes[type]);323 name, s->name, itv->options.kilobytes[type]);
324 break;324 break;
drivers/media/pci/meye/meye.c+1−1
@@ -1711,7 +1711,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) · 1710 unmodified lines
1711 v4l2_ctrl_handler_setup(&meye.hdl);1711 v4l2_ctrl_handler_setup(&meye.hdl);
1712 meye.vdev.ctrl_handler = &meye.hdl;1712 meye.vdev.ctrl_handler = &meye.hdl;
1713 1713
1714 if (video_register_device(&meye.vdev, VFL_TYPE_GRABBER,1714 if (video_register_device(&meye.vdev, VFL_TYPE_VIDEO,
1715 video_nr) < 0) {1715 video_nr) < 0) {
1716 v4l2_err(v4l2_dev, "video_register_device failed\n");1716 v4l2_err(v4l2_dev, "video_register_device failed\n");
1717 goto outvideoreg;1717 goto outvideoreg;
drivers/media/pci/saa7134/saa7134-core.c+1−1
@@ -1214,7 +1214,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, · 1213 unmodified lines
1214 if (saa7134_no_overlay <= 0)1214 if (saa7134_no_overlay <= 0)
1215 dev->video_dev->device_caps |= V4L2_CAP_VIDEO_OVERLAY;1215 dev->video_dev->device_caps |= V4L2_CAP_VIDEO_OVERLAY;
1216 1216
1217 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,1217 err = video_register_device(dev->video_dev,VFL_TYPE_VIDEO,
1218 video_nr[dev->nr]);1218 video_nr[dev->nr]);
1219 if (err < 0) {1219 if (err < 0) {
1220 pr_info("%s: can't register video device\n",1220 pr_info("%s: can't register video device\n",
drivers/media/pci/saa7134/saa7134-empress.c+1−1
@@ -291,7 +291,7 @@ static int empress_init(struct saa7134_dev *dev) · 290 unmodified lines
291 dev->empress_dev->device_caps |= V4L2_CAP_TUNER;291 dev->empress_dev->device_caps |= V4L2_CAP_TUNER;
292 292
293 video_set_drvdata(dev->empress_dev, dev);293 video_set_drvdata(dev->empress_dev, dev);
294 err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,294 err = video_register_device(dev->empress_dev,VFL_TYPE_VIDEO,
295 empress_nr[dev->nr]);295 empress_nr[dev->nr]);
296 if (err < 0) {296 if (err < 0) {
297 pr_info("%s: can't register video device\n",297 pr_info("%s: can't register video device\n",
drivers/media/pci/saa7146/hexium_gemini.c+1−1
@@ -289,7 +289,7 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d · 288 unmodified lines
289 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;289 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
290 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;290 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
291 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;291 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
292 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);292 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_VIDEO);
293 if (ret < 0) {293 if (ret < 0) {
294 pr_err("cannot register capture v4l2 device. skipping.\n");294 pr_err("cannot register capture v4l2 device. skipping.\n");
295 saa7146_vv_release(dev);295 saa7146_vv_release(dev);
drivers/media/pci/saa7146/hexium_orion.c+1−1
@@ -362,7 +362,7 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d · 361 unmodified lines
362 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;362 vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
363 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;363 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
364 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;364 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
365 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {365 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_VIDEO)) {
366 pr_err("cannot register capture v4l2 device. skipping.\n");366 pr_err("cannot register capture v4l2 device. skipping.\n");
367 return -1;367 return -1;
368 }368 }
drivers/media/pci/saa7146/mxb.c+1−1
@@ -707,7 +707,7 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data · 706 unmodified lines
707 vv_data.vid_ops.vidioc_g_register = vidioc_g_register;707 vv_data.vid_ops.vidioc_g_register = vidioc_g_register;
708 vv_data.vid_ops.vidioc_s_register = vidioc_s_register;708 vv_data.vid_ops.vidioc_s_register = vidioc_s_register;
709#endif709#endif
710 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {710 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_VIDEO)) {
711 ERR("cannot register capture v4l2 device. skipping.\n");711 ERR("cannot register capture v4l2 device. skipping.\n");
712 saa7146_vv_release(dev);712 saa7146_vv_release(dev);
713 return -1;713 return -1;
drivers/media/pci/saa7164/saa7164-encoder.c+1−1
@@ -1087,7 +1087,7 @@ int saa7164_encoder_register(struct saa7164_port *port) · 1086 unmodified lines
1087 v4l2_ctrl_handler_setup(hdl);1087 v4l2_ctrl_handler_setup(hdl);
1088 video_set_drvdata(port->v4l_device, port);1088 video_set_drvdata(port->v4l_device, port);
1089 result = video_register_device(port->v4l_device,1089 result = video_register_device(port->v4l_device,
1090 VFL_TYPE_GRABBER, -1);1090 VFL_TYPE_VIDEO, -1);
1091 if (result < 0) {1091 if (result < 0) {
1092 printk(KERN_INFO "%s: can't register mpeg device\n",1092 printk(KERN_INFO "%s: can't register mpeg device\n",
1093 dev->name);1093 dev->name);
drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c+1−1
@@ -1304,7 +1304,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, · 1303 unmodified lines
1304 solo_enc->vfd->queue = &solo_enc->vidq;1304 solo_enc->vfd->queue = &solo_enc->vidq;
1305 solo_enc->vfd->lock = &solo_enc->lock;1305 solo_enc->vfd->lock = &solo_enc->lock;
1306 video_set_drvdata(solo_enc->vfd, solo_enc);1306 video_set_drvdata(solo_enc->vfd, solo_enc);
1307 ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr);1307 ret = video_register_device(solo_enc->vfd, VFL_TYPE_VIDEO, nr);
1308 if (ret < 0)1308 if (ret < 0)
1309 goto vdev_release;1309 goto vdev_release;
1310 1310
drivers/media/pci/solo6x10/solo6x10-v4l2.c+1−1
@@ -692,7 +692,7 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) · 691 unmodified lines
692 while (erase_off(solo_dev))692 while (erase_off(solo_dev))
693 /* Do nothing */;693 /* Do nothing */;
694 694
695 ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr);695 ret = video_register_device(solo_dev->vfd, VFL_TYPE_VIDEO, nr);
696 if (ret < 0)696 if (ret < 0)
697 goto fail;697 goto fail;
698 698
drivers/media/pci/sta2x11/sta2x11_vip.c+1−1
@@ -1069,7 +1069,7 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev, · 1068 unmodified lines
1069 vip->video_dev.lock = &vip->v4l_lock;1069 vip->video_dev.lock = &vip->v4l_lock;
1070 video_set_drvdata(&vip->video_dev, vip);1070 video_set_drvdata(&vip->video_dev, vip);
1071 1071
1072 ret = video_register_device(&vip->video_dev, VFL_TYPE_GRABBER, -1);1072 ret = video_register_device(&vip->video_dev, VFL_TYPE_VIDEO, -1);
1073 if (ret)1073 if (ret)
1074 goto vrelease;1074 goto vrelease;
1075 1075
drivers/media/pci/ttpci/av7110_v4l.c+1−1
@@ -831,7 +831,7 @@ int av7110_init_v4l(struct av7110 *av7110) · 830 unmodified lines
831 if (FW_VERSION(av7110->arm_app) < 0x2623)831 if (FW_VERSION(av7110->arm_app) < 0x2623)
832 vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;832 vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;
833 833
834 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {834 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_VIDEO)) {
835 ERR("cannot register capture device. skipping\n");835 ERR("cannot register capture device. skipping\n");
836 saa7146_vv_release(dev);836 saa7146_vv_release(dev);
837 return -ENODEV;837 return -ENODEV;
drivers/media/pci/ttpci/budget-av.c+1−1
@@ -1470,7 +1470,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio · 1469 unmodified lines
1470 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;1470 vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
1471 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;1471 vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
1472 1472
1473 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {1473 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
1474 /* fixme: proper cleanup here */1474 /* fixme: proper cleanup here */
1475 ERR("cannot register capture v4l2 device\n");1475 ERR("cannot register capture v4l2 device\n");
1476 saa7146_vv_release(dev);1476 saa7146_vv_release(dev);
drivers/media/pci/tw5864/tw5864-video.c+1−1
@@ -1156,7 +1156,7 @@ static int tw5864_video_input_init(struct tw5864_input *input, int video_nr) · 1155 unmodified lines
1156 input->gop = GOP_SIZE;1156 input->gop = GOP_SIZE;
1157 input->frame_interval = 1;1157 input->frame_interval = 1;
1158 1158
1159 ret = video_register_device(&input->vdev, VFL_TYPE_GRABBER, video_nr);1159 ret = video_register_device(&input->vdev, VFL_TYPE_VIDEO, video_nr);
1160 if (ret)1160 if (ret)
1161 goto free_v4l2_hdl;1161 goto free_v4l2_hdl;
1162 1162
drivers/media/pci/tw68/tw68-video.c+1−1
@@ -962,7 +962,7 @@ int tw68_video_init2(struct tw68_dev *dev, int video_nr) · 961 unmodified lines
962 dev->vdev.lock = &dev->lock;962 dev->vdev.lock = &dev->lock;
963 dev->vdev.queue = &dev->vidq;963 dev->vdev.queue = &dev->vidq;
964 video_set_drvdata(&dev->vdev, dev);964 video_set_drvdata(&dev->vdev, dev);
965 return video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);965 return video_register_device(&dev->vdev, VFL_TYPE_VIDEO, video_nr);
966}966}
967 967
968/*968/*
drivers/media/pci/tw686x/tw686x-video.c+1−1
@@ -1282,7 +1282,7 @@ int tw686x_video_init(struct tw686x_dev *dev) · 1281 unmodified lines
1282 vc->device = vdev;1282 vc->device = vdev;
1283 video_set_drvdata(vdev, vc);1283 video_set_drvdata(vdev, vc);
1284 1284
1285 err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1285 err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1286 if (err < 0)1286 if (err < 0)
1287 goto error;1287 goto error;
1288 vc->num = vdev->num;1288 vc->num = vdev->num;
drivers/media/platform/Kconfig+49−37
@@ -507,6 +507,18 @@ config VIDEO_SUN8I_DEINTERLACE · 506 unmodified lines
507 capability found on some SoCs, like H3.507 capability found on some SoCs, like H3.
508 To compile this driver as a module choose m here.508 To compile this driver as a module choose m here.
509 509
510config VIDEO_SUN8I_ROTATE
511 tristate "Allwinner DE2 rotation driver"
512 depends on VIDEO_DEV && VIDEO_V4L2
513 depends on ARCH_SUNXI || COMPILE_TEST
514 depends on COMMON_CLK && OF
515 depends on PM
516 select VIDEOBUF2_DMA_CONTIG
517 select V4L2_MEM2MEM_DEV
518 help
519 Support for the Allwinner DE2 rotation unit.
520 To compile this driver as a module choose m here.
521
510endif # V4L_MEM2MEM_DRIVERS522endif # V4L_MEM2MEM_DRIVERS
511 523
512# TI VIDEO PORT Helper Modules524# TI VIDEO PORT Helper Modules
@@ -610,49 +622,49 @@ config CEC_GPIO · 97 unmodified lines
610 between compatible devices.622 between compatible devices.
611 623
612config VIDEO_SAMSUNG_S5P_CEC624config VIDEO_SAMSUNG_S5P_CEC
613 tristate "Samsung S5P CEC driver"625 tristate "Samsung S5P CEC driver"
614 depends on ARCH_EXYNOS || COMPILE_TEST626 depends on ARCH_EXYNOS || COMPILE_TEST
615 select CEC_CORE627 select CEC_CORE
616 select CEC_NOTIFIER628 select CEC_NOTIFIER
617 help629 help
618 This is a driver for Samsung S5P HDMI CEC interface. It uses the630 This is a driver for Samsung S5P HDMI CEC interface. It uses the
619 generic CEC framework interface.631 generic CEC framework interface.
620 CEC bus is present in the HDMI connector and enables communication632 CEC bus is present in the HDMI connector and enables communication
621 between compatible devices.633 between compatible devices.
622 634
623config VIDEO_STI_HDMI_CEC635config VIDEO_STI_HDMI_CEC
624 tristate "STMicroelectronics STiH4xx HDMI CEC driver"636 tristate "STMicroelectronics STiH4xx HDMI CEC driver"
625 depends on ARCH_STI || COMPILE_TEST637 depends on ARCH_STI || COMPILE_TEST
626 select CEC_CORE638 select CEC_CORE
627 select CEC_NOTIFIER639 select CEC_NOTIFIER
628 help640 help
629 This is a driver for STIH4xx HDMI CEC interface. It uses the641 This is a driver for STIH4xx HDMI CEC interface. It uses the
630 generic CEC framework interface.642 generic CEC framework interface.
631 CEC bus is present in the HDMI connector and enables communication643 CEC bus is present in the HDMI connector and enables communication
632 between compatible devices.644 between compatible devices.
633 645
634config VIDEO_STM32_HDMI_CEC646config VIDEO_STM32_HDMI_CEC
635 tristate "STMicroelectronics STM32 HDMI CEC driver"647 tristate "STMicroelectronics STM32 HDMI CEC driver"
636 depends on ARCH_STM32 || COMPILE_TEST648 depends on ARCH_STM32 || COMPILE_TEST
637 select REGMAP649 select REGMAP
638 select REGMAP_MMIO650 select REGMAP_MMIO
639 select CEC_CORE651 select CEC_CORE
640 help652 help
641 This is a driver for STM32 interface. It uses the653 This is a driver for STM32 interface. It uses the
642 generic CEC framework interface.654 generic CEC framework interface.
643 CEC bus is present in the HDMI connector and enables communication655 CEC bus is present in the HDMI connector and enables communication
644 between compatible devices.656 between compatible devices.
645 657
646config VIDEO_TEGRA_HDMI_CEC658config VIDEO_TEGRA_HDMI_CEC
647 tristate "Tegra HDMI CEC driver"659 tristate "Tegra HDMI CEC driver"
648 depends on ARCH_TEGRA || COMPILE_TEST660 depends on ARCH_TEGRA || COMPILE_TEST
649 select CEC_CORE661 select CEC_CORE
650 select CEC_NOTIFIER662 select CEC_NOTIFIER
651 help663 help
652 This is a driver for the Tegra HDMI CEC interface. It uses the664 This is a driver for the Tegra HDMI CEC interface. It uses the
653 generic CEC framework interface.665 generic CEC framework interface.
654 The CEC bus is present in the HDMI connector and enables communication666 The CEC bus is present in the HDMI connector and enables communication
655 between compatible devices.667 between compatible devices.
656 668
657config VIDEO_SECO_CEC669config VIDEO_SECO_CEC
658 tristate "SECO Boards HDMI CEC driver"670 tristate "SECO Boards HDMI CEC driver"
drivers/media/platform/am437x/am437x-vpfe.c+7−6
@@ -285,6 +285,7 @@ vpfe_ccdc_validate_param(struct vpfe_ccdc *ccdc, · 284 unmodified lines
285 max_data = ccdc_data_size_max_bit(ccdcparam->data_sz);285 max_data = ccdc_data_size_max_bit(ccdcparam->data_sz);
286 286
287 if (ccdcparam->alaw.gamma_wd > VPFE_CCDC_GAMMA_BITS_09_0 ||287 if (ccdcparam->alaw.gamma_wd > VPFE_CCDC_GAMMA_BITS_09_0 ||
288 ccdcparam->data_sz > VPFE_CCDC_DATA_8BITS ||
288 max_gamma > max_data) {289 max_gamma > max_data) {
289 vpfe_dbg(1, vpfe, "Invalid data line select\n");290 vpfe_dbg(1, vpfe, "Invalid data line select\n");
290 return -EINVAL;291 return -EINVAL;
@@ -324,7 +325,7 @@ static void vpfe_ccdc_restore_defaults(struct vpfe_ccdc *ccdc) · 33 unmodified lines
324 325
325static int vpfe_ccdc_close(struct vpfe_ccdc *ccdc, struct device *dev)326static int vpfe_ccdc_close(struct vpfe_ccdc *ccdc, struct device *dev)
326{327{
327 struct vpfe_device *vpfe = container_of(ccdc, struct vpfe_device, ccdc);328 struct vpfe_device *vpfe = to_vpfe(ccdc);
328 u32 dma_cntl, pcr;329 u32 dma_cntl, pcr;
329 330
330 pcr = vpfe_reg_read(ccdc, VPFE_PCR);331 pcr = vpfe_reg_read(ccdc, VPFE_PCR);
@@ -348,7 +349,7 @@ static int vpfe_ccdc_close(struct vpfe_ccdc *ccdc, struct device *dev) · 17 unmodified lines
348 349
349static int vpfe_ccdc_set_params(struct vpfe_ccdc *ccdc, void __user *params)350static int vpfe_ccdc_set_params(struct vpfe_ccdc *ccdc, void __user *params)
350{351{
351 struct vpfe_device *vpfe = container_of(ccdc, struct vpfe_device, ccdc);352 struct vpfe_device *vpfe = to_vpfe(ccdc);
352 struct vpfe_ccdc_config_params_raw raw_params;353 struct vpfe_ccdc_config_params_raw raw_params;
353 int x;354 int x;
354 355
@@ -504,7 +505,7 @@ vpfe_ccdc_config_black_compense(struct vpfe_ccdc *ccdc, · 149 unmodified lines
504 */505 */
505static void vpfe_ccdc_config_raw(struct vpfe_ccdc *ccdc)506static void vpfe_ccdc_config_raw(struct vpfe_ccdc *ccdc)
506{507{
507 struct vpfe_device *vpfe = container_of(ccdc, struct vpfe_device, ccdc);508 struct vpfe_device *vpfe = to_vpfe(ccdc);
508 struct vpfe_ccdc_config_params_raw *config_params =509 struct vpfe_ccdc_config_params_raw *config_params =
509 &ccdc->ccdc_cfg.bayer.config_params;510 &ccdc->ccdc_cfg.bayer.config_params;
510 struct ccdc_params_raw *params = &ccdc->ccdc_cfg.bayer;511 struct ccdc_params_raw *params = &ccdc->ccdc_cfg.bayer;
@@ -609,7 +610,7 @@ static inline enum ccdc_buftype vpfe_ccdc_get_buftype(struct vpfe_ccdc *ccdc) · 98 unmodified lines
609 610
610static int vpfe_ccdc_set_pixel_format(struct vpfe_ccdc *ccdc, u32 pixfmt)611static int vpfe_ccdc_set_pixel_format(struct vpfe_ccdc *ccdc, u32 pixfmt)
611{612{
612 struct vpfe_device *vpfe = container_of(ccdc, struct vpfe_device, ccdc);613 struct vpfe_device *vpfe = to_vpfe(ccdc);
613 614
614 vpfe_dbg(1, vpfe, "%s: if_type: %d, pixfmt:%s\n",615 vpfe_dbg(1, vpfe, "%s: if_type: %d, pixfmt:%s\n",
615 __func__, ccdc->ccdc_cfg.if_type, print_fourcc(pixfmt));616 __func__, ccdc->ccdc_cfg.if_type, print_fourcc(pixfmt));
@@ -741,7 +742,7 @@ static inline void vpfe_set_sdr_addr(struct vpfe_ccdc *ccdc, unsigned long addr) · 125 unmodified lines
741static int vpfe_ccdc_set_hw_if_params(struct vpfe_ccdc *ccdc,742static int vpfe_ccdc_set_hw_if_params(struct vpfe_ccdc *ccdc,
742 struct vpfe_hw_if_param *params)743 struct vpfe_hw_if_param *params)
743{744{
744 struct vpfe_device *vpfe = container_of(ccdc, struct vpfe_device, ccdc);745 struct vpfe_device *vpfe = to_vpfe(ccdc);
745 746
746 ccdc->ccdc_cfg.if_type = params->if_type;747 ccdc->ccdc_cfg.if_type = params->if_type;
747 748
@@ -2267,7 +2268,7 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe) · 1519 unmodified lines
2267 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |2268 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
2268 V4L2_CAP_READWRITE;2269 V4L2_CAP_READWRITE;
2269 video_set_drvdata(vdev, vpfe);2270 video_set_drvdata(vdev, vpfe);
2270 err = video_register_device(&vpfe->video_dev, VFL_TYPE_GRABBER, -1);2271 err = video_register_device(&vpfe->video_dev, VFL_TYPE_VIDEO, -1);
2271 if (err) {2272 if (err) {
2272 vpfe_err(vpfe,2273 vpfe_err(vpfe,
2273 "Unable to register video device.\n");2274 "Unable to register video device.\n");
drivers/media/platform/aspeed-video.c+58−28
@@ -1,4 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0+1// SPDX-License-Identifier: GPL-2.0-or-later
2// Copyright 2020 IBM Corp.
3// Copyright (c) 2019-2020 Intel Corporation
2 4
3#include <linux/atomic.h>5#include <linux/atomic.h>
4#include <linux/bitfield.h>6#include <linux/bitfield.h>
@@ -72,11 +74,8 @@ · 67 unmodified lines
72#define VE_SEQ_CTRL_CAP_BUSY BIT(16)74#define VE_SEQ_CTRL_CAP_BUSY BIT(16)
73#define VE_SEQ_CTRL_COMP_BUSY BIT(18)75#define VE_SEQ_CTRL_COMP_BUSY BIT(18)
74 76
75#ifdef CONFIG_MACH_ASPEED_G577#define AST2500_VE_SEQ_CTRL_JPEG_MODE BIT(13)
76#define VE_SEQ_CTRL_JPEG_MODE BIT(13) /* AST2500 */78#define AST2400_VE_SEQ_CTRL_JPEG_MODE BIT(8)
77#else
78#define VE_SEQ_CTRL_JPEG_MODE BIT(8) /* AST2400 */
79#endif /* CONFIG_MACH_ASPEED_G5 */
80 79
81#define VE_CTRL 0x00880#define VE_CTRL 0x008
82#define VE_CTRL_HSYNC_POL BIT(0)81#define VE_CTRL_HSYNC_POL BIT(0)
@@ -133,7 +132,8 @@ · 50 unmodified lines
133#define VE_COMP_CTRL_HQ_DCT_CHR GENMASK(26, 22)132#define VE_COMP_CTRL_HQ_DCT_CHR GENMASK(26, 22)
134#define VE_COMP_CTRL_HQ_DCT_LUM GENMASK(31, 27)133#define VE_COMP_CTRL_HQ_DCT_LUM GENMASK(31, 27)
135 134
136#define VE_OFFSET_COMP_STREAM 0x078135#define AST2400_VE_COMP_SIZE_READ_BACK 0x078
136#define AST2600_VE_COMP_SIZE_READ_BACK 0x084
137 137
138#define VE_SRC_LR_EDGE_DET 0x090138#define VE_SRC_LR_EDGE_DET 0x090
139#define VE_SRC_LR_EDGE_DET_LEFT GENMASK(11, 0)139#define VE_SRC_LR_EDGE_DET_LEFT GENMASK(11, 0)
@@ -220,6 +220,9 @@ struct aspeed_video { · 80 unmodified lines
220 struct video_device vdev;220 struct video_device vdev;
221 struct mutex video_lock; /* v4l2 and videobuf2 lock */221 struct mutex video_lock; /* v4l2 and videobuf2 lock */
222 222
223 u32 jpeg_mode;
224 u32 comp_size_read;
225
223 wait_queue_head_t wait;226 wait_queue_head_t wait;
224 spinlock_t lock; /* buffer list lock */227 spinlock_t lock; /* buffer list lock */
225 struct delayed_work res_work;228 struct delayed_work res_work;
@@ -243,6 +246,26 @@ struct aspeed_video { · 17 unmodified lines
243 246
244#define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)247#define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
245 248
249struct aspeed_video_config {
250 u32 jpeg_mode;
251 u32 comp_size_read;
252};
253
254static const struct aspeed_video_config ast2400_config = {
255 .jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
256 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
257};
258
259static const struct aspeed_video_config ast2500_config = {
260 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
261 .comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
262};
263
264static const struct aspeed_video_config ast2600_config = {
265 .jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
266 .comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
267};
268
246static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {269static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] = {
247 0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,270 0xe0ffd8ff, 0x464a1000, 0x01004649, 0x60000101, 0x00006000, 0x0f00feff,
248 0x00002d05, 0x00000000, 0x00000000, 0x00dbff00271 0x00002d05, 0x00000000, 0x00000000, 0x00dbff00
@@ -572,7 +595,7 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) · 323 unmodified lines
572 if (sts & VE_INTERRUPT_COMP_COMPLETE) {595 if (sts & VE_INTERRUPT_COMP_COMPLETE) {
573 struct aspeed_video_buffer *buf;596 struct aspeed_video_buffer *buf;
574 u32 frame_size = aspeed_video_read(video,597 u32 frame_size = aspeed_video_read(video,
575 VE_OFFSET_COMP_STREAM);598 video->comp_size_read);
576 599
577 spin_lock(&video->lock);600 spin_lock(&video->lock);
578 clear_bit(VIDEO_FRAME_INPRG, &video->flags);601 clear_bit(VIDEO_FRAME_INPRG, &video->flags);
@@ -907,7 +930,7 @@ static void aspeed_video_init_regs(struct aspeed_video *video) · 328 unmodified lines
907 FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |930 FIELD_PREP(VE_COMP_CTRL_DCT_LUM, video->jpeg_quality) |
908 FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);931 FIELD_PREP(VE_COMP_CTRL_DCT_CHR, video->jpeg_quality | 0x10);
909 u32 ctrl = VE_CTRL_AUTO_OR_CURSOR;932 u32 ctrl = VE_CTRL_AUTO_OR_CURSOR;
910 u32 seq_ctrl = VE_SEQ_CTRL_JPEG_MODE;933 u32 seq_ctrl = video->jpeg_mode;
911 934
912 if (video->frame_rate)935 if (video->frame_rate)
913 ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);936 ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
@@ -1565,14 +1588,14 @@ static int aspeed_video_setup_video(struct aspeed_video *video) · 651 unmodified lines
1565 V4L2_CAP_STREAMING;1588 V4L2_CAP_STREAMING;
1566 vdev->v4l2_dev = v4l2_dev;1589 vdev->v4l2_dev = v4l2_dev;
1567 strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));1590 strscpy(vdev->name, DEVICE_NAME, sizeof(vdev->name));
1568 vdev->vfl_type = VFL_TYPE_GRABBER;1591 vdev->vfl_type = VFL_TYPE_VIDEO;
1569 vdev->vfl_dir = VFL_DIR_RX;1592 vdev->vfl_dir = VFL_DIR_RX;
1570 vdev->release = video_device_release_empty;1593 vdev->release = video_device_release_empty;
1571 vdev->ioctl_ops = &aspeed_video_ioctl_ops;1594 vdev->ioctl_ops = &aspeed_video_ioctl_ops;
1572 vdev->lock = &video->video_lock;1595 vdev->lock = &video->video_lock;
1573 1596
1574 video_set_drvdata(vdev, video);1597 video_set_drvdata(vdev, video);
1575 rc = video_register_device(vdev, VFL_TYPE_GRABBER, 0);1598 rc = video_register_device(vdev, VFL_TYPE_VIDEO, 0);
1576 if (rc) {1599 if (rc) {
1577 vb2_queue_release(vbq);1600 vb2_queue_release(vbq);
1578 v4l2_ctrl_handler_free(&video->ctrl_handler);1601 v4l2_ctrl_handler_free(&video->ctrl_handler);
@@ -1653,16 +1676,37 @@ err_unprepare_eclk: · 74 unmodified lines
1653 return rc;1676 return rc;
1654}1677}
1655 1678
1679static const struct of_device_id aspeed_video_of_match[] = {
1680 { .compatible = "aspeed,ast2400-video-engine", .data = &ast2400_config },
1681 { .compatible = "aspeed,ast2500-video-engine", .data = &ast2500_config },
1682 { .compatible = "aspeed,ast2600-video-engine", .data = &ast2600_config },
1683 {}
1684};
1685MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
1686
1656static int aspeed_video_probe(struct platform_device *pdev)1687static int aspeed_video_probe(struct platform_device *pdev)
1657{1688{
1689 const struct aspeed_video_config *config;
1690 const struct of_device_id *match;
1691 struct aspeed_video *video;
1658 int rc;1692 int rc;
1659 struct resource *res;
1660 struct aspeed_video *video =
1661 devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
1662 1693
1694 video = devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL);
1663 if (!video)1695 if (!video)
1664 return -ENOMEM;1696 return -ENOMEM;
1665 1697
1698 video->base = devm_platform_ioremap_resource(pdev, 0);
1699 if (IS_ERR(video->base))
1700 return PTR_ERR(video->base);
1701
1702 match = of_match_node(aspeed_video_of_match, pdev->dev.of_node);
1703 if (!match)
1704 return -EINVAL;
1705
1706 config = match->data;
1707 video->jpeg_mode = config->jpeg_mode;
1708 video->comp_size_read = config->comp_size_read;
1709
1666 video->frame_rate = 30;1710 video->frame_rate = 30;
1667 video->dev = &pdev->dev;1711 video->dev = &pdev->dev;
1668 spin_lock_init(&video->lock);1712 spin_lock_init(&video->lock);
@@ -1671,13 +1715,6 @@ static int aspeed_video_probe(struct platform_device *pdev) · 2 unmodified lines
1671 INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);1715 INIT_DELAYED_WORK(&video->res_work, aspeed_video_resolution_work);
1672 INIT_LIST_HEAD(&video->buffers);1716 INIT_LIST_HEAD(&video->buffers);
1673 1717
1674 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1675
1676 video->base = devm_ioremap_resource(video->dev, res);
1677
1678 if (IS_ERR(video->base))
1679 return PTR_ERR(video->base);
1680
1681 rc = aspeed_video_init(video);1718 rc = aspeed_video_init(video);
1682 if (rc)1719 if (rc)
1683 return rc;1720 return rc;
@@ -1716,13 +1753,6 @@ static int aspeed_video_remove(struct platform_device *pdev) · 32 unmodified lines
1716 return 0;1753 return 0;
1717}1754}
1718 1755
1719static const struct of_device_id aspeed_video_of_match[] = {
1720 { .compatible = "aspeed,ast2400-video-engine" },
1721 { .compatible = "aspeed,ast2500-video-engine" },
1722 {}
1723};
1724MODULE_DEVICE_TABLE(of, aspeed_video_of_match);
1725
1726static struct platform_driver aspeed_video_driver = {1756static struct platform_driver aspeed_video_driver = {
1727 .driver = {1757 .driver = {
1728 .name = DEVICE_NAME,1758 .name = DEVICE_NAME,
drivers/media/platform/atmel/atmel-isc-base.c+196−28
@@ -22,6 +22,7 @@ · 21 unmodified lines
22#include <linux/pm_runtime.h>22#include <linux/pm_runtime.h>
23#include <linux/regmap.h>23#include <linux/regmap.h>
24#include <linux/videodev2.h>24#include <linux/videodev2.h>
25#include <linux/atmel-isc-media.h>
25 26
26#include <media/v4l2-ctrls.h>27#include <media/v4l2-ctrls.h>
27#include <media/v4l2-device.h>28#include <media/v4l2-device.h>
@@ -224,10 +225,35 @@ const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = { · 196 unmodified lines
224 (((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \225 (((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \
225 (((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))226 (((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))
226 227
228#define ISC_CTRL_ISC_TO_V4L2(x) ((x) == ISC_WB_O_ZERO_VAL ? 0 : (x))
229#define ISC_CTRL_V4L2_TO_ISC(x) ((x) ? (x) : ISC_WB_O_ZERO_VAL)
230
231static inline void isc_update_v4l2_ctrls(struct isc_device *isc)
232{
233 struct isc_ctrls *ctrls = &isc->ctrls;
234
235 /* In here we set the v4l2 controls w.r.t. our pipeline config */
236 v4l2_ctrl_s_ctrl(isc->r_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_R]);
237 v4l2_ctrl_s_ctrl(isc->b_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_B]);
238 v4l2_ctrl_s_ctrl(isc->gr_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GR]);
239 v4l2_ctrl_s_ctrl(isc->gb_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GB]);
240
241 v4l2_ctrl_s_ctrl(isc->r_off_ctrl,
242 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_R]));
243 v4l2_ctrl_s_ctrl(isc->b_off_ctrl,
244 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_B]));
245 v4l2_ctrl_s_ctrl(isc->gr_off_ctrl,
246 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_GR]));
247 v4l2_ctrl_s_ctrl(isc->gb_off_ctrl,
248 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_GB]));
249}
250
227static inline void isc_update_awb_ctrls(struct isc_device *isc)251static inline void isc_update_awb_ctrls(struct isc_device *isc)
228{252{
229 struct isc_ctrls *ctrls = &isc->ctrls;253 struct isc_ctrls *ctrls = &isc->ctrls;
230 254
255 /* In here we set our actual hw pipeline config */
256
231 regmap_write(isc->regmap, ISC_WB_O_RGR,257 regmap_write(isc->regmap, ISC_WB_O_RGR,
232 (ISC_WB_O_ZERO_VAL - (ctrls->offset[ISC_HIS_CFG_MODE_R])) |258 (ISC_WB_O_ZERO_VAL - (ctrls->offset[ISC_HIS_CFG_MODE_R])) |
233 ((ISC_WB_O_ZERO_VAL - ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));259 ((ISC_WB_O_ZERO_VAL - ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));
@@ -662,11 +688,9 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) · 428 unmodified lines
662 688
663 bay_cfg = isc->config.sd_format->cfa_baycfg;689 bay_cfg = isc->config.sd_format->cfa_baycfg;
664 690
665 if (ctrls->awb == ISC_WB_NONE)
666 isc_reset_awb_ctrls(isc);
667
668 regmap_write(regmap, ISC_WB_CFG, bay_cfg);691 regmap_write(regmap, ISC_WB_CFG, bay_cfg);
669 isc_update_awb_ctrls(isc);692 isc_update_awb_ctrls(isc);
693 isc_update_v4l2_ctrls(isc);
670 694
671 regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL);695 regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL);
672 696
@@ -1396,6 +1420,7 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) · 723 unmodified lines
1396 isc->try_config.sd_format != isc->config.sd_format) {1420 isc->try_config.sd_format != isc->config.sd_format) {
1397 isc->ctrls.hist_stat = HIST_INIT;1421 isc->ctrls.hist_stat = HIST_INIT;
1398 isc_reset_awb_ctrls(isc);1422 isc_reset_awb_ctrls(isc);
1423 isc_update_v4l2_ctrls(isc);
1399 }1424 }
1400 /* make the try configuration active */1425 /* make the try configuration active */
1401 isc->config = isc->try_config;1426 isc->config = isc->try_config;
@@ -1814,10 +1839,6 @@ static void isc_awb_work(struct work_struct *w) · 412 unmodified lines
1814 ctrls->hist_id = hist_id;1839 ctrls->hist_id = hist_id;
1815 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;1840 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
1816 1841
1817 /* if no more auto white balance, reset controls. */
1818 if (ctrls->awb == ISC_WB_NONE)
1819 isc_reset_awb_ctrls(isc);
1820
1821 pm_runtime_get_sync(isc->dev);1842 pm_runtime_get_sync(isc->dev);
1822 1843
1823 /*1844 /*
@@ -1842,6 +1863,8 @@ static void isc_awb_work(struct work_struct *w) · 18 unmodified lines
1842 if (ctrls->awb == ISC_WB_ONETIME) {1863 if (ctrls->awb == ISC_WB_ONETIME) {
1843 v4l2_info(&isc->v4l2_dev,1864 v4l2_info(&isc->v4l2_dev,
1844 "Completed one time white-balance adjustment.\n");1865 "Completed one time white-balance adjustment.\n");
1866 /* update the v4l2 controls values */
1867 isc_update_v4l2_ctrls(isc);
1845 ctrls->awb = ISC_WB_NONE;1868 ctrls->awb = ISC_WB_NONE;
1846 }1869 }
1847 }1870 }
@@ -1873,6 +1896,27 @@ static int isc_s_ctrl(struct v4l2_ctrl *ctrl) · 25 unmodified lines
1873 case V4L2_CID_GAMMA:1896 case V4L2_CID_GAMMA:
1874 ctrls->gamma_index = ctrl->val;1897 ctrls->gamma_index = ctrl->val;
1875 break;1898 break;
1899 default:
1900 return -EINVAL;
1901 }
1902
1903 return 0;
1904}
1905
1906static const struct v4l2_ctrl_ops isc_ctrl_ops = {
1907 .s_ctrl = isc_s_ctrl,
1908};
1909
1910static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
1911{
1912 struct isc_device *isc = container_of(ctrl->handler,
1913 struct isc_device, ctrls.handler);
1914 struct isc_ctrls *ctrls = &isc->ctrls;
1915
1916 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
1917 return 0;
1918
1919 switch (ctrl->id) {
1876 case V4L2_CID_AUTO_WHITE_BALANCE:1920 case V4L2_CID_AUTO_WHITE_BALANCE:
1877 if (ctrl->val == 1)1921 if (ctrl->val == 1)
1878 ctrls->awb = ISC_WB_AUTO;1922 ctrls->awb = ISC_WB_AUTO;
@@ -1883,36 +1927,142 @@ static int isc_s_ctrl(struct v4l2_ctrl *ctrl) · 4 unmodified lines
1883 if (!isc->config.sd_format)1927 if (!isc->config.sd_format)
1884 break;1928 break;
1885 1929
1886 if (ctrls->hist_stat != HIST_ENABLED)1930 /* configure the controls with new values from v4l2 */
1887 isc_reset_awb_ctrls(isc);1931 if (ctrl->cluster[ISC_CTRL_R_GAIN]->is_new)
1932 ctrls->gain[ISC_HIS_CFG_MODE_R] = isc->r_gain_ctrl->val;
1933 if (ctrl->cluster[ISC_CTRL_B_GAIN]->is_new)
1934 ctrls->gain[ISC_HIS_CFG_MODE_B] = isc->b_gain_ctrl->val;
1935 if (ctrl->cluster[ISC_CTRL_GR_GAIN]->is_new)
1936 ctrls->gain[ISC_HIS_CFG_MODE_GR] = isc->gr_gain_ctrl->val;
1937 if (ctrl->cluster[ISC_CTRL_GB_GAIN]->is_new)
1938 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val;
1939
1940 if (ctrl->cluster[ISC_CTRL_R_OFF]->is_new)
1941 ctrls->offset[ISC_HIS_CFG_MODE_R] =
1942 ISC_CTRL_V4L2_TO_ISC(isc->r_off_ctrl->val);
1943 if (ctrl->cluster[ISC_CTRL_B_OFF]->is_new)
1944 ctrls->offset[ISC_HIS_CFG_MODE_B] =
1945 ISC_CTRL_V4L2_TO_ISC(isc->b_off_ctrl->val);
1946 if (ctrl->cluster[ISC_CTRL_GR_OFF]->is_new)
1947 ctrls->offset[ISC_HIS_CFG_MODE_GR] =
1948 ISC_CTRL_V4L2_TO_ISC(isc->gr_off_ctrl->val);
1949 if (ctrl->cluster[ISC_CTRL_GB_OFF]->is_new)
1950 ctrls->offset[ISC_HIS_CFG_MODE_GB] =
1951 ISC_CTRL_V4L2_TO_ISC(isc->gb_off_ctrl->val);
1888 1952
1889 if (isc->ctrls.awb == ISC_WB_AUTO &&1953 isc_update_awb_ctrls(isc);
1954
1955 if (vb2_is_streaming(&isc->vb2_vidq)) {
1956 /*
1957 * If we are streaming, we can update profile to
1958 * have the new settings in place.
1959 */
1960 isc_update_profile(isc);
1961 } else {
1962 /*
1963 * The auto cluster will activate automatically this
1964 * control. This has to be deactivated when not
1965 * streaming.
1966 */
1967 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
1968 }
1969
1970 /* if we have autowhitebalance on, start histogram procedure */
1971 if (ctrls->awb == ISC_WB_AUTO &&
1890 vb2_is_streaming(&isc->vb2_vidq) &&1972 vb2_is_streaming(&isc->vb2_vidq) &&
1891 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))1973 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
1892 isc_set_histogram(isc, true);1974 isc_set_histogram(isc, true);
1893 1975
1894 break;1976 /*
1895 case V4L2_CID_DO_WHITE_BALANCE:1977 * for one time whitebalance adjustment, check the button,
1896 /* if AWB is enabled, do nothing */1978 * if it's pressed, perform the one time operation.
1897 if (ctrls->awb == ISC_WB_AUTO)1979 */
1898 return 0;1980 if (ctrls->awb == ISC_WB_NONE &&
1981 ctrl->cluster[ISC_CTRL_DO_WB]->is_new &&
1982 !(ctrl->cluster[ISC_CTRL_DO_WB]->flags &
1983 V4L2_CTRL_FLAG_INACTIVE)) {
1984 ctrls->awb = ISC_WB_ONETIME;
1985 isc_set_histogram(isc, true);
1986 v4l2_dbg(1, debug, &isc->v4l2_dev,
1987 "One time white-balance started.\n");
1988 }
1989 return 0;
1990 }
1991 return 0;
1992}
1899 1993
1900 ctrls->awb = ISC_WB_ONETIME;1994static int isc_g_volatile_awb_ctrl(struct v4l2_ctrl *ctrl)
1901 isc_set_histogram(isc, true);1995{
1902 v4l2_dbg(1, debug, &isc->v4l2_dev,1996 struct isc_device *isc = container_of(ctrl->handler,
1903 "One time white-balance started.\n");1997 struct isc_device, ctrls.handler);
1998 struct isc_ctrls *ctrls = &isc->ctrls;
1999
2000 switch (ctrl->id) {
2001 /* being a cluster, this id will be called for every control */
2002 case V4L2_CID_AUTO_WHITE_BALANCE:
2003 ctrl->cluster[ISC_CTRL_R_GAIN]->val =
2004 ctrls->gain[ISC_HIS_CFG_MODE_R];
2005 ctrl->cluster[ISC_CTRL_B_GAIN]->val =
2006 ctrls->gain[ISC_HIS_CFG_MODE_B];
2007 ctrl->cluster[ISC_CTRL_GR_GAIN]->val =
2008 ctrls->gain[ISC_HIS_CFG_MODE_GR];
2009 ctrl->cluster[ISC_CTRL_GB_GAIN]->val =
2010 ctrls->gain[ISC_HIS_CFG_MODE_GB];
2011
2012 ctrl->cluster[ISC_CTRL_R_OFF]->val =
2013 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_R]);
2014 ctrl->cluster[ISC_CTRL_B_OFF]->val =
2015 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_B]);
2016 ctrl->cluster[ISC_CTRL_GR_OFF]->val =
2017 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_GR]);
2018 ctrl->cluster[ISC_CTRL_GB_OFF]->val =
2019 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_GB]);
1904 break;2020 break;
1905 default:
1906 return -EINVAL;
1907 }2021 }
1908
1909 return 0;2022 return 0;
1910}2023}
1911 2024
1912static const struct v4l2_ctrl_ops isc_ctrl_ops = {2025static const struct v4l2_ctrl_ops isc_awb_ops = {
1913 .s_ctrl = isc_s_ctrl,2026 .s_ctrl = isc_s_awb_ctrl,
2027 .g_volatile_ctrl = isc_g_volatile_awb_ctrl,
1914};2028};
1915 2029
2030#define ISC_CTRL_OFF(_name, _id, _name_str) \
2031 static const struct v4l2_ctrl_config _name = { \
2032 .ops = &isc_awb_ops, \
2033 .id = _id, \
2034 .name = _name_str, \
2035 .type = V4L2_CTRL_TYPE_INTEGER, \
2036 .flags = V4L2_CTRL_FLAG_SLIDER, \
2037 .min = -4095, \
2038 .max = 4095, \
2039 .step = 1, \
2040 .def = 0, \
2041 }
2042
2043ISC_CTRL_OFF(isc_r_off_ctrl, ISC_CID_R_OFFSET, "Red Component Offset");
2044ISC_CTRL_OFF(isc_b_off_ctrl, ISC_CID_B_OFFSET, "Blue Component Offset");
2045ISC_CTRL_OFF(isc_gr_off_ctrl, ISC_CID_GR_OFFSET, "Green Red Component Offset");
2046ISC_CTRL_OFF(isc_gb_off_ctrl, ISC_CID_GB_OFFSET, "Green Blue Component Offset");
2047
2048#define ISC_CTRL_GAIN(_name, _id, _name_str) \
2049 static const struct v4l2_ctrl_config _name = { \
2050 .ops = &isc_awb_ops, \
2051 .id = _id, \
2052 .name = _name_str, \
2053 .type = V4L2_CTRL_TYPE_INTEGER, \
2054 .flags = V4L2_CTRL_FLAG_SLIDER, \
2055 .min = 0, \
2056 .max = 8191, \
2057 .step = 1, \
2058 .def = 512, \
2059 }
2060
2061ISC_CTRL_GAIN(isc_r_gain_ctrl, ISC_CID_R_GAIN, "Red Component Gain");
2062ISC_CTRL_GAIN(isc_b_gain_ctrl, ISC_CID_B_GAIN, "Blue Component Gain");
2063ISC_CTRL_GAIN(isc_gr_gain_ctrl, ISC_CID_GR_GAIN, "Green Red Component Gain");
2064ISC_CTRL_GAIN(isc_gb_gain_ctrl, ISC_CID_GB_GAIN, "Green Blue Component Gain");
2065
1916static int isc_ctrl_init(struct isc_device *isc)2066static int isc_ctrl_init(struct isc_device *isc)
1917{2067{
1918 const struct v4l2_ctrl_ops *ops = &isc_ctrl_ops;2068 const struct v4l2_ctrl_ops *ops = &isc_ctrl_ops;
@@ -1923,7 +2073,7 @@ static int isc_ctrl_init(struct isc_device *isc) · 4 unmodified lines
1923 ctrls->hist_stat = HIST_INIT;2073 ctrls->hist_stat = HIST_INIT;
1924 isc_reset_awb_ctrls(isc);2074 isc_reset_awb_ctrls(isc);
1925 2075
1926 ret = v4l2_ctrl_handler_init(hdl, 5);2076 ret = v4l2_ctrl_handler_init(hdl, 13);
1927 if (ret < 0)2077 if (ret < 0)
1928 return ret;2078 return ret;
1929 2079
@@ -1933,10 +2083,13 @@ static int isc_ctrl_init(struct isc_device *isc) · 3 unmodified lines
1933 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0);2083 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0);
1934 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256);2084 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256);
1935 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2);2085 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2);
1936 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);2086 isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops,
2087 V4L2_CID_AUTO_WHITE_BALANCE,
2088 0, 1, 1, 1);
1937 2089
1938 /* do_white_balance is a button, so min,max,step,default are ignored */2090 /* do_white_balance is a button, so min,max,step,default are ignored */
1939 isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DO_WHITE_BALANCE,2091 isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops,
2092 V4L2_CID_DO_WHITE_BALANCE,
1940 0, 0, 0, 0);2093 0, 0, 0, 0);
1941 2094
1942 if (!isc->do_wb_ctrl) {2095 if (!isc->do_wb_ctrl) {
@@ -1947,6 +2100,21 @@ static int isc_ctrl_init(struct isc_device *isc) · 4 unmodified lines
1947 2100
1948 v4l2_ctrl_activate(isc->do_wb_ctrl, false);2101 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
1949 2102
2103 isc->r_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_gain_ctrl, NULL);
2104 isc->b_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_gain_ctrl, NULL);
2105 isc->gr_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_gain_ctrl, NULL);
2106 isc->gb_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_gain_ctrl, NULL);
2107 isc->r_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_off_ctrl, NULL);
2108 isc->b_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_off_ctrl, NULL);
2109 isc->gr_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_off_ctrl, NULL);
2110 isc->gb_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_off_ctrl, NULL);
2111
2112 /*
2113 * The cluster is in auto mode with autowhitebalance enabled
2114 * and manual mode otherwise.
2115 */
2116 v4l2_ctrl_auto_cluster(10, &isc->awb_ctrl, 0, true);
2117
1950 v4l2_ctrl_handler_setup(hdl);2118 v4l2_ctrl_handler_setup(hdl);
1951 2119
1952 return 0;2120 return 0;
@@ -2143,7 +2311,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) · 190 unmodified lines
2143 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;2311 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
2144 video_set_drvdata(vdev, isc);2312 video_set_drvdata(vdev, isc);
2145 2313
2146 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);2314 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
2147 if (ret < 0) {2315 if (ret < 0) {
2148 v4l2_err(&isc->v4l2_dev,2316 v4l2_err(&isc->v4l2_dev,
2149 "video_register_device failed: %d\n", ret);2317 "video_register_device failed: %d\n", ret);
drivers/media/platform/atmel/atmel-isc.h+22−1
@@ -213,7 +213,6 @@ struct isc_device { · 212 unmodified lines
213 struct fmt_config try_config;213 struct fmt_config try_config;
214 214
215 struct isc_ctrls ctrls;215 struct isc_ctrls ctrls;
216 struct v4l2_ctrl *do_wb_ctrl;
217 struct work_struct awb_work;216 struct work_struct awb_work;
218 217
219 struct mutex lock; /* serialize access to file operations */218 struct mutex lock; /* serialize access to file operations */
@@ -223,6 +222,28 @@ struct isc_device { · 3 unmodified lines
223 222
224 struct isc_subdev_entity *current_subdev;223 struct isc_subdev_entity *current_subdev;
225 struct list_head subdev_entities;224 struct list_head subdev_entities;
225
226 struct {
227#define ISC_CTRL_DO_WB 1
228#define ISC_CTRL_R_GAIN 2
229#define ISC_CTRL_B_GAIN 3
230#define ISC_CTRL_GR_GAIN 4
231#define ISC_CTRL_GB_GAIN 5
232#define ISC_CTRL_R_OFF 6
233#define ISC_CTRL_B_OFF 7
234#define ISC_CTRL_GR_OFF 8
235#define ISC_CTRL_GB_OFF 9
236 struct v4l2_ctrl *awb_ctrl;
237 struct v4l2_ctrl *do_wb_ctrl;
238 struct v4l2_ctrl *r_gain_ctrl;
239 struct v4l2_ctrl *b_gain_ctrl;
240 struct v4l2_ctrl *gr_gain_ctrl;
241 struct v4l2_ctrl *gb_gain_ctrl;
242 struct v4l2_ctrl *r_off_ctrl;
243 struct v4l2_ctrl *b_off_ctrl;
244 struct v4l2_ctrl *gr_off_ctrl;
245 struct v4l2_ctrl *gb_off_ctrl;
246 };
226};247};
227 248
228#define GAMMA_MAX 2249#define GAMMA_MAX 2
drivers/media/platform/atmel/atmel-isi.c+1−1
@@ -1094,7 +1094,7 @@ static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier) · 1093 unmodified lines
1094 return ret;1094 return ret;
1095 }1095 }
1096 1096
1097 ret = video_register_device(isi->vdev, VFL_TYPE_GRABBER, -1);1097 ret = video_register_device(isi->vdev, VFL_TYPE_VIDEO, -1);
1098 if (ret) {1098 if (ret) {
1099 dev_err(isi->dev, "Failed to register video device\n");1099 dev_err(isi->dev, "Failed to register video device\n");
1100 return ret;1100 return ret;
drivers/media/platform/coda/coda-common.c+1−1
@@ -2726,7 +2726,7 @@ static int coda_register_device(struct coda_dev *dev, int i) · 2725 unmodified lines
2726 v4l2_disable_ioctl(vfd, VIDIOC_G_CROP);2726 v4l2_disable_ioctl(vfd, VIDIOC_G_CROP);
2727 v4l2_disable_ioctl(vfd, VIDIOC_S_CROP);2727 v4l2_disable_ioctl(vfd, VIDIOC_S_CROP);
2728 2728
2729 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);2729 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2730 if (!ret)2730 if (!ret)
2731 v4l2_info(&dev->v4l2_dev, "%s registered as %s\n",2731 v4l2_info(&dev->v4l2_dev, "%s registered as %s\n",
2732 type == CODA_INST_ENCODER ? "encoder" : "decoder",2732 type == CODA_INST_ENCODER ? "encoder" : "decoder",
drivers/media/platform/davinci/isif.c+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
29#include "ccdc_hw_device.h"29#include "ccdc_hw_device.h"
30 30
31/* Defaults for module configuration parameters */31/* Defaults for module configuration parameters */
32static struct isif_config_params_raw isif_config_defaults = {32static const struct isif_config_params_raw isif_config_defaults = {
33 .linearize = {33 .linearize = {
34 .en = 0,34 .en = 0,
35 .corr_shft = ISIF_NO_SHIFT,35 .corr_shft = ISIF_NO_SHIFT,
drivers/media/platform/davinci/vpbe_display.c+1−1
@@ -1339,7 +1339,7 @@ static int register_device(struct vpbe_layer *vpbe_display_layer, · 1338 unmodified lines
1339 1339
1340 vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;1340 vpbe_display_layer->video_dev.queue = &vpbe_display_layer->buffer_queue;
1341 err = video_register_device(&vpbe_display_layer->video_dev,1341 err = video_register_device(&vpbe_display_layer->video_dev,
1342 VFL_TYPE_GRABBER,1342 VFL_TYPE_VIDEO,
1343 -1);1343 -1);
1344 if (err)1344 if (err)
1345 return -ENODEV;1345 return -ENODEV;
drivers/media/platform/davinci/vpfe_capture.c+2−2
@@ -880,7 +880,7 @@ static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv, · 879 unmodified lines
880 /* Fill in the information about format */880 /* Fill in the information about format */
881 pix_fmt = vpfe_lookup_pix_format(pix);881 pix_fmt = vpfe_lookup_pix_format(pix);
882 if (pix_fmt) {882 if (pix_fmt) {
883 fmt->pixelformat = fmt->pixelformat;883 fmt->pixelformat = pix_fmt->pixelformat;
884 return 0;884 return 0;
885 }885 }
886 return -EINVAL;886 return -EINVAL;
@@ -1780,7 +1780,7 @@ static int vpfe_probe(struct platform_device *pdev) · 893 unmodified lines
1780 "video_dev=%p\n", &vpfe_dev->video_dev);1780 "video_dev=%p\n", &vpfe_dev->video_dev);
1781 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1781 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1782 ret = video_register_device(&vpfe_dev->video_dev,1782 ret = video_register_device(&vpfe_dev->video_dev,
1783 VFL_TYPE_GRABBER, -1);1783 VFL_TYPE_VIDEO, -1);
1784 1784
1785 if (ret) {1785 if (ret) {
1786 v4l2_err(pdev->dev.driver,1786 v4l2_err(pdev->dev.driver,
drivers/media/platform/davinci/vpif_capture.c+1−1
@@ -1466,7 +1466,7 @@ static int vpif_probe_complete(void) · 1465 unmodified lines
1466 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;1466 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1467 video_set_drvdata(&ch->video_dev, ch);1467 video_set_drvdata(&ch->video_dev, ch);
1468 err = video_register_device(vdev,1468 err = video_register_device(vdev,
1469 VFL_TYPE_GRABBER, (j ? 1 : 0));1469 VFL_TYPE_VIDEO, (j ? 1 : 0));
1470 if (err)1470 if (err)
1471 goto probe_out;1471 goto probe_out;
1472 }1472 }
drivers/media/platform/davinci/vpif_display.c+1−1
@@ -1214,7 +1214,7 @@ static int vpif_probe_complete(void) · 1213 unmodified lines
1214 vdev->lock = &common->lock;1214 vdev->lock = &common->lock;
1215 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;1215 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
1216 video_set_drvdata(&ch->video_dev, ch);1216 video_set_drvdata(&ch->video_dev, ch);
1217 err = video_register_device(vdev, VFL_TYPE_GRABBER,1217 err = video_register_device(vdev, VFL_TYPE_VIDEO,
1218 (j ? 3 : 2));1218 (j ? 3 : 2));
1219 if (err < 0)1219 if (err < 0)
1220 goto probe_out;1220 goto probe_out;
drivers/media/platform/exynos-gsc/gsc-m2m.c+1−1
@@ -771,7 +771,7 @@ int gsc_register_m2m_device(struct gsc_dev *gsc) · 770 unmodified lines
771 return PTR_ERR(gsc->m2m.m2m_dev);771 return PTR_ERR(gsc->m2m.m2m_dev);
772 }772 }
773 773
774 ret = video_register_device(&gsc->vdev, VFL_TYPE_GRABBER, -1);774 ret = video_register_device(&gsc->vdev, VFL_TYPE_VIDEO, -1);
775 if (ret) {775 if (ret) {
776 dev_err(&pdev->dev,776 dev_err(&pdev->dev,
777 "%s(): failed to register video device\n", __func__);777 "%s(): failed to register video device\n", __func__);
drivers/media/platform/exynos4-is/Kconfig+1−1
@@ -13,7 +13,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS · 12 unmodified lines
13if VIDEO_SAMSUNG_EXYNOS4_IS13if VIDEO_SAMSUNG_EXYNOS4_IS
14 14
15config VIDEO_EXYNOS4_IS_COMMON15config VIDEO_EXYNOS4_IS_COMMON
16 tristate16 tristate
17 17
18config VIDEO_S5P_FIMC18config VIDEO_S5P_FIMC
19 tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"19 tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
drivers/media/platform/exynos4-is/fimc-capture.c+1−1
@@ -1808,7 +1808,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, · 1807 unmodified lines
1808 if (ret)1808 if (ret)
1809 goto err_me_cleanup;1809 goto err_me_cleanup;
1810 1810
1811 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);1811 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
1812 if (ret)1812 if (ret)
1813 goto err_ctrl_free;1813 goto err_ctrl_free;
1814 1814
drivers/media/platform/exynos4-is/fimc-isp-video.c+1−1
@@ -619,7 +619,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp, · 618 unmodified lines
619 619
620 video_set_drvdata(vdev, isp);620 video_set_drvdata(vdev, isp);
621 621
622 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);622 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
623 if (ret < 0) {623 if (ret < 0) {
624 media_entity_cleanup(&vdev->entity);624 media_entity_cleanup(&vdev->entity);
625 return ret;625 return ret;
drivers/media/platform/exynos4-is/fimc-lite.c+4−1
@@ -1297,7 +1297,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) · 1296 unmodified lines
1297 video_set_drvdata(vfd, fimc);1297 video_set_drvdata(vfd, fimc);
1298 fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);1298 fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);
1299 1299
1300 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);1300 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
1301 if (ret < 0) {1301 if (ret < 0) {
1302 media_entity_cleanup(&vfd->entity);1302 media_entity_cleanup(&vfd->entity);
1303 fimc->ve.pipe = NULL;1303 fimc->ve.pipe = NULL;
@@ -1614,6 +1614,9 @@ static int fimc_lite_remove(struct platform_device *pdev) · 310 unmodified lines
1614 struct fimc_lite *fimc = platform_get_drvdata(pdev);1614 struct fimc_lite *fimc = platform_get_drvdata(pdev);
1615 struct device *dev = &pdev->dev;1615 struct device *dev = &pdev->dev;
1616 1616
1617 if (!pm_runtime_enabled(dev))
1618 clk_disable_unprepare(fimc->clock);
1619
1617 pm_runtime_disable(dev);1620 pm_runtime_disable(dev);
1618 pm_runtime_set_suspended(dev);1621 pm_runtime_set_suspended(dev);
1619 fimc_lite_unregister_capture_subdev(fimc);1622 fimc_lite_unregister_capture_subdev(fimc);
drivers/media/platform/exynos4-is/fimc-m2m.c+1−1
@@ -746,7 +746,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, · 745 unmodified lines
746 if (ret)746 if (ret)
747 goto err_me;747 goto err_me;
748 748
749 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);749 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
750 if (ret)750 if (ret)
751 goto err_vd;751 goto err_vd;
752 752
drivers/media/platform/fsl-viu.c+1−1
@@ -1486,7 +1486,7 @@ static int viu_of_probe(struct platform_device *op) · 1485 unmodified lines
1486 1486
1487 mutex_lock(&viu_dev->lock);1487 mutex_lock(&viu_dev->lock);
1488 1488
1489 ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);1489 ret = video_register_device(viu_dev->vdev, VFL_TYPE_VIDEO, -1);
1490 if (ret < 0) {1490 if (ret < 0) {
1491 video_device_release(viu_dev->vdev);1491 video_device_release(viu_dev->vdev);
1492 goto err_unlock;1492 goto err_unlock;
drivers/media/platform/imx-pxp.c+1−1
@@ -1709,7 +1709,7 @@ static int pxp_probe(struct platform_device *pdev) · 1708 unmodified lines
1709 goto err_v4l2;1709 goto err_v4l2;
1710 }1710 }
1711 1711
1712 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);1712 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
1713 if (ret) {1713 if (ret) {
1714 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");1714 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1715 goto err_m2m;1715 goto err_m2m;
drivers/media/platform/m2m-deinterlace.c+1−1
@@ -953,7 +953,7 @@ static int deinterlace_probe(struct platform_device *pdev) · 952 unmodified lines
953 vfd->lock = &pcdev->dev_mutex;953 vfd->lock = &pcdev->dev_mutex;
954 vfd->v4l2_dev = &pcdev->v4l2_dev;954 vfd->v4l2_dev = &pcdev->v4l2_dev;
955 955
956 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);956 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
957 if (ret) {957 if (ret) {
958 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");958 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
959 goto unreg_dev;959 goto unreg_dev;
drivers/media/platform/marvell-ccic/mcam-core.c+1−1
@@ -1802,7 +1802,7 @@ static int mccic_notify_bound(struct v4l2_async_notifier *notifier, · 1801 unmodified lines
1802 cam->vdev.lock = &cam->s_mutex;1802 cam->vdev.lock = &cam->s_mutex;
1803 cam->vdev.queue = &cam->vb_queue;1803 cam->vdev.queue = &cam->vb_queue;
1804 video_set_drvdata(&cam->vdev, cam);1804 video_set_drvdata(&cam->vdev, cam);
1805 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);1805 ret = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
1806 if (ret) {1806 if (ret) {
1807 cam->sensor = NULL;1807 cam->sensor = NULL;
1808 goto out;1808 goto out;
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c+1−1
@@ -1150,7 +1150,7 @@ static int mtk_jpeg_probe(struct platform_device *pdev) · 1149 unmodified lines
1150 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |1150 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
1151 V4L2_CAP_VIDEO_M2M_MPLANE;1151 V4L2_CAP_VIDEO_M2M_MPLANE;
1152 1152
1153 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_GRABBER, 3);1153 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_VIDEO, 3);
1154 if (ret) {1154 if (ret) {
1155 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");1155 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1156 goto err_dec_vdev_register;1156 goto err_dec_vdev_register;
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c+6−0
@@ -110,6 +110,12 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node, · 109 unmodified lines
110 110
111 for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {111 for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
112 comp->clk[i] = of_clk_get(node, i);112 comp->clk[i] = of_clk_get(node, i);
113 if (IS_ERR(comp->clk[i])) {
114 if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
115 dev_err(dev, "Failed to get clock\n");
116
117 return PTR_ERR(comp->clk[i]);
118 }
113 119
114 /* Only RDMA needs two clocks */120 /* Only RDMA needs two clocks */
115 if (comp->type != MTK_MDP_RDMA)121 if (comp->type != MTK_MDP_RDMA)
drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c+1−1
@@ -1229,7 +1229,7 @@ int mtk_mdp_register_m2m_device(struct mtk_mdp_dev *mdp) · 1228 unmodified lines
1229 goto err_m2m_init;1229 goto err_m2m_init;
1230 }1230 }
1231 1231
1232 ret = video_register_device(mdp->vdev, VFL_TYPE_GRABBER, 2);1232 ret = video_register_device(mdp->vdev, VFL_TYPE_VIDEO, 2);
1233 if (ret) {1233 if (ret) {
1234 dev_err(dev, "failed to register video device\n");1234 dev_err(dev, "failed to register video device\n");
1235 goto err_vdev_register;1235 goto err_vdev_register;
drivers/media/platform/mtk-mdp/mtk_mdp_vpu.c+5−4
@@ -15,7 +15,7 @@ static inline struct mtk_mdp_ctx *vpu_to_ctx(struct mtk_mdp_vpu *vpu) · 14 unmodified lines
15 return container_of(vpu, struct mtk_mdp_ctx, vpu);15 return container_of(vpu, struct mtk_mdp_ctx, vpu);
16}16}
17 17
18static void mtk_mdp_vpu_handle_init_ack(struct mdp_ipi_comm_ack *msg)18static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg)
19{19{
20 struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)20 struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)
21 (unsigned long)msg->ap_inst;21 (unsigned long)msg->ap_inst;
@@ -26,10 +26,11 @@ static void mtk_mdp_vpu_handle_init_ack(struct mdp_ipi_comm_ack *msg) · 4 unmodified lines
26 vpu->inst_addr = msg->vpu_inst_addr;26 vpu->inst_addr = msg->vpu_inst_addr;
27}27}
28 28
29static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len, void *priv)29static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len,
30 void *priv)
30{31{
31 unsigned int msg_id = *(unsigned int *)data;32 const struct mdp_ipi_comm_ack *msg = data;
32 struct mdp_ipi_comm_ack *msg = (struct mdp_ipi_comm_ack *)data;33 unsigned int msg_id = msg->msg_id;
33 struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)34 struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)
34 (unsigned long)msg->ap_inst;35 (unsigned long)msg->ap_inst;
35 struct mtk_mdp_ctx *ctx;36 struct mtk_mdp_ctx *ctx;
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c+1−1
@@ -331,7 +331,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) · 330 unmodified lines
331 goto err_event_workq;331 goto err_event_workq;
332 }332 }
333 333
334 ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 0);334 ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0);
335 if (ret) {335 if (ret) {
336 mtk_v4l2_err("Failed to register video device");336 mtk_v4l2_err("Failed to register video device");
337 goto err_dec_reg;337 goto err_dec_reg;
drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c+1−1
@@ -356,7 +356,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) · 355 unmodified lines
356 goto err_event_workq;356 goto err_event_workq;
357 }357 }
358 358
359 ret = video_register_device(vfd_enc, VFL_TYPE_GRABBER, 1);359 ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, 1);
360 if (ret) {360 if (ret) {
361 mtk_v4l2_err("Failed to register video device");361 mtk_v4l2_err("Failed to register video device");
362 goto err_enc_reg;362 goto err_enc_reg;
drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c+25−4
@@ -110,7 +110,11 @@ struct vp9_sf_ref_fb { · 109 unmodified lines
110 * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W)110 * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W)
111 111
112 * @profile : profile sparsed from vpu (AP-R, VPU-W)112 * @profile : profile sparsed from vpu (AP-R, VPU-W)
113 * @show_frame : display this frame or not (AP-R, VPU-W)113 * @show_frame : [BIT(0)] display this frame or not (AP-R, VPU-W)
114 * [BIT(1)] reset segment data or not (AP-R, VPU-W)
115 * [BIT(2)] trig decoder hardware or not (AP-R, VPU-W)
116 * [BIT(3)] ask VPU to set bits(0~4) accordingly (AP-W, VPU-R)
117 * [BIT(4)] do not reset segment data before every frame (AP-R, VPU-W)
114 * @show_existing_frame : inform this frame is show existing frame118 * @show_existing_frame : inform this frame is show existing frame
115 * (AP-R, VPU-W)119 * (AP-R, VPU-W)
116 * @frm_to_show_idx : index to show frame (AP-R, VPU-W)120 * @frm_to_show_idx : index to show frame (AP-R, VPU-W)
@@ -494,12 +498,12 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) · 377 unmodified lines
494 frm_to_show->fb->base_y.size);498 frm_to_show->fb->base_y.size);
495 }499 }
496 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {500 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
497 if (vsi->show_frame)501 if (vsi->show_frame & BIT(0))
498 vp9_add_to_fb_disp_list(inst, inst->cur_fb);502 vp9_add_to_fb_disp_list(inst, inst->cur_fb);
499 }503 }
500 } else {504 } else {
501 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {505 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
502 if (vsi->show_frame)506 if (vsi->show_frame & BIT(0))
503 vp9_add_to_fb_disp_list(inst, frm_to_show->fb);507 vp9_add_to_fb_disp_list(inst, frm_to_show->fb);
504 }508 }
505 }509 }
@@ -800,6 +804,9 @@ static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx) · 294 unmodified lines
800 }804 }
801 805
802 inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi;806 inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi;
807
808 inst->vsi->show_frame |= BIT(3);
809
803 init_all_fb_lists(inst);810 init_all_fb_lists(inst);
804 811
805 ctx->drv_handle = inst;812 ctx->drv_handle = inst;
@@ -870,13 +877,27 @@ static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs, · 64 unmodified lines
870 vsi->sf_frm_sz[idx]);877 vsi->sf_frm_sz[idx]);
871 }878 }
872 }879 }
873 memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size);880
881 if (!(vsi->show_frame & BIT(4)))
882 memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size);
883
874 ret = vpu_dec_start(&inst->vpu, data, 3);884 ret = vpu_dec_start(&inst->vpu, data, 3);
875 if (ret) {885 if (ret) {
876 mtk_vcodec_err(inst, "vpu_dec_start failed");886 mtk_vcodec_err(inst, "vpu_dec_start failed");
877 goto DECODE_ERROR;887 goto DECODE_ERROR;
878 }888 }
879 889
890 if (vsi->show_frame & BIT(1)) {
891 memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size);
892
893 if (vsi->show_frame & BIT(2)) {
894 if (vpu_dec_start(&inst->vpu, NULL, 0)) {
895 mtk_vcodec_err(inst, "vpu trig decoder failed");
896 goto DECODE_ERROR;
897 }
898 }
899 }
900
880 ret = validate_vsi_array_indexes(inst, vsi);901 ret = validate_vsi_array_indexes(inst, vsi);
881 if (ret) {902 if (ret) {
882 mtk_vcodec_err(inst, "Invalid values from VPU.");903 mtk_vcodec_err(inst, "Invalid values from VPU.");
drivers/media/platform/mtk-vcodec/vdec_vpu_if.c+3−3
@@ -9,7 +9,7 @@ · 8 unmodified lines
9#include "vdec_ipi_msg.h"9#include "vdec_ipi_msg.h"
10#include "vdec_vpu_if.h"10#include "vdec_vpu_if.h"
11 11
12static void handle_init_ack_msg(struct vdec_vpu_ipi_init_ack *msg)12static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
13{13{
14 struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)14 struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
15 (unsigned long)msg->ap_inst_addr;15 (unsigned long)msg->ap_inst_addr;
@@ -34,9 +34,9 @@ static void handle_init_ack_msg(struct vdec_vpu_ipi_init_ack *msg) · 18 unmodified lines
34 * This function runs in interrupt context and it means there's an IPI MSG34 * This function runs in interrupt context and it means there's an IPI MSG
35 * from VPU.35 * from VPU.
36 */36 */
37static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)37static void vpu_dec_ipi_handler(const void *data, unsigned int len, void *priv)
38{38{
39 struct vdec_vpu_ipi_ack *msg = data;39 const struct vdec_vpu_ipi_ack *msg = data;
40 struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)40 struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
41 (unsigned long)msg->ap_inst_addr;41 (unsigned long)msg->ap_inst_addr;
42 42
drivers/media/platform/mtk-vcodec/venc_vpu_if.c+6−6
@@ -8,26 +8,26 @@ · 7 unmodified lines
8#include "venc_ipi_msg.h"8#include "venc_ipi_msg.h"
9#include "venc_vpu_if.h"9#include "venc_vpu_if.h"
10 10
11static void handle_enc_init_msg(struct venc_vpu_inst *vpu, void *data)11static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
12{12{
13 struct venc_vpu_ipi_msg_init *msg = data;13 const struct venc_vpu_ipi_msg_init *msg = data;
14 14
15 vpu->inst_addr = msg->vpu_inst_addr;15 vpu->inst_addr = msg->vpu_inst_addr;
16 vpu->vsi = vpu_mapping_dm_addr(vpu->dev, msg->vpu_inst_addr);16 vpu->vsi = vpu_mapping_dm_addr(vpu->dev, msg->vpu_inst_addr);
17}17}
18 18
19static void handle_enc_encode_msg(struct venc_vpu_inst *vpu, void *data)19static void handle_enc_encode_msg(struct venc_vpu_inst *vpu, const void *data)
20{20{
21 struct venc_vpu_ipi_msg_enc *msg = data;21 const struct venc_vpu_ipi_msg_enc *msg = data;
22 22
23 vpu->state = msg->state;23 vpu->state = msg->state;
24 vpu->bs_size = msg->bs_size;24 vpu->bs_size = msg->bs_size;
25 vpu->is_key_frm = msg->is_key_frm;25 vpu->is_key_frm = msg->is_key_frm;
26}26}
27 27
28static void vpu_enc_ipi_handler(void *data, unsigned int len, void *priv)28static void vpu_enc_ipi_handler(const void *data, unsigned int len, void *priv)
29{29{
30 struct venc_vpu_ipi_msg_common *msg = data;30 const struct venc_vpu_ipi_msg_common *msg = data;
31 struct venc_vpu_inst *vpu =31 struct venc_vpu_inst *vpu =
32 (struct venc_vpu_inst *)(unsigned long)msg->venc_inst;32 (struct venc_vpu_inst *)(unsigned long)msg->venc_inst;
33 33
drivers/media/platform/mtk-vpu/mtk_vpu.c+36−25
@@ -46,6 +46,8 @@ · 45 unmodified lines
46/* binary firmware name */46/* binary firmware name */
47#define VPU_P_FW "vpu_p.bin"47#define VPU_P_FW "vpu_p.bin"
48#define VPU_D_FW "vpu_d.bin"48#define VPU_D_FW "vpu_d.bin"
49#define VPU_P_FW_NEW "mediatek/mt8173/vpu_p.bin"
50#define VPU_D_FW_NEW "mediatek/mt8173/vpu_d.bin"
49 51
50#define VPU_RESET 0x052#define VPU_RESET 0x0
51#define VPU_TCM_CFG 0x000853#define VPU_TCM_CFG 0x0008
@@ -203,8 +205,8 @@ struct mtk_vpu { · 151 unmodified lines
203 struct vpu_run run;205 struct vpu_run run;
204 struct vpu_wdt wdt;206 struct vpu_wdt wdt;
205 struct vpu_ipi_desc ipi_desc[IPI_MAX];207 struct vpu_ipi_desc ipi_desc[IPI_MAX];
206 struct share_obj *recv_buf;208 struct share_obj __iomem *recv_buf;
207 struct share_obj *send_buf;209 struct share_obj __iomem *send_buf;
208 struct device *dev;210 struct device *dev;
209 struct clk *clk;211 struct clk *clk;
210 bool fw_loaded;212 bool fw_loaded;
@@ -292,7 +294,7 @@ int vpu_ipi_send(struct platform_device *pdev, · 81 unmodified lines
292 unsigned int len)294 unsigned int len)
293{295{
294 struct mtk_vpu *vpu = platform_get_drvdata(pdev);296 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
295 struct share_obj *send_obj = vpu->send_buf;297 struct share_obj __iomem *send_obj = vpu->send_buf;
296 unsigned long timeout;298 unsigned long timeout;
297 int ret = 0;299 int ret = 0;
298 300
@@ -325,9 +327,9 @@ int vpu_ipi_send(struct platform_device *pdev, · 26 unmodified lines
325 }327 }
326 } while (vpu_cfg_readl(vpu, HOST_TO_VPU));328 } while (vpu_cfg_readl(vpu, HOST_TO_VPU));
327 329
328 memcpy((void *)send_obj->share_buf, buf, len);330 memcpy_toio(send_obj->share_buf, buf, len);
329 send_obj->len = len;331 writel(len, &send_obj->len);
330 send_obj->id = id;332 writel(id, &send_obj->id);
331 333
332 vpu->ipi_id_ack[id] = false;334 vpu->ipi_id_ack[id] = false;
333 /* send the command to VPU */335 /* send the command to VPU */
@@ -477,16 +479,24 @@ static int load_requested_vpu(struct mtk_vpu *vpu, · 143 unmodified lines
477 size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE;479 size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE;
478 size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE;480 size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE;
479 char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW;481 char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW;
482 char *fw_new_name = fw_type ? VPU_D_FW_NEW : VPU_P_FW_NEW;
480 const struct firmware *vpu_fw;483 const struct firmware *vpu_fw;
481 size_t dl_size = 0;484 size_t dl_size = 0;
482 size_t extra_fw_size = 0;485 size_t extra_fw_size = 0;
483 void *dest;486 void *dest;
484 int ret;487 int ret;
485 488
486 ret = request_firmware(&vpu_fw, fw_name, vpu->dev);489 ret = request_firmware(&vpu_fw, fw_new_name, vpu->dev);
487 if (ret < 0) {490 if (ret < 0) {
488 dev_err(vpu->dev, "Failed to load %s, %d\n", fw_name, ret);491 dev_info(vpu->dev, "Failed to load %s, %d, retry\n",
489 return ret;492 fw_new_name, ret);
493
494 ret = request_firmware(&vpu_fw, fw_name, vpu->dev);
495 if (ret < 0) {
496 dev_err(vpu->dev, "Failed to load %s, %d\n", fw_name,
497 ret);
498 return ret;
499 }
490 }500 }
491 dl_size = vpu_fw->size;501 dl_size = vpu_fw->size;
492 if (dl_size > fw_size) {502 if (dl_size > fw_size) {
@@ -600,10 +610,10 @@ OUT_LOAD_FW: · 107 unmodified lines
600}610}
601EXPORT_SYMBOL_GPL(vpu_load_firmware);611EXPORT_SYMBOL_GPL(vpu_load_firmware);
602 612
603static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)613static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv)
604{614{
605 struct mtk_vpu *vpu = (struct mtk_vpu *)priv;615 struct mtk_vpu *vpu = priv;
606 struct vpu_run *run = (struct vpu_run *)data;616 const struct vpu_run *run = data;
607 617
608 vpu->run.signaled = run->signaled;618 vpu->run.signaled = run->signaled;
609 strscpy(vpu->run.fw_ver, run->fw_ver, sizeof(vpu->run.fw_ver));619 strscpy(vpu->run.fw_ver, run->fw_ver, sizeof(vpu->run.fw_ver));
@@ -700,19 +710,21 @@ static int vpu_alloc_ext_mem(struct mtk_vpu *vpu, u32 fw_type) · 90 unmodified lines
700 710
701static void vpu_ipi_handler(struct mtk_vpu *vpu)711static void vpu_ipi_handler(struct mtk_vpu *vpu)
702{712{
703 struct share_obj *rcv_obj = vpu->recv_buf;713 struct share_obj __iomem *rcv_obj = vpu->recv_buf;
704 struct vpu_ipi_desc *ipi_desc = vpu->ipi_desc;714 struct vpu_ipi_desc *ipi_desc = vpu->ipi_desc;
705 715 unsigned char data[SHARE_BUF_SIZE];
706 if (rcv_obj->id < IPI_MAX && ipi_desc[rcv_obj->id].handler) {716 s32 id = readl(&rcv_obj->id);
707 ipi_desc[rcv_obj->id].handler(rcv_obj->share_buf,717
708 rcv_obj->len,718 memcpy_fromio(data, rcv_obj->share_buf, sizeof(data));
709 ipi_desc[rcv_obj->id].priv);719 if (id < IPI_MAX && ipi_desc[id].handler) {
710 if (rcv_obj->id > IPI_VPU_INIT) {720 ipi_desc[id].handler(data, readl(&rcv_obj->len),
711 vpu->ipi_id_ack[rcv_obj->id] = true;721 ipi_desc[id].priv);
722 if (id > IPI_VPU_INIT) {
723 vpu->ipi_id_ack[id] = true;
712 wake_up(&vpu->ack_wq);724 wake_up(&vpu->ack_wq);
713 }725 }
714 } else {726 } else {
715 dev_err(vpu->dev, "No such ipi id = %d\n", rcv_obj->id);727 dev_err(vpu->dev, "No such ipi id = %d\n", id);
716 }728 }
717}729}
718 730
@@ -722,11 +734,10 @@ static int vpu_ipi_init(struct mtk_vpu *vpu) · 3 unmodified lines
722 vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);734 vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
723 735
724 /* shared buffer initialization */736 /* shared buffer initialization */
725 vpu->recv_buf = (__force struct share_obj *)(vpu->reg.tcm +737 vpu->recv_buf = vpu->reg.tcm + VPU_DTCM_OFFSET;
726 VPU_DTCM_OFFSET);
727 vpu->send_buf = vpu->recv_buf + 1;738 vpu->send_buf = vpu->recv_buf + 1;
728 memset(vpu->recv_buf, 0, sizeof(struct share_obj));739 memset_io(vpu->recv_buf, 0, sizeof(struct share_obj));
729 memset(vpu->send_buf, 0, sizeof(struct share_obj));740 memset_io(vpu->send_buf, 0, sizeof(struct share_obj));
730 741
731 return 0;742 return 0;
732}743}
drivers/media/platform/mtk-vpu/mtk_vpu.h+1−1
@@ -15,7 +15,7 @@ · 14 unmodified lines
15 * VPU interfaces with other blocks by share memory and interrupt.15 * VPU interfaces with other blocks by share memory and interrupt.
16 **/16 **/
17 17
18typedef void (*ipi_handler_t) (void *data,18typedef void (*ipi_handler_t) (const void *data,
19 unsigned int len,19 unsigned int len,
20 void *priv);20 void *priv);
21 21
drivers/media/platform/mx2_emmaprp.c+1−1
@@ -866,7 +866,7 @@ static int emmaprp_probe(struct platform_device *pdev) · 865 unmodified lines
866 goto rel_vdev;866 goto rel_vdev;
867 }867 }
868 868
869 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);869 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
870 if (ret) {870 if (ret) {
871 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");871 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
872 goto rel_m2m;872 goto rel_m2m;
drivers/media/platform/omap/omap_vout.c+1−1
@@ -1500,7 +1500,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) · 1499 unmodified lines
1500 /* Register the Video device with V4L21500 /* Register the Video device with V4L2
1501 */1501 */
1502 vfd = vout->vfd;1502 vfd = vout->vfd;
1503 if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {1503 if (video_register_device(vfd, VFL_TYPE_VIDEO, -1) < 0) {
1504 dev_err(&pdev->dev,1504 dev_err(&pdev->dev,
1505 ": Could not register Video for Linux device\n");1505 ": Could not register Video for Linux device\n");
1506 vfd->minor = -1;1506 vfd->minor = -1;
drivers/media/platform/omap3isp/ispccdc.c+4−0
@@ -1312,6 +1312,10 @@ static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable) · 1311 unmodified lines
1312{1312{
1313 struct isp_device *isp = to_isp_device(ccdc);1313 struct isp_device *isp = to_isp_device(ccdc);
1314 1314
1315 /* Avoid restarting the CCDC when streaming is stopping. */
1316 if (enable && ccdc->stopping & CCDC_STOP_REQUEST)
1317 return;
1318
1315 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,1319 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,
1316 ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);1320 ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);
1317 1321
drivers/media/platform/omap3isp/ispvideo.c+4−4
@@ -1311,7 +1311,7 @@ static int isp_video_open(struct file *file) · 1310 unmodified lines
1311 goto done;1311 goto done;
1312 }1312 }
1313 1313
1314 ret = v4l2_pipeline_pm_use(&video->video.entity, 1);1314 ret = v4l2_pipeline_pm_get(&video->video.entity);
1315 if (ret < 0) {1315 if (ret < 0) {
1316 omap3isp_put(video->isp);1316 omap3isp_put(video->isp);
1317 goto done;1317 goto done;
@@ -1363,7 +1363,7 @@ static int isp_video_release(struct file *file) · 45 unmodified lines
1363 vb2_queue_release(&handle->queue);1363 vb2_queue_release(&handle->queue);
1364 mutex_unlock(&video->queue_lock);1364 mutex_unlock(&video->queue_lock);
1365 1365
1366 v4l2_pipeline_pm_use(&video->video.entity, 0);1366 v4l2_pipeline_pm_put(&video->video.entity);
1367 1367
1368 /* Release the file handle. */1368 /* Release the file handle. */
1369 v4l2_fh_del(vfh);1369 v4l2_fh_del(vfh);
@@ -1453,7 +1453,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name) · 83 unmodified lines
1453 video->video.fops = &isp_video_fops;1453 video->video.fops = &isp_video_fops;
1454 snprintf(video->video.name, sizeof(video->video.name),1454 snprintf(video->video.name, sizeof(video->video.name),
1455 "OMAP3 ISP %s %s", name, direction);1455 "OMAP3 ISP %s %s", name, direction);
1456 video->video.vfl_type = VFL_TYPE_GRABBER;1456 video->video.vfl_type = VFL_TYPE_VIDEO;
1457 video->video.release = video_device_release_empty;1457 video->video.release = video_device_release_empty;
1458 video->video.ioctl_ops = &isp_video_ioctl_ops;1458 video->video.ioctl_ops = &isp_video_ioctl_ops;
1459 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)1459 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1484,7 +1484,7 @@ int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev) · 24 unmodified lines
1484 1484
1485 video->video.v4l2_dev = vdev;1485 video->video.v4l2_dev = vdev;
1486 1486
1487 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);1487 ret = video_register_device(&video->video, VFL_TYPE_VIDEO, -1);
1488 if (ret < 0)1488 if (ret < 0)
1489 dev_err(video->isp->dev,1489 dev_err(video->isp->dev,
1490 "%s: could not register video device (%d)\n",1490 "%s: could not register video device (%d)\n",
drivers/media/platform/pxa_camera.c+11−11
@@ -2191,7 +2191,7 @@ static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, · 2190 unmodified lines
2191 if (err)2191 if (err)
2192 goto out_sensor_poweroff;2192 goto out_sensor_poweroff;
2193 2193
2194 err = video_register_device(&pcdev->vdev, VFL_TYPE_GRABBER, -1);2194 err = video_register_device(&pcdev->vdev, VFL_TYPE_VIDEO, -1);
2195 if (err) {2195 if (err) {
2196 v4l2_err(v4l2_dev, "register video device failed: %d\n", err);2196 v4l2_err(v4l2_dev, "register video device failed: %d\n", err);
2197 pcdev->sensor = NULL;2197 pcdev->sensor = NULL;
@@ -2440,23 +2440,23 @@ static int pxa_camera_probe(struct platform_device *pdev) · 242 unmodified lines
2440 pcdev->base = base;2440 pcdev->base = base;
2441 2441
2442 /* request dma */2442 /* request dma */
2443 pcdev->dma_chans[0] = dma_request_slave_channel(&pdev->dev, "CI_Y");2443 pcdev->dma_chans[0] = dma_request_chan(&pdev->dev, "CI_Y");
2444 if (!pcdev->dma_chans[0]) {2444 if (IS_ERR(pcdev->dma_chans[0])) {
2445 dev_err(&pdev->dev, "Can't request DMA for Y\n");2445 dev_err(&pdev->dev, "Can't request DMA for Y\n");
2446 return -ENODEV;2446 return PTR_ERR(pcdev->dma_chans[0]);
2447 }2447 }
2448 2448
2449 pcdev->dma_chans[1] = dma_request_slave_channel(&pdev->dev, "CI_U");2449 pcdev->dma_chans[1] = dma_request_chan(&pdev->dev, "CI_U");
2450 if (!pcdev->dma_chans[1]) {2450 if (IS_ERR(pcdev->dma_chans[1])) {
2451 dev_err(&pdev->dev, "Can't request DMA for Y\n");2451 dev_err(&pdev->dev, "Can't request DMA for U\n");
2452 err = -ENODEV;2452 err = PTR_ERR(pcdev->dma_chans[1]);
2453 goto exit_free_dma_y;2453 goto exit_free_dma_y;
2454 }2454 }
2455 2455
2456 pcdev->dma_chans[2] = dma_request_slave_channel(&pdev->dev, "CI_V");2456 pcdev->dma_chans[2] = dma_request_chan(&pdev->dev, "CI_V");
2457 if (!pcdev->dma_chans[2]) {2457 if (IS_ERR(pcdev->dma_chans[2])) {
2458 dev_err(&pdev->dev, "Can't request DMA for V\n");2458 dev_err(&pdev->dev, "Can't request DMA for V\n");
2459 err = -ENODEV;2459 err = PTR_ERR(pcdev->dma_chans[2]);
2460 goto exit_free_dma_u;2460 goto exit_free_dma_u;
2461 }2461 }
2462 2462
drivers/media/platform/qcom/camss/camss-video.c+3−3
@@ -745,7 +745,7 @@ static int video_open(struct file *file) · 744 unmodified lines
745 745
746 file->private_data = vfh;746 file->private_data = vfh;
747 747
748 ret = v4l2_pipeline_pm_use(&vdev->entity, 1);748 ret = v4l2_pipeline_pm_get(&vdev->entity);
749 if (ret < 0) {749 if (ret < 0) {
750 dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",750 dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
751 ret);751 ret);
@@ -771,7 +771,7 @@ static int video_release(struct file *file) · 19 unmodified lines
771 771
772 vb2_fop_release(file);772 vb2_fop_release(file);
773 773
774 v4l2_pipeline_pm_use(&vdev->entity, 0);774 v4l2_pipeline_pm_put(&vdev->entity);
775 775
776 file->private_data = NULL;776 file->private_data = NULL;
777 777
@@ -921,7 +921,7 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, · 143 unmodified lines
921 vdev->lock = &video->lock;921 vdev->lock = &video->lock;
922 strscpy(vdev->name, name, sizeof(vdev->name));922 strscpy(vdev->name, name, sizeof(vdev->name));
923 923
924 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);924 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
925 if (ret < 0) {925 if (ret < 0) {
926 dev_err(v4l2_dev->dev, "Failed to register video device: %d\n",926 dev_err(v4l2_dev->dev, "Failed to register video device: %d\n",
927 ret);927 ret);
drivers/media/platform/qcom/venus/Makefile+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 3
4venus-core-objs += core.o helpers.o firmware.o \4venus-core-objs += core.o helpers.o firmware.o \
5 hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \5 hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
6 hfi_parser.o6 hfi_parser.o pm_helpers.o
7 7
8venus-dec-objs += vdec.o vdec_ctrls.o8venus-dec-objs += vdec.o vdec_ctrls.o
9venus-enc-objs += venc.o venc_ctrls.o9venus-enc-objs += venc.o venc_ctrls.o
drivers/media/platform/qcom/venus/core.c+104−63
@@ -3,7 +3,6 @@ · 2 unmodified lines
3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2017 Linaro Ltd.4 * Copyright (C) 2017 Linaro Ltd.
5 */5 */
6#include <linux/clk.h>
7#include <linux/init.h>6#include <linux/init.h>
8#include <linux/interconnect.h>7#include <linux/interconnect.h>
9#include <linux/ioctl.h>8#include <linux/ioctl.h>
@@ -19,9 +18,8 @@ · 9 unmodified lines
19#include <media/v4l2-ioctl.h>18#include <media/v4l2-ioctl.h>
20 19
21#include "core.h"20#include "core.h"
22#include "vdec.h"
23#include "venc.h"
24#include "firmware.h"21#include "firmware.h"
22#include "pm_helpers.h"
25 23
26static void venus_event_notify(struct venus_core *core, u32 event)24static void venus_event_notify(struct venus_core *core, u32 event)
27{25{
@@ -100,50 +98,6 @@ static void venus_sys_error_handler(struct work_struct *work) · 72 unmodified lines
100 mutex_unlock(&core->lock);98 mutex_unlock(&core->lock);
101}99}
102 100
103static int venus_clks_get(struct venus_core *core)
104{
105 const struct venus_resources *res = core->res;
106 struct device *dev = core->dev;
107 unsigned int i;
108
109 for (i = 0; i < res->clks_num; i++) {
110 core->clks[i] = devm_clk_get(dev, res->clks[i]);
111 if (IS_ERR(core->clks[i]))
112 return PTR_ERR(core->clks[i]);
113 }
114
115 return 0;
116}
117
118static int venus_clks_enable(struct venus_core *core)
119{
120 const struct venus_resources *res = core->res;
121 unsigned int i;
122 int ret;
123
124 for (i = 0; i < res->clks_num; i++) {
125 ret = clk_prepare_enable(core->clks[i]);
126 if (ret)
127 goto err;
128 }
129
130 return 0;
131err:
132 while (i--)
133 clk_disable_unprepare(core->clks[i]);
134
135 return ret;
136}
137
138static void venus_clks_disable(struct venus_core *core)
139{
140 const struct venus_resources *res = core->res;
141 unsigned int i = res->clks_num;
142
143 while (i--)
144 clk_disable_unprepare(core->clks[i]);
145}
146
147static u32 to_v4l2_codec_type(u32 codec)101static u32 to_v4l2_codec_type(u32 codec)
148{102{
149 switch (codec) {103 switch (codec) {
@@ -256,9 +210,15 @@ static int venus_probe(struct platform_device *pdev) · 106 unmodified lines
256 if (!core->res)210 if (!core->res)
257 return -ENODEV;211 return -ENODEV;
258 212
259 ret = venus_clks_get(core);213 core->pm_ops = venus_pm_get(core->res->hfi_version);
260 if (ret)214 if (!core->pm_ops)
261 return ret;215 return -ENODEV;
216
217 if (core->pm_ops->core_get) {
218 ret = core->pm_ops->core_get(dev);
219 if (ret)
220 return ret;
221 }
262 222
263 ret = dma_set_mask_and_coherent(dev, core->res->dma_mask);223 ret = dma_set_mask_and_coherent(dev, core->res->dma_mask);
264 if (ret)224 if (ret)
@@ -350,6 +310,7 @@ err_runtime_disable: · 85 unmodified lines
350static int venus_remove(struct platform_device *pdev)310static int venus_remove(struct platform_device *pdev)
351{311{
352 struct venus_core *core = platform_get_drvdata(pdev);312 struct venus_core *core = platform_get_drvdata(pdev);
313 const struct venus_pm_ops *pm_ops = core->pm_ops;
353 struct device *dev = core->dev;314 struct device *dev = core->dev;
354 int ret;315 int ret;
355 316
@@ -368,6 +329,9 @@ static int venus_remove(struct platform_device *pdev) · 12 unmodified lines
368 pm_runtime_put_sync(dev);329 pm_runtime_put_sync(dev);
369 pm_runtime_disable(dev);330 pm_runtime_disable(dev);
370 331
332 if (pm_ops->core_put)
333 pm_ops->core_put(dev);
334
371 icc_put(core->video_path);335 icc_put(core->video_path);
372 icc_put(core->cpucfg_path);336 icc_put(core->cpucfg_path);
373 337
@@ -379,11 +343,15 @@ static int venus_remove(struct platform_device *pdev) · 5 unmodified lines
379static __maybe_unused int venus_runtime_suspend(struct device *dev)343static __maybe_unused int venus_runtime_suspend(struct device *dev)
380{344{
381 struct venus_core *core = dev_get_drvdata(dev);345 struct venus_core *core = dev_get_drvdata(dev);
346 const struct venus_pm_ops *pm_ops = core->pm_ops;
382 int ret;347 int ret;
383 348
384 ret = hfi_core_suspend(core);349 ret = hfi_core_suspend(core);
350 if (ret)
351 return ret;
385 352
386 venus_clks_disable(core);353 if (pm_ops->core_power)
354 ret = pm_ops->core_power(dev, POWER_OFF);
387 355
388 return ret;356 return ret;
389}357}
@@ -391,21 +359,16 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev) · 1 unmodified line
391static __maybe_unused int venus_runtime_resume(struct device *dev)359static __maybe_unused int venus_runtime_resume(struct device *dev)
392{360{
393 struct venus_core *core = dev_get_drvdata(dev);361 struct venus_core *core = dev_get_drvdata(dev);
362 const struct venus_pm_ops *pm_ops = core->pm_ops;
394 int ret;363 int ret;
395 364
396 ret = venus_clks_enable(core);365 if (pm_ops->core_power) {
397 if (ret)366 ret = pm_ops->core_power(dev, POWER_ON);
398 return ret;367 if (ret)
399 368 return ret;
400 ret = hfi_core_resume(core, false);369 }
401 if (ret)
402 goto err_clks_disable;
403
404 return 0;
405 370
406err_clks_disable:371 return hfi_core_resume(core, false);
407 venus_clks_disable(core);
408 return ret;
409}372}
410 373
411static const struct dev_pm_ops venus_pm_ops = {374static const struct dev_pm_ops venus_pm_ops = {
@@ -463,6 +426,9 @@ static const struct venus_resources msm8996_res = { · 51 unmodified lines
463 .reg_tbl_size = ARRAY_SIZE(msm8996_reg_preset),426 .reg_tbl_size = ARRAY_SIZE(msm8996_reg_preset),
464 .clks = {"core", "iface", "bus", "mbus" },427 .clks = {"core", "iface", "bus", "mbus" },
465 .clks_num = 4,428 .clks_num = 4,
429 .vcodec0_clks = { "core" },
430 .vcodec1_clks = { "core" },
431 .vcodec_clks_num = 1,
466 .max_load = 2563200,432 .max_load = 2563200,
467 .hfi_version = HFI_VERSION_3XX,433 .hfi_version = HFI_VERSION_3XX,
468 .vmem_id = VIDC_RESOURCE_NONE,434 .vmem_id = VIDC_RESOURCE_NONE,
@@ -517,6 +483,35 @@ static const struct venus_resources sdm845_res = { · 48 unmodified lines
517 .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),483 .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
518 .clks = {"core", "iface", "bus" },484 .clks = {"core", "iface", "bus" },
519 .clks_num = 3,485 .clks_num = 3,
486 .vcodec0_clks = { "core", "bus" },
487 .vcodec1_clks = { "core", "bus" },
488 .vcodec_clks_num = 2,
489 .max_load = 3110400, /* 4096x2160@90 */
490 .hfi_version = HFI_VERSION_4XX,
491 .vmem_id = VIDC_RESOURCE_NONE,
492 .vmem_size = 0,
493 .vmem_addr = 0,
494 .dma_mask = 0xe0000000 - 1,
495 .fwname = "qcom/venus-5.2/venus.mdt",
496};
497
498static const struct venus_resources sdm845_res_v2 = {
499 .freq_tbl = sdm845_freq_table,
500 .freq_tbl_size = ARRAY_SIZE(sdm845_freq_table),
501 .bw_tbl_enc = sdm845_bw_table_enc,
502 .bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
503 .bw_tbl_dec = sdm845_bw_table_dec,
504 .bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
505 .codec_freq_data = sdm845_codec_freq_data,
506 .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
507 .clks = {"core", "iface", "bus" },
508 .clks_num = 3,
509 .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
510 .vcodec1_clks = { "vcodec1_core", "vcodec1_bus" },
511 .vcodec_clks_num = 2,
512 .vcodec_pmdomains = { "venus", "vcodec0", "vcodec1" },
513 .vcodec_pmdomains_num = 3,
514 .vcodec_num = 2,
520 .max_load = 3110400, /* 4096x2160@90 */515 .max_load = 3110400, /* 4096x2160@90 */
521 .hfi_version = HFI_VERSION_4XX,516 .hfi_version = HFI_VERSION_4XX,
522 .vmem_id = VIDC_RESOURCE_NONE,517 .vmem_id = VIDC_RESOURCE_NONE,
@@ -526,10 +521,56 @@ static const struct venus_resources sdm845_res = { · 3 unmodified lines
526 .fwname = "qcom/venus-5.2/venus.mdt",521 .fwname = "qcom/venus-5.2/venus.mdt",
527};522};
528 523
524static const struct freq_tbl sc7180_freq_table[] = {
525 { 0, 500000000 },
526 { 0, 434000000 },
527 { 0, 340000000 },
528 { 0, 270000000 },
529 { 0, 150000000 },
530};
531
532static const struct bw_tbl sc7180_bw_table_enc[] = {
533 { 972000, 750000, 0, 0, 0 }, /* 3840x2160@30 */
534 { 489600, 451000, 0, 0, 0 }, /* 1920x1080@60 */
535 { 244800, 234000, 0, 0, 0 }, /* 1920x1080@30 */
536};
537
538static const struct bw_tbl sc7180_bw_table_dec[] = {
539 { 1036800, 1386000, 0, 1875000, 0 }, /* 4096x2160@30 */
540 { 489600, 865000, 0, 1146000, 0 }, /* 1920x1080@60 */
541 { 244800, 530000, 0, 583000, 0 }, /* 1920x1080@30 */
542};
543
544static const struct venus_resources sc7180_res = {
545 .freq_tbl = sc7180_freq_table,
546 .freq_tbl_size = ARRAY_SIZE(sc7180_freq_table),
547 .bw_tbl_enc = sc7180_bw_table_enc,
548 .bw_tbl_enc_size = ARRAY_SIZE(sc7180_bw_table_enc),
549 .bw_tbl_dec = sc7180_bw_table_dec,
550 .bw_tbl_dec_size = ARRAY_SIZE(sc7180_bw_table_dec),
551 .codec_freq_data = sdm845_codec_freq_data,
552 .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
553 .clks = {"core", "iface", "bus" },
554 .clks_num = 3,
555 .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
556 .vcodec_clks_num = 2,
557 .vcodec_pmdomains = { "venus", "vcodec0" },
558 .vcodec_pmdomains_num = 2,
559 .vcodec_num = 1,
560 .hfi_version = HFI_VERSION_4XX,
561 .vmem_id = VIDC_RESOURCE_NONE,
562 .vmem_size = 0,
563 .vmem_addr = 0,
564 .dma_mask = 0xe0000000 - 1,
565 .fwname = "qcom/venus-5.4/venus.mdt",
566};
567
529static const struct of_device_id venus_dt_match[] = {568static const struct of_device_id venus_dt_match[] = {
530 { .compatible = "qcom,msm8916-venus", .data = &msm8916_res, },569 { .compatible = "qcom,msm8916-venus", .data = &msm8916_res, },
531 { .compatible = "qcom,msm8996-venus", .data = &msm8996_res, },570 { .compatible = "qcom,msm8996-venus", .data = &msm8996_res, },
532 { .compatible = "qcom,sdm845-venus", .data = &sdm845_res, },571 { .compatible = "qcom,sdm845-venus", .data = &sdm845_res, },
572 { .compatible = "qcom,sdm845-venus-v2", .data = &sdm845_res_v2, },
573 { .compatible = "qcom,sc7180-venus", .data = &sc7180_res, },
533 { }574 { }
534};575};
535MODULE_DEVICE_TABLE(of, venus_dt_match);576MODULE_DEVICE_TABLE(of, venus_dt_match);
drivers/media/platform/qcom/venus/core.h+24−9
@@ -14,7 +14,9 @@ · 13 unmodified lines
14 14
15#include "hfi.h"15#include "hfi.h"
16 16
17#define VIDC_CLKS_NUM_MAX 417#define VIDC_CLKS_NUM_MAX 4
18#define VIDC_VCODEC_CLKS_NUM_MAX 2
19#define VIDC_PMDOMAINS_NUM_MAX 3
18 20
19struct freq_tbl {21struct freq_tbl {
20 unsigned int load;22 unsigned int load;
@@ -55,6 +57,12 @@ struct venus_resources { · 34 unmodified lines
55 unsigned int codec_freq_data_size;57 unsigned int codec_freq_data_size;
56 const char * const clks[VIDC_CLKS_NUM_MAX];58 const char * const clks[VIDC_CLKS_NUM_MAX];
57 unsigned int clks_num;59 unsigned int clks_num;
60 const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
61 const char * const vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX];
62 unsigned int vcodec_clks_num;
63 const char * const vcodec_pmdomains[VIDC_PMDOMAINS_NUM_MAX];
64 unsigned int vcodec_pmdomains_num;
65 unsigned int vcodec_num;
58 enum hfi_version hfi_version;66 enum hfi_version hfi_version;
59 u32 max_load;67 u32 max_load;
60 unsigned int vmem_id;68 unsigned int vmem_id;
@@ -100,10 +108,10 @@ struct venus_caps { · 39 unmodified lines
100 * @base: IO memory base address108 * @base: IO memory base address
101 * @irq: Venus irq109 * @irq: Venus irq
102 * @clks: an array of struct clk pointers110 * @clks: an array of struct clk pointers
103 * @core0_clk: a struct clk pointer for core0111 * @vcodec0_clks: an array of vcodec0 struct clk pointers
104 * @core1_clk: a struct clk pointer for core1112 * @vcodec1_clks: an array of vcodec1 struct clk pointers
105 * @core0_bus_clk: a struct clk pointer for core0 bus clock113 * @pd_dl_venus: pmdomain device-link for venus domain
106 * @core1_bus_clk: a struct clk pointer for core1 bus clock114 * @pmdomains: an array of pmdomains struct device pointers
107 * @vdev_dec: a reference to video device structure for decoder instances115 * @vdev_dec: a reference to video device structure for decoder instances
108 * @vdev_enc: a reference to video device structure for encoder instances116 * @vdev_enc: a reference to video device structure for encoder instances
109 * @v4l2_dev: a holder for v4l2 device structure117 * @v4l2_dev: a holder for v4l2 device structure
@@ -132,12 +140,12 @@ struct venus_core { · 22 unmodified lines
132 void __iomem *base;140 void __iomem *base;
133 int irq;141 int irq;
134 struct clk *clks[VIDC_CLKS_NUM_MAX];142 struct clk *clks[VIDC_CLKS_NUM_MAX];
135 struct clk *core0_clk;143 struct clk *vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
136 struct clk *core1_clk;144 struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX];
137 struct clk *core0_bus_clk;
138 struct clk *core1_bus_clk;
139 struct icc_path *video_path;145 struct icc_path *video_path;
140 struct icc_path *cpucfg_path;146 struct icc_path *cpucfg_path;
147 struct device_link *pd_dl_venus;
148 struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX];
141 struct video_device *vdev_dec;149 struct video_device *vdev_dec;
142 struct video_device *vdev_enc;150 struct video_device *vdev_enc;
143 struct v4l2_device v4l2_dev;151 struct v4l2_device v4l2_dev;
@@ -159,6 +167,7 @@ struct venus_core { · 15 unmodified lines
159 unsigned int error;167 unsigned int error;
160 bool sys_error;168 bool sys_error;
161 const struct hfi_core_ops *core_ops;169 const struct hfi_core_ops *core_ops;
170 const struct venus_pm_ops *pm_ops;
162 unsigned long enc_codecs;171 unsigned long enc_codecs;
163 unsigned long dec_codecs;172 unsigned long dec_codecs;
164 unsigned int max_sessions_supported;173 unsigned int max_sessions_supported;
@@ -172,6 +181,8 @@ struct venus_core { · 7 unmodified lines
172 struct delayed_work work;181 struct delayed_work work;
173 struct venus_caps caps[MAX_CODEC_NUM];182 struct venus_caps caps[MAX_CODEC_NUM];
174 unsigned int codecs_count;183 unsigned int codecs_count;
184 unsigned int core0_usage_count;
185 unsigned int core1_usage_count;
175};186};
176 187
177struct vdec_controls {188struct vdec_controls {
@@ -187,6 +198,7 @@ struct venc_controls { · 9 unmodified lines
187 u32 bitrate_mode;198 u32 bitrate_mode;
188 u32 bitrate;199 u32 bitrate;
189 u32 bitrate_peak;200 u32 bitrate_peak;
201 u32 rc_enable;
190 202
191 u32 h264_i_period;203 u32 h264_i_period;
192 u32 h264_entropy_mode;204 u32 h264_entropy_mode;
@@ -344,6 +356,7 @@ struct venus_inst { · 151 unmodified lines
344 unsigned int subscriptions;356 unsigned int subscriptions;
345 int buf_count;357 int buf_count;
346 struct venus_ts_metadata tss[VIDEO_MAX_FRAME];358 struct venus_ts_metadata tss[VIDEO_MAX_FRAME];
359 unsigned long payloads[VIDEO_MAX_FRAME];
347 u64 fps;360 u64 fps;
348 struct v4l2_fract timeperframe;361 struct v4l2_fract timeperframe;
349 const struct venus_format *fmt_out;362 const struct venus_format *fmt_out;
@@ -370,6 +383,8 @@ struct venus_inst { · 20 unmodified lines
370 const struct hfi_inst_ops *ops;383 const struct hfi_inst_ops *ops;
371 u32 session_type;384 u32 session_type;
372 union hfi_get_property hprop;385 union hfi_get_property hprop;
386 unsigned int core_acquired: 1;
387 unsigned int bit_depth;
373};388};
374 389
375#define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX)390#define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX)
drivers/media/platform/qcom/venus/firmware.c+9−4
@@ -44,8 +44,14 @@ static void venus_reset_cpu(struct venus_core *core) · 43 unmodified lines
44 44
45int venus_set_hw_state(struct venus_core *core, bool resume)45int venus_set_hw_state(struct venus_core *core, bool resume)
46{46{
47 if (core->use_tz)47 int ret;
48 return qcom_scm_set_remote_state(resume, 0);48
49 if (core->use_tz) {
50 ret = qcom_scm_set_remote_state(resume, 0);
51 if (resume && ret == -EINVAL)
52 ret = 0;
53 return ret;
54 }
49 55
50 if (resume)56 if (resume)
51 venus_reset_cpu(core);57 venus_reset_cpu(core);
@@ -100,8 +106,7 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, · 48 unmodified lines
100 106
101 mem_va = memremap(r.start, *mem_size, MEMREMAP_WC);107 mem_va = memremap(r.start, *mem_size, MEMREMAP_WC);
102 if (!mem_va) {108 if (!mem_va) {
103 dev_err(dev, "unable to map memory region: %pa+%zx\n",109 dev_err(dev, "unable to map memory region: %pR\n", &r);
104 &r.start, *mem_size);
105 ret = -ENOMEM;110 ret = -ENOMEM;
106 goto err_release_fw;111 goto err_release_fw;
107 }112 }
drivers/media/platform/qcom/venus/helpers.c+116−332
@@ -3,12 +3,8 @@ · 2 unmodified lines
3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2017 Linaro Ltd.4 * Copyright (C) 2017 Linaro Ltd.
5 */5 */
6#include <linux/clk.h>
7#include <linux/iopoll.h>
8#include <linux/interconnect.h>
9#include <linux/list.h>6#include <linux/list.h>
10#include <linux/mutex.h>7#include <linux/mutex.h>
11#include <linux/pm_runtime.h>
12#include <linux/slab.h>8#include <linux/slab.h>
13#include <media/videobuf2-dma-sg.h>9#include <media/videobuf2-dma-sg.h>
14#include <media/v4l2-mem2mem.h>10#include <media/v4l2-mem2mem.h>
@@ -17,7 +13,7 @@ · 2 unmodified lines
17#include "core.h"13#include "core.h"
18#include "helpers.h"14#include "helpers.h"
19#include "hfi_helper.h"15#include "hfi_helper.h"
20#include "hfi_venus_io.h"16#include "pm_helpers.h"
21 17
22struct intbuf {18struct intbuf {
23 struct list_head list;19 struct list_head list;
@@ -360,266 +356,6 @@ err: · 336 unmodified lines
360}356}
361EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);357EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);
362 358
363static u32 load_per_instance(struct venus_inst *inst)
364{
365 u32 mbs;
366
367 if (!inst || !(inst->state >= INST_INIT && inst->state < INST_STOP))
368 return 0;
369
370 mbs = (ALIGN(inst->width, 16) / 16) * (ALIGN(inst->height, 16) / 16);
371
372 return mbs * inst->fps;
373}
374
375static u32 load_per_type(struct venus_core *core, u32 session_type)
376{
377 struct venus_inst *inst = NULL;
378 u32 mbs_per_sec = 0;
379
380 mutex_lock(&core->lock);
381 list_for_each_entry(inst, &core->instances, list) {
382 if (inst->session_type != session_type)
383 continue;
384
385 mbs_per_sec += load_per_instance(inst);
386 }
387 mutex_unlock(&core->lock);
388
389 return mbs_per_sec;
390}
391
392static void mbs_to_bw(struct venus_inst *inst, u32 mbs, u32 *avg, u32 *peak)
393{
394 const struct venus_resources *res = inst->core->res;
395 const struct bw_tbl *bw_tbl;
396 unsigned int num_rows, i;
397
398 *avg = 0;
399 *peak = 0;
400
401 if (mbs == 0)
402 return;
403
404 if (inst->session_type == VIDC_SESSION_TYPE_ENC) {
405 num_rows = res->bw_tbl_enc_size;
406 bw_tbl = res->bw_tbl_enc;
407 } else if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
408 num_rows = res->bw_tbl_dec_size;
409 bw_tbl = res->bw_tbl_dec;
410 } else {
411 return;
412 }
413
414 if (!bw_tbl || num_rows == 0)
415 return;
416
417 for (i = 0; i < num_rows; i++) {
418 if (mbs > bw_tbl[i].mbs_per_sec)
419 break;
420
421 if (inst->dpb_fmt & HFI_COLOR_FORMAT_10_BIT_BASE) {
422 *avg = bw_tbl[i].avg_10bit;
423 *peak = bw_tbl[i].peak_10bit;
424 } else {
425 *avg = bw_tbl[i].avg;
426 *peak = bw_tbl[i].peak;
427 }
428 }
429}
430
431static int load_scale_bw(struct venus_core *core)
432{
433 struct venus_inst *inst = NULL;
434 u32 mbs_per_sec, avg, peak, total_avg = 0, total_peak = 0;
435
436 mutex_lock(&core->lock);
437 list_for_each_entry(inst, &core->instances, list) {
438 mbs_per_sec = load_per_instance(inst);
439 mbs_to_bw(inst, mbs_per_sec, &avg, &peak);
440 total_avg += avg;
441 total_peak += peak;
442 }
443 mutex_unlock(&core->lock);
444
445 dev_dbg(core->dev, "total: avg_bw: %u, peak_bw: %u\n",
446 total_avg, total_peak);
447
448 return icc_set_bw(core->video_path, total_avg, total_peak);
449}
450
451static int set_clk_freq(struct venus_core *core, unsigned long freq)
452{
453 struct clk *clk = core->clks[0];
454 int ret;
455
456 ret = clk_set_rate(clk, freq);
457 if (ret)
458 return ret;
459
460 ret = clk_set_rate(core->core0_clk, freq);
461 if (ret)
462 return ret;
463
464 ret = clk_set_rate(core->core1_clk, freq);
465 if (ret)
466 return ret;
467
468 return 0;
469}
470
471static int scale_clocks(struct venus_inst *inst)
472{
473 struct venus_core *core = inst->core;
474 const struct freq_tbl *table = core->res->freq_tbl;
475 unsigned int num_rows = core->res->freq_tbl_size;
476 unsigned long freq = table[0].freq;
477 struct device *dev = core->dev;
478 u32 mbs_per_sec;
479 unsigned int i;
480 int ret;
481
482 mbs_per_sec = load_per_type(core, VIDC_SESSION_TYPE_ENC) +
483 load_per_type(core, VIDC_SESSION_TYPE_DEC);
484
485 if (mbs_per_sec > core->res->max_load)
486 dev_warn(dev, "HW is overloaded, needed: %d max: %d\n",
487 mbs_per_sec, core->res->max_load);
488
489 if (!mbs_per_sec && num_rows > 1) {
490 freq = table[num_rows - 1].freq;
491 goto set_freq;
492 }
493
494 for (i = 0; i < num_rows; i++) {
495 if (mbs_per_sec > table[i].load)
496 break;
497 freq = table[i].freq;
498 }
499
500set_freq:
501
502 ret = set_clk_freq(core, freq);
503 if (ret) {
504 dev_err(dev, "failed to set clock rate %lu (%d)\n",
505 freq, ret);
506 return ret;
507 }
508
509 ret = load_scale_bw(core);
510 if (ret) {
511 dev_err(dev, "failed to set bandwidth (%d)\n",
512 ret);
513 return ret;
514 }
515
516 return 0;
517}
518
519static unsigned long calculate_inst_freq(struct venus_inst *inst,
520 unsigned long filled_len)
521{
522 unsigned long vpp_freq = 0, vsp_freq = 0;
523 u32 fps = (u32)inst->fps;
524 u32 mbs_per_sec;
525
526 mbs_per_sec = load_per_instance(inst) / fps;
527
528 vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
529 /* 21 / 20 is overhead factor */
530 vpp_freq += vpp_freq / 20;
531 vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
532
533 /* 10 / 7 is overhead factor */
534 if (inst->session_type == VIDC_SESSION_TYPE_ENC)
535 vsp_freq += (inst->controls.enc.bitrate * 10) / 7;
536 else
537 vsp_freq += ((fps * filled_len * 8) * 10) / 7;
538
539 return max(vpp_freq, vsp_freq);
540}
541
542static int scale_clocks_v4(struct venus_inst *inst)
543{
544 struct venus_core *core = inst->core;
545 const struct freq_tbl *table = core->res->freq_tbl;
546 unsigned int num_rows = core->res->freq_tbl_size;
547 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
548 struct device *dev = core->dev;
549 unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
550 unsigned long filled_len = 0;
551 struct venus_buffer *buf, *n;
552 struct vb2_buffer *vb;
553 int i, ret;
554
555 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
556 vb = &buf->vb.vb2_buf;
557 filled_len = max(filled_len, vb2_get_plane_payload(vb, 0));
558 }
559
560 if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len)
561 return 0;
562
563 freq = calculate_inst_freq(inst, filled_len);
564 inst->clk_data.freq = freq;
565
566 mutex_lock(&core->lock);
567 list_for_each_entry(inst, &core->instances, list) {
568 if (inst->clk_data.core_id == VIDC_CORE_ID_1) {
569 freq_core1 += inst->clk_data.freq;
570 } else if (inst->clk_data.core_id == VIDC_CORE_ID_2) {
571 freq_core2 += inst->clk_data.freq;
572 } else if (inst->clk_data.core_id == VIDC_CORE_ID_3) {
573 freq_core1 += inst->clk_data.freq;
574 freq_core2 += inst->clk_data.freq;
575 }
576 }
577 mutex_unlock(&core->lock);
578
579 freq = max(freq_core1, freq_core2);
580
581 if (freq >= table[0].freq) {
582 freq = table[0].freq;
583 dev_warn(dev, "HW is overloaded, needed: %lu max: %lu\n",
584 freq, table[0].freq);
585 goto set_freq;
586 }
587
588 for (i = num_rows - 1 ; i >= 0; i--) {
589 if (freq <= table[i].freq) {
590 freq = table[i].freq;
591 break;
592 }
593 }
594
595set_freq:
596
597 ret = set_clk_freq(core, freq);
598 if (ret) {
599 dev_err(dev, "failed to set clock rate %lu (%d)\n",
600 freq, ret);
601 return ret;
602 }
603
604 ret = load_scale_bw(core);
605 if (ret) {
606 dev_err(dev, "failed to set bandwidth (%d)\n",
607 ret);
608 return ret;
609 }
610
611 return 0;
612}
613
614int venus_helper_load_scale_clocks(struct venus_inst *inst)
615{
616 if (IS_V4(inst->core))
617 return scale_clocks_v4(inst);
618
619 return scale_clocks(inst);
620}
621EXPORT_SYMBOL_GPL(venus_helper_load_scale_clocks);
622
623static void fill_buffer_desc(const struct venus_buffer *buf,359static void fill_buffer_desc(const struct venus_buffer *buf,
624 struct hfi_buffer_desc *bd, bool response)360 struct hfi_buffer_desc *bd, bool response)
625{361{
@@ -723,7 +459,7 @@ session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) · 97 unmodified lines
723 if (inst->session_type == VIDC_SESSION_TYPE_DEC)459 if (inst->session_type == VIDC_SESSION_TYPE_DEC)
724 put_ts_metadata(inst, vbuf);460 put_ts_metadata(inst, vbuf);
725 461
726 venus_helper_load_scale_clocks(inst);462 venus_pm_load_scale(inst);
727 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {463 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
728 if (inst->session_type == VIDC_SESSION_TYPE_ENC)464 if (inst->session_type == VIDC_SESSION_TYPE_ENC)
729 fdata.buffer_type = HFI_BUFFER_OUTPUT;465 fdata.buffer_type = HFI_BUFFER_OUTPUT;
@@ -890,6 +626,78 @@ static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height) · 160 unmodified lines
890 max(extradata, y_stride * 48), SZ_4K);626 max(extradata, y_stride * 48), SZ_4K);
891}627}
892 628
629static u32 get_framesize_raw_p010(u32 width, u32 height)
630{
631 u32 y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines;
632
633 y_stride = ALIGN(width * 2, 256);
634 uv_stride = ALIGN(width * 2, 256);
635 y_sclines = ALIGN(height, 32);
636 uv_sclines = ALIGN((height + 1) >> 1, 16);
637 y_plane = y_stride * y_sclines;
638 uv_plane = uv_stride * uv_sclines;
639
640 return ALIGN((y_plane + uv_plane), SZ_4K);
641}
642
643static u32 get_framesize_raw_p010_ubwc(u32 width, u32 height)
644{
645 u32 y_stride, uv_stride, y_sclines, uv_sclines;
646 u32 y_ubwc_plane, uv_ubwc_plane;
647 u32 y_meta_stride, y_meta_scanlines;
648 u32 uv_meta_stride, uv_meta_scanlines;
649 u32 y_meta_plane, uv_meta_plane;
650 u32 size;
651
652 y_stride = ALIGN(width * 2, 256);
653 uv_stride = ALIGN(width * 2, 256);
654 y_sclines = ALIGN(height, 16);
655 uv_sclines = ALIGN((height + 1) >> 1, 16);
656
657 y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
658 uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
659 y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
660 y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
661 y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
662 uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64);
663 uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
664 uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
665
666 size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
667
668 return ALIGN(size, SZ_4K);
669}
670
671static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height)
672{
673 u32 y_stride, uv_stride, y_sclines, uv_sclines;
674 u32 y_ubwc_plane, uv_ubwc_plane;
675 u32 y_meta_stride, y_meta_scanlines;
676 u32 uv_meta_stride, uv_meta_scanlines;
677 u32 y_meta_plane, uv_meta_plane;
678 u32 extradata = SZ_16K;
679 u32 size;
680
681 y_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
682 uv_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
683 y_sclines = ALIGN(height, 16);
684 uv_sclines = ALIGN((height + 1) >> 1, 16);
685
686 y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
687 uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
688 y_meta_stride = ALIGN(DIV_ROUND_UP(width, 48), 64);
689 y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
690 y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
691 uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64);
692 uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
693 uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
694
695 size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
696 size += max(extradata + SZ_8K, y_stride * 48);
697
698 return ALIGN(size, SZ_4K);
699}
700
893u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)701u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
894{702{
895 switch (hfi_fmt) {703 switch (hfi_fmt) {
@@ -898,6 +706,12 @@ u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height) · 2 unmodified lines
898 return get_framesize_raw_nv12(width, height);706 return get_framesize_raw_nv12(width, height);
899 case HFI_COLOR_FORMAT_NV12_UBWC:707 case HFI_COLOR_FORMAT_NV12_UBWC:
900 return get_framesize_raw_nv12_ubwc(width, height);708 return get_framesize_raw_nv12_ubwc(width, height);
709 case HFI_COLOR_FORMAT_P010:
710 return get_framesize_raw_p010(width, height);
711 case HFI_COLOR_FORMAT_P010_UBWC:
712 return get_framesize_raw_p010_ubwc(width, height);
713 case HFI_COLOR_FORMAT_YUV420_TP10_UBWC:
714 return get_framesize_raw_yuv420_tp10_ubwc(width, height);
901 default:715 default:
902 return 0;716 return 0;
903 }717 }
@@ -987,21 +801,6 @@ int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode) · 83 unmodified lines
987}801}
988EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);802EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
989 803
990int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage)
991{
992 const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
993 struct hfi_videocores_usage_type cu;
994
995 inst->clk_data.core_id = usage;
996 if (!IS_V4(inst->core))
997 return 0;
998
999 cu.video_core_enable_mask = usage;
1000
1001 return hfi_session_set_property(inst, ptype, &cu);
1002}
1003EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
1004
1005int venus_helper_init_codec_freq_data(struct venus_inst *inst)804int venus_helper_init_codec_freq_data(struct venus_inst *inst)
1006{805{
1007 const struct codec_freq_data *data;806 const struct codec_freq_data *data;
@@ -1289,6 +1088,15 @@ int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb) · 281 unmodified lines
1289}1088}
1290EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare);1089EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare);
1291 1090
1091static void cache_payload(struct venus_inst *inst, struct vb2_buffer *vb)
1092{
1093 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1094 unsigned int idx = vbuf->vb2_buf.index;
1095
1096 if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1097 inst->payloads[idx] = vb2_get_plane_payload(vb, 0);
1098}
1099
1292void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)1100void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
1293{1101{
1294 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);1102 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -1300,6 +1108,8 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb) · 5 unmodified lines
1300 1108
1301 v4l2_m2m_buf_queue(m2m_ctx, vbuf);1109 v4l2_m2m_buf_queue(m2m_ctx, vbuf);
1302 1110
1111 cache_payload(inst, vb);
1112
1303 if (inst->session_type == VIDC_SESSION_TYPE_ENC &&1113 if (inst->session_type == VIDC_SESSION_TYPE_ENC &&
1304 !(inst->streamon_out && inst->streamon_cap))1114 !(inst->streamon_out && inst->streamon_cap))
1305 goto unlock;1115 goto unlock;
@@ -1354,7 +1164,7 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q) · 48 unmodified lines
1354 1164
1355 venus_helper_free_dpb_bufs(inst);1165 venus_helper_free_dpb_bufs(inst);
1356 1166
1357 venus_helper_load_scale_clocks(inst);1167 venus_pm_load_scale(inst);
1358 INIT_LIST_HEAD(&inst->registeredbufs);1168 INIT_LIST_HEAD(&inst->registeredbufs);
1359 }1169 }
1360 1170
@@ -1365,6 +1175,8 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q) · 4 unmodified lines
1365 else1175 else
1366 inst->streamon_cap = 0;1176 inst->streamon_cap = 0;
1367 1177
1178 venus_pm_release_core(inst);
1179
1368 mutex_unlock(&inst->lock);1180 mutex_unlock(&inst->lock);
1369}1181}
1370EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);1182EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);
@@ -1417,7 +1229,7 @@ int venus_helper_vb2_start_streaming(struct venus_inst *inst) · 46 unmodified lines
1417 if (ret)1229 if (ret)
1418 goto err_bufs_free;1230 goto err_bufs_free;
1419 1231
1420 venus_helper_load_scale_clocks(inst);1232 venus_pm_load_scale(inst);
1421 1233
1422 ret = hfi_session_load_res(inst);1234 ret = hfi_session_load_res(inst);
1423 if (ret)1235 if (ret)
@@ -1512,6 +1324,27 @@ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt, · 88 unmodified lines
1512 if (!caps)1324 if (!caps)
1513 return -EINVAL;1325 return -EINVAL;
1514 1326
1327 if (inst->bit_depth == VIDC_BITDEPTH_10 &&
1328 inst->session_type == VIDC_SESSION_TYPE_DEC) {
1329 found_ubwc =
1330 find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
1331 HFI_COLOR_FORMAT_YUV420_TP10_UBWC);
1332 found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2,
1333 HFI_COLOR_FORMAT_NV12);
1334 if (found_ubwc && found) {
1335 /*
1336 * Hard-code DPB buffers to be 10bit UBWC and decoder
1337 * output buffers in 8bit NV12 until V4L2 is able to
1338 * expose compressed/tiled formats to applications.
1339 */
1340 *out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
1341 *out2_fmt = HFI_COLOR_FORMAT_NV12;
1342 return 0;
1343 }
1344
1345 return -EINVAL;
1346 }
1347
1515 if (ubwc) {1348 if (ubwc) {
1516 ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE;1349 ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE;
1517 found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,1350 found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
@@ -1542,52 +1375,3 @@ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt, · 24 unmodified lines
1542 return -EINVAL;1375 return -EINVAL;
1543}1376}
1544EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts);1377EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts);
1545
1546int venus_helper_power_enable(struct venus_core *core, u32 session_type,
1547 bool enable)
1548{
1549 void __iomem *ctrl, *stat;
1550 u32 val;
1551 int ret;
1552
1553 if (!IS_V3(core) && !IS_V4(core))
1554 return 0;
1555
1556 if (IS_V3(core)) {
1557 if (session_type == VIDC_SESSION_TYPE_DEC)
1558 ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
1559 else
1560 ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
1561 if (enable)
1562 writel(0, ctrl);
1563 else
1564 writel(1, ctrl);
1565
1566 return 0;
1567 }
1568
1569 if (session_type == VIDC_SESSION_TYPE_DEC) {
1570 ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
1571 stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
1572 } else {
1573 ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
1574 stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
1575 }
1576
1577 if (enable) {
1578 writel(0, ctrl);
1579
1580 ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
1581 if (ret)
1582 return ret;
1583 } else {
1584 writel(1, ctrl);
1585
1586 ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
1587 if (ret)
1588 return ret;
1589 }
1590
1591 return 0;
1592}
1593EXPORT_SYMBOL_GPL(venus_helper_power_enable);
drivers/media/platform/qcom/venus/helpers.h+0−4
@@ -34,7 +34,6 @@ int venus_helper_set_output_resolution(struct venus_inst *inst, · 33 unmodified lines
34 u32 buftype);34 u32 buftype);
35int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);35int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
36int venus_helper_init_codec_freq_data(struct venus_inst *inst);36int venus_helper_init_codec_freq_data(struct venus_inst *inst);
37int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage);
38int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,37int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
39 unsigned int output_bufs,38 unsigned int output_bufs,
40 unsigned int output2_bufs);39 unsigned int output2_bufs);
@@ -53,14 +52,11 @@ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 fmt, u32 *out_fmt, · 12 unmodified lines
53 u32 *out2_fmt, bool ubwc);52 u32 *out2_fmt, bool ubwc);
54int venus_helper_alloc_dpb_bufs(struct venus_inst *inst);53int venus_helper_alloc_dpb_bufs(struct venus_inst *inst);
55int venus_helper_free_dpb_bufs(struct venus_inst *inst);54int venus_helper_free_dpb_bufs(struct venus_inst *inst);
56int venus_helper_power_enable(struct venus_core *core, u32 session_type,
57 bool enable);
58int venus_helper_intbufs_alloc(struct venus_inst *inst);55int venus_helper_intbufs_alloc(struct venus_inst *inst);
59int venus_helper_intbufs_free(struct venus_inst *inst);56int venus_helper_intbufs_free(struct venus_inst *inst);
60int venus_helper_intbufs_realloc(struct venus_inst *inst);57int venus_helper_intbufs_realloc(struct venus_inst *inst);
61int venus_helper_queue_dpb_bufs(struct venus_inst *inst);58int venus_helper_queue_dpb_bufs(struct venus_inst *inst);
62int venus_helper_unregister_bufs(struct venus_inst *inst);59int venus_helper_unregister_bufs(struct venus_inst *inst);
63int venus_helper_load_scale_clocks(struct venus_inst *inst);
64int venus_helper_process_initial_cap_bufs(struct venus_inst *inst);60int venus_helper_process_initial_cap_bufs(struct venus_inst *inst);
65int venus_helper_process_initial_out_bufs(struct venus_inst *inst);61int venus_helper_process_initial_out_bufs(struct venus_inst *inst);
66void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,62void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
drivers/media/platform/qcom/venus/hfi_cmds.c+2−0
@@ -1207,6 +1207,8 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt, · 1206 unmodified lines
1207 case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:1207 case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
1208 case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:1208 case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
1209 case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE:1209 case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE:
1210 case HFI_PROPERTY_PARAM_VENC_SESSION_QP:
1211 case HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE:
1210 /* not implemented on Venus 4xx */1212 /* not implemented on Venus 4xx */
1211 return -ENOTSUPP;1213 return -ENOTSUPP;
1212 default:1214 default:
drivers/media/platform/qcom/venus/hfi_helper.h+6−0
@@ -550,6 +550,7 @@ struct hfi_bitrate { · 549 unmodified lines
550#define HFI_CAPABILITY_LCU_SIZE 0x14550#define HFI_CAPABILITY_LCU_SIZE 0x14
551#define HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS 0x15551#define HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS 0x15
552#define HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE 0x16552#define HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE 0x16
553#define HFI_CAPABILITY_MAX_VIDEOCORES 0x2b
553 554
554struct hfi_capability {555struct hfi_capability {
555 u32 capability_type;556 u32 capability_type;
@@ -792,6 +793,9 @@ struct hfi_h264_vui_timing_info { · 236 unmodified lines
792 u32 time_scale;793 u32 time_scale;
793};794};
794 795
796#define VIDC_BITDEPTH_8 0x00000
797#define VIDC_BITDEPTH_10 0x20002
798
795struct hfi_bit_depth {799struct hfi_bit_depth {
796 u32 buffer_type;800 u32 buffer_type;
797 u32 bit_depth;801 u32 bit_depth;
@@ -840,8 +844,10 @@ struct hfi_extradata_input_crop { · 42 unmodified lines
840#define HFI_COLOR_FORMAT_10_BIT_BASE 0x4000844#define HFI_COLOR_FORMAT_10_BIT_BASE 0x4000
841 845
842#define HFI_COLOR_FORMAT_YUV420_TP10 0x4002846#define HFI_COLOR_FORMAT_YUV420_TP10 0x4002
847#define HFI_COLOR_FORMAT_P010 0x4003
843#define HFI_COLOR_FORMAT_NV12_UBWC 0x8002848#define HFI_COLOR_FORMAT_NV12_UBWC 0x8002
844#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC 0xc002849#define HFI_COLOR_FORMAT_YUV420_TP10_UBWC 0xc002
850#define HFI_COLOR_FORMAT_P010_UBWC 0xc003
845#define HFI_COLOR_FORMAT_RGBA8888_UBWC 0x8010851#define HFI_COLOR_FORMAT_RGBA8888_UBWC 0x8010
846 852
847struct hfi_uncompressed_format_select {853struct hfi_uncompressed_format_select {
drivers/media/platform/qcom/venus/hfi_parser.c+1−0
@@ -181,6 +181,7 @@ static void parse_codecs(struct venus_core *core, void *data) · 180 unmodified lines
181 if (IS_V1(core)) {181 if (IS_V1(core)) {
182 core->dec_codecs &= ~HFI_VIDEO_CODEC_HEVC;182 core->dec_codecs &= ~HFI_VIDEO_CODEC_HEVC;
183 core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK;183 core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK;
184 core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC;
184 }185 }
185}186}
186 187
drivers/media/platform/qcom/venus/hfi_parser.h+5−0
@@ -107,4 +107,9 @@ static inline u32 frate_step(struct venus_inst *inst) · 106 unmodified lines
107 return cap_step(inst, HFI_CAPABILITY_FRAMERATE);107 return cap_step(inst, HFI_CAPABILITY_FRAMERATE);
108}108}
109 109
110static inline u32 core_num_max(struct venus_inst *inst)
111{
112 return cap_max(inst, HFI_CAPABILITY_MAX_VIDEOCORES);
113}
114
110#endif115#endif
drivers/media/platform/qcom/venus/pm_helpers.c+959−0
@@ -0,0 +1,959 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2019 Linaro Ltd.
4 *
5 * Author: Stanimir Varbanov <stanimir.varbanov@linaro.org>
6 */
7#include <linux/clk.h>
8#include <linux/interconnect.h>
9#include <linux/iopoll.h>
10#include <linux/kernel.h>
11#include <linux/pm_domain.h>
12#include <linux/pm_runtime.h>
13#include <linux/types.h>
14#include <media/v4l2-mem2mem.h>
15
16#include "core.h"
17#include "hfi_parser.h"
18#include "hfi_venus_io.h"
19#include "pm_helpers.h"
20
21static bool legacy_binding;
22
23static int core_clks_get(struct venus_core *core)
24{
25 const struct venus_resources *res = core->res;
26 struct device *dev = core->dev;
27 unsigned int i;
28
29 for (i = 0; i < res->clks_num; i++) {
30 core->clks[i] = devm_clk_get(dev, res->clks[i]);
31 if (IS_ERR(core->clks[i]))
32 return PTR_ERR(core->clks[i]);
33 }
34
35 return 0;
36}
37
38static int core_clks_enable(struct venus_core *core)
39{
40 const struct venus_resources *res = core->res;
41 unsigned int i;
42 int ret;
43
44 for (i = 0; i < res->clks_num; i++) {
45 ret = clk_prepare_enable(core->clks[i]);
46 if (ret)
47 goto err;
48 }
49
50 return 0;
51err:
52 while (i--)
53 clk_disable_unprepare(core->clks[i]);
54
55 return ret;
56}
57
58static void core_clks_disable(struct venus_core *core)
59{
60 const struct venus_resources *res = core->res;
61 unsigned int i = res->clks_num;
62
63 while (i--)
64 clk_disable_unprepare(core->clks[i]);
65}
66
67static int core_clks_set_rate(struct venus_core *core, unsigned long freq)
68{
69 struct clk *clk = core->clks[0];
70 int ret;
71
72 ret = clk_set_rate(clk, freq);
73 if (ret)
74 return ret;
75
76 ret = clk_set_rate(core->vcodec0_clks[0], freq);
77 if (ret)
78 return ret;
79
80 ret = clk_set_rate(core->vcodec1_clks[0], freq);
81 if (ret)
82 return ret;
83
84 return 0;
85}
86
87static int vcodec_clks_get(struct venus_core *core, struct device *dev,
88 struct clk **clks, const char * const *id)
89{
90 const struct venus_resources *res = core->res;
91 unsigned int i;
92
93 for (i = 0; i < res->vcodec_clks_num; i++) {
94 if (!id[i])
95 continue;
96 clks[i] = devm_clk_get(dev, id[i]);
97 if (IS_ERR(clks[i]))
98 return PTR_ERR(clks[i]);
99 }
100
101 return 0;
102}
103
104static int vcodec_clks_enable(struct venus_core *core, struct clk **clks)
105{
106 const struct venus_resources *res = core->res;
107 unsigned int i;
108 int ret;
109
110 for (i = 0; i < res->vcodec_clks_num; i++) {
111 ret = clk_prepare_enable(clks[i]);
112 if (ret)
113 goto err;
114 }
115
116 return 0;
117err:
118 while (i--)
119 clk_disable_unprepare(clks[i]);
120
121 return ret;
122}
123
124static void vcodec_clks_disable(struct venus_core *core, struct clk **clks)
125{
126 const struct venus_resources *res = core->res;
127 unsigned int i = res->vcodec_clks_num;
128
129 while (i--)
130 clk_disable_unprepare(clks[i]);
131}
132
133static u32 load_per_instance(struct venus_inst *inst)
134{
135 u32 mbs;
136
137 if (!inst || !(inst->state >= INST_INIT && inst->state < INST_STOP))
138 return 0;
139
140 mbs = (ALIGN(inst->width, 16) / 16) * (ALIGN(inst->height, 16) / 16);
141
142 return mbs * inst->fps;
143}
144
145static u32 load_per_type(struct venus_core *core, u32 session_type)
146{
147 struct venus_inst *inst = NULL;
148 u32 mbs_per_sec = 0;
149
150 mutex_lock(&core->lock);
151 list_for_each_entry(inst, &core->instances, list) {
152 if (inst->session_type != session_type)
153 continue;
154
155 mbs_per_sec += load_per_instance(inst);
156 }
157 mutex_unlock(&core->lock);
158
159 return mbs_per_sec;
160}
161
162static void mbs_to_bw(struct venus_inst *inst, u32 mbs, u32 *avg, u32 *peak)
163{
164 const struct venus_resources *res = inst->core->res;
165 const struct bw_tbl *bw_tbl;
166 unsigned int num_rows, i;
167
168 *avg = 0;
169 *peak = 0;
170
171 if (mbs == 0)
172 return;
173
174 if (inst->session_type == VIDC_SESSION_TYPE_ENC) {
175 num_rows = res->bw_tbl_enc_size;
176 bw_tbl = res->bw_tbl_enc;
177 } else if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
178 num_rows = res->bw_tbl_dec_size;
179 bw_tbl = res->bw_tbl_dec;
180 } else {
181 return;
182 }
183
184 if (!bw_tbl || num_rows == 0)
185 return;
186
187 for (i = 0; i < num_rows; i++) {
188 if (mbs > bw_tbl[i].mbs_per_sec)
189 break;
190
191 if (inst->dpb_fmt & HFI_COLOR_FORMAT_10_BIT_BASE) {
192 *avg = bw_tbl[i].avg_10bit;
193 *peak = bw_tbl[i].peak_10bit;
194 } else {
195 *avg = bw_tbl[i].avg;
196 *peak = bw_tbl[i].peak;
197 }
198 }
199}
200
201static int load_scale_bw(struct venus_core *core)
202{
203 struct venus_inst *inst = NULL;
204 u32 mbs_per_sec, avg, peak, total_avg = 0, total_peak = 0;
205
206 mutex_lock(&core->lock);
207 list_for_each_entry(inst, &core->instances, list) {
208 mbs_per_sec = load_per_instance(inst);
209 mbs_to_bw(inst, mbs_per_sec, &avg, &peak);
210 total_avg += avg;
211 total_peak += peak;
212 }
213 mutex_unlock(&core->lock);
214
215 dev_dbg(core->dev, "total: avg_bw: %u, peak_bw: %u\n",
216 total_avg, total_peak);
217
218 return icc_set_bw(core->video_path, total_avg, total_peak);
219}
220
221static int load_scale_v1(struct venus_inst *inst)
222{
223 struct venus_core *core = inst->core;
224 const struct freq_tbl *table = core->res->freq_tbl;
225 unsigned int num_rows = core->res->freq_tbl_size;
226 unsigned long freq = table[0].freq;
227 struct device *dev = core->dev;
228 u32 mbs_per_sec;
229 unsigned int i;
230 int ret;
231
232 mbs_per_sec = load_per_type(core, VIDC_SESSION_TYPE_ENC) +
233 load_per_type(core, VIDC_SESSION_TYPE_DEC);
234
235 if (mbs_per_sec > core->res->max_load)
236 dev_warn(dev, "HW is overloaded, needed: %d max: %d\n",
237 mbs_per_sec, core->res->max_load);
238
239 if (!mbs_per_sec && num_rows > 1) {
240 freq = table[num_rows - 1].freq;
241 goto set_freq;
242 }
243
244 for (i = 0; i < num_rows; i++) {
245 if (mbs_per_sec > table[i].load)
246 break;
247 freq = table[i].freq;
248 }
249
250set_freq:
251
252 ret = core_clks_set_rate(core, freq);
253 if (ret) {
254 dev_err(dev, "failed to set clock rate %lu (%d)\n",
255 freq, ret);
256 return ret;
257 }
258
259 ret = load_scale_bw(core);
260 if (ret) {
261 dev_err(dev, "failed to set bandwidth (%d)\n",
262 ret);
263 return ret;
264 }
265
266 return 0;
267}
268
269static int core_get_v1(struct device *dev)
270{
271 struct venus_core *core = dev_get_drvdata(dev);
272
273 return core_clks_get(core);
274}
275
276static int core_power_v1(struct device *dev, int on)
277{
278 struct venus_core *core = dev_get_drvdata(dev);
279 int ret = 0;
280
281 if (on == POWER_ON)
282 ret = core_clks_enable(core);
283 else
284 core_clks_disable(core);
285
286 return ret;
287}
288
289static const struct venus_pm_ops pm_ops_v1 = {
290 .core_get = core_get_v1,
291 .core_power = core_power_v1,
292 .load_scale = load_scale_v1,
293};
294
295static void
296vcodec_control_v3(struct venus_core *core, u32 session_type, bool enable)
297{
298 void __iomem *ctrl;
299
300 if (session_type == VIDC_SESSION_TYPE_DEC)
301 ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
302 else
303 ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
304
305 if (enable)
306 writel(0, ctrl);
307 else
308 writel(1, ctrl);
309}
310
311static int vdec_get_v3(struct device *dev)
312{
313 struct venus_core *core = dev_get_drvdata(dev);
314
315 return vcodec_clks_get(core, dev, core->vcodec0_clks,
316 core->res->vcodec0_clks);
317}
318
319static int vdec_power_v3(struct device *dev, int on)
320{
321 struct venus_core *core = dev_get_drvdata(dev);
322 int ret = 0;
323
324 vcodec_control_v3(core, VIDC_SESSION_TYPE_DEC, true);
325
326 if (on == POWER_ON)
327 ret = vcodec_clks_enable(core, core->vcodec0_clks);
328 else
329 vcodec_clks_disable(core, core->vcodec0_clks);
330
331 vcodec_control_v3(core, VIDC_SESSION_TYPE_DEC, false);
332
333 return ret;
334}
335
336static int venc_get_v3(struct device *dev)
337{
338 struct venus_core *core = dev_get_drvdata(dev);
339
340 return vcodec_clks_get(core, dev, core->vcodec1_clks,
341 core->res->vcodec1_clks);
342}
343
344static int venc_power_v3(struct device *dev, int on)
345{
346 struct venus_core *core = dev_get_drvdata(dev);
347 int ret = 0;
348
349 vcodec_control_v3(core, VIDC_SESSION_TYPE_ENC, true);
350
351 if (on == POWER_ON)
352 ret = vcodec_clks_enable(core, core->vcodec1_clks);
353 else
354 vcodec_clks_disable(core, core->vcodec1_clks);
355
356 vcodec_control_v3(core, VIDC_SESSION_TYPE_ENC, false);
357
358 return ret;
359}
360
361static const struct venus_pm_ops pm_ops_v3 = {
362 .core_get = core_get_v1,
363 .core_power = core_power_v1,
364 .vdec_get = vdec_get_v3,
365 .vdec_power = vdec_power_v3,
366 .venc_get = venc_get_v3,
367 .venc_power = venc_power_v3,
368 .load_scale = load_scale_v1,
369};
370
371static int vcodec_control_v4(struct venus_core *core, u32 coreid, bool enable)
372{
373 void __iomem *ctrl, *stat;
374 u32 val;
375 int ret;
376
377 if (coreid == VIDC_CORE_ID_1) {
378 ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
379 stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
380 } else {
381 ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
382 stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
383 }
384
385 if (enable) {
386 writel(0, ctrl);
387
388 ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
389 if (ret)
390 return ret;
391 } else {
392 writel(1, ctrl);
393
394 ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
395 if (ret)
396 return ret;
397 }
398
399 return 0;
400}
401
402static int poweroff_coreid(struct venus_core *core, unsigned int coreid_mask)
403{
404 int ret;
405
406 if (coreid_mask & VIDC_CORE_ID_1) {
407 ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
408 if (ret)
409 return ret;
410
411 vcodec_clks_disable(core, core->vcodec0_clks);
412
413 ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
414 if (ret)
415 return ret;
416
417 ret = pm_runtime_put_sync(core->pmdomains[1]);
418 if (ret < 0)
419 return ret;
420 }
421
422 if (coreid_mask & VIDC_CORE_ID_2) {
423 ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
424 if (ret)
425 return ret;
426
427 vcodec_clks_disable(core, core->vcodec1_clks);
428
429 ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
430 if (ret)
431 return ret;
432
433 ret = pm_runtime_put_sync(core->pmdomains[2]);
434 if (ret < 0)
435 return ret;
436 }
437
438 return 0;
439}
440
441static int poweron_coreid(struct venus_core *core, unsigned int coreid_mask)
442{
443 int ret;
444
445 if (coreid_mask & VIDC_CORE_ID_1) {
446 ret = pm_runtime_get_sync(core->pmdomains[1]);
447 if (ret < 0)
448 return ret;
449
450 ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
451 if (ret)
452 return ret;
453
454 ret = vcodec_clks_enable(core, core->vcodec0_clks);
455 if (ret)
456 return ret;
457
458 ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
459 if (ret < 0)
460 return ret;
461 }
462
463 if (coreid_mask & VIDC_CORE_ID_2) {
464 ret = pm_runtime_get_sync(core->pmdomains[2]);
465 if (ret < 0)
466 return ret;
467
468 ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
469 if (ret)
470 return ret;
471
472 ret = vcodec_clks_enable(core, core->vcodec1_clks);
473 if (ret)
474 return ret;
475
476 ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
477 if (ret < 0)
478 return ret;
479 }
480
481 return 0;
482}
483
484static void
485min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load)
486{
487 u32 mbs_per_sec, load, core1_load = 0, core2_load = 0;
488 u32 cores_max = core_num_max(inst);
489 struct venus_core *core = inst->core;
490 struct venus_inst *inst_pos;
491 unsigned long vpp_freq;
492 u32 coreid;
493
494 mutex_lock(&core->lock);
495
496 list_for_each_entry(inst_pos, &core->instances, list) {
497 if (inst_pos == inst)
498 continue;
499 vpp_freq = inst_pos->clk_data.codec_freq_data->vpp_freq;
500 coreid = inst_pos->clk_data.core_id;
501
502 mbs_per_sec = load_per_instance(inst_pos);
503 load = mbs_per_sec * vpp_freq;
504
505 if ((coreid & VIDC_CORE_ID_3) == VIDC_CORE_ID_3) {
506 core1_load += load / 2;
507 core2_load += load / 2;
508 } else if (coreid & VIDC_CORE_ID_1) {
509 core1_load += load;
510 } else if (coreid & VIDC_CORE_ID_2) {
511 core2_load += load;
512 }
513 }
514
515 *min_coreid = core1_load <= core2_load ?
516 VIDC_CORE_ID_1 : VIDC_CORE_ID_2;
517 *min_load = min(core1_load, core2_load);
518
519 if (cores_max < VIDC_CORE_ID_2 || core->res->vcodec_num < 2) {
520 *min_coreid = VIDC_CORE_ID_1;
521 *min_load = core1_load;
522 }
523
524 mutex_unlock(&core->lock);
525}
526
527static int decide_core(struct venus_inst *inst)
528{
529 const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
530 struct venus_core *core = inst->core;
531 u32 min_coreid, min_load, inst_load;
532 struct hfi_videocores_usage_type cu;
533 unsigned long max_freq;
534
535 if (legacy_binding) {
536 if (inst->session_type == VIDC_SESSION_TYPE_DEC)
537 cu.video_core_enable_mask = VIDC_CORE_ID_1;
538 else
539 cu.video_core_enable_mask = VIDC_CORE_ID_2;
540
541 goto done;
542 }
543
544 if (inst->clk_data.core_id != VIDC_CORE_ID_DEFAULT)
545 return 0;
546
547 inst_load = load_per_instance(inst);
548 inst_load *= inst->clk_data.codec_freq_data->vpp_freq;
549 max_freq = core->res->freq_tbl[0].freq;
550
551 min_loaded_core(inst, &min_coreid, &min_load);
552
553 if ((inst_load + min_load) > max_freq) {
554 dev_warn(core->dev, "HW is overloaded, needed: %u max: %lu\n",
555 inst_load, max_freq);
556 return -EINVAL;
557 }
558
559 inst->clk_data.core_id = min_coreid;
560 cu.video_core_enable_mask = min_coreid;
561
562done:
563 return hfi_session_set_property(inst, ptype, &cu);
564}
565
566static int acquire_core(struct venus_inst *inst)
567{
568 struct venus_core *core = inst->core;
569 unsigned int coreid_mask = 0;
570
571 if (inst->core_acquired)
572 return 0;
573
574 inst->core_acquired = true;
575
576 if (inst->clk_data.core_id & VIDC_CORE_ID_1) {
577 if (core->core0_usage_count++)
578 return 0;
579
580 coreid_mask = VIDC_CORE_ID_1;
581 }
582
583 if (inst->clk_data.core_id & VIDC_CORE_ID_2) {
584 if (core->core1_usage_count++)
585 return 0;
586
587 coreid_mask |= VIDC_CORE_ID_2;
588 }
589
590 return poweron_coreid(core, coreid_mask);
591}
592
593static int release_core(struct venus_inst *inst)
594{
595 struct venus_core *core = inst->core;
596 unsigned int coreid_mask = 0;
597 int ret;
598
599 if (!inst->core_acquired)
600 return 0;
601
602 if (inst->clk_data.core_id & VIDC_CORE_ID_1) {
603 if (--core->core0_usage_count)
604 goto done;
605
606 coreid_mask = VIDC_CORE_ID_1;
607 }
608
609 if (inst->clk_data.core_id & VIDC_CORE_ID_2) {
610 if (--core->core1_usage_count)
611 goto done;
612
613 coreid_mask |= VIDC_CORE_ID_2;
614 }
615
616 ret = poweroff_coreid(core, coreid_mask);
617 if (ret)
618 return ret;
619
620done:
621 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
622 inst->core_acquired = false;
623 return 0;
624}
625
626static int coreid_power_v4(struct venus_inst *inst, int on)
627{
628 struct venus_core *core = inst->core;
629 int ret;
630
631 if (legacy_binding)
632 return 0;
633
634 if (on == POWER_ON) {
635 ret = decide_core(inst);
636 if (ret)
637 return ret;
638
639 mutex_lock(&core->lock);
640 ret = acquire_core(inst);
641 mutex_unlock(&core->lock);
642 } else {
643 mutex_lock(&core->lock);
644 ret = release_core(inst);
645 mutex_unlock(&core->lock);
646 }
647
648 return ret;
649}
650
651static int vdec_get_v4(struct device *dev)
652{
653 struct venus_core *core = dev_get_drvdata(dev);
654
655 if (!legacy_binding)
656 return 0;
657
658 return vcodec_clks_get(core, dev, core->vcodec0_clks,
659 core->res->vcodec0_clks);
660}
661
662static void vdec_put_v4(struct device *dev)
663{
664 struct venus_core *core = dev_get_drvdata(dev);
665 unsigned int i;
666
667 if (!legacy_binding)
668 return;
669
670 for (i = 0; i < core->res->vcodec_clks_num; i++)
671 core->vcodec0_clks[i] = NULL;
672}
673
674static int vdec_power_v4(struct device *dev, int on)
675{
676 struct venus_core *core = dev_get_drvdata(dev);
677 int ret;
678
679 if (!legacy_binding)
680 return 0;
681
682 ret = vcodec_control_v4(core, VIDC_CORE_ID_1, true);
683 if (ret)
684 return ret;
685
686 if (on == POWER_ON)
687 ret = vcodec_clks_enable(core, core->vcodec0_clks);
688 else
689 vcodec_clks_disable(core, core->vcodec0_clks);
690
691 vcodec_control_v4(core, VIDC_CORE_ID_1, false);
692
693 return ret;
694}
695
696static int venc_get_v4(struct device *dev)
697{
698 struct venus_core *core = dev_get_drvdata(dev);
699
700 if (!legacy_binding)
701 return 0;
702
703 return vcodec_clks_get(core, dev, core->vcodec1_clks,
704 core->res->vcodec1_clks);
705}
706
707static void venc_put_v4(struct device *dev)
708{
709 struct venus_core *core = dev_get_drvdata(dev);
710 unsigned int i;
711
712 if (!legacy_binding)
713 return;
714
715 for (i = 0; i < core->res->vcodec_clks_num; i++)
716 core->vcodec1_clks[i] = NULL;
717}
718
719static int venc_power_v4(struct device *dev, int on)
720{
721 struct venus_core *core = dev_get_drvdata(dev);
722 int ret;
723
724 if (!legacy_binding)
725 return 0;
726
727 ret = vcodec_control_v4(core, VIDC_CORE_ID_2, true);
728 if (ret)
729 return ret;
730
731 if (on == POWER_ON)
732 ret = vcodec_clks_enable(core, core->vcodec1_clks);
733 else
734 vcodec_clks_disable(core, core->vcodec1_clks);
735
736 vcodec_control_v4(core, VIDC_CORE_ID_2, false);
737
738 return ret;
739}
740
741static int vcodec_domains_get(struct device *dev)
742{
743 struct venus_core *core = dev_get_drvdata(dev);
744 const struct venus_resources *res = core->res;
745 struct device *pd;
746 unsigned int i;
747
748 if (!res->vcodec_pmdomains_num)
749 return -ENODEV;
750
751 for (i = 0; i < res->vcodec_pmdomains_num; i++) {
752 pd = dev_pm_domain_attach_by_name(dev,
753 res->vcodec_pmdomains[i]);
754 if (IS_ERR(pd))
755 return PTR_ERR(pd);
756 core->pmdomains[i] = pd;
757 }
758
759 core->pd_dl_venus = device_link_add(dev, core->pmdomains[0],
760 DL_FLAG_PM_RUNTIME |
761 DL_FLAG_STATELESS |
762 DL_FLAG_RPM_ACTIVE);
763 if (!core->pd_dl_venus)
764 return -ENODEV;
765
766 return 0;
767}
768
769static void vcodec_domains_put(struct device *dev)
770{
771 struct venus_core *core = dev_get_drvdata(dev);
772 const struct venus_resources *res = core->res;
773 unsigned int i;
774
775 if (!res->vcodec_pmdomains_num)
776 return;
777
778 if (core->pd_dl_venus)
779 device_link_del(core->pd_dl_venus);
780
781 for (i = 0; i < res->vcodec_pmdomains_num; i++) {
782 if (IS_ERR_OR_NULL(core->pmdomains[i]))
783 continue;
784 dev_pm_domain_detach(core->pmdomains[i], true);
785 }
786}
787
788static int core_get_v4(struct device *dev)
789{
790 struct venus_core *core = dev_get_drvdata(dev);
791 const struct venus_resources *res = core->res;
792 int ret;
793
794 ret = core_clks_get(core);
795 if (ret)
796 return ret;
797
798 if (!res->vcodec_pmdomains_num)
799 legacy_binding = true;
800
801 dev_info(dev, "%s legacy binding\n", legacy_binding ? "" : "non");
802
803 ret = vcodec_clks_get(core, dev, core->vcodec0_clks, res->vcodec0_clks);
804 if (ret)
805 return ret;
806
807 ret = vcodec_clks_get(core, dev, core->vcodec1_clks, res->vcodec1_clks);
808 if (ret)
809 return ret;
810
811 if (legacy_binding)
812 return 0;
813
814 ret = vcodec_domains_get(dev);
815 if (ret)
816 return ret;
817
818 return 0;
819}
820
821static void core_put_v4(struct device *dev)
822{
823 if (legacy_binding)
824 return;
825
826 vcodec_domains_put(dev);
827}
828
829static int core_power_v4(struct device *dev, int on)
830{
831 struct venus_core *core = dev_get_drvdata(dev);
832 int ret = 0;
833
834 if (on == POWER_ON)
835 ret = core_clks_enable(core);
836 else
837 core_clks_disable(core);
838
839 return ret;
840}
841
842static unsigned long calculate_inst_freq(struct venus_inst *inst,
843 unsigned long filled_len)
844{
845 unsigned long vpp_freq = 0, vsp_freq = 0;
846 u32 fps = (u32)inst->fps;
847 u32 mbs_per_sec;
848
849 mbs_per_sec = load_per_instance(inst) / fps;
850
851 vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
852 /* 21 / 20 is overhead factor */
853 vpp_freq += vpp_freq / 20;
854 vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
855
856 /* 10 / 7 is overhead factor */
857 if (inst->session_type == VIDC_SESSION_TYPE_ENC)
858 vsp_freq += (inst->controls.enc.bitrate * 10) / 7;
859 else
860 vsp_freq += ((fps * filled_len * 8) * 10) / 7;
861
862 return max(vpp_freq, vsp_freq);
863}
864
865static int load_scale_v4(struct venus_inst *inst)
866{
867 struct venus_core *core = inst->core;
868 const struct freq_tbl *table = core->res->freq_tbl;
869 unsigned int num_rows = core->res->freq_tbl_size;
870 struct device *dev = core->dev;
871 unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
872 unsigned long filled_len = 0;
873 int i, ret;
874
875 for (i = 0; i < inst->num_input_bufs; i++)
876 filled_len = max(filled_len, inst->payloads[i]);
877
878 if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len)
879 return 0;
880
881 freq = calculate_inst_freq(inst, filled_len);
882 inst->clk_data.freq = freq;
883
884 mutex_lock(&core->lock);
885 list_for_each_entry(inst, &core->instances, list) {
886 if (inst->clk_data.core_id == VIDC_CORE_ID_1) {
887 freq_core1 += inst->clk_data.freq;
888 } else if (inst->clk_data.core_id == VIDC_CORE_ID_2) {
889 freq_core2 += inst->clk_data.freq;
890 } else if (inst->clk_data.core_id == VIDC_CORE_ID_3) {
891 freq_core1 += inst->clk_data.freq;
892 freq_core2 += inst->clk_data.freq;
893 }
894 }
895 mutex_unlock(&core->lock);
896
897 freq = max(freq_core1, freq_core2);
898
899 if (freq >= table[0].freq) {
900 freq = table[0].freq;
901 dev_warn(dev, "HW is overloaded, needed: %lu max: %lu\n",
902 freq, table[0].freq);
903 goto set_freq;
904 }
905
906 for (i = num_rows - 1 ; i >= 0; i--) {
907 if (freq <= table[i].freq) {
908 freq = table[i].freq;
909 break;
910 }
911 }
912
913set_freq:
914
915 ret = core_clks_set_rate(core, freq);
916 if (ret) {
917 dev_err(dev, "failed to set clock rate %lu (%d)\n",
918 freq, ret);
919 return ret;
920 }
921
922 ret = load_scale_bw(core);
923 if (ret) {
924 dev_err(dev, "failed to set bandwidth (%d)\n",
925 ret);
926 return ret;
927 }
928
929 return 0;
930}
931
932static const struct venus_pm_ops pm_ops_v4 = {
933 .core_get = core_get_v4,
934 .core_put = core_put_v4,
935 .core_power = core_power_v4,
936 .vdec_get = vdec_get_v4,
937 .vdec_put = vdec_put_v4,
938 .vdec_power = vdec_power_v4,
939 .venc_get = venc_get_v4,
940 .venc_put = venc_put_v4,
941 .venc_power = venc_power_v4,
942 .coreid_power = coreid_power_v4,
943 .load_scale = load_scale_v4,
944};
945
946const struct venus_pm_ops *venus_pm_get(enum hfi_version version)
947{
948 switch (version) {
949 case HFI_VERSION_1XX:
950 default:
951 return &pm_ops_v1;
952 case HFI_VERSION_3XX:
953 return &pm_ops_v3;
954 case HFI_VERSION_4XX:
955 return &pm_ops_v4;
956 }
957
958 return NULL;
959}
drivers/media/platform/qcom/venus/pm_helpers.h+65−0
@@ -0,0 +1,65 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/* Copyright (C) 2019 Linaro Ltd. */
3#ifndef __VENUS_PM_HELPERS_H__
4#define __VENUS_PM_HELPERS_H__
5
6struct device;
7
8#define POWER_ON 1
9#define POWER_OFF 0
10
11struct venus_pm_ops {
12 int (*core_get)(struct device *dev);
13 void (*core_put)(struct device *dev);
14 int (*core_power)(struct device *dev, int on);
15
16 int (*vdec_get)(struct device *dev);
17 void (*vdec_put)(struct device *dev);
18 int (*vdec_power)(struct device *dev, int on);
19
20 int (*venc_get)(struct device *dev);
21 void (*venc_put)(struct device *dev);
22 int (*venc_power)(struct device *dev, int on);
23
24 int (*coreid_power)(struct venus_inst *inst, int on);
25
26 int (*load_scale)(struct venus_inst *inst);
27};
28
29const struct venus_pm_ops *venus_pm_get(enum hfi_version version);
30
31static inline int venus_pm_load_scale(struct venus_inst *inst)
32{
33 struct venus_core *core = inst->core;
34
35 if (!core->pm_ops || !core->pm_ops->load_scale)
36 return 0;
37
38 return core->pm_ops->load_scale(inst);
39}
40
41static inline int venus_pm_acquire_core(struct venus_inst *inst)
42{
43 struct venus_core *core = inst->core;
44 const struct venus_pm_ops *pm_ops = core->pm_ops;
45 int ret = 0;
46
47 if (pm_ops && pm_ops->coreid_power)
48 ret = pm_ops->coreid_power(inst, POWER_ON);
49
50 return ret;
51}
52
53static inline int venus_pm_release_core(struct venus_inst *inst)
54{
55 struct venus_core *core = inst->core;
56 const struct venus_pm_ops *pm_ops = core->pm_ops;
57 int ret = 0;
58
59 if (pm_ops && pm_ops->coreid_power)
60 ret = pm_ops->coreid_power(inst, POWER_OFF);
61
62 return ret;
63}
64
65#endif
drivers/media/platform/qcom/venus/vdec.c+32−54
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include "core.h"20#include "core.h"
21#include "helpers.h"21#include "helpers.h"
22#include "vdec.h"22#include "vdec.h"
23#include "pm_helpers.h"
23 24
24/*25/*
25 * Three resons to keep MPLANE formats (despite that the number of planes26 * Three resons to keep MPLANE formats (despite that the number of planes
@@ -578,10 +579,6 @@ static int vdec_output_conf(struct venus_inst *inst) · 552 unmodified lines
578 if (ret)579 if (ret)
579 return ret;580 return ret;
580 581
581 ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_1);
582 if (ret)
583 return ret;
584
585 if (core->res->hfi_version == HFI_VERSION_1XX) {582 if (core->res->hfi_version == HFI_VERSION_1XX) {
586 ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;583 ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
587 ret = hfi_session_set_property(inst, ptype, &en);584 ret = hfi_session_set_property(inst, ptype, &en);
@@ -868,7 +865,7 @@ reconfigure: · 280 unmodified lines
868 if (ret)865 if (ret)
869 goto free_dpb_bufs;866 goto free_dpb_bufs;
870 867
871 venus_helper_load_scale_clocks(inst);868 venus_pm_load_scale(inst);
872 869
873 ret = hfi_session_continue(inst);870 ret = hfi_session_continue(inst);
874 if (ret)871 if (ret)
@@ -950,6 +947,10 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) · 75 unmodified lines
950 947
951 mutex_lock(&inst->lock);948 mutex_lock(&inst->lock);
952 949
950 ret = venus_pm_acquire_core(inst);
951 if (ret)
952 goto error;
953
953 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)954 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
954 ret = vdec_start_capture(inst);955 ret = vdec_start_capture(inst);
955 else956 else
@@ -1076,7 +1077,8 @@ static void vdec_session_release(struct venus_inst *inst) · 120 unmodified lines
1076 hfi_session_abort(inst);1077 hfi_session_abort(inst);
1077 1078
1078 venus_helper_free_dpb_bufs(inst);1079 venus_helper_free_dpb_bufs(inst);
1079 venus_helper_load_scale_clocks(inst);1080 venus_pm_load_scale(inst);
1081 venus_pm_release_core(inst);
1080 INIT_LIST_HEAD(&inst->registeredbufs);1082 INIT_LIST_HEAD(&inst->registeredbufs);
1081 1083
1082 mutex_unlock(&inst->lock);1084 mutex_unlock(&inst->lock);
@@ -1191,6 +1193,9 @@ static void vdec_event_change(struct venus_inst *inst, · 108 unmodified lines
1191 inst->out_width = ev_data->width;1193 inst->out_width = ev_data->width;
1192 inst->out_height = ev_data->height;1194 inst->out_height = ev_data->height;
1193 1195
1196 if (inst->bit_depth != ev_data->bit_depth)
1197 inst->bit_depth = ev_data->bit_depth;
1198
1194 dev_dbg(dev, "event %s sufficient resources (%ux%u)\n",1199 dev_dbg(dev, "event %s sufficient resources (%ux%u)\n",
1195 sufficient ? "" : "not", ev_data->width, ev_data->height);1200 sufficient ? "" : "not", ev_data->width, ev_data->height);
1196 1201
@@ -1336,6 +1341,9 @@ static int vdec_open(struct file *file) · 139 unmodified lines
1336 inst->num_output_bufs = 1;1341 inst->num_output_bufs = 1;
1337 inst->codec_state = VENUS_DEC_STATE_DEINIT;1342 inst->codec_state = VENUS_DEC_STATE_DEINIT;
1338 inst->buf_count = 0;1343 inst->buf_count = 0;
1344 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
1345 inst->core_acquired = false;
1346 inst->bit_depth = VIDC_BITDEPTH_8;
1339 init_waitqueue_head(&inst->reconf_wait);1347 init_waitqueue_head(&inst->reconf_wait);
1340 venus_helper_init_instance(inst);1348 venus_helper_init_instance(inst);
1341 1349
@@ -1432,20 +1440,14 @@ static int vdec_probe(struct platform_device *pdev) · 90 unmodified lines
1432 if (!core)1440 if (!core)
1433 return -EPROBE_DEFER;1441 return -EPROBE_DEFER;
1434 1442
1435 if (IS_V3(core) || IS_V4(core)) {1443 platform_set_drvdata(pdev, core);
1436 core->core0_clk = devm_clk_get(dev, "core");
1437 if (IS_ERR(core->core0_clk))
1438 return PTR_ERR(core->core0_clk);
1439 }
1440 1444
1441 if (IS_V4(core)) {1445 if (core->pm_ops->vdec_get) {
1442 core->core0_bus_clk = devm_clk_get(dev, "bus");1446 ret = core->pm_ops->vdec_get(dev);
1443 if (IS_ERR(core->core0_bus_clk))1447 if (ret)
1444 return PTR_ERR(core->core0_bus_clk);1448 return ret;
1445 }1449 }
1446 1450
1447 platform_set_drvdata(pdev, core);
1448
1449 vdev = video_device_alloc();1451 vdev = video_device_alloc();
1450 if (!vdev)1452 if (!vdev)
1451 return -ENOMEM;1453 return -ENOMEM;
@@ -1458,7 +1460,7 @@ static int vdec_probe(struct platform_device *pdev) · 6 unmodified lines
1458 vdev->v4l2_dev = &core->v4l2_dev;1460 vdev->v4l2_dev = &core->v4l2_dev;
1459 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;1461 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
1460 1462
1461 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1463 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1462 if (ret)1464 if (ret)
1463 goto err_vdev_release;1465 goto err_vdev_release;
1464 1466
@@ -1482,57 +1484,33 @@ static int vdec_remove(struct platform_device *pdev) · 17 unmodified lines
1482 video_unregister_device(core->vdev_dec);1484 video_unregister_device(core->vdev_dec);
1483 pm_runtime_disable(core->dev_dec);1485 pm_runtime_disable(core->dev_dec);
1484 1486
1487 if (core->pm_ops->vdec_put)
1488 core->pm_ops->vdec_put(core->dev_dec);
1489
1485 return 0;1490 return 0;
1486}1491}
1487 1492
1488static __maybe_unused int vdec_runtime_suspend(struct device *dev)1493static __maybe_unused int vdec_runtime_suspend(struct device *dev)
1489{1494{
1490 struct venus_core *core = dev_get_drvdata(dev);1495 struct venus_core *core = dev_get_drvdata(dev);
1491 int ret;1496 const struct venus_pm_ops *pm_ops = core->pm_ops;
1492 1497 int ret = 0;
1493 if (IS_V1(core))
1494 return 0;
1495
1496 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
1497 if (ret)
1498 return ret;
1499
1500 if (IS_V4(core))
1501 clk_disable_unprepare(core->core0_bus_clk);
1502 1498
1503 clk_disable_unprepare(core->core0_clk);1499 if (pm_ops->vdec_power)
1500 ret = pm_ops->vdec_power(dev, POWER_OFF);
1504 1501
1505 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);1502 return ret;
1506}1503}
1507 1504
1508static __maybe_unused int vdec_runtime_resume(struct device *dev)1505static __maybe_unused int vdec_runtime_resume(struct device *dev)
1509{1506{
1510 struct venus_core *core = dev_get_drvdata(dev);1507 struct venus_core *core = dev_get_drvdata(dev);
1511 int ret;1508 const struct venus_pm_ops *pm_ops = core->pm_ops;
1512 1509 int ret = 0;
1513 if (IS_V1(core))
1514 return 0;
1515
1516 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
1517 if (ret)
1518 return ret;
1519
1520 ret = clk_prepare_enable(core->core0_clk);
1521 if (ret)
1522 goto err_power_disable;
1523
1524 if (IS_V4(core))
1525 ret = clk_prepare_enable(core->core0_bus_clk);
1526
1527 if (ret)
1528 goto err_unprepare_core0;
1529 1510
1530 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);1511 if (pm_ops->vdec_power)
1512 ret = pm_ops->vdec_power(dev, POWER_ON);
1531 1513
1532err_unprepare_core0:
1533 clk_disable_unprepare(core->core0_clk);
1534err_power_disable:
1535 venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
1536 return ret;1514 return ret;
1537}1515}
1538 1516
drivers/media/platform/qcom/venus/venc.c+28−53
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include "core.h"20#include "core.h"
21#include "helpers.h"21#include "helpers.h"
22#include "venc.h"22#include "venc.h"
23#include "pm_helpers.h"
23 24
24#define NUM_B_FRAMES_MAX 425#define NUM_B_FRAMES_MAX 4
25 26
@@ -655,10 +656,6 @@ static int venc_set_properties(struct venus_inst *inst) · 629 unmodified lines
655 if (ret)656 if (ret)
656 return ret;657 return ret;
657 658
658 ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2);
659 if (ret)
660 return ret;
661
662 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE;659 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE;
663 frate.buffer_type = HFI_BUFFER_OUTPUT;660 frate.buffer_type = HFI_BUFFER_OUTPUT;
664 frate.framerate = inst->fps * (1 << 16);661 frate.framerate = inst->fps * (1 << 16);
@@ -731,7 +728,9 @@ static int venc_set_properties(struct venus_inst *inst) · 66 unmodified lines
731 if (ret)728 if (ret)
732 return ret;729 return ret;
733 730
734 if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)731 if (!ctr->rc_enable)
732 rate_control = HFI_RATE_CONTROL_OFF;
733 else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
735 rate_control = HFI_RATE_CONTROL_VBR_CFR;734 rate_control = HFI_RATE_CONTROL_VBR_CFR;
736 else735 else
737 rate_control = HFI_RATE_CONTROL_CBR_CFR;736 rate_control = HFI_RATE_CONTROL_CBR_CFR;
@@ -991,6 +990,10 @@ static int venc_start_streaming(struct vb2_queue *q, unsigned int count) · 253 unmodified lines
991 if (ret)990 if (ret)
992 goto bufs_done;991 goto bufs_done;
993 992
993 ret = venus_pm_acquire_core(inst);
994 if (ret)
995 goto deinit_sess;
996
994 ret = venc_set_properties(inst);997 ret = venc_set_properties(inst);
995 if (ret)998 if (ret)
996 goto deinit_sess;999 goto deinit_sess;
@@ -1159,6 +1162,8 @@ static int venc_open(struct file *file) · 162 unmodified lines
1159 1162
1160 inst->core = core;1163 inst->core = core;
1161 inst->session_type = VIDC_SESSION_TYPE_ENC;1164 inst->session_type = VIDC_SESSION_TYPE_ENC;
1165 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
1166 inst->core_acquired = false;
1162 1167
1163 venus_helper_init_instance(inst);1168 venus_helper_init_instance(inst);
1164 1169
@@ -1255,20 +1260,14 @@ static int venc_probe(struct platform_device *pdev) · 90 unmodified lines
1255 if (!core)1260 if (!core)
1256 return -EPROBE_DEFER;1261 return -EPROBE_DEFER;
1257 1262
1258 if (IS_V3(core) || IS_V4(core)) {1263 platform_set_drvdata(pdev, core);
1259 core->core1_clk = devm_clk_get(dev, "core");
1260 if (IS_ERR(core->core1_clk))
1261 return PTR_ERR(core->core1_clk);
1262 }
1263 1264
1264 if (IS_V4(core)) {1265 if (core->pm_ops->venc_get) {
1265 core->core1_bus_clk = devm_clk_get(dev, "bus");1266 ret = core->pm_ops->venc_get(dev);
1266 if (IS_ERR(core->core1_bus_clk))1267 if (ret)
1267 return PTR_ERR(core->core1_bus_clk);1268 return ret;
1268 }1269 }
1269 1270
1270 platform_set_drvdata(pdev, core);
1271
1272 vdev = video_device_alloc();1271 vdev = video_device_alloc();
1273 if (!vdev)1272 if (!vdev)
1274 return -ENOMEM;1273 return -ENOMEM;
@@ -1281,7 +1280,7 @@ static int venc_probe(struct platform_device *pdev) · 6 unmodified lines
1281 vdev->v4l2_dev = &core->v4l2_dev;1280 vdev->v4l2_dev = &core->v4l2_dev;
1282 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;1281 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
1283 1282
1284 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1283 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1285 if (ret)1284 if (ret)
1286 goto err_vdev_release;1285 goto err_vdev_release;
1287 1286
@@ -1305,57 +1304,33 @@ static int venc_remove(struct platform_device *pdev) · 17 unmodified lines
1305 video_unregister_device(core->vdev_enc);1304 video_unregister_device(core->vdev_enc);
1306 pm_runtime_disable(core->dev_enc);1305 pm_runtime_disable(core->dev_enc);
1307 1306
1307 if (core->pm_ops->venc_put)
1308 core->pm_ops->venc_put(core->dev_enc);
1309
1308 return 0;1310 return 0;
1309}1311}
1310 1312
1311static __maybe_unused int venc_runtime_suspend(struct device *dev)1313static __maybe_unused int venc_runtime_suspend(struct device *dev)
1312{1314{
1313 struct venus_core *core = dev_get_drvdata(dev);1315 struct venus_core *core = dev_get_drvdata(dev);
1314 int ret;1316 const struct venus_pm_ops *pm_ops = core->pm_ops;
1315 1317 int ret = 0;
1316 if (IS_V1(core))
1317 return 0;
1318
1319 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true);
1320 if (ret)
1321 return ret;
1322
1323 if (IS_V4(core))
1324 clk_disable_unprepare(core->core1_bus_clk);
1325 1318
1326 clk_disable_unprepare(core->core1_clk);1319 if (pm_ops->venc_power)
1320 ret = pm_ops->venc_power(dev, POWER_OFF);
1327 1321
1328 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false);1322 return ret;
1329}1323}
1330 1324
1331static __maybe_unused int venc_runtime_resume(struct device *dev)1325static __maybe_unused int venc_runtime_resume(struct device *dev)
1332{1326{
1333 struct venus_core *core = dev_get_drvdata(dev);1327 struct venus_core *core = dev_get_drvdata(dev);
1334 int ret;1328 const struct venus_pm_ops *pm_ops = core->pm_ops;
1335 1329 int ret = 0;
1336 if (IS_V1(core))
1337 return 0;
1338
1339 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true);
1340 if (ret)
1341 return ret;
1342
1343 ret = clk_prepare_enable(core->core1_clk);
1344 if (ret)
1345 goto err_power_disable;
1346
1347 if (IS_V4(core))
1348 ret = clk_prepare_enable(core->core1_bus_clk);
1349
1350 if (ret)
1351 goto err_unprepare_core1;
1352 1330
1353 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false);1331 if (pm_ops->venc_power)
1332 ret = pm_ops->venc_power(dev, POWER_ON);
1354 1333
1355err_unprepare_core1:
1356 clk_disable_unprepare(core->core1_clk);
1357err_power_disable:
1358 venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false);
1359 return ret;1334 return ret;
1360}1335}
1361 1336
drivers/media/platform/qcom/venus/venc_ctrls.c+7−1
@@ -199,6 +199,9 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) · 198 unmodified lines
199 }199 }
200 mutex_unlock(&inst->lock);200 mutex_unlock(&inst->lock);
201 break;201 break;
202 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
203 ctr->rc_enable = ctrl->val;
204 break;
202 default:205 default:
203 return -EINVAL;206 return -EINVAL;
204 }207 }
@@ -214,7 +217,7 @@ int venc_ctrl_init(struct venus_inst *inst) · 9 unmodified lines
214{217{
215 int ret;218 int ret;
216 219
217 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 30);220 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 31);
218 if (ret)221 if (ret)
219 return ret;222 return ret;
220 223
@@ -351,6 +354,9 @@ int venc_ctrl_init(struct venus_inst *inst) · 130 unmodified lines
351 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,354 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
352 V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);355 V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
353 356
357 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
358 V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);
359
354 ret = inst->ctrl_handler.error;360 ret = inst->ctrl_handler.error;
355 if (ret)361 if (ret)
356 goto err;362 goto err;
drivers/media/platform/rcar-vin/rcar-dma.c+71−20
@@ -535,7 +535,7 @@ static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) · 534 unmodified lines
535 535
536 /* Set scaling coefficient */536 /* Set scaling coefficient */
537 crop_height = vin->crop.height;537 crop_height = vin->crop.height;
538 if (V4L2_FIELD_IS_INTERLACED(vin->format.field))538 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
539 crop_height *= 2;539 crop_height *= 2;
540 540
541 ys = 0;541 ys = 0;
@@ -564,7 +564,7 @@ static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) · 22 unmodified lines
564 rvin_write(vin, 0, VNSLPOC_REG);564 rvin_write(vin, 0, VNSLPOC_REG);
565 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);565 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);
566 566
567 if (V4L2_FIELD_IS_INTERLACED(vin->format.field))567 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
568 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);568 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);
569 else569 else
570 rvin_write(vin, vin->format.height - 1, VNELPOC_REG);570 rvin_write(vin, vin->format.height - 1, VNELPOC_REG);
@@ -626,6 +626,8 @@ static int rvin_setup(struct rvin_dev *vin) · 55 unmodified lines
626 case V4L2_FIELD_INTERLACED_BT:626 case V4L2_FIELD_INTERLACED_BT:
627 vnmc = VNMC_IM_FULL | VNMC_FOC;627 vnmc = VNMC_IM_FULL | VNMC_FOC;
628 break;628 break;
629 case V4L2_FIELD_SEQ_TB:
630 case V4L2_FIELD_SEQ_BT:
629 case V4L2_FIELD_NONE:631 case V4L2_FIELD_NONE:
630 vnmc = VNMC_IM_ODD_EVEN;632 vnmc = VNMC_IM_ODD_EVEN;
631 progressive = true;633 progressive = true;
@@ -842,27 +844,52 @@ static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot) · 210 unmodified lines
842 struct rvin_buffer *buf;844 struct rvin_buffer *buf;
843 struct vb2_v4l2_buffer *vbuf;845 struct vb2_v4l2_buffer *vbuf;
844 dma_addr_t phys_addr;846 dma_addr_t phys_addr;
847 int prev;
845 848
846 /* A already populated slot shall never be overwritten. */849 /* A already populated slot shall never be overwritten. */
847 if (WARN_ON(vin->queue_buf[slot] != NULL))850 if (WARN_ON(vin->buf_hw[slot].buffer))
848 return;851 return;
849 852
850 vin_dbg(vin, "Filling HW slot: %d\n", slot);853 prev = (slot == 0 ? HW_BUFFER_NUM : slot) - 1;
851 854
852 if (list_empty(&vin->buf_list)) {855 if (vin->buf_hw[prev].type == HALF_TOP) {
853 vin->queue_buf[slot] = NULL;856 vbuf = vin->buf_hw[prev].buffer;
857 vin->buf_hw[slot].buffer = vbuf;
858 vin->buf_hw[slot].type = HALF_BOTTOM;
859 switch (vin->format.pixelformat) {
860 case V4L2_PIX_FMT_NV12:
861 case V4L2_PIX_FMT_NV16:
862 phys_addr = vin->buf_hw[prev].phys +
863 vin->format.sizeimage / 4;
864 break;
865 default:
866 phys_addr = vin->buf_hw[prev].phys +
867 vin->format.sizeimage / 2;
868 break;
869 }
870 } else if (list_empty(&vin->buf_list)) {
871 vin->buf_hw[slot].buffer = NULL;
872 vin->buf_hw[slot].type = FULL;
854 phys_addr = vin->scratch_phys;873 phys_addr = vin->scratch_phys;
855 } else {874 } else {
856 /* Keep track of buffer we give to HW */875 /* Keep track of buffer we give to HW */
857 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);876 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
858 vbuf = &buf->vb;877 vbuf = &buf->vb;
859 list_del_init(to_buf_list(vbuf));878 list_del_init(to_buf_list(vbuf));
860 vin->queue_buf[slot] = vbuf;879 vin->buf_hw[slot].buffer = vbuf;
880
881 vin->buf_hw[slot].type =
882 V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ?
883 HALF_TOP : FULL;
861 884
862 /* Setup DMA */885 /* Setup DMA */
863 phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);886 phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
864 }887 }
865 888
889 vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n",
890 slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer);
891
892 vin->buf_hw[slot].phys = phys_addr;
866 rvin_set_slot_addr(vin, slot, phys_addr);893 rvin_set_slot_addr(vin, slot, phys_addr);
867}894}
868 895
@@ -870,6 +897,11 @@ static int rvin_capture_start(struct rvin_dev *vin) · 1 unmodified line
870{897{
871 int slot, ret;898 int slot, ret;
872 899
900 for (slot = 0; slot < HW_BUFFER_NUM; slot++) {
901 vin->buf_hw[slot].buffer = NULL;
902 vin->buf_hw[slot].type = FULL;
903 }
904
873 for (slot = 0; slot < HW_BUFFER_NUM; slot++)905 for (slot = 0; slot < HW_BUFFER_NUM; slot++)
874 rvin_fill_hw_slot(vin, slot);906 rvin_fill_hw_slot(vin, slot);
875 907
@@ -953,13 +985,24 @@ static irqreturn_t rvin_irq(int irq, void *data) · 77 unmodified lines
953 }985 }
954 986
955 /* Capture frame */987 /* Capture frame */
956 if (vin->queue_buf[slot]) {988 if (vin->buf_hw[slot].buffer) {
957 vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms);989 /*
958 vin->queue_buf[slot]->sequence = vin->sequence;990 * Nothing to do but refill the hardware slot if
959 vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();991 * capture only filled first half of vb2 buffer.
960 vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf,992 */
993 if (vin->buf_hw[slot].type == HALF_TOP) {
994 vin->buf_hw[slot].buffer = NULL;
995 rvin_fill_hw_slot(vin, slot);
996 goto done;
997 }
998
999 vin->buf_hw[slot].buffer->field =
1000 rvin_get_active_field(vin, vnms);
1001 vin->buf_hw[slot].buffer->sequence = vin->sequence;
1002 vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns();
1003 vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf,
961 VB2_BUF_STATE_DONE);1004 VB2_BUF_STATE_DONE);
962 vin->queue_buf[slot] = NULL;1005 vin->buf_hw[slot].buffer = NULL;
963 } else {1006 } else {
964 /* Scratch buffer was used, dropping frame. */1007 /* Scratch buffer was used, dropping frame. */
965 vin_dbg(vin, "Dropping frame %u\n", vin->sequence);1008 vin_dbg(vin, "Dropping frame %u\n", vin->sequence);
@@ -980,14 +1023,22 @@ static void return_all_buffers(struct rvin_dev *vin, · 14 unmodified lines
980 enum vb2_buffer_state state)1023 enum vb2_buffer_state state)
981{1024{
982 struct rvin_buffer *buf, *node;1025 struct rvin_buffer *buf, *node;
983 int i;1026 struct vb2_v4l2_buffer *freed[HW_BUFFER_NUM];
1027 unsigned int i, n;
984 1028
985 for (i = 0; i < HW_BUFFER_NUM; i++) {1029 for (i = 0; i < HW_BUFFER_NUM; i++) {
986 if (vin->queue_buf[i]) {1030 freed[i] = vin->buf_hw[i].buffer;
987 vb2_buffer_done(&vin->queue_buf[i]->vb2_buf,1031 vin->buf_hw[i].buffer = NULL;
988 state);1032
989 vin->queue_buf[i] = NULL;1033 for (n = 0; n < i; n++) {
1034 if (freed[i] == freed[n]) {
1035 freed[i] = NULL;
1036 break;
1037 }
990 }1038 }
1039
1040 if (freed[i])
1041 vb2_buffer_done(&freed[i]->vb2_buf, state);
991 }1042 }
992 1043
993 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {1044 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
@@ -1291,7 +1342,7 @@ int rvin_dma_register(struct rvin_dev *vin, int irq) · 297 unmodified lines
1291 vin->state = STOPPED;1342 vin->state = STOPPED;
1292 1343
1293 for (i = 0; i < HW_BUFFER_NUM; i++)1344 for (i = 0; i < HW_BUFFER_NUM; i++)
1294 vin->queue_buf[i] = NULL;1345 vin->buf_hw[i].buffer = NULL;
1295 1346
1296 /* buffer queue */1347 /* buffer queue */
1297 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1348 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
drivers/media/platform/rcar-vin/rcar-v4l2.c+25−9
@@ -73,11 +73,22 @@ const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin, · 72 unmodified lines
73{73{
74 int i;74 int i;
75 75
76 if (vin->info->model == RCAR_M1 && pixelformat == V4L2_PIX_FMT_XBGR32)76 switch (pixelformat) {
77 return NULL;77 case V4L2_PIX_FMT_XBGR32:
78 78 if (vin->info->model == RCAR_M1)
79 if (pixelformat == V4L2_PIX_FMT_NV12 && !vin->info->nv12)79 return NULL;
80 return NULL;80 break;
81 case V4L2_PIX_FMT_NV12:
82 /*
83 * If NV12 is supported it's only supported on channels 0, 1, 4,
84 * 5, 8, 9, 12 and 13.
85 */
86 if (!vin->info->nv12 || !(BIT(vin->id) & 0x3333))
87 return NULL;
88 break;
89 default:
90 break;
91 }
81 92
82 for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)93 for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)
83 if (rvin_formats[i].fourcc == pixelformat)94 if (rvin_formats[i].fourcc == pixelformat)
@@ -107,6 +118,9 @@ static u32 rvin_format_bytesperline(struct rvin_dev *vin, · 23 unmodified lines
107 break;118 break;
108 }119 }
109 120
121 if (V4L2_FIELD_IS_SEQUENTIAL(pix->field))
122 align = 0x80;
123
110 return ALIGN(pix->width, align) * fmt->bpp;124 return ALIGN(pix->width, align) * fmt->bpp;
111}125}
112 126
@@ -137,6 +151,8 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) · 24 unmodified lines
137 case V4L2_FIELD_INTERLACED_BT:151 case V4L2_FIELD_INTERLACED_BT:
138 case V4L2_FIELD_INTERLACED:152 case V4L2_FIELD_INTERLACED:
139 case V4L2_FIELD_ALTERNATE:153 case V4L2_FIELD_ALTERNATE:
154 case V4L2_FIELD_SEQ_TB:
155 case V4L2_FIELD_SEQ_BT:
140 break;156 break;
141 default:157 default:
142 pix->field = RVIN_DEFAULT_FIELD;158 pix->field = RVIN_DEFAULT_FIELD;
@@ -826,7 +842,7 @@ static int rvin_open(struct file *file) · 683 unmodified lines
826 goto err_unlock;842 goto err_unlock;
827 843
828 if (vin->info->use_mc)844 if (vin->info->use_mc)
829 ret = v4l2_pipeline_pm_use(&vin->vdev.entity, 1);845 ret = v4l2_pipeline_pm_get(&vin->vdev.entity);
830 else if (v4l2_fh_is_singular_file(file))846 else if (v4l2_fh_is_singular_file(file))
831 ret = rvin_power_parallel(vin, true);847 ret = rvin_power_parallel(vin, true);
832 848
@@ -842,7 +858,7 @@ static int rvin_open(struct file *file) · 9 unmodified lines
842 return 0;858 return 0;
843err_power:859err_power:
844 if (vin->info->use_mc)860 if (vin->info->use_mc)
845 v4l2_pipeline_pm_use(&vin->vdev.entity, 0);861 v4l2_pipeline_pm_put(&vin->vdev.entity);
846 else if (v4l2_fh_is_singular_file(file))862 else if (v4l2_fh_is_singular_file(file))
847 rvin_power_parallel(vin, false);863 rvin_power_parallel(vin, false);
848err_open:864err_open:
@@ -870,7 +886,7 @@ static int rvin_release(struct file *file) · 21 unmodified lines
870 ret = _vb2_fop_release(file, NULL);886 ret = _vb2_fop_release(file, NULL);
871 887
872 if (vin->info->use_mc) {888 if (vin->info->use_mc) {
873 v4l2_pipeline_pm_use(&vin->vdev.entity, 0);889 v4l2_pipeline_pm_put(&vin->vdev.entity);
874 } else {890 } else {
875 if (fh_singular)891 if (fh_singular)
876 rvin_power_parallel(vin, false);892 rvin_power_parallel(vin, false);
@@ -953,7 +969,7 @@ int rvin_v4l2_register(struct rvin_dev *vin) · 76 unmodified lines
953 969
954 rvin_format_align(vin, &vin->format);970 rvin_format_align(vin, &vin->format);
955 971
956 ret = video_register_device(&vin->vdev, VFL_TYPE_GRABBER, -1);972 ret = video_register_device(&vin->vdev, VFL_TYPE_VIDEO, -1);
957 if (ret) {973 if (ret) {
958 vin_err(vin, "Failed to register video device\n");974 vin_err(vin, "Failed to register video device\n");
959 return ret;975 return ret;
drivers/media/platform/rcar-vin/rcar-vin.h+24−4
@@ -60,6 +60,23 @@ enum rvin_dma_state { · 59 unmodified lines
60 STOPPING,60 STOPPING,
61};61};
62 62
63/**
64 * enum rvin_buffer_type
65 *
66 * Describes how a buffer is given to the hardware. To be able
67 * to capture SEQ_TB/BT it's needed to capture to the same vb2
68 * buffer twice so the type of buffer needs to be kept.
69 *
70 * FULL - One capture fills the whole vb2 buffer
71 * HALF_TOP - One capture fills the top half of the vb2 buffer
72 * HALF_BOTTOM - One capture fills the bottom half of the vb2 buffer
73 */
74enum rvin_buffer_type {
75 FULL,
76 HALF_TOP,
77 HALF_BOTTOM,
78};
79
63/**80/**
64 * struct rvin_video_format - Data format stored in memory81 * struct rvin_video_format - Data format stored in memory
65 * @fourcc: Pixelformat82 * @fourcc: Pixelformat
@@ -164,9 +181,8 @@ struct rvin_info { · 98 unmodified lines
164 * @scratch: cpu address for scratch buffer181 * @scratch: cpu address for scratch buffer
165 * @scratch_phys: physical address of the scratch buffer182 * @scratch_phys: physical address of the scratch buffer
166 *183 *
167 * @qlock: protects @queue_buf, @buf_list, @sequence184 * @qlock: protects @buf_hw, @buf_list, @sequence and @state
168 * @state185 * @buf_hw: Keeps track of buffers given to HW slot
169 * @queue_buf: Keeps track of buffers given to HW slot
170 * @buf_list: list of queued buffers186 * @buf_list: list of queued buffers
171 * @sequence: V4L2 buffers sequence number187 * @sequence: V4L2 buffers sequence number
172 * @state: keeps track of operation state188 * @state: keeps track of operation state
@@ -205,7 +221,11 @@ struct rvin_dev { · 32 unmodified lines
205 dma_addr_t scratch_phys;221 dma_addr_t scratch_phys;
206 222
207 spinlock_t qlock;223 spinlock_t qlock;
208 struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];224 struct {
225 struct vb2_v4l2_buffer *buffer;
226 enum rvin_buffer_type type;
227 dma_addr_t phys;
228 } buf_hw[HW_BUFFER_NUM];
209 struct list_head buf_list;229 struct list_head buf_list;
210 unsigned int sequence;230 unsigned int sequence;
211 enum rvin_dma_state state;231 enum rvin_dma_state state;
drivers/media/platform/rcar_drif.c+8−4
@@ -275,10 +275,14 @@ static int rcar_drif_alloc_dmachannels(struct rcar_drif_sdr *sdr) · 274 unmodified lines
275 for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) {275 for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) {
276 struct rcar_drif *ch = sdr->ch[i];276 struct rcar_drif *ch = sdr->ch[i];
277 277
278 ch->dmach = dma_request_slave_channel(&ch->pdev->dev, "rx");278 ch->dmach = dma_request_chan(&ch->pdev->dev, "rx");
279 if (!ch->dmach) {279 if (IS_ERR(ch->dmach)) {
280 rdrif_err(sdr, "ch%u: dma channel req failed\n", i);280 ret = PTR_ERR(ch->dmach);
281 ret = -ENODEV;281 if (ret != -EPROBE_DEFER)
282 rdrif_err(sdr,
283 "ch%u: dma channel req failed: %pe\n",
284 i, ch->dmach);
285 ch->dmach = NULL;
282 goto dmach_error;286 goto dmach_error;
283 }287 }
284 288
drivers/media/platform/rcar_fdp1.c+1−1
@@ -2344,7 +2344,7 @@ static int fdp1_probe(struct platform_device *pdev) · 2343 unmodified lines
2344 video_set_drvdata(vfd, fdp1);2344 video_set_drvdata(vfd, fdp1);
2345 strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));2345 strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));
2346 2346
2347 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);2347 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2348 if (ret) {2348 if (ret) {
2349 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");2349 v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2350 goto release_m2m;2350 goto release_m2m;
drivers/media/platform/rcar_jpu.c+2−2
@@ -1663,7 +1663,7 @@ static int jpu_probe(struct platform_device *pdev) · 1662 unmodified lines
1663 jpu->vfd_encoder.device_caps = V4L2_CAP_STREAMING |1663 jpu->vfd_encoder.device_caps = V4L2_CAP_STREAMING |
1664 V4L2_CAP_VIDEO_M2M_MPLANE;1664 V4L2_CAP_VIDEO_M2M_MPLANE;
1665 1665
1666 ret = video_register_device(&jpu->vfd_encoder, VFL_TYPE_GRABBER, -1);1666 ret = video_register_device(&jpu->vfd_encoder, VFL_TYPE_VIDEO, -1);
1667 if (ret) {1667 if (ret) {
1668 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");1668 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");
1669 goto m2m_init_rollback;1669 goto m2m_init_rollback;
@@ -1682,7 +1682,7 @@ static int jpu_probe(struct platform_device *pdev) · 12 unmodified lines
1682 jpu->vfd_decoder.device_caps = V4L2_CAP_STREAMING |1682 jpu->vfd_decoder.device_caps = V4L2_CAP_STREAMING |
1683 V4L2_CAP_VIDEO_M2M_MPLANE;1683 V4L2_CAP_VIDEO_M2M_MPLANE;
1684 1684
1685 ret = video_register_device(&jpu->vfd_decoder, VFL_TYPE_GRABBER, -1);1685 ret = video_register_device(&jpu->vfd_decoder, VFL_TYPE_VIDEO, -1);
1686 if (ret) {1686 if (ret) {
1687 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");1687 v4l2_err(&jpu->v4l2_dev, "Failed to register video device\n");
1688 goto enc_vdev_register_rollback;1688 goto enc_vdev_register_rollback;
drivers/media/platform/renesas-ceu.c+1−1
@@ -1450,7 +1450,7 @@ static int ceu_notify_complete(struct v4l2_async_notifier *notifier) · 1449 unmodified lines
1450 V4L2_CAP_STREAMING;1450 V4L2_CAP_STREAMING;
1451 video_set_drvdata(vdev, ceudev);1451 video_set_drvdata(vdev, ceudev);
1452 1452
1453 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1453 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1454 if (ret < 0) {1454 if (ret < 0) {
1455 v4l2_err(vdev->v4l2_dev,1455 v4l2_err(vdev->v4l2_dev,
1456 "video_register_device failed: %d\n", ret);1456 "video_register_device failed: %d\n", ret);
drivers/media/platform/rockchip/rga/rga.c+1−1
@@ -889,7 +889,7 @@ static int rga_probe(struct platform_device *pdev) · 888 unmodified lines
889 def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;889 def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
890 def_frame.size = def_frame.stride * def_frame.height;890 def_frame.size = def_frame.stride * def_frame.height;
891 891
892 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);892 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
893 if (ret) {893 if (ret) {
894 v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");894 v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
895 goto rel_vdev;895 goto rel_vdev;
drivers/media/platform/s3c-camif/camif-capture.c+1−1
@@ -1158,7 +1158,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) · 1157 unmodified lines
1158 vfd->ctrl_handler = &vp->ctrl_handler;1158 vfd->ctrl_handler = &vp->ctrl_handler;
1159 vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;1159 vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
1160 1160
1161 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);1161 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
1162 if (ret)1162 if (ret)
1163 goto err_ctrlh_free;1163 goto err_ctrlh_free;
1164 1164
drivers/media/platform/s5p-g2d/g2d.c+1−1
@@ -695,7 +695,7 @@ static int g2d_probe(struct platform_device *pdev) · 694 unmodified lines
695 vfd->lock = &dev->mutex;695 vfd->lock = &dev->mutex;
696 vfd->v4l2_dev = &dev->v4l2_dev;696 vfd->v4l2_dev = &dev->v4l2_dev;
697 vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;697 vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
698 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);698 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
699 if (ret) {699 if (ret) {
700 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");700 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
701 goto rel_vdev;701 goto rel_vdev;
drivers/media/platform/s5p-jpeg/jpeg-core.c+2−2
@@ -2946,7 +2946,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev) · 2945 unmodified lines
2946 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;2946 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
2947 jpeg->vfd_encoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;2947 jpeg->vfd_encoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
2948 2948
2949 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);2949 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_VIDEO, -1);
2950 if (ret) {2950 if (ret) {
2951 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");2951 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2952 video_device_release(jpeg->vfd_encoder);2952 video_device_release(jpeg->vfd_encoder);
@@ -2976,7 +2976,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev) · 23 unmodified lines
2976 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;2976 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
2977 jpeg->vfd_decoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;2977 jpeg->vfd_decoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
2978 2978
2979 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);2979 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_VIDEO, -1);
2980 if (ret) {2980 if (ret) {
2981 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");2981 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2982 video_device_release(jpeg->vfd_decoder);2982 video_device_release(jpeg->vfd_decoder);
drivers/media/platform/s5p-mfc/s5p_mfc.c+2−2
@@ -1376,7 +1376,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) · 1375 unmodified lines
1376 s5p_mfc_init_regs(dev);1376 s5p_mfc_init_regs(dev);
1377 1377
1378 /* Register decoder and encoder */1378 /* Register decoder and encoder */
1379 ret = video_register_device(dev->vfd_dec, VFL_TYPE_GRABBER, 0);1379 ret = video_register_device(dev->vfd_dec, VFL_TYPE_VIDEO, 0);
1380 if (ret) {1380 if (ret) {
1381 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");1381 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1382 goto err_dec_reg;1382 goto err_dec_reg;
@@ -1384,7 +1384,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) · 1 unmodified line
1384 v4l2_info(&dev->v4l2_dev,1384 v4l2_info(&dev->v4l2_dev,
1385 "decoder registered as /dev/video%d\n", dev->vfd_dec->num);1385 "decoder registered as /dev/video%d\n", dev->vfd_dec->num);
1386 1386
1387 ret = video_register_device(dev->vfd_enc, VFL_TYPE_GRABBER, 0);1387 ret = video_register_device(dev->vfd_enc, VFL_TYPE_VIDEO, 0);
1388 if (ret) {1388 if (ret) {
1389 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");1389 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1390 goto err_enc_reg;1390 goto err_enc_reg;
drivers/media/platform/sh_veu.c+1−1
@@ -1160,7 +1160,7 @@ static int sh_veu_probe(struct platform_device *pdev) · 1159 unmodified lines
1160 pm_runtime_enable(&pdev->dev);1160 pm_runtime_enable(&pdev->dev);
1161 pm_runtime_resume(&pdev->dev);1161 pm_runtime_resume(&pdev->dev);
1162 1162
1163 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1163 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1164 pm_runtime_suspend(&pdev->dev);1164 pm_runtime_suspend(&pdev->dev);
1165 if (ret < 0)1165 if (ret < 0)
1166 goto evidreg;1166 goto evidreg;
drivers/media/platform/sh_vou.c+1−1
@@ -1323,7 +1323,7 @@ static int sh_vou_probe(struct platform_device *pdev) · 1322 unmodified lines
1323 goto ei2cnd;1323 goto ei2cnd;
1324 }1324 }
1325 1325
1326 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1326 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1327 if (ret < 0)1327 if (ret < 0)
1328 goto evregdev;1328 goto evregdev;
1329 1329
drivers/media/platform/sti/bdisp/bdisp-v4l2.c+1−1
@@ -1066,7 +1066,7 @@ static int bdisp_register_device(struct bdisp_dev *bdisp) · 1065 unmodified lines
1066 return PTR_ERR(bdisp->m2m.m2m_dev);1066 return PTR_ERR(bdisp->m2m.m2m_dev);
1067 }1067 }
1068 1068
1069 ret = video_register_device(&bdisp->vdev, VFL_TYPE_GRABBER, -1);1069 ret = video_register_device(&bdisp->vdev, VFL_TYPE_VIDEO, -1);
1070 if (ret) {1070 if (ret) {
1071 dev_err(bdisp->dev,1071 dev_err(bdisp->dev,
1072 "%s(): failed to register video device\n", __func__);1072 "%s(): failed to register video device\n", __func__);
drivers/media/platform/sti/delta/delta-v4l2.c+1−1
@@ -1781,7 +1781,7 @@ static int delta_register_device(struct delta_dev *delta) · 1780 unmodified lines
1781 snprintf(vdev->name, sizeof(vdev->name), "%s-%s",1781 snprintf(vdev->name, sizeof(vdev->name), "%s-%s",
1782 DELTA_NAME, DELTA_FW_VERSION);1782 DELTA_NAME, DELTA_FW_VERSION);
1783 1783
1784 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1784 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1785 if (ret) {1785 if (ret) {
1786 dev_err(delta->dev, "%s failed to register video device\n",1786 dev_err(delta->dev, "%s failed to register video device\n",
1787 DELTA_PREFIX);1787 DELTA_PREFIX);
drivers/media/platform/sti/hva/hva-v4l2.c+1−1
@@ -1316,7 +1316,7 @@ static int hva_register_device(struct hva_dev *hva) · 1315 unmodified lines
1316 snprintf(vdev->name, sizeof(vdev->name), "%s%lx", HVA_NAME,1316 snprintf(vdev->name, sizeof(vdev->name), "%s%lx", HVA_NAME,
1317 hva->ip_version);1317 hva->ip_version);
1318 1318
1319 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1319 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1320 if (ret) {1320 if (ret) {
1321 dev_err(dev, "%s failed to register video device\n",1321 dev_err(dev, "%s failed to register video device\n",
1322 HVA_PREFIX);1322 HVA_PREFIX);
drivers/media/platform/stm32/stm32-cec.c+8−2
@@ -291,7 +291,9 @@ static int stm32_cec_probe(struct platform_device *pdev) · 290 unmodified lines
291 291
292 cec->clk_cec = devm_clk_get(&pdev->dev, "cec");292 cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
293 if (IS_ERR(cec->clk_cec)) {293 if (IS_ERR(cec->clk_cec)) {
294 dev_err(&pdev->dev, "Cannot get cec clock\n");294 if (PTR_ERR(cec->clk_cec) != -EPROBE_DEFER)
295 dev_err(&pdev->dev, "Cannot get cec clock\n");
296
295 return PTR_ERR(cec->clk_cec);297 return PTR_ERR(cec->clk_cec);
296 }298 }
297 299
@@ -302,10 +304,14 @@ static int stm32_cec_probe(struct platform_device *pdev) · 4 unmodified lines
302 }304 }
303 305
304 cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");306 cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
307 if (IS_ERR(cec->clk_hdmi_cec) &&
308 PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER)
309 return -EPROBE_DEFER;
310
305 if (!IS_ERR(cec->clk_hdmi_cec)) {311 if (!IS_ERR(cec->clk_hdmi_cec)) {
306 ret = clk_prepare(cec->clk_hdmi_cec);312 ret = clk_prepare(cec->clk_hdmi_cec);
307 if (ret) {313 if (ret) {
308 dev_err(&pdev->dev, "Unable to prepare hdmi-cec clock\n");314 dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
309 return ret;315 return ret;
310 }316 }
311 }317 }
drivers/media/platform/stm32/stm32-dcmi.c+8−5
@@ -1910,10 +1910,13 @@ static int dcmi_probe(struct platform_device *pdev) · 1909 unmodified lines
1910 return PTR_ERR(mclk);1910 return PTR_ERR(mclk);
1911 }1911 }
1912 1912
1913 chan = dma_request_slave_channel(&pdev->dev, "tx");1913 chan = dma_request_chan(&pdev->dev, "tx");
1914 if (!chan) {1914 if (IS_ERR(chan)) {
1915 dev_info(&pdev->dev, "Unable to request DMA channel, defer probing\n");1915 ret = PTR_ERR(chan);
1916 return -EPROBE_DEFER;1916 if (ret != -EPROBE_DEFER)
1917 dev_err(&pdev->dev,
1918 "Failed to request DMA channel: %d\n", ret);
1919 return ret;
1917 }1920 }
1918 1921
1919 spin_lock_init(&dcmi->irqlock);1922 spin_lock_init(&dcmi->irqlock);
@@ -1971,7 +1974,7 @@ static int dcmi_probe(struct platform_device *pdev) · 51 unmodified lines
1971 }1974 }
1972 dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;1975 dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
1973 1976
1974 ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1);1977 ret = video_register_device(dcmi->vdev, VFL_TYPE_VIDEO, -1);
1975 if (ret) {1978 if (ret) {
1976 dev_err(dcmi->dev, "Failed to register video device\n");1979 dev_err(dcmi->dev, "Failed to register video device\n");
1977 goto err_media_entity_cleanup;1980 goto err_media_entity_cleanup;
drivers/media/platform/sunxi/Makefile+1−0
@@ -1,3 +1,4 @@
1obj-y += sun4i-csi/1obj-y += sun4i-csi/
2obj-y += sun6i-csi/2obj-y += sun6i-csi/
3obj-y += sun8i-di/3obj-y += sun8i-di/
4obj-y += sun8i-rotate/
drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c+4−4
@@ -214,7 +214,7 @@ static int sun4i_csi_open(struct file *file) · 213 unmodified lines
214 if (ret < 0)214 if (ret < 0)
215 goto err_pm_put;215 goto err_pm_put;
216 216
217 ret = v4l2_pipeline_pm_use(&csi->vdev.entity, 1);217 ret = v4l2_pipeline_pm_get(&csi->vdev.entity);
218 if (ret)218 if (ret)
219 goto err_pm_put;219 goto err_pm_put;
220 220
@@ -227,7 +227,7 @@ static int sun4i_csi_open(struct file *file) · 6 unmodified lines
227 return 0;227 return 0;
228 228
229err_pipeline_pm_put:229err_pipeline_pm_put:
230 v4l2_pipeline_pm_use(&csi->vdev.entity, 0);230 v4l2_pipeline_pm_put(&csi->vdev.entity);
231 231
232err_pm_put:232err_pm_put:
233 pm_runtime_put(csi->dev);233 pm_runtime_put(csi->dev);
@@ -243,7 +243,7 @@ static int sun4i_csi_release(struct file *file) · 9 unmodified lines
243 mutex_lock(&csi->lock);243 mutex_lock(&csi->lock);
244 244
245 v4l2_fh_release(file);245 v4l2_fh_release(file);
246 v4l2_pipeline_pm_use(&csi->vdev.entity, 0);246 v4l2_pipeline_pm_put(&csi->vdev.entity);
247 pm_runtime_put(csi->dev);247 pm_runtime_put(csi->dev);
248 248
249 mutex_unlock(&csi->lock);249 mutex_unlock(&csi->lock);
@@ -374,7 +374,7 @@ int sun4i_csi_v4l2_register(struct sun4i_csi *csi) · 124 unmodified lines
374 vdev->ioctl_ops = &sun4i_csi_ioctl_ops;374 vdev->ioctl_ops = &sun4i_csi_ioctl_ops;
375 video_set_drvdata(vdev, csi);375 video_set_drvdata(vdev, csi);
376 376
377 ret = video_register_device(&csi->vdev, VFL_TYPE_GRABBER, -1);377 ret = video_register_device(&csi->vdev, VFL_TYPE_VIDEO, -1);
378 if (ret)378 if (ret)
379 return ret;379 return ret;
380 380
drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c+4−4
@@ -474,7 +474,7 @@ static int sun6i_video_open(struct file *file) · 473 unmodified lines
474 if (ret < 0)474 if (ret < 0)
475 goto unlock;475 goto unlock;
476 476
477 ret = v4l2_pipeline_pm_use(&video->vdev.entity, 1);477 ret = v4l2_pipeline_pm_get(&video->vdev.entity);
478 if (ret < 0)478 if (ret < 0)
479 goto fh_release;479 goto fh_release;
480 480
@@ -507,7 +507,7 @@ static int sun6i_video_close(struct file *file) · 26 unmodified lines
507 507
508 _vb2_fop_release(file, NULL);508 _vb2_fop_release(file, NULL);
509 509
510 v4l2_pipeline_pm_use(&video->vdev.entity, 0);510 v4l2_pipeline_pm_put(&video->vdev.entity);
511 511
512 if (last_fh)512 if (last_fh)
513 sun6i_csi_set_power(video->csi, false);513 sun6i_csi_set_power(video->csi, false);
@@ -648,7 +648,7 @@ int sun6i_video_init(struct sun6i_video *video, struct sun6i_csi *csi, · 134 unmodified lines
648 vdev->release = video_device_release_empty;648 vdev->release = video_device_release_empty;
649 vdev->fops = &sun6i_video_fops;649 vdev->fops = &sun6i_video_fops;
650 vdev->ioctl_ops = &sun6i_video_ioctl_ops;650 vdev->ioctl_ops = &sun6i_video_ioctl_ops;
651 vdev->vfl_type = VFL_TYPE_GRABBER;651 vdev->vfl_type = VFL_TYPE_VIDEO;
652 vdev->vfl_dir = VFL_DIR_RX;652 vdev->vfl_dir = VFL_DIR_RX;
653 vdev->v4l2_dev = &csi->v4l2_dev;653 vdev->v4l2_dev = &csi->v4l2_dev;
654 vdev->queue = vidq;654 vdev->queue = vidq;
@@ -656,7 +656,7 @@ int sun6i_video_init(struct sun6i_video *video, struct sun6i_csi *csi, · 1 unmodified line
656 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;656 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
657 video_set_drvdata(vdev, video);657 video_set_drvdata(vdev, video);
658 658
659 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);659 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
660 if (ret < 0) {660 if (ret < 0) {
661 v4l2_err(&csi->v4l2_dev,661 v4l2_err(&csi->v4l2_dev,
662 "video_register_device failed: %d\n", ret);662 "video_register_device failed: %d\n", ret);
drivers/media/platform/sunxi/sun8i-di/sun8i-di.c+2−5
@@ -814,11 +814,8 @@ static int deinterlace_probe(struct platform_device *pdev) · 813 unmodified lines
814 dev->dev = &pdev->dev;814 dev->dev = &pdev->dev;
815 815
816 irq = platform_get_irq(pdev, 0);816 irq = platform_get_irq(pdev, 0);
817 if (irq <= 0) {817 if (irq <= 0)
818 dev_err(dev->dev, "Failed to get IRQ\n");
819
820 return irq;818 return irq;
821 }
822 819
823 ret = devm_request_irq(dev->dev, irq, deinterlace_irq,820 ret = devm_request_irq(dev->dev, irq, deinterlace_irq,
824 0, dev_name(dev->dev), dev);821 0, dev_name(dev->dev), dev);
@@ -882,7 +879,7 @@ static int deinterlace_probe(struct platform_device *pdev) · 57 unmodified lines
882 deinterlace_video_device.name);879 deinterlace_video_device.name);
883 video_set_drvdata(vfd, dev);880 video_set_drvdata(vfd, dev);
884 881
885 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);882 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
886 if (ret) {883 if (ret) {
887 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");884 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
888 885
drivers/media/platform/sunxi/sun8i-rotate/Makefile+5−0
@@ -0,0 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0
2sun8i-rotate-y += sun8i_rotate.o
3sun8i-rotate-y += sun8i_formats.o
4
5obj-$(CONFIG_VIDEO_SUN8I_ROTATE) += sun8i-rotate.o
drivers/media/platform/sunxi/sun8i-rotate/sun8i-formats.h+25−0
@@ -0,0 +1,25 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net> */
3
4#ifndef _SUN8I_FORMATS_H_
5#define _SUN8I_FORMATS_H_
6
7#include <linux/videodev2.h>
8
9#define ROTATE_FLAG_YUV BIT(0)
10#define ROTATE_FLAG_OUTPUT BIT(1)
11
12struct rotate_format {
13 u32 fourcc;
14 u32 hw_format;
15 int planes;
16 int bpp[3];
17 int hsub;
18 int vsub;
19 unsigned int flags;
20};
21
22const struct rotate_format *rotate_find_format(u32 pixelformat);
23int rotate_enum_fmt(struct v4l2_fmtdesc *f, bool dst);
24
25#endif
drivers/media/platform/sunxi/sun8i-rotate/sun8i-rotate.h+135−0
@@ -0,0 +1,135 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Allwinner DE2 rotation driver
4 *
5 * Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
6 */
7
8#ifndef _SUN8I_ROTATE_H_
9#define _SUN8I_ROTATE_H_
10
11#include <media/v4l2-ctrls.h>
12#include <media/v4l2-device.h>
13#include <media/v4l2-mem2mem.h>
14#include <media/videobuf2-v4l2.h>
15#include <media/videobuf2-dma-contig.h>
16
17#include <linux/platform_device.h>
18
19#define ROTATE_NAME "sun8i-rotate"
20
21#define ROTATE_GLB_CTL 0x00
22#define ROTATE_GLB_CTL_START BIT(31)
23#define ROTATE_GLB_CTL_RESET BIT(30)
24#define ROTATE_GLB_CTL_BURST_LEN(x) ((x) << 16)
25#define ROTATE_GLB_CTL_HFLIP BIT(7)
26#define ROTATE_GLB_CTL_VFLIP BIT(6)
27#define ROTATE_GLB_CTL_ROTATION(x) ((x) << 4)
28#define ROTATE_GLB_CTL_MODE(x) ((x) << 0)
29
30#define ROTATE_INT 0x04
31#define ROTATE_INT_FINISH_IRQ_EN BIT(16)
32#define ROTATE_INT_FINISH_IRQ BIT(0)
33
34#define ROTATE_IN_FMT 0x20
35#define ROTATE_IN_FMT_FORMAT(x) ((x) << 0)
36
37#define ROTATE_IN_SIZE 0x24
38#define ROTATE_IN_PITCH0 0x30
39#define ROTATE_IN_PITCH1 0x34
40#define ROTATE_IN_PITCH2 0x38
41#define ROTATE_IN_ADDRL0 0x40
42#define ROTATE_IN_ADDRH0 0x44
43#define ROTATE_IN_ADDRL1 0x48
44#define ROTATE_IN_ADDRH1 0x4c
45#define ROTATE_IN_ADDRL2 0x50
46#define ROTATE_IN_ADDRH2 0x54
47#define ROTATE_OUT_SIZE 0x84
48#define ROTATE_OUT_PITCH0 0x90
49#define ROTATE_OUT_PITCH1 0x94
50#define ROTATE_OUT_PITCH2 0x98
51#define ROTATE_OUT_ADDRL0 0xA0
52#define ROTATE_OUT_ADDRH0 0xA4
53#define ROTATE_OUT_ADDRL1 0xA8
54#define ROTATE_OUT_ADDRH1 0xAC
55#define ROTATE_OUT_ADDRL2 0xB0
56#define ROTATE_OUT_ADDRH2 0xB4
57
58#define ROTATE_BURST_8 0x07
59#define ROTATE_BURST_16 0x0f
60#define ROTATE_BURST_32 0x1f
61#define ROTATE_BURST_64 0x3f
62
63#define ROTATE_MODE_COPY_ROTATE 0x01
64
65#define ROTATE_FORMAT_ARGB32 0x00
66#define ROTATE_FORMAT_ABGR32 0x01
67#define ROTATE_FORMAT_RGBA32 0x02
68#define ROTATE_FORMAT_BGRA32 0x03
69#define ROTATE_FORMAT_XRGB32 0x04
70#define ROTATE_FORMAT_XBGR32 0x05
71#define ROTATE_FORMAT_RGBX32 0x06
72#define ROTATE_FORMAT_BGRX32 0x07
73#define ROTATE_FORMAT_RGB24 0x08
74#define ROTATE_FORMAT_BGR24 0x09
75#define ROTATE_FORMAT_RGB565 0x0a
76#define ROTATE_FORMAT_BGR565 0x0b
77#define ROTATE_FORMAT_ARGB4444 0x0c
78#define ROTATE_FORMAT_ABGR4444 0x0d
79#define ROTATE_FORMAT_RGBA4444 0x0e
80#define ROTATE_FORMAT_BGRA4444 0x0f
81#define ROTATE_FORMAT_ARGB1555 0x10
82#define ROTATE_FORMAT_ABGR1555 0x11
83#define ROTATE_FORMAT_RGBA5551 0x12
84#define ROTATE_FORMAT_BGRA5551 0x13
85
86#define ROTATE_FORMAT_YUYV 0x20
87#define ROTATE_FORMAT_UYVY 0x21
88#define ROTATE_FORMAT_YVYU 0x22
89#define ROTATE_FORMAT_VYUV 0x23
90#define ROTATE_FORMAT_NV61 0x24
91#define ROTATE_FORMAT_NV16 0x25
92#define ROTATE_FORMAT_YUV422P 0x26
93#define ROTATE_FORMAT_NV21 0x28
94#define ROTATE_FORMAT_NV12 0x29
95#define ROTATE_FORMAT_YUV420P 0x2A
96
97#define ROTATE_SIZE(w, h) (((h) - 1) << 16 | ((w) - 1))
98
99#define ROTATE_MIN_WIDTH 8U
100#define ROTATE_MIN_HEIGHT 8U
101#define ROTATE_MAX_WIDTH 4096U
102#define ROTATE_MAX_HEIGHT 4096U
103
104struct rotate_ctx {
105 struct v4l2_fh fh;
106 struct rotate_dev *dev;
107
108 struct v4l2_pix_format src_fmt;
109 struct v4l2_pix_format dst_fmt;
110
111 struct v4l2_ctrl_handler ctrl_handler;
112
113 u32 hflip;
114 u32 vflip;
115 u32 rotate;
116};
117
118struct rotate_dev {
119 struct v4l2_device v4l2_dev;
120 struct video_device vfd;
121 struct device *dev;
122 struct v4l2_m2m_dev *m2m_dev;
123
124 /* Device file mutex */
125 struct mutex dev_mutex;
126
127 void __iomem *base;
128
129 struct clk *bus_clk;
130 struct clk *mod_clk;
131
132 struct reset_control *rstc;
133};
134
135#endif
drivers/media/platform/sunxi/sun8i-rotate/sun8i_formats.c+273−0
@@ -0,0 +1,273 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net> */
3
4#include "sun8i-formats.h"
5#include "sun8i-rotate.h"
6
7/*
8 * Formats not included in array:
9 * ROTATE_FORMAT_BGR565
10 * ROTATE_FORMAT_VYUV
11 */
12
13static const struct rotate_format rotate_formats[] = {
14 {
15 .fourcc = V4L2_PIX_FMT_ARGB32,
16 .hw_format = ROTATE_FORMAT_ARGB32,
17 .planes = 1,
18 .bpp = { 4, 0, 0 },
19 .hsub = 1,
20 .vsub = 1,
21 .flags = ROTATE_FLAG_OUTPUT
22 }, {
23 .fourcc = V4L2_PIX_FMT_ABGR32,
24 .hw_format = ROTATE_FORMAT_ABGR32,
25 .planes = 1,
26 .bpp = { 4, 0, 0 },
27 .hsub = 1,
28 .vsub = 1,
29 .flags = ROTATE_FLAG_OUTPUT
30 }, {
31 .fourcc = V4L2_PIX_FMT_RGBA32,
32 .hw_format = ROTATE_FORMAT_RGBA32,
33 .planes = 1,
34 .bpp = { 4, 0, 0 },
35 .hsub = 1,
36 .vsub = 1,
37 .flags = ROTATE_FLAG_OUTPUT
38 }, {
39 .fourcc = V4L2_PIX_FMT_BGRA32,
40 .hw_format = ROTATE_FORMAT_BGRA32,
41 .planes = 1,
42 .bpp = { 4, 0, 0 },
43 .hsub = 1,
44 .vsub = 1,
45 .flags = ROTATE_FLAG_OUTPUT
46 }, {
47 .fourcc = V4L2_PIX_FMT_XRGB32,
48 .hw_format = ROTATE_FORMAT_XRGB32,
49 .planes = 1,
50 .bpp = { 4, 0, 0 },
51 .hsub = 1,
52 .vsub = 1,
53 .flags = ROTATE_FLAG_OUTPUT
54 }, {
55 .fourcc = V4L2_PIX_FMT_XBGR32,
56 .hw_format = ROTATE_FORMAT_XBGR32,
57 .planes = 1,
58 .bpp = { 4, 0, 0 },
59 .hsub = 1,
60 .vsub = 1,
61 .flags = ROTATE_FLAG_OUTPUT
62 }, {
63 .fourcc = V4L2_PIX_FMT_RGB32,
64 .hw_format = ROTATE_FORMAT_RGBX32,
65 .planes = 1,
66 .bpp = { 4, 0, 0 },
67 .hsub = 1,
68 .vsub = 1,
69 .flags = ROTATE_FLAG_OUTPUT
70 }, {
71 .fourcc = V4L2_PIX_FMT_BGR32,
72 .hw_format = ROTATE_FORMAT_BGRX32,
73 .planes = 1,
74 .bpp = { 4, 0, 0 },
75 .hsub = 1,
76 .vsub = 1,
77 .flags = ROTATE_FLAG_OUTPUT
78 }, {
79 .fourcc = V4L2_PIX_FMT_RGB24,
80 .hw_format = ROTATE_FORMAT_RGB24,
81 .planes = 1,
82 .bpp = { 3, 0, 0 },
83 .hsub = 1,
84 .vsub = 1,
85 .flags = ROTATE_FLAG_OUTPUT
86 }, {
87 .fourcc = V4L2_PIX_FMT_BGR24,
88 .hw_format = ROTATE_FORMAT_BGR24,
89 .planes = 1,
90 .bpp = { 3, 0, 0 },
91 .hsub = 1,
92 .vsub = 1,
93 .flags = ROTATE_FLAG_OUTPUT
94 }, {
95 .fourcc = V4L2_PIX_FMT_RGB565,
96 .hw_format = ROTATE_FORMAT_RGB565,
97 .planes = 1,
98 .bpp = { 2, 0, 0 },
99 .hsub = 1,
100 .vsub = 1,
101 .flags = ROTATE_FLAG_OUTPUT
102 }, {
103 .fourcc = V4L2_PIX_FMT_ARGB444,
104 .hw_format = ROTATE_FORMAT_ARGB4444,
105 .planes = 1,
106 .bpp = { 2, 0, 0 },
107 .hsub = 1,
108 .vsub = 1,
109 .flags = ROTATE_FLAG_OUTPUT
110 }, {
111 .fourcc = V4L2_PIX_FMT_ABGR444,
112 .hw_format = ROTATE_FORMAT_ABGR4444,
113 .planes = 1,
114 .bpp = { 2, 0, 0 },
115 .hsub = 1,
116 .vsub = 1,
117 .flags = ROTATE_FLAG_OUTPUT
118 }, {
119 .fourcc = V4L2_PIX_FMT_RGBA444,
120 .hw_format = ROTATE_FORMAT_RGBA4444,
121 .planes = 1,
122 .bpp = { 2, 0, 0 },
123 .hsub = 1,
124 .vsub = 1,
125 .flags = ROTATE_FLAG_OUTPUT
126 }, {
127 .fourcc = V4L2_PIX_FMT_BGRA444,
128 .hw_format = ROTATE_FORMAT_BGRA4444,
129 .planes = 1,
130 .bpp = { 2, 0, 0 },
131 .hsub = 1,
132 .vsub = 1,
133 .flags = ROTATE_FLAG_OUTPUT
134 }, {
135 .fourcc = V4L2_PIX_FMT_ARGB555,
136 .hw_format = ROTATE_FORMAT_ARGB1555,
137 .planes = 1,
138 .bpp = { 2, 0, 0 },
139 .hsub = 1,
140 .vsub = 1,
141 .flags = ROTATE_FLAG_OUTPUT
142 }, {
143 .fourcc = V4L2_PIX_FMT_ABGR555,
144 .hw_format = ROTATE_FORMAT_ABGR1555,
145 .planes = 1,
146 .bpp = { 2, 0, 0 },
147 .hsub = 1,
148 .vsub = 1,
149 .flags = ROTATE_FLAG_OUTPUT
150 }, {
151 .fourcc = V4L2_PIX_FMT_RGBA555,
152 .hw_format = ROTATE_FORMAT_RGBA5551,
153 .planes = 1,
154 .bpp = { 2, 0, 0 },
155 .hsub = 1,
156 .vsub = 1,
157 .flags = ROTATE_FLAG_OUTPUT
158 }, {
159 .fourcc = V4L2_PIX_FMT_BGRA555,
160 .hw_format = ROTATE_FORMAT_BGRA5551,
161 .planes = 1,
162 .bpp = { 2, 0, 0 },
163 .hsub = 1,
164 .vsub = 1,
165 .flags = ROTATE_FLAG_OUTPUT
166 }, {
167 .fourcc = V4L2_PIX_FMT_YVYU,
168 .hw_format = ROTATE_FORMAT_YVYU,
169 .planes = 1,
170 .bpp = { 2, 0, 0 },
171 .hsub = 2,
172 .vsub = 1,
173 .flags = ROTATE_FLAG_YUV
174 }, {
175 .fourcc = V4L2_PIX_FMT_UYVY,
176 .hw_format = ROTATE_FORMAT_UYVY,
177 .planes = 1,
178 .bpp = { 2, 0, 0 },
179 .hsub = 2,
180 .vsub = 1,
181 .flags = ROTATE_FLAG_YUV
182 }, {
183 .fourcc = V4L2_PIX_FMT_YUYV,
184 .hw_format = ROTATE_FORMAT_YUYV,
185 .planes = 1,
186 .bpp = { 2, 0, 0 },
187 .hsub = 2,
188 .vsub = 1,
189 .flags = ROTATE_FLAG_YUV
190 }, {
191 .fourcc = V4L2_PIX_FMT_NV61,
192 .hw_format = ROTATE_FORMAT_NV61,
193 .planes = 2,
194 .bpp = { 1, 2, 0 },
195 .hsub = 2,
196 .vsub = 1,
197 .flags = ROTATE_FLAG_YUV
198 }, {
199 .fourcc = V4L2_PIX_FMT_NV16,
200 .hw_format = ROTATE_FORMAT_NV16,
201 .planes = 2,
202 .bpp = { 1, 2, 0 },
203 .hsub = 2,
204 .vsub = 1,
205 .flags = ROTATE_FLAG_YUV
206 }, {
207 .fourcc = V4L2_PIX_FMT_YUV422P,
208 .hw_format = ROTATE_FORMAT_YUV422P,
209 .planes = 3,
210 .bpp = { 1, 1, 1 },
211 .hsub = 2,
212 .vsub = 1,
213 .flags = ROTATE_FLAG_YUV
214 }, {
215 .fourcc = V4L2_PIX_FMT_NV21,
216 .hw_format = ROTATE_FORMAT_NV21,
217 .planes = 2,
218 .bpp = { 1, 2, 0 },
219 .hsub = 2,
220 .vsub = 2,
221 .flags = ROTATE_FLAG_YUV
222 }, {
223 .fourcc = V4L2_PIX_FMT_NV12,
224 .hw_format = ROTATE_FORMAT_NV12,
225 .planes = 2,
226 .bpp = { 1, 2, 0 },
227 .hsub = 2,
228 .vsub = 2,
229 .flags = ROTATE_FLAG_YUV
230 }, {
231 .fourcc = V4L2_PIX_FMT_YUV420,
232 .hw_format = ROTATE_FORMAT_YUV420P,
233 .planes = 3,
234 .bpp = { 1, 1, 1 },
235 .hsub = 2,
236 .vsub = 2,
237 .flags = ROTATE_FLAG_YUV | ROTATE_FLAG_OUTPUT
238 },
239};
240
241const struct rotate_format *rotate_find_format(u32 pixelformat)
242{
243 unsigned int i;
244
245 for (i = 0; i < ARRAY_SIZE(rotate_formats); i++)
246 if (rotate_formats[i].fourcc == pixelformat)
247 return &rotate_formats[i];
248
249 return NULL;
250}
251
252int rotate_enum_fmt(struct v4l2_fmtdesc *f, bool dst)
253{
254 int i, index;
255
256 index = 0;
257
258 for (i = 0; i < ARRAY_SIZE(rotate_formats); i++) {
259 /* not all formats can be used for capture buffers */
260 if (dst && !(rotate_formats[i].flags & ROTATE_FLAG_OUTPUT))
261 continue;
262
263 if (index == f->index) {
264 f->pixelformat = rotate_formats[i].fourcc;
265
266 return 0;
267 }
268
269 index++;
270 }
271
272 return -EINVAL;
273}
drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c+924−0
@@ -0,0 +1,924 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Allwinner sun8i DE2 rotation driver
4 *
5 * Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
6 */
7
8#include <linux/clk.h>
9#include <linux/interrupt.h>
10#include <linux/io.h>
11#include <linux/iopoll.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_device.h>
15#include <linux/pm_runtime.h>
16#include <linux/reset.h>
17
18#include <media/v4l2-device.h>
19#include <media/v4l2-event.h>
20#include <media/v4l2-ioctl.h>
21#include <media/v4l2-mem2mem.h>
22
23#include "sun8i-formats.h"
24#include "sun8i-rotate.h"
25
26static inline u32 rotate_read(struct rotate_dev *dev, u32 reg)
27{
28 return readl(dev->base + reg);
29}
30
31static inline void rotate_write(struct rotate_dev *dev, u32 reg, u32 value)
32{
33 writel(value, dev->base + reg);
34}
35
36static inline void rotate_set_bits(struct rotate_dev *dev, u32 reg, u32 bits)
37{
38 writel(readl(dev->base + reg) | bits, dev->base + reg);
39}
40
41static void rotate_calc_addr_pitch(dma_addr_t buffer,
42 u32 bytesperline, u32 height,
43 const struct rotate_format *fmt,
44 dma_addr_t *addr, u32 *pitch)
45{
46 u32 size;
47 int i;
48
49 for (i = 0; i < fmt->planes; i++) {
50 pitch[i] = bytesperline;
51 addr[i] = buffer;
52 if (i > 0)
53 pitch[i] /= fmt->hsub / fmt->bpp[i];
54 size = pitch[i] * height;
55 if (i > 0)
56 size /= fmt->vsub;
57 buffer += size;
58 }
59}
60
61static void rotate_device_run(void *priv)
62{
63 struct rotate_ctx *ctx = priv;
64 struct rotate_dev *dev = ctx->dev;
65 struct vb2_v4l2_buffer *src, *dst;
66 const struct rotate_format *fmt;
67 dma_addr_t addr[3];
68 u32 val, pitch[3];
69
70 src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
71 dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
72
73 v4l2_m2m_buf_copy_metadata(src, dst, true);
74
75 val = ROTATE_GLB_CTL_MODE(ROTATE_MODE_COPY_ROTATE);
76 if (ctx->hflip)
77 val |= ROTATE_GLB_CTL_HFLIP;
78 if (ctx->vflip)
79 val |= ROTATE_GLB_CTL_VFLIP;
80 val |= ROTATE_GLB_CTL_ROTATION(ctx->rotate / 90);
81 if (ctx->rotate != 90 && ctx->rotate != 270)
82 val |= ROTATE_GLB_CTL_BURST_LEN(ROTATE_BURST_64);
83 else
84 val |= ROTATE_GLB_CTL_BURST_LEN(ROTATE_BURST_8);
85 rotate_write(dev, ROTATE_GLB_CTL, val);
86
87 fmt = rotate_find_format(ctx->src_fmt.pixelformat);
88 if (!fmt)
89 return;
90
91 rotate_write(dev, ROTATE_IN_FMT, ROTATE_IN_FMT_FORMAT(fmt->hw_format));
92
93 rotate_calc_addr_pitch(vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0),
94 ctx->src_fmt.bytesperline, ctx->src_fmt.height,
95 fmt, addr, pitch);
96
97 rotate_write(dev, ROTATE_IN_SIZE,
98 ROTATE_SIZE(ctx->src_fmt.width, ctx->src_fmt.height));
99
100 rotate_write(dev, ROTATE_IN_PITCH0, pitch[0]);
101 rotate_write(dev, ROTATE_IN_PITCH1, pitch[1]);
102 rotate_write(dev, ROTATE_IN_PITCH2, pitch[2]);
103
104 rotate_write(dev, ROTATE_IN_ADDRL0, addr[0]);
105 rotate_write(dev, ROTATE_IN_ADDRL1, addr[1]);
106 rotate_write(dev, ROTATE_IN_ADDRL2, addr[2]);
107
108 rotate_write(dev, ROTATE_IN_ADDRH0, 0);
109 rotate_write(dev, ROTATE_IN_ADDRH1, 0);
110 rotate_write(dev, ROTATE_IN_ADDRH2, 0);
111
112 fmt = rotate_find_format(ctx->dst_fmt.pixelformat);
113 if (!fmt)
114 return;
115
116 rotate_calc_addr_pitch(vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0),
117 ctx->dst_fmt.bytesperline, ctx->dst_fmt.height,
118 fmt, addr, pitch);
119
120 rotate_write(dev, ROTATE_OUT_SIZE,
121 ROTATE_SIZE(ctx->dst_fmt.width, ctx->dst_fmt.height));
122
123 rotate_write(dev, ROTATE_OUT_PITCH0, pitch[0]);
124 rotate_write(dev, ROTATE_OUT_PITCH1, pitch[1]);
125 rotate_write(dev, ROTATE_OUT_PITCH2, pitch[2]);
126
127 rotate_write(dev, ROTATE_OUT_ADDRL0, addr[0]);
128 rotate_write(dev, ROTATE_OUT_ADDRL1, addr[1]);
129 rotate_write(dev, ROTATE_OUT_ADDRL2, addr[2]);
130
131 rotate_write(dev, ROTATE_OUT_ADDRH0, 0);
132 rotate_write(dev, ROTATE_OUT_ADDRH1, 0);
133 rotate_write(dev, ROTATE_OUT_ADDRH2, 0);
134
135 rotate_set_bits(dev, ROTATE_INT, ROTATE_INT_FINISH_IRQ_EN);
136 rotate_set_bits(dev, ROTATE_GLB_CTL, ROTATE_GLB_CTL_START);
137}
138
139static irqreturn_t rotate_irq(int irq, void *data)
140{
141 struct vb2_v4l2_buffer *buffer;
142 struct rotate_dev *dev = data;
143 struct rotate_ctx *ctx;
144 unsigned int val;
145
146 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
147 if (!ctx) {
148 v4l2_err(&dev->v4l2_dev,
149 "Instance released before the end of transaction\n");
150 return IRQ_NONE;
151 }
152
153 val = rotate_read(dev, ROTATE_INT);
154 if (!(val & ROTATE_INT_FINISH_IRQ))
155 return IRQ_NONE;
156
157 /* clear flag and disable irq */
158 rotate_write(dev, ROTATE_INT, ROTATE_INT_FINISH_IRQ);
159
160 buffer = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
161 v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_DONE);
162
163 buffer = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
164 v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_DONE);
165
166 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
167
168 return IRQ_HANDLED;
169}
170
171static inline struct rotate_ctx *rotate_file2ctx(struct file *file)
172{
173 return container_of(file->private_data, struct rotate_ctx, fh);
174}
175
176static void rotate_prepare_format(struct v4l2_pix_format *pix_fmt)
177{
178 unsigned int height, width, alignment, sizeimage, size, bpl;
179 const struct rotate_format *fmt;
180 int i;
181
182 fmt = rotate_find_format(pix_fmt->pixelformat);
183 if (!fmt)
184 return;
185
186 width = ALIGN(pix_fmt->width, fmt->hsub);
187 height = ALIGN(pix_fmt->height, fmt->vsub);
188
189 /* all pitches have to be 16 byte aligned */
190 alignment = 16;
191 if (fmt->planes > 1)
192 alignment *= fmt->hsub / fmt->bpp[1];
193 bpl = ALIGN(width * fmt->bpp[0], alignment);
194
195 sizeimage = 0;
196 for (i = 0; i < fmt->planes; i++) {
197 size = bpl * height;
198 if (i > 0) {
199 size *= fmt->bpp[i];
200 size /= fmt->hsub;
201 size /= fmt->vsub;
202 }
203 sizeimage += size;
204 }
205
206 pix_fmt->width = width;
207 pix_fmt->height = height;
208 pix_fmt->bytesperline = bpl;
209 pix_fmt->sizeimage = sizeimage;
210}
211
212static int rotate_querycap(struct file *file, void *priv,
213 struct v4l2_capability *cap)
214{
215 strscpy(cap->driver, ROTATE_NAME, sizeof(cap->driver));
216 strscpy(cap->card, ROTATE_NAME, sizeof(cap->card));
217 snprintf(cap->bus_info, sizeof(cap->bus_info),
218 "platform:%s", ROTATE_NAME);
219
220 return 0;
221}
222
223static int rotate_enum_fmt_vid_cap(struct file *file, void *priv,
224 struct v4l2_fmtdesc *f)
225{
226 return rotate_enum_fmt(f, true);
227}
228
229static int rotate_enum_fmt_vid_out(struct file *file, void *priv,
230 struct v4l2_fmtdesc *f)
231{
232 return rotate_enum_fmt(f, false);
233}
234
235static int rotate_enum_framesizes(struct file *file, void *priv,
236 struct v4l2_frmsizeenum *fsize)
237{
238 const struct rotate_format *fmt;
239
240 if (fsize->index != 0)
241 return -EINVAL;
242
243 fmt = rotate_find_format(fsize->pixel_format);
244 if (!fmt)
245 return -EINVAL;
246
247 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
248 fsize->stepwise.min_width = ROTATE_MIN_WIDTH;
249 fsize->stepwise.min_height = ROTATE_MIN_HEIGHT;
250 fsize->stepwise.max_width = ROTATE_MAX_WIDTH;
251 fsize->stepwise.max_height = ROTATE_MAX_HEIGHT;
252 fsize->stepwise.step_width = fmt->hsub;
253 fsize->stepwise.step_height = fmt->vsub;
254
255 return 0;
256}
257
258static int rotate_set_cap_format(struct rotate_ctx *ctx,
259 struct v4l2_pix_format *f,
260 u32 rotate)
261{
262 const struct rotate_format *fmt;
263
264 fmt = rotate_find_format(ctx->src_fmt.pixelformat);
265 if (!fmt)
266 return -EINVAL;
267
268 if (fmt->flags & ROTATE_FLAG_YUV)
269 f->pixelformat = V4L2_PIX_FMT_YUV420;
270 else
271 f->pixelformat = ctx->src_fmt.pixelformat;
272
273 f->field = V4L2_FIELD_NONE;
274
275 if (rotate == 90 || rotate == 270) {
276 f->width = ctx->src_fmt.height;
277 f->height = ctx->src_fmt.width;
278 } else {
279 f->width = ctx->src_fmt.width;
280 f->height = ctx->src_fmt.height;
281 }
282
283 rotate_prepare_format(f);
284
285 return 0;
286}
287
288static int rotate_g_fmt_vid_cap(struct file *file, void *priv,
289 struct v4l2_format *f)
290{
291 struct rotate_ctx *ctx = rotate_file2ctx(file);
292
293 f->fmt.pix = ctx->dst_fmt;
294
295 return 0;
296}
297
298static int rotate_g_fmt_vid_out(struct file *file, void *priv,
299 struct v4l2_format *f)
300{
301 struct rotate_ctx *ctx = rotate_file2ctx(file);
302
303 f->fmt.pix = ctx->src_fmt;
304
305 return 0;
306}
307
308static int rotate_try_fmt_vid_cap(struct file *file, void *priv,
309 struct v4l2_format *f)
310{
311 struct rotate_ctx *ctx = rotate_file2ctx(file);
312
313 return rotate_set_cap_format(ctx, &f->fmt.pix, ctx->rotate);
314}
315
316static int rotate_try_fmt_vid_out(struct file *file, void *priv,
317 struct v4l2_format *f)
318{
319 if (!rotate_find_format(f->fmt.pix.pixelformat))
320 f->fmt.pix.pixelformat = V4L2_PIX_FMT_ARGB32;
321
322 if (f->fmt.pix.width < ROTATE_MIN_WIDTH)
323 f->fmt.pix.width = ROTATE_MIN_WIDTH;
324 if (f->fmt.pix.height < ROTATE_MIN_HEIGHT)
325 f->fmt.pix.height = ROTATE_MIN_HEIGHT;
326
327 if (f->fmt.pix.width > ROTATE_MAX_WIDTH)
328 f->fmt.pix.width = ROTATE_MAX_WIDTH;
329 if (f->fmt.pix.height > ROTATE_MAX_HEIGHT)
330 f->fmt.pix.height = ROTATE_MAX_HEIGHT;
331
332 f->fmt.pix.field = V4L2_FIELD_NONE;
333
334 rotate_prepare_format(&f->fmt.pix);
335
336 return 0;
337}
338
339static int rotate_s_fmt_vid_cap(struct file *file, void *priv,
340 struct v4l2_format *f)
341{
342 struct rotate_ctx *ctx = rotate_file2ctx(file);
343 struct vb2_queue *vq;
344 int ret;
345
346 ret = rotate_try_fmt_vid_cap(file, priv, f);
347 if (ret)
348 return ret;
349
350 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
351 if (vb2_is_busy(vq))
352 return -EBUSY;
353
354 ctx->dst_fmt = f->fmt.pix;
355
356 return 0;
357}
358
359static int rotate_s_fmt_vid_out(struct file *file, void *priv,
360 struct v4l2_format *f)
361{
362 struct rotate_ctx *ctx = rotate_file2ctx(file);
363 struct vb2_queue *vq;
364 int ret;
365
366 ret = rotate_try_fmt_vid_out(file, priv, f);
367 if (ret)
368 return ret;
369
370 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
371 if (vb2_is_busy(vq))
372 return -EBUSY;
373
374 /*
375 * Capture queue has to be also checked, because format and size
376 * depends on output format and size.
377 */
378 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
379 if (vb2_is_busy(vq))
380 return -EBUSY;
381
382 ctx->src_fmt = f->fmt.pix;
383
384 /* Propagate colorspace information to capture. */
385 ctx->dst_fmt.colorspace = f->fmt.pix.colorspace;
386 ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func;
387 ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc;
388 ctx->dst_fmt.quantization = f->fmt.pix.quantization;
389
390 return rotate_set_cap_format(ctx, &ctx->dst_fmt, ctx->rotate);
391}
392
393static const struct v4l2_ioctl_ops rotate_ioctl_ops = {
394 .vidioc_querycap = rotate_querycap,
395
396 .vidioc_enum_framesizes = rotate_enum_framesizes,
397
398 .vidioc_enum_fmt_vid_cap = rotate_enum_fmt_vid_cap,
399 .vidioc_g_fmt_vid_cap = rotate_g_fmt_vid_cap,
400 .vidioc_try_fmt_vid_cap = rotate_try_fmt_vid_cap,
401 .vidioc_s_fmt_vid_cap = rotate_s_fmt_vid_cap,
402
403 .vidioc_enum_fmt_vid_out = rotate_enum_fmt_vid_out,
404 .vidioc_g_fmt_vid_out = rotate_g_fmt_vid_out,
405 .vidioc_try_fmt_vid_out = rotate_try_fmt_vid_out,
406 .vidioc_s_fmt_vid_out = rotate_s_fmt_vid_out,
407
408 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
409 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
410 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
411 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
412 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
413 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
414 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
415
416 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
417 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
418
419 .vidioc_log_status = v4l2_ctrl_log_status,
420 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
421 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
422};
423
424static int rotate_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
425 unsigned int *nplanes, unsigned int sizes[],
426 struct device *alloc_devs[])
427{
428 struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
429 struct v4l2_pix_format *pix_fmt;
430
431 if (V4L2_TYPE_IS_OUTPUT(vq->type))
432 pix_fmt = &ctx->src_fmt;
433 else
434 pix_fmt = &ctx->dst_fmt;
435
436 if (*nplanes) {
437 if (sizes[0] < pix_fmt->sizeimage)
438 return -EINVAL;
439 } else {
440 sizes[0] = pix_fmt->sizeimage;
441 *nplanes = 1;
442 }
443
444 return 0;
445}
446
447static int rotate_buf_prepare(struct vb2_buffer *vb)
448{
449 struct vb2_queue *vq = vb->vb2_queue;
450 struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
451 struct v4l2_pix_format *pix_fmt;
452
453 if (V4L2_TYPE_IS_OUTPUT(vq->type))
454 pix_fmt = &ctx->src_fmt;
455 else
456 pix_fmt = &ctx->dst_fmt;
457
458 if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage)
459 return -EINVAL;
460
461 vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
462
463 return 0;
464}
465
466static void rotate_buf_queue(struct vb2_buffer *vb)
467{
468 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
469 struct rotate_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
470
471 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
472}
473
474static void rotate_queue_cleanup(struct vb2_queue *vq, u32 state)
475{
476 struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
477 struct vb2_v4l2_buffer *vbuf;
478
479 do {
480 if (V4L2_TYPE_IS_OUTPUT(vq->type))
481 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
482 else
483 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
484
485 if (vbuf)
486 v4l2_m2m_buf_done(vbuf, state);
487 } while (vbuf);
488}
489
490static int rotate_start_streaming(struct vb2_queue *vq, unsigned int count)
491{
492 if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
493 struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
494 struct device *dev = ctx->dev->dev;
495 int ret;
496
497 ret = pm_runtime_get_sync(dev);
498 if (ret < 0) {
499 dev_err(dev, "Failed to enable module\n");
500
501 return ret;
502 }
503 }
504
505 return 0;
506}
507
508static void rotate_stop_streaming(struct vb2_queue *vq)
509{
510 if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
511 struct rotate_ctx *ctx = vb2_get_drv_priv(vq);
512
513 pm_runtime_put(ctx->dev->dev);
514 }
515
516 rotate_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
517}
518
519static const struct vb2_ops rotate_qops = {
520 .queue_setup = rotate_queue_setup,
521 .buf_prepare = rotate_buf_prepare,
522 .buf_queue = rotate_buf_queue,
523 .start_streaming = rotate_start_streaming,
524 .stop_streaming = rotate_stop_streaming,
525 .wait_prepare = vb2_ops_wait_prepare,
526 .wait_finish = vb2_ops_wait_finish,
527};
528
529static int rotate_queue_init(void *priv, struct vb2_queue *src_vq,
530 struct vb2_queue *dst_vq)
531{
532 struct rotate_ctx *ctx = priv;
533 int ret;
534
535 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
536 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
537 src_vq->drv_priv = ctx;
538 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
539 src_vq->min_buffers_needed = 1;
540 src_vq->ops = &rotate_qops;
541 src_vq->mem_ops = &vb2_dma_contig_memops;
542 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
543 src_vq->lock = &ctx->dev->dev_mutex;
544 src_vq->dev = ctx->dev->dev;
545
546 ret = vb2_queue_init(src_vq);
547 if (ret)
548 return ret;
549
550 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
551 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
552 dst_vq->drv_priv = ctx;
553 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
554 dst_vq->min_buffers_needed = 2;
555 dst_vq->ops = &rotate_qops;
556 dst_vq->mem_ops = &vb2_dma_contig_memops;
557 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
558 dst_vq->lock = &ctx->dev->dev_mutex;
559 dst_vq->dev = ctx->dev->dev;
560
561 ret = vb2_queue_init(dst_vq);
562 if (ret)
563 return ret;
564
565 return 0;
566}
567
568static int rotate_s_ctrl(struct v4l2_ctrl *ctrl)
569{
570 struct rotate_ctx *ctx = container_of(ctrl->handler,
571 struct rotate_ctx,
572 ctrl_handler);
573 struct v4l2_pix_format fmt;
574
575 switch (ctrl->id) {
576 case V4L2_CID_HFLIP:
577 ctx->hflip = ctrl->val;
578 break;
579 case V4L2_CID_VFLIP:
580 ctx->vflip = ctrl->val;
581 break;
582 case V4L2_CID_ROTATE:
583 rotate_set_cap_format(ctx, &fmt, ctrl->val);
584
585 /* Check if capture format needs to be changed */
586 if (fmt.width != ctx->dst_fmt.width ||
587 fmt.height != ctx->dst_fmt.height ||
588 fmt.bytesperline != ctx->dst_fmt.bytesperline ||
589 fmt.sizeimage != ctx->dst_fmt.sizeimage) {
590 struct vb2_queue *vq;
591
592 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
593 V4L2_BUF_TYPE_VIDEO_CAPTURE);
594 if (vb2_is_busy(vq))
595 return -EBUSY;
596
597 rotate_set_cap_format(ctx, &ctx->dst_fmt, ctrl->val);
598 }
599
600 ctx->rotate = ctrl->val;
601 break;
602 default:
603 return -EINVAL;
604 }
605
606 return 0;
607}
608
609static const struct v4l2_ctrl_ops rotate_ctrl_ops = {
610 .s_ctrl = rotate_s_ctrl,
611};
612
613static int rotate_setup_ctrls(struct rotate_ctx *ctx)
614{
615 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
616
617 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rotate_ctrl_ops,
618 V4L2_CID_HFLIP, 0, 1, 1, 0);
619
620 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rotate_ctrl_ops,
621 V4L2_CID_VFLIP, 0, 1, 1, 0);
622
623 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rotate_ctrl_ops,
624 V4L2_CID_ROTATE, 0, 270, 90, 0);
625
626 if (ctx->ctrl_handler.error) {
627 int err = ctx->ctrl_handler.error;
628
629 v4l2_err(&ctx->dev->v4l2_dev, "control setup failed!\n");
630 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
631
632 return err;
633 }
634
635 return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
636}
637
638static int rotate_open(struct file *file)
639{
640 struct rotate_dev *dev = video_drvdata(file);
641 struct rotate_ctx *ctx = NULL;
642 int ret;
643
644 if (mutex_lock_interruptible(&dev->dev_mutex))
645 return -ERESTARTSYS;
646
647 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
648 if (!ctx) {
649 mutex_unlock(&dev->dev_mutex);
650 return -ENOMEM;
651 }
652
653 /* default output format */
654 ctx->src_fmt.pixelformat = V4L2_PIX_FMT_ARGB32;
655 ctx->src_fmt.field = V4L2_FIELD_NONE;
656 ctx->src_fmt.width = 640;
657 ctx->src_fmt.height = 480;
658 rotate_prepare_format(&ctx->src_fmt);
659
660 /* default capture format */
661 rotate_set_cap_format(ctx, &ctx->dst_fmt, ctx->rotate);
662
663 v4l2_fh_init(&ctx->fh, video_devdata(file));
664 file->private_data = &ctx->fh;
665 ctx->dev = dev;
666
667 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
668 &rotate_queue_init);
669 if (IS_ERR(ctx->fh.m2m_ctx)) {
670 ret = PTR_ERR(ctx->fh.m2m_ctx);
671 goto err_free;
672 }
673
674 v4l2_fh_add(&ctx->fh);
675
676 ret = rotate_setup_ctrls(ctx);
677 if (ret)
678 goto err_free;
679
680 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
681
682 mutex_unlock(&dev->dev_mutex);
683
684 return 0;
685
686err_free:
687 kfree(ctx);
688 mutex_unlock(&dev->dev_mutex);
689
690 return ret;
691}
692
693static int rotate_release(struct file *file)
694{
695 struct rotate_dev *dev = video_drvdata(file);
696 struct rotate_ctx *ctx = container_of(file->private_data,
697 struct rotate_ctx, fh);
698
699 mutex_lock(&dev->dev_mutex);
700
701 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
702 v4l2_fh_del(&ctx->fh);
703 v4l2_fh_exit(&ctx->fh);
704 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
705
706 kfree(ctx);
707
708 mutex_unlock(&dev->dev_mutex);
709
710 return 0;
711}
712
713static const struct v4l2_file_operations rotate_fops = {
714 .owner = THIS_MODULE,
715 .open = rotate_open,
716 .release = rotate_release,
717 .poll = v4l2_m2m_fop_poll,
718 .unlocked_ioctl = video_ioctl2,
719 .mmap = v4l2_m2m_fop_mmap,
720};
721
722static const struct video_device rotate_video_device = {
723 .name = ROTATE_NAME,
724 .vfl_dir = VFL_DIR_M2M,
725 .fops = &rotate_fops,
726 .ioctl_ops = &rotate_ioctl_ops,
727 .minor = -1,
728 .release = video_device_release_empty,
729 .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
730};
731
732static const struct v4l2_m2m_ops rotate_m2m_ops = {
733 .device_run = rotate_device_run,
734};
735
736static int rotate_probe(struct platform_device *pdev)
737{
738 struct rotate_dev *dev;
739 struct video_device *vfd;
740 int irq, ret;
741
742 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
743 if (!dev)
744 return -ENOMEM;
745
746 dev->vfd = rotate_video_device;
747 dev->dev = &pdev->dev;
748
749 irq = platform_get_irq(pdev, 0);
750 if (irq <= 0) {
751 dev_err(dev->dev, "Failed to get IRQ\n");
752
753 return irq;
754 }
755
756 ret = devm_request_irq(dev->dev, irq, rotate_irq,
757 0, dev_name(dev->dev), dev);
758 if (ret) {
759 dev_err(dev->dev, "Failed to request IRQ\n");
760
761 return ret;
762 }
763
764 dev->base = devm_platform_ioremap_resource(pdev, 0);
765 if (IS_ERR(dev->base))
766 return PTR_ERR(dev->base);
767
768 dev->bus_clk = devm_clk_get(dev->dev, "bus");
769 if (IS_ERR(dev->bus_clk)) {
770 dev_err(dev->dev, "Failed to get bus clock\n");
771
772 return PTR_ERR(dev->bus_clk);
773 }
774
775 dev->mod_clk = devm_clk_get(dev->dev, "mod");
776 if (IS_ERR(dev->mod_clk)) {
777 dev_err(dev->dev, "Failed to get mod clock\n");
778
779 return PTR_ERR(dev->mod_clk);
780 }
781
782 dev->rstc = devm_reset_control_get(dev->dev, NULL);
783 if (IS_ERR(dev->rstc)) {
784 dev_err(dev->dev, "Failed to get reset control\n");
785
786 return PTR_ERR(dev->rstc);
787 }
788
789 mutex_init(&dev->dev_mutex);
790
791 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
792 if (ret) {
793 dev_err(dev->dev, "Failed to register V4L2 device\n");
794
795 return ret;
796 }
797
798 vfd = &dev->vfd;
799 vfd->lock = &dev->dev_mutex;
800 vfd->v4l2_dev = &dev->v4l2_dev;
801
802 snprintf(vfd->name, sizeof(vfd->name), "%s",
803 rotate_video_device.name);
804 video_set_drvdata(vfd, dev);
805
806 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
807 if (ret) {
808 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
809
810 goto err_v4l2;
811 }
812
813 v4l2_info(&dev->v4l2_dev,
814 "Device registered as /dev/video%d\n", vfd->num);
815
816 dev->m2m_dev = v4l2_m2m_init(&rotate_m2m_ops);
817 if (IS_ERR(dev->m2m_dev)) {
818 v4l2_err(&dev->v4l2_dev,
819 "Failed to initialize V4L2 M2M device\n");
820 ret = PTR_ERR(dev->m2m_dev);
821
822 goto err_video;
823 }
824
825 platform_set_drvdata(pdev, dev);
826
827 pm_runtime_enable(dev->dev);
828
829 return 0;
830
831err_video:
832 video_unregister_device(&dev->vfd);
833err_v4l2:
834 v4l2_device_unregister(&dev->v4l2_dev);
835
836 return ret;
837}
838
839static int rotate_remove(struct platform_device *pdev)
840{
841 struct rotate_dev *dev = platform_get_drvdata(pdev);
842
843 v4l2_m2m_release(dev->m2m_dev);
844 video_unregister_device(&dev->vfd);
845 v4l2_device_unregister(&dev->v4l2_dev);
846
847 pm_runtime_force_suspend(&pdev->dev);
848
849 return 0;
850}
851
852static int rotate_runtime_resume(struct device *device)
853{
854 struct rotate_dev *dev = dev_get_drvdata(device);
855 int ret;
856
857 ret = clk_prepare_enable(dev->bus_clk);
858 if (ret) {
859 dev_err(dev->dev, "Failed to enable bus clock\n");
860
861 return ret;
862 }
863
864 ret = clk_prepare_enable(dev->mod_clk);
865 if (ret) {
866 dev_err(dev->dev, "Failed to enable mod clock\n");
867
868 goto err_bus_clk;
869 }
870
871 ret = reset_control_deassert(dev->rstc);
872 if (ret) {
873 dev_err(dev->dev, "Failed to apply reset\n");
874
875 goto err_mod_clk;
876 }
877
878 return 0;
879
880err_mod_clk:
881 clk_disable_unprepare(dev->mod_clk);
882err_bus_clk:
883 clk_disable_unprepare(dev->bus_clk);
884
885 return ret;
886}
887
888static int rotate_runtime_suspend(struct device *device)
889{
890 struct rotate_dev *dev = dev_get_drvdata(device);
891
892 reset_control_assert(dev->rstc);
893
894 clk_disable_unprepare(dev->mod_clk);
895 clk_disable_unprepare(dev->bus_clk);
896
897 return 0;
898}
899
900static const struct of_device_id rotate_dt_match[] = {
901 { .compatible = "allwinner,sun8i-a83t-de2-rotate" },
902 { /* sentinel */ }
903};
904MODULE_DEVICE_TABLE(of, rotate_dt_match);
905
906static const struct dev_pm_ops rotate_pm_ops = {
907 .runtime_resume = rotate_runtime_resume,
908 .runtime_suspend = rotate_runtime_suspend,
909};
910
911static struct platform_driver rotate_driver = {
912 .probe = rotate_probe,
913 .remove = rotate_remove,
914 .driver = {
915 .name = ROTATE_NAME,
916 .of_match_table = rotate_dt_match,
917 .pm = &rotate_pm_ops,
918 },
919};
920module_platform_driver(rotate_driver);
921
922MODULE_LICENSE("GPL v2");
923MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
924MODULE_DESCRIPTION("Allwinner DE2 rotate driver");
drivers/media/platform/ti-vpe/cal.c+17−14
@@ -372,8 +372,6 @@ struct cal_ctx { · 371 unmodified lines
372 struct v4l2_subdev *sensor;372 struct v4l2_subdev *sensor;
373 struct v4l2_fwnode_endpoint endpoint;373 struct v4l2_fwnode_endpoint endpoint;
374 374
375 struct v4l2_async_subdev asd;
376
377 struct v4l2_fh fh;375 struct v4l2_fh fh;
378 struct cal_dev *dev;376 struct cal_dev *dev;
379 struct cc_data *cc;377 struct cc_data *cc;
@@ -722,16 +720,16 @@ static void enable_irqs(struct cal_ctx *ctx) · 342 unmodified lines
722 720
723static void disable_irqs(struct cal_ctx *ctx)721static void disable_irqs(struct cal_ctx *ctx)
724{722{
723 u32 val;
724
725 /* Disable IRQ_WDMA_END 0/1 */725 /* Disable IRQ_WDMA_END 0/1 */
726 reg_write_field(ctx->dev,726 val = 0;
727 CAL_HL_IRQENABLE_CLR(2),727 set_field(&val, CAL_HL_IRQ_CLEAR, CAL_HL_IRQ_MASK(ctx->csi2_port));
728 CAL_HL_IRQ_CLEAR,728 reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(2), val);
729 CAL_HL_IRQ_MASK(ctx->csi2_port));
730 /* Disable IRQ_WDMA_START 0/1 */729 /* Disable IRQ_WDMA_START 0/1 */
731 reg_write_field(ctx->dev,730 val = 0;
732 CAL_HL_IRQENABLE_CLR(3),731 set_field(&val, CAL_HL_IRQ_CLEAR, CAL_HL_IRQ_MASK(ctx->csi2_port));
733 CAL_HL_IRQ_CLEAR,732 reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(3), val);
734 CAL_HL_IRQ_MASK(ctx->csi2_port));
735 /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */733 /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
736 reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0);734 reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0);
737}735}
@@ -1948,7 +1946,7 @@ static int cal_complete_ctx(struct cal_ctx *ctx) · 1210 unmodified lines
1948 vfd->lock = &ctx->mutex;1946 vfd->lock = &ctx->mutex;
1949 video_set_drvdata(vfd, ctx);1947 video_set_drvdata(vfd, ctx);
1950 1948
1951 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);1949 ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr);
1952 if (ret < 0)1950 if (ret < 0)
1953 return ret;1951 return ret;
1954 1952
@@ -2032,7 +2030,6 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) · 77 unmodified lines
2032 2030
2033 parent = pdev->dev.of_node;2031 parent = pdev->dev.of_node;
2034 2032
2035 asd = &ctx->asd;
2036 endpoint = &ctx->endpoint;2033 endpoint = &ctx->endpoint;
2037 2034
2038 ep_node = NULL;2035 ep_node = NULL;
@@ -2079,8 +2076,6 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) · 40 unmodified lines
2079 ctx_dbg(3, ctx, "can't get remote parent\n");2076 ctx_dbg(3, ctx, "can't get remote parent\n");
2080 goto cleanup_exit;2077 goto cleanup_exit;
2081 }2078 }
2082 asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
2083 asd->match.fwnode = of_fwnode_handle(sensor_node);
2084 2079
2085 v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint);2080 v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint);
2086 2081
@@ -2110,9 +2105,17 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) · 23 unmodified lines
2110 2105
2111 v4l2_async_notifier_init(&ctx->notifier);2106 v4l2_async_notifier_init(&ctx->notifier);
2112 2107
2108 asd = kzalloc(sizeof(*asd), GFP_KERNEL);
2109 if (!asd)
2110 goto cleanup_exit;
2111
2112 asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
2113 asd->match.fwnode = of_fwnode_handle(sensor_node);
2114
2113 ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd);2115 ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd);
2114 if (ret) {2116 if (ret) {
2115 ctx_err(ctx, "Error adding asd\n");2117 ctx_err(ctx, "Error adding asd\n");
2118 kfree(asd);
2116 goto cleanup_exit;2119 goto cleanup_exit;
2117 }2120 }
2118 2121
drivers/media/platform/ti-vpe/vpe.c+1−1
@@ -2500,7 +2500,7 @@ static void vpe_fw_cb(struct platform_device *pdev) · 2499 unmodified lines
2500 vfd->lock = &dev->dev_mutex;2500 vfd->lock = &dev->dev_mutex;
2501 vfd->v4l2_dev = &dev->v4l2_dev;2501 vfd->v4l2_dev = &dev->v4l2_dev;
2502 2502
2503 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);2503 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2504 if (ret) {2504 if (ret) {
2505 vpe_err(dev, "Failed to register video device\n");2505 vpe_err(dev, "Failed to register video device\n");
2506 2506
drivers/media/platform/via-camera.c+1−1
@@ -1262,7 +1262,7 @@ static int viacam_probe(struct platform_device *pdev) · 1261 unmodified lines
1262 cam->vdev.lock = &cam->lock;1262 cam->vdev.lock = &cam->lock;
1263 cam->vdev.queue = vq;1263 cam->vdev.queue = vq;
1264 video_set_drvdata(&cam->vdev, cam);1264 video_set_drvdata(&cam->vdev, cam);
1265 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);1265 ret = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
1266 if (ret)1266 if (ret)
1267 goto out_irq;1267 goto out_irq;
1268 1268
drivers/media/platform/vicodec/vicodec-core.c+53−111
@@ -117,15 +117,10 @@ struct vicodec_ctx { · 116 unmodified lines
117 struct vicodec_dev *dev;117 struct vicodec_dev *dev;
118 bool is_enc;118 bool is_enc;
119 bool is_stateless;119 bool is_stateless;
120 bool is_draining;
121 bool next_is_last;
122 bool has_stopped;
123 spinlock_t *lock;120 spinlock_t *lock;
124 121
125 struct v4l2_ctrl_handler hdl;122 struct v4l2_ctrl_handler hdl;
126 123
127 struct vb2_v4l2_buffer *last_src_buf;
128
129 /* Source and destination queue data */124 /* Source and destination queue data */
130 struct vicodec_q_data q_data[2];125 struct vicodec_q_data q_data[2];
131 struct v4l2_fwht_state state;126 struct v4l2_fwht_state state;
@@ -431,11 +426,11 @@ static void device_run(void *priv) · 299 unmodified lines
431 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);426 v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
432 427
433 spin_lock(ctx->lock);428 spin_lock(ctx->lock);
434 if (!ctx->comp_has_next_frame && src_buf == ctx->last_src_buf) {429 if (!ctx->comp_has_next_frame &&
430 v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
435 dst_buf->flags |= V4L2_BUF_FLAG_LAST;431 dst_buf->flags |= V4L2_BUF_FLAG_LAST;
436 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);432 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
437 ctx->is_draining = false;433 v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
438 ctx->has_stopped = true;
439 }434 }
440 if (ctx->is_enc || ctx->is_stateless) {435 if (ctx->is_enc || ctx->is_stateless) {
441 src_buf->sequence = q_src->sequence++;436 src_buf->sequence = q_src->sequence++;
@@ -586,8 +581,6 @@ static int job_ready(void *priv) · 144 unmodified lines
586 unsigned int max_to_copy;581 unsigned int max_to_copy;
587 unsigned int comp_frame_size;582 unsigned int comp_frame_size;
588 583
589 if (ctx->has_stopped)
590 return 0;
591 if (ctx->source_changed)584 if (ctx->source_changed)
592 return 0;585 return 0;
593 if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame)586 if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame)
@@ -607,7 +600,8 @@ restart: · 13 unmodified lines
607 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {600 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
608 state = get_next_header(ctx, &p, p_src + sz - p);601 state = get_next_header(ctx, &p, p_src + sz - p);
609 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {602 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
610 if (ctx->is_draining && src_buf == ctx->last_src_buf)603 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx,
604 src_buf))
611 return 1;605 return 1;
612 job_remove_src_buf(ctx, state);606 job_remove_src_buf(ctx, state);
613 goto restart;607 goto restart;
@@ -636,7 +630,8 @@ restart: · 22 unmodified lines
636 p += copy;630 p += copy;
637 ctx->comp_size += copy;631 ctx->comp_size += copy;
638 if (ctx->comp_size < max_to_copy) {632 if (ctx->comp_size < max_to_copy) {
639 if (ctx->is_draining && src_buf == ctx->last_src_buf)633 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx,
634 src_buf))
640 return 1;635 return 1;
641 job_remove_src_buf(ctx, state);636 job_remove_src_buf(ctx, state);
642 goto restart;637 goto restart;
@@ -1219,41 +1214,6 @@ static int vidioc_s_selection(struct file *file, void *priv, · 576 unmodified lines
1219 return 0;1214 return 0;
1220}1215}
1221 1216
1222static int vicodec_mark_last_buf(struct vicodec_ctx *ctx)
1223{
1224 struct vb2_v4l2_buffer *next_dst_buf;
1225 int ret = 0;
1226
1227 spin_lock(ctx->lock);
1228 if (ctx->is_draining) {
1229 ret = -EBUSY;
1230 goto unlock;
1231 }
1232 if (ctx->has_stopped)
1233 goto unlock;
1234
1235 ctx->last_src_buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
1236 ctx->is_draining = true;
1237 if (ctx->last_src_buf)
1238 goto unlock;
1239
1240 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1241 if (!next_dst_buf) {
1242 ctx->next_is_last = true;
1243 goto unlock;
1244 }
1245
1246 next_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
1247 vb2_buffer_done(&next_dst_buf->vb2_buf, VB2_BUF_STATE_DONE);
1248 ctx->is_draining = false;
1249 ctx->has_stopped = true;
1250 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
1251
1252unlock:
1253 spin_unlock(ctx->lock);
1254 return ret;
1255}
1256
1257static int vicodec_encoder_cmd(struct file *file, void *fh,1217static int vicodec_encoder_cmd(struct file *file, void *fh,
1258 struct v4l2_encoder_cmd *ec)1218 struct v4l2_encoder_cmd *ec)
1259{1219{
@@ -1268,18 +1228,19 @@ static int vicodec_encoder_cmd(struct file *file, void *fh, · 8 unmodified lines
1268 !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))1228 !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
1269 return 0;1229 return 0;
1270 1230
1271 if (ec->cmd == V4L2_ENC_CMD_STOP)1231 ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec);
1272 return vicodec_mark_last_buf(ctx);1232 if (ret < 0)
1273 ret = 0;1233 return ret;
1274 spin_lock(ctx->lock);1234
1275 if (ctx->is_draining) {1235 if (ec->cmd == V4L2_ENC_CMD_STOP &&
1276 ret = -EBUSY;1236 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1277 } else if (ctx->has_stopped) {1237 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
1278 ctx->has_stopped = false;1238
1239 if (ec->cmd == V4L2_ENC_CMD_START &&
1240 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1279 vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);1241 vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
1280 }1242
1281 spin_unlock(ctx->lock);1243 return 0;
1282 return ret;
1283}1244}
1284 1245
1285static int vicodec_decoder_cmd(struct file *file, void *fh,1246static int vicodec_decoder_cmd(struct file *file, void *fh,
@@ -1296,18 +1257,19 @@ static int vicodec_decoder_cmd(struct file *file, void *fh, · 10 unmodified lines
1296 !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))1257 !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
1297 return 0;1258 return 0;
1298 1259
1299 if (dc->cmd == V4L2_DEC_CMD_STOP)1260 ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc);
1300 return vicodec_mark_last_buf(ctx);1261 if (ret < 0)
1301 ret = 0;1262 return ret;
1302 spin_lock(ctx->lock);1263
1303 if (ctx->is_draining) {1264 if (dc->cmd == V4L2_DEC_CMD_STOP &&
1304 ret = -EBUSY;1265 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1305 } else if (ctx->has_stopped) {1266 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
1306 ctx->has_stopped = false;1267
1268 if (dc->cmd == V4L2_DEC_CMD_START &&
1269 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1307 vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);1270 vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
1308 }1271
1309 spin_unlock(ctx->lock);1272 return 0;
1310 return ret;
1311}1273}
1312 1274
1313static int vicodec_enum_framesizes(struct file *file, void *fh,1275static int vicodec_enum_framesizes(struct file *file, void *fh,
@@ -1480,23 +1442,21 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) · 166 unmodified lines
1480 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,1442 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1481 };1443 };
1482 1444
1483 if (vb2_is_streaming(vq_cap)) {1445 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) &&
1484 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) &&1446 vb2_is_streaming(vb->vb2_queue) &&
1485 ctx->next_is_last) {1447 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
1486 unsigned int i;1448 unsigned int i;
1487 1449
1488 for (i = 0; i < vb->num_planes; i++)1450 for (i = 0; i < vb->num_planes; i++)
1489 vb->planes[i].bytesused = 0;1451 vb->planes[i].bytesused = 0;
1490 vbuf->flags = V4L2_BUF_FLAG_LAST;1452
1491 vbuf->field = V4L2_FIELD_NONE;1453 vbuf->field = V4L2_FIELD_NONE;
1492 vbuf->sequence = get_q_data(ctx, vb->vb2_queue->type)->sequence++;1454 vbuf->sequence =
1493 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);1455 get_q_data(ctx, vb->vb2_queue->type)->sequence++;
1494 ctx->is_draining = false;1456
1495 ctx->has_stopped = true;1457 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
1496 ctx->next_is_last = false;1458 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
1497 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);1459 return;
1498 return;
1499 }
1500 }1460 }
1501 1461
1502 /* buf_queue handles only the first source change event */1462 /* buf_queue handles only the first source change event */
@@ -1609,8 +1569,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, · 106 unmodified lines
1609 chroma_div = info->width_div * info->height_div;1569 chroma_div = info->width_div * info->height_div;
1610 q_data->sequence = 0;1570 q_data->sequence = 0;
1611 1571
1612 if (V4L2_TYPE_IS_OUTPUT(q->type))1572 v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
1613 ctx->last_src_buf = NULL;
1614 1573
1615 state->gop_cnt = 0;1574 state->gop_cnt = 0;
1616 1575
@@ -1689,29 +1648,12 @@ static void vicodec_stop_streaming(struct vb2_queue *q) · 72 unmodified lines
1689 1648
1690 vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);1649 vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);
1691 1650
1692 if (V4L2_TYPE_IS_OUTPUT(q->type)) {1651 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
1693 if (ctx->is_draining) {1652
1694 struct vb2_v4l2_buffer *next_dst_buf;1653 if (V4L2_TYPE_IS_OUTPUT(q->type) &&
1695 1654 v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1696 spin_lock(ctx->lock);1655 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
1697 ctx->last_src_buf = NULL;1656
1698 next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1699 if (!next_dst_buf) {
1700 ctx->next_is_last = true;
1701 } else {
1702 next_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
1703 vb2_buffer_done(&next_dst_buf->vb2_buf, VB2_BUF_STATE_DONE);
1704 ctx->is_draining = false;
1705 ctx->has_stopped = true;
1706 v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
1707 }
1708 spin_unlock(ctx->lock);
1709 }
1710 } else {
1711 ctx->is_draining = false;
1712 ctx->has_stopped = false;
1713 ctx->next_is_last = false;
1714 }
1715 if (!ctx->is_enc && V4L2_TYPE_IS_OUTPUT(q->type))1657 if (!ctx->is_enc && V4L2_TYPE_IS_OUTPUT(q->type))
1716 ctx->first_source_change_sent = false;1658 ctx->first_source_change_sent = false;
1717 1659
@@ -2120,7 +2062,7 @@ static int register_instance(struct vicodec_dev *dev, · 402 unmodified lines
2120 }2062 }
2121 video_set_drvdata(vfd, dev);2063 video_set_drvdata(vfd, dev);
2122 2064
2123 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);2065 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2124 if (ret) {2066 if (ret) {
2125 v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name);2067 v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name);
2126 v4l2_m2m_release(dev_instance->m2m_dev);2068 v4l2_m2m_release(dev_instance->m2m_dev);
drivers/media/platform/vim2m.c+1−1
@@ -1333,7 +1333,7 @@ static int vim2m_probe(struct platform_device *pdev) · 1332 unmodified lines
1333 vfd->lock = &dev->dev_mutex;1333 vfd->lock = &dev->dev_mutex;
1334 vfd->v4l2_dev = &dev->v4l2_dev;1334 vfd->v4l2_dev = &dev->v4l2_dev;
1335 1335
1336 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);1336 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
1337 if (ret) {1337 if (ret) {
1338 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");1338 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1339 goto error_v4l2;1339 goto error_v4l2;
drivers/media/platform/vimc/vimc-capture.c+10−10
@@ -325,20 +325,20 @@ static const struct media_entity_operations vimc_cap_mops = { · 324 unmodified lines
325 .link_validate = vimc_vdev_link_validate,325 .link_validate = vimc_vdev_link_validate,
326};326};
327 327
328static void vimc_cap_release(struct video_device *vdev)328void vimc_cap_release(struct vimc_ent_device *ved)
329{329{
330 struct vimc_cap_device *vcap =330 struct vimc_cap_device *vcap =
331 container_of(vdev, struct vimc_cap_device, vdev);331 container_of(ved, struct vimc_cap_device, ved);
332 332
333 media_entity_cleanup(vcap->ved.ent);333 media_entity_cleanup(vcap->ved.ent);
334 kfree(vcap);334 kfree(vcap);
335}335}
336 336
337void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)337void vimc_cap_unregister(struct vimc_ent_device *ved)
338{338{
339 struct vimc_cap_device *vcap;339 struct vimc_cap_device *vcap =
340 container_of(ved, struct vimc_cap_device, ved);
340 341
341 vcap = container_of(ved, struct vimc_cap_device, ved);
342 vb2_queue_release(&vcap->queue);342 vb2_queue_release(&vcap->queue);
343 video_unregister_device(&vcap->vdev);343 video_unregister_device(&vcap->vdev);
344}344}
@@ -423,7 +423,7 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc, · 78 unmodified lines
423 423
424 ret = vb2_queue_init(q);424 ret = vb2_queue_init(q);
425 if (ret) {425 if (ret) {
426 dev_err(&vimc->pdev.dev, "%s: vb2 queue init failed (err=%d)\n",426 dev_err(vimc->mdev.dev, "%s: vb2 queue init failed (err=%d)\n",
427 vcfg_name, ret);427 vcfg_name, ret);
428 goto err_clean_m_ent;428 goto err_clean_m_ent;
429 }429 }
@@ -443,13 +443,13 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc, · 13 unmodified lines
443 vcap->ved.ent = &vcap->vdev.entity;443 vcap->ved.ent = &vcap->vdev.entity;
444 vcap->ved.process_frame = vimc_cap_process_frame;444 vcap->ved.process_frame = vimc_cap_process_frame;
445 vcap->ved.vdev_get_format = vimc_cap_get_format;445 vcap->ved.vdev_get_format = vimc_cap_get_format;
446 vcap->ved.dev = &vimc->pdev.dev;446 vcap->ved.dev = vimc->mdev.dev;
447 447
448 /* Initialize the video_device struct */448 /* Initialize the video_device struct */
449 vdev = &vcap->vdev;449 vdev = &vcap->vdev;
450 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;450 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
451 vdev->entity.ops = &vimc_cap_mops;451 vdev->entity.ops = &vimc_cap_mops;
452 vdev->release = vimc_cap_release;452 vdev->release = video_device_release_empty;
453 vdev->fops = &vimc_cap_fops;453 vdev->fops = &vimc_cap_fops;
454 vdev->ioctl_ops = &vimc_cap_ioctl_ops;454 vdev->ioctl_ops = &vimc_cap_ioctl_ops;
455 vdev->lock = &vcap->lock;455 vdev->lock = &vcap->lock;
@@ -460,9 +460,9 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc, · 4 unmodified lines
460 video_set_drvdata(vdev, &vcap->ved);460 video_set_drvdata(vdev, &vcap->ved);
461 461
462 /* Register the video_device with the v4l2 and the media framework */462 /* Register the video_device with the v4l2 and the media framework */
463 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);463 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
464 if (ret) {464 if (ret) {
465 dev_err(&vimc->pdev.dev, "%s: video register failed (err=%d)\n",465 dev_err(vimc->mdev.dev, "%s: video register failed (err=%d)\n",
466 vcap->vdev.name, ret);466 vcap->vdev.name, ret);
467 goto err_release_queue;467 goto err_release_queue;
468 }468 }
drivers/media/platform/vimc/vimc-common.c+0−2
@@ -327,7 +327,6 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, · 326 unmodified lines
327 u32 function,327 u32 function,
328 u16 num_pads,328 u16 num_pads,
329 struct media_pad *pads,329 struct media_pad *pads,
330 const struct v4l2_subdev_internal_ops *sd_int_ops,
331 const struct v4l2_subdev_ops *sd_ops)330 const struct v4l2_subdev_ops *sd_ops)
332{331{
333 int ret;332 int ret;
@@ -337,7 +336,6 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, · 3 unmodified lines
337 336
338 /* Initialize the subdev */337 /* Initialize the subdev */
339 v4l2_subdev_init(sd, sd_ops);338 v4l2_subdev_init(sd, sd_ops);
340 sd->internal_ops = sd_int_ops;
341 sd->entity.function = function;339 sd->entity.function = function;
342 sd->entity.ops = &vimc_ent_sd_mops;340 sd->entity.ops = &vimc_ent_sd_mops;
343 sd->owner = THIS_MODULE;341 sd->owner = THIS_MODULE;
drivers/media/platform/vimc/vimc-common.h+13−14
@@ -106,14 +106,12 @@ struct vimc_ent_device { · 105 unmodified lines
106/**106/**
107 * struct vimc_device - main device for vimc driver107 * struct vimc_device - main device for vimc driver
108 *108 *
109 * @pdev pointer to the platform device
110 * @pipe_cfg pointer to the vimc pipeline configuration structure109 * @pipe_cfg pointer to the vimc pipeline configuration structure
111 * @ent_devs array of vimc_ent_device pointers110 * @ent_devs array of vimc_ent_device pointers
112 * @mdev the associated media_device parent111 * @mdev the associated media_device parent
113 * @v4l2_dev Internal v4l2 parent device112 * @v4l2_dev Internal v4l2 parent device
114 */113 */
115struct vimc_device {114struct vimc_device {
116 struct platform_device pdev;
117 const struct vimc_pipeline_config *pipe_cfg;115 const struct vimc_pipeline_config *pipe_cfg;
118 struct vimc_ent_device **ent_devs;116 struct vimc_ent_device **ent_devs;
119 struct media_device mdev;117 struct media_device mdev;
@@ -127,16 +125,18 @@ struct vimc_device { · 7 unmodified lines
127 * @name entity name125 * @name entity name
128 * @ved pointer to vimc_ent_device (a node in the126 * @ved pointer to vimc_ent_device (a node in the
129 * topology)127 * topology)
130 * @add subdev add hook - initializes and registers128 * @add initializes and registers
131 * subdev called from vimc-core129 * vim entity - called from vimc-core
132 * @rm subdev rm hook - unregisters and frees130 * @unregister unregisters vimc entity - called from vimc-core
133 * subdev called from vimc-core131 * @release releases vimc entity - called from the v4l2_dev
132 * release callback
134 */133 */
135struct vimc_ent_config {134struct vimc_ent_config {
136 const char *name;135 const char *name;
137 struct vimc_ent_device *(*add)(struct vimc_device *vimc,136 struct vimc_ent_device *(*add)(struct vimc_device *vimc,
138 const char *vcfg_name);137 const char *vcfg_name);
139 void (*rm)(struct vimc_device *vimc, struct vimc_ent_device *ved);138 void (*unregister)(struct vimc_ent_device *ved);
139 void (*release)(struct vimc_ent_device *ved);
140};140};
141 141
142/**142/**
@@ -147,22 +147,23 @@ struct vimc_ent_config { · 4 unmodified lines
147 */147 */
148bool vimc_is_source(struct media_entity *ent);148bool vimc_is_source(struct media_entity *ent);
149 149
150/* prototypes for vimc_ent_config add and rm hooks */150/* prototypes for vimc_ent_config hooks */
151struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,151struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
152 const char *vcfg_name);152 const char *vcfg_name);
153void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);153void vimc_cap_unregister(struct vimc_ent_device *ved);
154void vimc_cap_release(struct vimc_ent_device *ved);
154 155
155struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,156struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
156 const char *vcfg_name);157 const char *vcfg_name);
157void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);158void vimc_deb_release(struct vimc_ent_device *ved);
158 159
159struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,160struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
160 const char *vcfg_name);161 const char *vcfg_name);
161void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);162void vimc_sca_release(struct vimc_ent_device *ved);
162 163
163struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,164struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
164 const char *vcfg_name);165 const char *vcfg_name);
165void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);166void vimc_sen_release(struct vimc_ent_device *ved);
166 167
167/**168/**
168 * vimc_pix_map_by_index - get vimc_pix_map struct by its index169 * vimc_pix_map_by_index - get vimc_pix_map struct by its index
@@ -197,7 +198,6 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat); · 28 unmodified lines
197 * @num_pads: number of pads to initialize198 * @num_pads: number of pads to initialize
198 * @pads: the array of pads of the entity, the caller should set the199 * @pads: the array of pads of the entity, the caller should set the
199 flags of the pads200 flags of the pads
200 * @sd_int_ops: pointer to &struct v4l2_subdev_internal_ops
201 * @sd_ops: pointer to &struct v4l2_subdev_ops.201 * @sd_ops: pointer to &struct v4l2_subdev_ops.
202 *202 *
203 * Helper function initialize and register the struct vimc_ent_device and struct203 * Helper function initialize and register the struct vimc_ent_device and struct
@@ -210,7 +210,6 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, · 6 unmodified lines
210 u32 function,210 u32 function,
211 u16 num_pads,211 u16 num_pads,
212 struct media_pad *pads,212 struct media_pad *pads,
213 const struct v4l2_subdev_internal_ops *sd_int_ops,
214 const struct v4l2_subdev_ops *sd_ops);213 const struct v4l2_subdev_ops *sd_ops);
215 214
216/**215/**
drivers/media/platform/vimc/vimc-core.c+61−32
@@ -48,48 +48,51 @@ static struct vimc_ent_config ent_config[] = { · 47 unmodified lines
48 {48 {
49 .name = "Sensor A",49 .name = "Sensor A",
50 .add = vimc_sen_add,50 .add = vimc_sen_add,
51 .rm = vimc_sen_rm,51 .release = vimc_sen_release,
52 },52 },
53 {53 {
54 .name = "Sensor B",54 .name = "Sensor B",
55 .add = vimc_sen_add,55 .add = vimc_sen_add,
56 .rm = vimc_sen_rm,56 .release = vimc_sen_release,
57 },57 },
58 {58 {
59 .name = "Debayer A",59 .name = "Debayer A",
60 .add = vimc_deb_add,60 .add = vimc_deb_add,
61 .rm = vimc_deb_rm,61 .release = vimc_deb_release,
62 },62 },
63 {63 {
64 .name = "Debayer B",64 .name = "Debayer B",
65 .add = vimc_deb_add,65 .add = vimc_deb_add,
66 .rm = vimc_deb_rm,66 .release = vimc_deb_release,
67 },67 },
68 {68 {
69 .name = "Raw Capture 0",69 .name = "Raw Capture 0",
70 .add = vimc_cap_add,70 .add = vimc_cap_add,
71 .rm = vimc_cap_rm,71 .unregister = vimc_cap_unregister,
72 .release = vimc_cap_release,
72 },73 },
73 {74 {
74 .name = "Raw Capture 1",75 .name = "Raw Capture 1",
75 .add = vimc_cap_add,76 .add = vimc_cap_add,
76 .rm = vimc_cap_rm,77 .unregister = vimc_cap_unregister,
78 .release = vimc_cap_release,
77 },79 },
78 {80 {
79 /* TODO: change this to vimc-input when it is implemented */81 /* TODO: change this to vimc-input when it is implemented */
80 .name = "RGB/YUV Input",82 .name = "RGB/YUV Input",
81 .add = vimc_sen_add,83 .add = vimc_sen_add,
82 .rm = vimc_sen_rm,84 .release = vimc_sen_release,
83 },85 },
84 {86 {
85 .name = "Scaler",87 .name = "Scaler",
86 .add = vimc_sca_add,88 .add = vimc_sca_add,
87 .rm = vimc_sca_rm,89 .release = vimc_sca_release,
88 },90 },
89 {91 {
90 .name = "RGB/YUV Capture",92 .name = "RGB/YUV Capture",
91 .add = vimc_cap_add,93 .add = vimc_cap_add,
92 .rm = vimc_cap_rm,94 .unregister = vimc_cap_unregister,
95 .release = vimc_cap_release,
93 },96 },
94};97};
95 98
@@ -162,12 +165,12 @@ static int vimc_add_subdevs(struct vimc_device *vimc) · 66 unmodified lines
162 unsigned int i;165 unsigned int i;
163 166
164 for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {167 for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
165 dev_dbg(&vimc->pdev.dev, "new entity for %s\n",168 dev_dbg(vimc->mdev.dev, "new entity for %s\n",
166 vimc->pipe_cfg->ents[i].name);169 vimc->pipe_cfg->ents[i].name);
167 vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,170 vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
168 vimc->pipe_cfg->ents[i].name);171 vimc->pipe_cfg->ents[i].name);
169 if (!vimc->ent_devs[i]) {172 if (!vimc->ent_devs[i]) {
170 dev_err(&vimc->pdev.dev, "add new entity for %s\n",173 dev_err(vimc->mdev.dev, "add new entity for %s\n",
171 vimc->pipe_cfg->ents[i].name);174 vimc->pipe_cfg->ents[i].name);
172 return -EINVAL;175 return -EINVAL;
173 }176 }
@@ -175,13 +178,33 @@ static int vimc_add_subdevs(struct vimc_device *vimc) · 1 unmodified line
175 return 0;178 return 0;
176}179}
177 180
178static void vimc_rm_subdevs(struct vimc_device *vimc)181static void vimc_release_subdevs(struct vimc_device *vimc)
179{182{
180 unsigned int i;183 unsigned int i;
181 184
182 for (i = 0; i < vimc->pipe_cfg->num_ents; i++)185 for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
183 if (vimc->ent_devs[i])186 if (vimc->ent_devs[i])
184 vimc->pipe_cfg->ents[i].rm(vimc, vimc->ent_devs[i]);187 vimc->pipe_cfg->ents[i].release(vimc->ent_devs[i]);
188}
189
190static void vimc_unregister_subdevs(struct vimc_device *vimc)
191{
192 unsigned int i;
193
194 for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
195 if (vimc->ent_devs[i] && vimc->pipe_cfg->ents[i].unregister)
196 vimc->pipe_cfg->ents[i].unregister(vimc->ent_devs[i]);
197}
198
199static void vimc_v4l2_dev_release(struct v4l2_device *v4l2_dev)
200{
201 struct vimc_device *vimc =
202 container_of(v4l2_dev, struct vimc_device, v4l2_dev);
203
204 vimc_release_subdevs(vimc);
205 media_device_cleanup(&vimc->mdev);
206 kfree(vimc->ent_devs);
207 kfree(vimc);
185}208}
186 209
187static int vimc_register_devices(struct vimc_device *vimc)210static int vimc_register_devices(struct vimc_device *vimc)
@@ -195,7 +218,6 @@ static int vimc_register_devices(struct vimc_device *vimc) · 7 unmodified lines
195 "v4l2 device register failed (err=%d)\n", ret);218 "v4l2 device register failed (err=%d)\n", ret);
196 return ret;219 return ret;
197 }220 }
198
199 /* allocate ent_devs */221 /* allocate ent_devs */
200 vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,222 vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
201 sizeof(*vimc->ent_devs), GFP_KERNEL);223 sizeof(*vimc->ent_devs), GFP_KERNEL);
@@ -236,9 +258,9 @@ static int vimc_register_devices(struct vimc_device *vimc) · 34 unmodified lines
236 258
237err_mdev_unregister:259err_mdev_unregister:
238 media_device_unregister(&vimc->mdev);260 media_device_unregister(&vimc->mdev);
239 media_device_cleanup(&vimc->mdev);
240err_rm_subdevs:261err_rm_subdevs:
241 vimc_rm_subdevs(vimc);262 vimc_unregister_subdevs(vimc);
263 vimc_release_subdevs(vimc);
242 kfree(vimc->ent_devs);264 kfree(vimc->ent_devs);
243err_v4l2_unregister:265err_v4l2_unregister:
244 v4l2_device_unregister(&vimc->v4l2_dev);266 v4l2_device_unregister(&vimc->v4l2_dev);
@@ -248,20 +270,23 @@ err_v4l2_unregister: · 3 unmodified lines
248 270
249static void vimc_unregister(struct vimc_device *vimc)271static void vimc_unregister(struct vimc_device *vimc)
250{272{
273 vimc_unregister_subdevs(vimc);
251 media_device_unregister(&vimc->mdev);274 media_device_unregister(&vimc->mdev);
252 media_device_cleanup(&vimc->mdev);
253 v4l2_device_unregister(&vimc->v4l2_dev);275 v4l2_device_unregister(&vimc->v4l2_dev);
254 kfree(vimc->ent_devs);
255}276}
256 277
257static int vimc_probe(struct platform_device *pdev)278static int vimc_probe(struct platform_device *pdev)
258{279{
259 struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev);280 struct vimc_device *vimc;
260 int ret;281 int ret;
261 282
262 dev_dbg(&pdev->dev, "probe");283 dev_dbg(&pdev->dev, "probe");
263 284
264 memset(&vimc->mdev, 0, sizeof(vimc->mdev));285 vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
286 if (!vimc)
287 return -ENOMEM;
288
289 vimc->pipe_cfg = &pipe_cfg;
265 290
266 /* Link the media device within the v4l2_device */291 /* Link the media device within the v4l2_device */
267 vimc->v4l2_dev.mdev = &vimc->mdev;292 vimc->v4l2_dev.mdev = &vimc->mdev;
@@ -277,20 +302,27 @@ static int vimc_probe(struct platform_device *pdev) · 9 unmodified lines
277 ret = vimc_register_devices(vimc);302 ret = vimc_register_devices(vimc);
278 if (ret) {303 if (ret) {
279 media_device_cleanup(&vimc->mdev);304 media_device_cleanup(&vimc->mdev);
305 kfree(vimc);
280 return ret;306 return ret;
281 }307 }
308 /*
309 * the release cb is set only after successful registration.
310 * if the registration fails, we release directly from probe
311 */
282 312
313 vimc->v4l2_dev.release = vimc_v4l2_dev_release;
314 platform_set_drvdata(pdev, vimc);
283 return 0;315 return 0;
284}316}
285 317
286static int vimc_remove(struct platform_device *pdev)318static int vimc_remove(struct platform_device *pdev)
287{319{
288 struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev);320 struct vimc_device *vimc = platform_get_drvdata(pdev);
289 321
290 dev_dbg(&pdev->dev, "remove");322 dev_dbg(&pdev->dev, "remove");
291 323
292 vimc_rm_subdevs(vimc);
293 vimc_unregister(vimc);324 vimc_unregister(vimc);
325 v4l2_device_put(&vimc->v4l2_dev);
294 326
295 return 0;327 return 0;
296}328}
@@ -299,12 +331,9 @@ static void vimc_dev_release(struct device *dev) · 2 unmodified lines
299{331{
300}332}
301 333
302static struct vimc_device vimc_dev = {334static struct platform_device vimc_pdev = {
303 .pipe_cfg = &pipe_cfg,335 .name = VIMC_PDEV_NAME,
304 .pdev = {336 .dev.release = vimc_dev_release,
305 .name = VIMC_PDEV_NAME,
306 .dev.release = vimc_dev_release,
307 }
308};337};
309 338
310static struct platform_driver vimc_pdrv = {339static struct platform_driver vimc_pdrv = {
@@ -319,16 +348,16 @@ static int __init vimc_init(void) · 8 unmodified lines
319{348{
320 int ret;349 int ret;
321 350
322 ret = platform_device_register(&vimc_dev.pdev);351 ret = platform_device_register(&vimc_pdev);
323 if (ret) {352 if (ret) {
324 dev_err(&vimc_dev.pdev.dev,353 dev_err(&vimc_pdev.dev,
325 "platform device registration failed (err=%d)\n", ret);354 "platform device registration failed (err=%d)\n", ret);
326 return ret;355 return ret;
327 }356 }
328 357
329 ret = platform_driver_register(&vimc_pdrv);358 ret = platform_driver_register(&vimc_pdrv);
330 if (ret) {359 if (ret) {
331 dev_err(&vimc_dev.pdev.dev,360 dev_err(&vimc_pdev.dev,
332 "platform driver registration failed (err=%d)\n", ret);361 "platform driver registration failed (err=%d)\n", ret);
333 platform_driver_unregister(&vimc_pdrv);362 platform_driver_unregister(&vimc_pdrv);
334 return ret;363 return ret;
@@ -341,7 +370,7 @@ static void __exit vimc_exit(void) · 6 unmodified lines
341{370{
342 platform_driver_unregister(&vimc_pdrv);371 platform_driver_unregister(&vimc_pdrv);
343 372
344 platform_device_unregister(&vimc_dev.pdev);373 platform_device_unregister(&vimc_pdev);
345}374}
346 375
347module_init(vimc_init);376module_init(vimc_init);
drivers/media/platform/vimc/vimc-debayer.c+4−17
@@ -494,28 +494,16 @@ static const struct v4l2_ctrl_ops vimc_deb_ctrl_ops = { · 493 unmodified lines
494 .s_ctrl = vimc_deb_s_ctrl,494 .s_ctrl = vimc_deb_s_ctrl,
495};495};
496 496
497static void vimc_deb_release(struct v4l2_subdev *sd)497void vimc_deb_release(struct vimc_ent_device *ved)
498{498{
499 struct vimc_deb_device *vdeb =499 struct vimc_deb_device *vdeb =
500 container_of(sd, struct vimc_deb_device, sd);500 container_of(ved, struct vimc_deb_device, ved);
501 501
502 v4l2_ctrl_handler_free(&vdeb->hdl);502 v4l2_ctrl_handler_free(&vdeb->hdl);
503 media_entity_cleanup(vdeb->ved.ent);503 media_entity_cleanup(vdeb->ved.ent);
504 kfree(vdeb);504 kfree(vdeb);
505}505}
506 506
507static const struct v4l2_subdev_internal_ops vimc_deb_int_ops = {
508 .release = vimc_deb_release,
509};
510
511void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
512{
513 struct vimc_deb_device *vdeb;
514
515 vdeb = container_of(ved, struct vimc_deb_device, ved);
516 v4l2_device_unregister_subdev(&vdeb->sd);
517}
518
519static const struct v4l2_ctrl_config vimc_deb_ctrl_class = {507static const struct v4l2_ctrl_config vimc_deb_ctrl_class = {
520 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,508 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
521 .id = VIMC_CID_VIMC_CLASS,509 .id = VIMC_CID_VIMC_CLASS,
@@ -563,13 +551,12 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc, · 41 unmodified lines
563 ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,551 ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
564 vcfg_name,552 vcfg_name,
565 MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,553 MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
566 vdeb->pads,554 vdeb->pads, &vimc_deb_ops);
567 &vimc_deb_int_ops, &vimc_deb_ops);
568 if (ret)555 if (ret)
569 goto err_free_hdl;556 goto err_free_hdl;
570 557
571 vdeb->ved.process_frame = vimc_deb_process_frame;558 vdeb->ved.process_frame = vimc_deb_process_frame;
572 vdeb->ved.dev = &vimc->pdev.dev;559 vdeb->ved.dev = vimc->mdev.dev;
573 vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;560 vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;
574 561
575 /* Initialize the frame format */562 /* Initialize the frame format */
drivers/media/platform/vimc/vimc-scaler.c+4−17
@@ -464,27 +464,15 @@ static void *vimc_sca_process_frame(struct vimc_ent_device *ved, · 463 unmodified lines
464 return vsca->src_frame;464 return vsca->src_frame;
465};465};
466 466
467static void vimc_sca_release(struct v4l2_subdev *sd)467void vimc_sca_release(struct vimc_ent_device *ved)
468{468{
469 struct vimc_sca_device *vsca =469 struct vimc_sca_device *vsca =
470 container_of(sd, struct vimc_sca_device, sd);470 container_of(ved, struct vimc_sca_device, ved);
471 471
472 media_entity_cleanup(vsca->ved.ent);472 media_entity_cleanup(vsca->ved.ent);
473 kfree(vsca);473 kfree(vsca);
474}474}
475 475
476static const struct v4l2_subdev_internal_ops vimc_sca_int_ops = {
477 .release = vimc_sca_release,
478};
479
480void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
481{
482 struct vimc_sca_device *vsca;
483
484 vsca = container_of(ved, struct vimc_sca_device, ved);
485 v4l2_device_unregister_subdev(&vsca->sd);
486}
487
488struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,476struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
489 const char *vcfg_name)477 const char *vcfg_name)
490{478{
@@ -504,15 +492,14 @@ struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc, · 13 unmodified lines
504 ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,492 ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
505 vcfg_name,493 vcfg_name,
506 MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,494 MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
507 vsca->pads,495 vsca->pads, &vimc_sca_ops);
508 &vimc_sca_int_ops, &vimc_sca_ops);
509 if (ret) {496 if (ret) {
510 kfree(vsca);497 kfree(vsca);
511 return NULL;498 return NULL;
512 }499 }
513 500
514 vsca->ved.process_frame = vimc_sca_process_frame;501 vsca->ved.process_frame = vimc_sca_process_frame;
515 vsca->ved.dev = &vimc->pdev.dev;502 vsca->ved.dev = vimc->mdev.dev;
516 503
517 /* Initialize the frame format */504 /* Initialize the frame format */
518 vsca->sink_fmt = sink_fmt_default;505 vsca->sink_fmt = sink_fmt_default;
drivers/media/platform/vimc/vimc-sensor.c+4−16
@@ -279,10 +279,10 @@ static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = { · 278 unmodified lines
279 .s_ctrl = vimc_sen_s_ctrl,279 .s_ctrl = vimc_sen_s_ctrl,
280};280};
281 281
282static void vimc_sen_release(struct v4l2_subdev *sd)282void vimc_sen_release(struct vimc_ent_device *ved)
283{283{
284 struct vimc_sen_device *vsen =284 struct vimc_sen_device *vsen =
285 container_of(sd, struct vimc_sen_device, sd);285 container_of(ved, struct vimc_sen_device, ved);
286 286
287 v4l2_ctrl_handler_free(&vsen->hdl);287 v4l2_ctrl_handler_free(&vsen->hdl);
288 tpg_free(&vsen->tpg);288 tpg_free(&vsen->tpg);
@@ -290,18 +290,6 @@ static void vimc_sen_release(struct v4l2_subdev *sd) · 1 unmodified line
290 kfree(vsen);290 kfree(vsen);
291}291}
292 292
293static const struct v4l2_subdev_internal_ops vimc_sen_int_ops = {
294 .release = vimc_sen_release,
295};
296
297void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
298{
299 struct vimc_sen_device *vsen;
300
301 vsen = container_of(ved, struct vimc_sen_device, ved);
302 v4l2_device_unregister_subdev(&vsen->sd);
303}
304
305/* Image Processing Controls */293/* Image Processing Controls */
306static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {294static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
307 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,295 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
@@ -365,12 +353,12 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc, · 57 unmodified lines
365 ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,353 ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
366 vcfg_name,354 vcfg_name,
367 MEDIA_ENT_F_CAM_SENSOR, 1, &vsen->pad,355 MEDIA_ENT_F_CAM_SENSOR, 1, &vsen->pad,
368 &vimc_sen_int_ops, &vimc_sen_ops);356 &vimc_sen_ops);
369 if (ret)357 if (ret)
370 goto err_free_tpg;358 goto err_free_tpg;
371 359
372 vsen->ved.process_frame = vimc_sen_process_frame;360 vsen->ved.process_frame = vimc_sen_process_frame;
373 vsen->ved.dev = &vimc->pdev.dev;361 vsen->ved.dev = vimc->mdev.dev;
374 362
375 /* Initialize the frame format */363 /* Initialize the frame format */
376 vsen->mbus_format = fmt_default;364 vsen->mbus_format = fmt_default;
drivers/media/platform/vimc/vimc-streamer.c+14−3
@@ -207,16 +207,27 @@ int vimc_streamer_s_stream(struct vimc_stream *stream, · 206 unmodified lines
207 stream->kthread = kthread_run(vimc_streamer_thread, stream,207 stream->kthread = kthread_run(vimc_streamer_thread, stream,
208 "vimc-streamer thread");208 "vimc-streamer thread");
209 209
210 if (IS_ERR(stream->kthread))210 if (IS_ERR(stream->kthread)) {
211 return PTR_ERR(stream->kthread);211 ret = PTR_ERR(stream->kthread);
212 dev_err(ved->dev, "kthread_run failed with %d\n", ret);
213 vimc_streamer_pipeline_terminate(stream);
214 stream->kthread = NULL;
215 return ret;
216 }
212 217
213 } else {218 } else {
214 if (!stream->kthread)219 if (!stream->kthread)
215 return 0;220 return 0;
216 221
217 ret = kthread_stop(stream->kthread);222 ret = kthread_stop(stream->kthread);
223 /*
224 * kthread_stop returns -EINTR in cases when streamon was
225 * immediately followed by streamoff, and the thread didn't had
226 * a chance to run. Ignore errors to stop the stream in the
227 * pipeline.
228 */
218 if (ret)229 if (ret)
219 return ret;230 dev_dbg(ved->dev, "kthread_stop returned '%d'\n", ret);
220 231
221 stream->kthread = NULL;232 stream->kthread = NULL;
222 233
drivers/media/platform/vivid/vivid-core.c+7−7
@@ -407,7 +407,7 @@ static int vidioc_log_status(struct file *file, void *fh) · 406 unmodified lines
407 struct video_device *vdev = video_devdata(file);407 struct video_device *vdev = video_devdata(file);
408 408
409 v4l2_ctrl_log_status(file, fh);409 v4l2_ctrl_log_status(file, fh);
410 if (vdev->vfl_dir == VFL_DIR_RX && vdev->vfl_type == VFL_TYPE_GRABBER)410 if (vdev->vfl_dir == VFL_DIR_RX && vdev->vfl_type == VFL_TYPE_VIDEO)
411 tpg_log_status(&dev->tpg);411 tpg_log_status(&dev->tpg);
412 return 0;412 return 0;
413}413}
@@ -1525,7 +1525,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 1111 unmodified lines
1525 }1525 }
1526#endif1526#endif
1527 1527
1528 ret = video_register_device(vfd, VFL_TYPE_GRABBER, vid_cap_nr[inst]);1528 ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_cap_nr[inst]);
1529 if (ret < 0)1529 if (ret < 0)
1530 goto unreg_dev;1530 goto unreg_dev;
1531 v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",1531 v4l2_info(&dev->v4l2_dev, "V4L2 capture device registered as %s\n",
@@ -1571,14 +1571,14 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 39 unmodified lines
1571 }1571 }
1572 v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n",1572 v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n",
1573 dev_name(&dev->cec_tx_adap[i]->devnode.dev), i);1573 dev_name(&dev->cec_tx_adap[i]->devnode.dev), i);
1574 if (i <= out_type_counter[HDMI])1574 if (i < out_type_counter[HDMI])
1575 cec_s_phys_addr(dev->cec_tx_adap[i], i << 12, false);1575 cec_s_phys_addr(dev->cec_tx_adap[i], (i + 1) << 12, false);
1576 else1576 else
1577 cec_s_phys_addr(dev->cec_tx_adap[i], 0x1000, false);1577 cec_s_phys_addr(dev->cec_tx_adap[i], 0x1000, false);
1578 }1578 }
1579#endif1579#endif
1580 1580
1581 ret = video_register_device(vfd, VFL_TYPE_GRABBER, vid_out_nr[inst]);1581 ret = video_register_device(vfd, VFL_TYPE_VIDEO, vid_out_nr[inst]);
1582 if (ret < 0)1582 if (ret < 0)
1583 goto unreg_dev;1583 goto unreg_dev;
1584 v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s\n",1584 v4l2_info(&dev->v4l2_dev, "V4L2 output device registered as %s\n",
@@ -1734,7 +1734,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 149 unmodified lines
1734 if (ret)1734 if (ret)
1735 goto unreg_dev;1735 goto unreg_dev;
1736#endif1736#endif
1737 ret = video_register_device(vfd, VFL_TYPE_GRABBER,1737 ret = video_register_device(vfd, VFL_TYPE_VIDEO,
1738 meta_cap_nr[inst]);1738 meta_cap_nr[inst]);
1739 if (ret < 0)1739 if (ret < 0)
1740 goto unreg_dev;1740 goto unreg_dev;
@@ -1764,7 +1764,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 23 unmodified lines
1764 if (ret)1764 if (ret)
1765 goto unreg_dev;1765 goto unreg_dev;
1766#endif1766#endif
1767 ret = video_register_device(vfd, VFL_TYPE_GRABBER,1767 ret = video_register_device(vfd, VFL_TYPE_VIDEO,
1768 meta_out_nr[inst]);1768 meta_out_nr[inst]);
1769 if (ret < 0)1769 if (ret < 0)
1770 goto unreg_dev;1770 goto unreg_dev;
drivers/media/platform/vsp1/vsp1_histo.c+2−2
@@ -551,7 +551,7 @@ int vsp1_histogram_init(struct vsp1_device *vsp1, struct vsp1_histogram *histo, · 550 unmodified lines
551 histo->video.fops = &histo_v4l2_fops;551 histo->video.fops = &histo_v4l2_fops;
552 snprintf(histo->video.name, sizeof(histo->video.name),552 snprintf(histo->video.name, sizeof(histo->video.name),
553 "%s histo", histo->entity.subdev.name);553 "%s histo", histo->entity.subdev.name);
554 histo->video.vfl_type = VFL_TYPE_GRABBER;554 histo->video.vfl_type = VFL_TYPE_VIDEO;
555 histo->video.release = video_device_release_empty;555 histo->video.release = video_device_release_empty;
556 histo->video.ioctl_ops = &histo_v4l2_ioctl_ops;556 histo->video.ioctl_ops = &histo_v4l2_ioctl_ops;
557 histo->video.device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;557 histo->video.device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
@@ -576,7 +576,7 @@ int vsp1_histogram_init(struct vsp1_device *vsp1, struct vsp1_histogram *histo, · 18 unmodified lines
576 576
577 /* ... and register the video device. */577 /* ... and register the video device. */
578 histo->video.queue = &histo->queue;578 histo->video.queue = &histo->queue;
579 ret = video_register_device(&histo->video, VFL_TYPE_GRABBER, -1);579 ret = video_register_device(&histo->video, VFL_TYPE_VIDEO, -1);
580 if (ret < 0) {580 if (ret < 0) {
581 dev_err(vsp1->dev, "failed to register video device\n");581 dev_err(vsp1->dev, "failed to register video device\n");
582 goto error;582 goto error;
drivers/media/platform/vsp1/vsp1_regs.h+1−1
@@ -706,7 +706,7 @@ · 705 unmodified lines
706#define VI6_HGT_HUE_AREA_LOWER_SHIFT 16706#define VI6_HGT_HUE_AREA_LOWER_SHIFT 16
707#define VI6_HGT_HUE_AREA_UPPER_SHIFT 0707#define VI6_HGT_HUE_AREA_UPPER_SHIFT 0
708#define VI6_HGT_LB_TH 0x3424708#define VI6_HGT_LB_TH 0x3424
709#define VI6_HGT_LBn_H(n) (0x3438 + (n) * 8)709#define VI6_HGT_LBn_H(n) (0x3428 + (n) * 8)
710#define VI6_HGT_LBn_V(n) (0x342c + (n) * 8)710#define VI6_HGT_LBn_V(n) (0x342c + (n) * 8)
711#define VI6_HGT_HISTO(m, n) (0x3450 + (m) * 128 + (n) * 4)711#define VI6_HGT_HISTO(m, n) (0x3450 + (m) * 128 + (n) * 4)
712#define VI6_HGT_MAXMIN 0x3750712#define VI6_HGT_MAXMIN 0x3750
drivers/media/platform/vsp1/vsp1_video.c+2−2
@@ -1293,7 +1293,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1, · 1292 unmodified lines
1293 video->video.fops = &vsp1_video_fops;1293 video->video.fops = &vsp1_video_fops;
1294 snprintf(video->video.name, sizeof(video->video.name), "%s %s",1294 snprintf(video->video.name, sizeof(video->video.name), "%s %s",
1295 rwpf->entity.subdev.name, direction);1295 rwpf->entity.subdev.name, direction);
1296 video->video.vfl_type = VFL_TYPE_GRABBER;1296 video->video.vfl_type = VFL_TYPE_VIDEO;
1297 video->video.release = video_device_release_empty;1297 video->video.release = video_device_release_empty;
1298 video->video.ioctl_ops = &vsp1_video_ioctl_ops;1298 video->video.ioctl_ops = &vsp1_video_ioctl_ops;
1299 1299
@@ -1316,7 +1316,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1, · 16 unmodified lines
1316 1316
1317 /* ... and register the video device. */1317 /* ... and register the video device. */
1318 video->video.queue = &video->queue;1318 video->video.queue = &video->queue;
1319 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);1319 ret = video_register_device(&video->video, VFL_TYPE_VIDEO, -1);
1320 if (ret < 0) {1320 if (ret < 0) {
1321 dev_err(video->vsp1->dev, "failed to register video device\n");1321 dev_err(video->vsp1->dev, "failed to register video device\n");
1322 goto error;1322 goto error;
drivers/media/platform/xilinx/xilinx-dma.c+8−7
@@ -685,7 +685,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, · 684 unmodified lines
685 xdev->dev->of_node,685 xdev->dev->of_node,
686 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input",686 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input",
687 port);687 port);
688 dma->video.vfl_type = VFL_TYPE_GRABBER;688 dma->video.vfl_type = VFL_TYPE_VIDEO;
689 dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE689 dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
690 ? VFL_DIR_RX : VFL_DIR_TX;690 ? VFL_DIR_RX : VFL_DIR_TX;
691 dma->video.release = video_device_release_empty;691 dma->video.release = video_device_release_empty;
@@ -725,16 +725,17 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, · 33 unmodified lines
725 725
726 /* ... and the DMA channel. */726 /* ... and the DMA channel. */
727 snprintf(name, sizeof(name), "port%u", port);727 snprintf(name, sizeof(name), "port%u", port);
728 dma->dma = dma_request_slave_channel(dma->xdev->dev, name);728 dma->dma = dma_request_chan(dma->xdev->dev, name);
729 if (dma->dma == NULL) {729 if (IS_ERR(dma->dma)) {
730 dev_err(dma->xdev->dev, "no VDMA channel found\n");730 ret = PTR_ERR(dma->dma);
731 ret = -ENODEV;731 if (ret != -EPROBE_DEFER)
732 dev_err(dma->xdev->dev, "no VDMA channel found\n");
732 goto error;733 goto error;
733 }734 }
734 735
735 dma->align = 1 << dma->dma->device->copy_align;736 dma->align = 1 << dma->dma->device->copy_align;
736 737
737 ret = video_register_device(&dma->video, VFL_TYPE_GRABBER, -1);738 ret = video_register_device(&dma->video, VFL_TYPE_VIDEO, -1);
738 if (ret < 0) {739 if (ret < 0) {
739 dev_err(dma->xdev->dev, "failed to register video device\n");740 dev_err(dma->xdev->dev, "failed to register video device\n");
740 goto error;741 goto error;
@@ -752,7 +753,7 @@ void xvip_dma_cleanup(struct xvip_dma *dma) · 11 unmodified lines
752 if (video_is_registered(&dma->video))753 if (video_is_registered(&dma->video))
753 video_unregister_device(&dma->video);754 video_unregister_device(&dma->video);
754 755
755 if (dma->dma)756 if (!IS_ERR_OR_NULL(dma->dma))
756 dma_release_channel(dma->dma);757 dma_release_channel(dma->dma);
757 758
758 media_entity_cleanup(&dma->video.entity);759 media_entity_cleanup(&dma->video.entity);
drivers/media/radio/si470x/Kconfig+2−2
@@ -1,7 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2config RADIO_SI470X2config RADIO_SI470X
3 tristate "Silicon Labs Si470x FM Radio Receiver support"3 tristate "Silicon Labs Si470x FM Radio Receiver support"
4 depends on VIDEO_V4L24 depends on VIDEO_V4L2
5 help5 help
6 This is a driver for devices with the Silicon Labs SI470x6 This is a driver for devices with the Silicon Labs SI470x
7 chip (either via USB or I2C buses).7 chip (either via USB or I2C buses).
drivers/media/rc/bpf-lirc.c+0−5
@@ -35,11 +35,6 @@ static const struct bpf_func_proto rc_repeat_proto = { · 34 unmodified lines
35 .arg1_type = ARG_PTR_TO_CTX,35 .arg1_type = ARG_PTR_TO_CTX,
36};36};
37 37
38/*
39 * Currently rc-core does not support 64-bit scancodes, but there are many
40 * known protocols with more than 32 bits. So, define the interface as u64
41 * as a future-proof.
42 */
43BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,38BPF_CALL_4(bpf_rc_keydown, u32*, sample, u32, protocol, u64, scancode,
44 u32, toggle)39 u32, toggle)
45{40{
drivers/media/rc/iguanair.c+1−1
@@ -76,7 +76,7 @@ struct send_packet { · 75 unmodified lines
76 uint8_t channels;76 uint8_t channels;
77 uint8_t busy7;77 uint8_t busy7;
78 uint8_t busy4;78 uint8_t busy4;
79 uint8_t payload[0];79 uint8_t payload[];
80};80};
81 81
82static void process_ir_data(struct iguanair *ir, unsigned len)82static void process_ir_data(struct iguanair *ir, unsigned len)
drivers/media/rc/ir-xmp-decoder.c+1−1
@@ -166,7 +166,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) · 165 unmodified lines
166 } else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) {166 } else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) {
167 /* store nibble raw data, decode after trailer */167 /* store nibble raw data, decode after trailer */
168 if (data->count == 16) {168 if (data->count == 16) {
169 dev_dbg(&dev->dev, "to many pulses (%d) ignoring: %u\n",169 dev_dbg(&dev->dev, "too many pulses (%d) ignoring: %u\n",
170 data->count, ev.duration);170 data->count, ev.duration);
171 data->state = STATE_INACTIVE;171 data->state = STATE_INACTIVE;
172 return -EINVAL;172 return -EINVAL;
drivers/media/rc/keymaps/Makefile+1−0
@@ -119,6 +119,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ · 118 unmodified lines
119 rc-videomate-m1f.o \119 rc-videomate-m1f.o \
120 rc-videomate-s350.o \120 rc-videomate-s350.o \
121 rc-videomate-tv-pvr.o \121 rc-videomate-tv-pvr.o \
122 rc-videostrong-kii-pro.o \
122 rc-wetek-hub.o \123 rc-wetek-hub.o \
123 rc-wetek-play2.o \124 rc-wetek-play2.o \
124 rc-winfast.o \125 rc-winfast.o \
drivers/media/rc/keymaps/rc-videostrong-kii-pro.c+83−0
@@ -0,0 +1,83 @@
1// SPDX-License-Identifier: GPL-2.0+
2//
3// Copyright (C) 2019 Mohammad Rasim <mohammad.rasim96@gmail.com>
4
5#include <media/rc-map.h>
6#include <linux/module.h>
7
8//
9// Keytable for the Videostrong KII Pro STB remote control
10//
11
12static struct rc_map_table kii_pro[] = {
13 { 0x59, KEY_POWER },
14 { 0x19, KEY_MUTE },
15 { 0x42, KEY_RED },
16 { 0x40, KEY_GREEN },
17 { 0x00, KEY_YELLOW },
18 { 0x03, KEY_BLUE },
19 { 0x4a, KEY_BACK },
20 { 0x48, KEY_FORWARD },
21 { 0x08, KEY_PREVIOUSSONG},
22 { 0x0b, KEY_NEXTSONG},
23 { 0x46, KEY_PLAYPAUSE },
24 { 0x44, KEY_STOP },
25 { 0x1f, KEY_FAVORITES}, //KEY_F5?
26 { 0x04, KEY_PVR },
27 { 0x4d, KEY_EPG },
28 { 0x02, KEY_INFO },
29 { 0x09, KEY_SUBTITLE },
30 { 0x01, KEY_AUDIO },
31 { 0x0d, KEY_HOMEPAGE },
32 { 0x11, KEY_TV }, // DTV ?
33 { 0x06, KEY_UP },
34 { 0x5a, KEY_LEFT },
35 { 0x1a, KEY_ENTER }, // KEY_OK ?
36 { 0x1b, KEY_RIGHT },
37 { 0x16, KEY_DOWN },
38 { 0x45, KEY_MENU },
39 { 0x05, KEY_ESC },
40 { 0x13, KEY_VOLUMEUP },
41 { 0x17, KEY_VOLUMEDOWN },
42 { 0x58, KEY_APPSELECT },
43 { 0x12, KEY_VENDOR }, // mouse
44 { 0x55, KEY_PAGEUP }, // KEY_CHANNELUP ?
45 { 0x15, KEY_PAGEDOWN }, // KEY_CHANNELDOWN ?
46 { 0x52, KEY_1 },
47 { 0x50, KEY_2 },
48 { 0x10, KEY_3 },
49 { 0x56, KEY_4 },
50 { 0x54, KEY_5 },
51 { 0x14, KEY_6 },
52 { 0x4e, KEY_7 },
53 { 0x4c, KEY_8 },
54 { 0x0c, KEY_9 },
55 { 0x18, KEY_WWW }, // KEY_F7
56 { 0x0f, KEY_0 },
57 { 0x51, KEY_BACKSPACE },
58};
59
60static struct rc_map_list kii_pro_map = {
61 .map = {
62 .scan = kii_pro,
63 .size = ARRAY_SIZE(kii_pro),
64 .rc_proto = RC_PROTO_NEC,
65 .name = RC_MAP_KII_PRO,
66 }
67};
68
69static int __init init_rc_map_kii_pro(void)
70{
71 return rc_map_register(&kii_pro_map);
72}
73
74static void __exit exit_rc_map_kii_pro(void)
75{
76 rc_map_unregister(&kii_pro_map);
77}
78
79module_init(init_rc_map_kii_pro)
80module_exit(exit_rc_map_kii_pro)
81
82MODULE_LICENSE("GPL");
83MODULE_AUTHOR("Mohammad Rasim <mohammad.rasim96@gmail.com>");
drivers/media/rc/lirc_dev.c+1−6
@@ -269,12 +269,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, · 268 unmodified lines
269 goto out_unlock;269 goto out_unlock;
270 }270 }
271 271
272 /*272 /* We only have encoders for 32-bit protocols. */
273 * The scancode field in lirc_scancode is 64-bit simply
274 * to future-proof it, since there are IR protocols encode
275 * use more than 32 bits. For now only 32-bit protocols
276 * are supported.
277 */
278 if (scan.scancode > U32_MAX ||273 if (scan.scancode > U32_MAX ||
279 !rc_validate_scancode(scan.rc_proto, scan.scancode)) {274 !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
280 ret = -EINVAL;275 ret = -EINVAL;
drivers/media/rc/nuvoton-cir.c+2−2
@@ -230,10 +230,10 @@ static ssize_t wakeup_data_show(struct device *dev, · 229 unmodified lines
230 for (i = 0; i < fifo_len; i++) {230 for (i = 0; i < fifo_len; i++) {
231 duration = nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY);231 duration = nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY);
232 duration = (duration & BUF_LEN_MASK) * SAMPLE_PERIOD;232 duration = (duration & BUF_LEN_MASK) * SAMPLE_PERIOD;
233 buf_len += snprintf(buf + buf_len, PAGE_SIZE - buf_len,233 buf_len += scnprintf(buf + buf_len, PAGE_SIZE - buf_len,
234 "%d ", duration);234 "%d ", duration);
235 }235 }
236 buf_len += snprintf(buf + buf_len, PAGE_SIZE - buf_len, "\n");236 buf_len += scnprintf(buf + buf_len, PAGE_SIZE - buf_len, "\n");
237 237
238 spin_unlock_irqrestore(&nvt->lock, flags);238 spin_unlock_irqrestore(&nvt->lock, flags);
239 239
drivers/media/rc/rc-main.c+58−22
@@ -163,6 +163,41 @@ static struct rc_map_list empty_map = { · 162 unmodified lines
163 }163 }
164};164};
165 165
166/**
167 * scancode_to_u64() - converts scancode in &struct input_keymap_entry
168 * @ke: keymap entry containing scancode to be converted.
169 * @scancode: pointer to the location where converted scancode should
170 * be stored.
171 *
172 * This function is a version of input_scancode_to_scalar specialized for
173 * rc-core.
174 */
175static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode)
176{
177 switch (ke->len) {
178 case 1:
179 *scancode = *((u8 *)ke->scancode);
180 break;
181
182 case 2:
183 *scancode = *((u16 *)ke->scancode);
184 break;
185
186 case 4:
187 *scancode = *((u32 *)ke->scancode);
188 break;
189
190 case 8:
191 *scancode = *((u64 *)ke->scancode);
192 break;
193
194 default:
195 return -EINVAL;
196 }
197
198 return 0;
199}
200
166/**201/**
167 * ir_create_table() - initializes a scancode table202 * ir_create_table() - initializes a scancode table
168 * @dev: the rc_dev device203 * @dev: the rc_dev device
@@ -285,13 +320,13 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, · 116 unmodified lines
285 320
286 /* Did the user wish to remove the mapping? */321 /* Did the user wish to remove the mapping? */
287 if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {322 if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
288 dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n",323 dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\n",
289 index, rc_map->scan[index].scancode);324 index, rc_map->scan[index].scancode);
290 rc_map->len--;325 rc_map->len--;
291 memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],326 memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
292 (rc_map->len - index) * sizeof(struct rc_map_table));327 (rc_map->len - index) * sizeof(struct rc_map_table));
293 } else {328 } else {
294 dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n",329 dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",
295 index,330 index,
296 old_keycode == KEY_RESERVED ? "New" : "Replacing",331 old_keycode == KEY_RESERVED ? "New" : "Replacing",
297 rc_map->scan[index].scancode, new_keycode);332 rc_map->scan[index].scancode, new_keycode);
@@ -334,8 +369,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, · 36 unmodified lines
334 */369 */
335static unsigned int ir_establish_scancode(struct rc_dev *dev,370static unsigned int ir_establish_scancode(struct rc_dev *dev,
336 struct rc_map *rc_map,371 struct rc_map *rc_map,
337 unsigned int scancode,372 u64 scancode, bool resize)
338 bool resize)
339{373{
340 unsigned int i;374 unsigned int i;
341 375
@@ -394,7 +428,7 @@ static int ir_setkeycode(struct input_dev *idev, · 52 unmodified lines
394 struct rc_dev *rdev = input_get_drvdata(idev);428 struct rc_dev *rdev = input_get_drvdata(idev);
395 struct rc_map *rc_map = &rdev->rc_map;429 struct rc_map *rc_map = &rdev->rc_map;
396 unsigned int index;430 unsigned int index;
397 unsigned int scancode;431 u64 scancode;
398 int retval = 0;432 int retval = 0;
399 unsigned long flags;433 unsigned long flags;
400 434
@@ -407,7 +441,7 @@ static int ir_setkeycode(struct input_dev *idev, · 6 unmodified lines
407 goto out;441 goto out;
408 }442 }
409 } else {443 } else {
410 retval = input_scancode_to_scalar(ke, &scancode);444 retval = scancode_to_u64(ke, &scancode);
411 if (retval)445 if (retval)
412 goto out;446 goto out;
413 447
@@ -434,8 +468,7 @@ out: · 20 unmodified lines
434 *468 *
435 * return: -ENOMEM if all keycodes could not be inserted, otherwise zero.469 * return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
436 */470 */
437static int ir_setkeytable(struct rc_dev *dev,471static int ir_setkeytable(struct rc_dev *dev, const struct rc_map *from)
438 const struct rc_map *from)
439{472{
440 struct rc_map *rc_map = &dev->rc_map;473 struct rc_map *rc_map = &dev->rc_map;
441 unsigned int i, index;474 unsigned int i, index;
@@ -466,7 +499,7 @@ static int ir_setkeytable(struct rc_dev *dev, · 24 unmodified lines
466 499
467static int rc_map_cmp(const void *key, const void *elt)500static int rc_map_cmp(const void *key, const void *elt)
468{501{
469 const unsigned int *scancode = key;502 const u64 *scancode = key;
470 const struct rc_map_table *e = elt;503 const struct rc_map_table *e = elt;
471 504
472 if (*scancode < e->scancode)505 if (*scancode < e->scancode)
@@ -487,7 +520,7 @@ static int rc_map_cmp(const void *key, const void *elt) · 14 unmodified lines
487 * return: index in the table, -1U if not found520 * return: index in the table, -1U if not found
488 */521 */
489static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,522static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
490 unsigned int scancode)523 u64 scancode)
491{524{
492 struct rc_map_table *res;525 struct rc_map_table *res;
493 526
@@ -516,7 +549,7 @@ static int ir_getkeycode(struct input_dev *idev, · 22 unmodified lines
516 struct rc_map_table *entry;549 struct rc_map_table *entry;
517 unsigned long flags;550 unsigned long flags;
518 unsigned int index;551 unsigned int index;
519 unsigned int scancode;552 u64 scancode;
520 int retval;553 int retval;
521 554
522 spin_lock_irqsave(&rc_map->lock, flags);555 spin_lock_irqsave(&rc_map->lock, flags);
@@ -524,7 +557,7 @@ static int ir_getkeycode(struct input_dev *idev, · 1 unmodified line
524 if (ke->flags & INPUT_KEYMAP_BY_INDEX) {557 if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
525 index = ke->index;558 index = ke->index;
526 } else {559 } else {
527 retval = input_scancode_to_scalar(ke, &scancode);560 retval = scancode_to_u64(ke, &scancode);
528 if (retval)561 if (retval)
529 goto out;562 goto out;
530 563
@@ -538,7 +571,6 @@ static int ir_getkeycode(struct input_dev *idev, · 7 unmodified lines
538 ke->keycode = entry->keycode;571 ke->keycode = entry->keycode;
539 ke->len = sizeof(entry->scancode);572 ke->len = sizeof(entry->scancode);
540 memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));573 memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
541
542 } else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {574 } else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
543 /*575 /*
544 * We do not really know the valid range of scancodes576 * We do not really know the valid range of scancodes
@@ -570,7 +602,7 @@ out: · 25 unmodified lines
570 *602 *
571 * return: the corresponding keycode, or KEY_RESERVED603 * return: the corresponding keycode, or KEY_RESERVED
572 */604 */
573u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)605u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)
574{606{
575 struct rc_map *rc_map = &dev->rc_map;607 struct rc_map *rc_map = &dev->rc_map;
576 unsigned int keycode;608 unsigned int keycode;
@@ -586,7 +618,7 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) · 9 unmodified lines
586 spin_unlock_irqrestore(&rc_map->lock, flags);618 spin_unlock_irqrestore(&rc_map->lock, flags);
587 619
588 if (keycode != KEY_RESERVED)620 if (keycode != KEY_RESERVED)
589 dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n",621 dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n",
590 dev->device_name, scancode, keycode);622 dev->device_name, scancode, keycode);
591 623
592 return keycode;624 return keycode;
@@ -719,8 +751,11 @@ void rc_repeat(struct rc_dev *dev) · 126 unmodified lines
719 751
720 spin_lock_irqsave(&dev->keylock, flags);752 spin_lock_irqsave(&dev->keylock, flags);
721 753
722 input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);754 if (dev->last_scancode <= U32_MAX) {
723 input_sync(dev->input_dev);755 input_event(dev->input_dev, EV_MSC, MSC_SCAN,
756 dev->last_scancode);
757 input_sync(dev->input_dev);
758 }
724 759
725 if (dev->keypressed) {760 if (dev->keypressed) {
726 dev->keyup_jiffies = jiffies + timeout;761 dev->keyup_jiffies = jiffies + timeout;
@@ -743,7 +778,7 @@ EXPORT_SYMBOL_GPL(rc_repeat); · 16 unmodified lines
743 * called with keylock held.778 * called with keylock held.
744 */779 */
745static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,780static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
746 u32 scancode, u32 keycode, u8 toggle)781 u64 scancode, u32 keycode, u8 toggle)
747{782{
748 bool new_event = (!dev->keypressed ||783 bool new_event = (!dev->keypressed ||
749 dev->last_protocol != protocol ||784 dev->last_protocol != protocol ||
@@ -761,7 +796,8 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, · 11 unmodified lines
761 if (new_event && dev->keypressed)796 if (new_event && dev->keypressed)
762 ir_do_keyup(dev, false);797 ir_do_keyup(dev, false);
763 798
764 input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);799 if (scancode <= U32_MAX)
800 input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
765 801
766 dev->last_protocol = protocol;802 dev->last_protocol = protocol;
767 dev->last_scancode = scancode;803 dev->last_scancode = scancode;
@@ -772,7 +808,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, · 4 unmodified lines
772 /* Register a keypress */808 /* Register a keypress */
773 dev->keypressed = true;809 dev->keypressed = true;
774 810
775 dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",811 dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n",
776 dev->device_name, keycode, protocol, scancode);812 dev->device_name, keycode, protocol, scancode);
777 input_report_key(dev->input_dev, keycode, 1);813 input_report_key(dev->input_dev, keycode, 1);
778 814
@@ -809,7 +845,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, · 30 unmodified lines
809 * This routine is used to signal that a key has been pressed on the845 * This routine is used to signal that a key has been pressed on the
810 * remote control.846 * remote control.
811 */847 */
812void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,848void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,
813 u8 toggle)849 u8 toggle)
814{850{
815 unsigned long flags;851 unsigned long flags;
@@ -840,7 +876,7 @@ EXPORT_SYMBOL_GPL(rc_keydown); · 24 unmodified lines
840 * remote control. The driver must manually call rc_keyup() at a later stage.876 * remote control. The driver must manually call rc_keyup() at a later stage.
841 */877 */
842void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,878void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
843 u32 scancode, u8 toggle)879 u64 scancode, u8 toggle)
844{880{
845 unsigned long flags;881 unsigned long flags;
846 u32 keycode = rc_g_keycode_from_table(dev, scancode);882 u32 keycode = rc_g_keycode_from_table(dev, scancode);
drivers/media/spi/gs1662.c+16−4
@@ -147,11 +147,17 @@ static int gs_read_register(struct spi_device *spi, u16 addr, u16 *value) · 146 unmodified lines
147 {147 {
148 .tx_buf = &buf_addr,148 .tx_buf = &buf_addr,
149 .len = 2,149 .len = 2,
150 .delay_usecs = 1,150 .delay = {
151 .value = 1,
152 .unit = SPI_DELAY_UNIT_USECS
153 },
151 }, {154 }, {
152 .rx_buf = &buf_value,155 .rx_buf = &buf_value,
153 .len = 2,156 .len = 2,
154 .delay_usecs = 1,157 .delay = {
158 .value = 1,
159 .unit = SPI_DELAY_UNIT_USECS
160 },
155 },161 },
156 };162 };
157 163
@@ -175,11 +181,17 @@ static int gs_write_register(struct spi_device *spi, u16 addr, u16 value) · 17 unmodified lines
175 {181 {
176 .tx_buf = &buf_addr,182 .tx_buf = &buf_addr,
177 .len = 2,183 .len = 2,
178 .delay_usecs = 1,184 .delay = {
185 .value = 1,
186 .unit = SPI_DELAY_UNIT_USECS
187 },
179 }, {188 }, {
180 .tx_buf = &buf_value,189 .tx_buf = &buf_value,
181 .len = 2,190 .len = 2,
182 .delay_usecs = 1,191 .delay = {
192 .value = 1,
193 .unit = SPI_DELAY_UNIT_USECS
194 },
183 },195 },
184 };196 };
185 197
drivers/media/usb/Kconfig+0−1
@@ -25,7 +25,6 @@ if MEDIA_ANALOG_TV_SUPPORT · 24 unmodified lines
25 comment "Analog TV USB devices"25 comment "Analog TV USB devices"
26source "drivers/media/usb/pvrusb2/Kconfig"26source "drivers/media/usb/pvrusb2/Kconfig"
27source "drivers/media/usb/hdpvr/Kconfig"27source "drivers/media/usb/hdpvr/Kconfig"
28source "drivers/media/usb/usbvision/Kconfig"
29source "drivers/media/usb/stk1160/Kconfig"28source "drivers/media/usb/stk1160/Kconfig"
30source "drivers/media/usb/go7007/Kconfig"29source "drivers/media/usb/go7007/Kconfig"
31endif30endif
drivers/media/usb/Makefile+0−1
@@ -17,7 +17,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ · 16 unmodified lines
17obj-$(CONFIG_VIDEO_AU0828) += au0828/17obj-$(CONFIG_VIDEO_AU0828) += au0828/
18obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/18obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
19obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/19obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
20obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
21obj-$(CONFIG_VIDEO_STK1160) += stk1160/20obj-$(CONFIG_VIDEO_STK1160) += stk1160/
22obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/21obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
23obj-$(CONFIG_VIDEO_TM6000) += tm6000/22obj-$(CONFIG_VIDEO_TM6000) += tm6000/
drivers/media/usb/au0828/au0828-video.c+2−2
@@ -1042,7 +1042,7 @@ static int au0828_v4l2_close(struct file *filp) · 1041 unmodified lines
1042 dev->streaming_users, dev->users);1042 dev->streaming_users, dev->users);
1043 1043
1044 mutex_lock(&dev->lock);1044 mutex_lock(&dev->lock);
1045 if (vdev->vfl_type == VFL_TYPE_GRABBER && dev->vid_timeout_running) {1045 if (vdev->vfl_type == VFL_TYPE_VIDEO && dev->vid_timeout_running) {
1046 /* Cancel timeout thread in case they didn't call streamoff */1046 /* Cancel timeout thread in case they didn't call streamoff */
1047 dev->vid_timeout_running = 0;1047 dev->vid_timeout_running = 0;
1048 del_timer_sync(&dev->vid_timeout);1048 del_timer_sync(&dev->vid_timeout);
@@ -2007,7 +2007,7 @@ int au0828_analog_register(struct au0828_dev *dev, · 958 unmodified lines
2007 2007
2008 /* Register the v4l2 device */2008 /* Register the v4l2 device */
2009 video_set_drvdata(&dev->vdev, dev);2009 video_set_drvdata(&dev->vdev, dev);
2010 retval = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);2010 retval = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1);
2011 if (retval != 0) {2011 if (retval != 0) {
2012 dprintk(1, "unable to register video device (error = %d).\n",2012 dprintk(1, "unable to register video device (error = %d).\n",
2013 retval);2013 retval);
drivers/media/usb/b2c2/flexcop-usb.c+3−3
@@ -511,6 +511,9 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb) · 510 unmodified lines
511 return ret;511 return ret;
512 }512 }
513 513
514 if (fc_usb->uintf->cur_altsetting->desc.bNumEndpoints < 1)
515 return -ENODEV;
516
514 switch (fc_usb->udev->speed) {517 switch (fc_usb->udev->speed) {
515 case USB_SPEED_LOW:518 case USB_SPEED_LOW:
516 err("cannot handle USB speed because it is too slow.");519 err("cannot handle USB speed because it is too slow.");
@@ -544,9 +547,6 @@ static int flexcop_usb_probe(struct usb_interface *intf, · 27 unmodified lines
544 struct flexcop_device *fc = NULL;547 struct flexcop_device *fc = NULL;
545 int ret;548 int ret;
546 549
547 if (intf->cur_altsetting->desc.bNumEndpoints < 1)
548 return -ENODEV;
549
550 if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {550 if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
551 err("out of memory\n");551 err("out of memory\n");
552 return -ENOMEM;552 return -ENOMEM;
drivers/media/usb/cpia2/cpia2_v4l.c+1−1
@@ -1134,7 +1134,7 @@ int cpia2_register_camera(struct camera_data *cam) · 1133 unmodified lines
1134 reset_camera_struct_v4l(cam);1134 reset_camera_struct_v4l(cam);
1135 1135
1136 /* register v4l device */1136 /* register v4l device */
1137 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {1137 if (video_register_device(&cam->vdev, VFL_TYPE_VIDEO, video_nr) < 0) {
1138 ERR("video_register_device failed\n");1138 ERR("video_register_device failed\n");
1139 return -ENODEV;1139 return -ENODEV;
1140 }1140 }
drivers/media/usb/cx231xx/cx231xx-417.c+1−1
@@ -1790,7 +1790,7 @@ int cx231xx_417_register(struct cx231xx *dev) · 1789 unmodified lines
1790 dev->v4l_device.queue = q;1790 dev->v4l_device.queue = q;
1791 1791
1792 err = video_register_device(&dev->v4l_device,1792 err = video_register_device(&dev->v4l_device,
1793 VFL_TYPE_GRABBER, -1);1793 VFL_TYPE_VIDEO, -1);
1794 if (err < 0) {1794 if (err < 0) {
1795 dprintk(3, "%s: can't register mpeg device\n", dev->name);1795 dprintk(3, "%s: can't register mpeg device\n", dev->name);
1796 v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);1796 v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
drivers/media/usb/cx231xx/cx231xx-dvb.c+1−1
@@ -147,7 +147,7 @@ static struct tda18271_config pv_tda18271_config = { · 146 unmodified lines
147 .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,147 .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
148};148};
149 149
150static struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = {150static const struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = {
151 .qam_if_khz = 4000,151 .qam_if_khz = 4000,
152 .vsb_if_khz = 3250,152 .vsb_if_khz = 3250,
153 .spectral_inversion = 1,153 .spectral_inversion = 1,
drivers/media/usb/cx231xx/cx231xx-video.c+1−1
@@ -1785,7 +1785,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) · 1784 unmodified lines
1785 dev->vdev.device_caps |= V4L2_CAP_TUNER;1785 dev->vdev.device_caps |= V4L2_CAP_TUNER;
1786 1786
1787 /* register v4l2 video video_device */1787 /* register v4l2 video video_device */
1788 ret = video_register_device(&dev->vdev, VFL_TYPE_GRABBER,1788 ret = video_register_device(&dev->vdev, VFL_TYPE_VIDEO,
1789 video_nr[dev->devno]);1789 video_nr[dev->devno]);
1790 if (ret) {1790 if (ret) {
1791 dev_err(dev->dev,1791 dev_err(dev->dev,
drivers/media/usb/dvb-usb-v2/anysee.c+2−2
@@ -318,14 +318,14 @@ static struct tda10023_config anysee_tda10023_tda18212_config = { · 317 unmodified lines
318 .deltaf = 0xba02,318 .deltaf = 0xba02,
319};319};
320 320
321static struct tda18212_config anysee_tda18212_config = {321static const struct tda18212_config anysee_tda18212_config = {
322 .if_dvbt_6 = 4150,322 .if_dvbt_6 = 4150,
323 .if_dvbt_7 = 4150,323 .if_dvbt_7 = 4150,
324 .if_dvbt_8 = 4150,324 .if_dvbt_8 = 4150,
325 .if_dvbc = 5000,325 .if_dvbc = 5000,
326};326};
327 327
328static struct tda18212_config anysee_tda18212_config2 = {328static const struct tda18212_config anysee_tda18212_config2 = {
329 .if_dvbt_6 = 3550,329 .if_dvbt_6 = 3550,
330 .if_dvbt_7 = 3700,330 .if_dvbt_7 = 3700,
331 .if_dvbt_8 = 4150,331 .if_dvbt_8 = 4150,
drivers/media/usb/dvb-usb-v2/lmedm04.c+1−4
@@ -486,13 +486,10 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], · 485 unmodified lines
486 static u8 obuf[64], ibuf[64];486 static u8 obuf[64], ibuf[64];
487 int i, read, read_o;487 int i, read, read_o;
488 u16 len;488 u16 len;
489 u8 gate = st->i2c_gate;489 u8 gate;
490 490
491 mutex_lock(&d->i2c_mutex);491 mutex_lock(&d->i2c_mutex);
492 492
493 if (gate == 0)
494 gate = 5;
495
496 for (i = 0; i < num; i++) {493 for (i = 0; i < num; i++) {
497 read_o = msg[i].flags & I2C_M_RD;494 read_o = msg[i].flags & I2C_M_RD;
498 read = i + 1 < num && msg[i + 1].flags & I2C_M_RD;495 read = i + 1 < num && msg[i + 1].flags & I2C_M_RD;
drivers/media/usb/dvb-usb-v2/rtl28xxu.c+3−0
@@ -552,6 +552,9 @@ tuner_found: · 551 unmodified lines
552 if (ret)552 if (ret)
553 goto err;553 goto err;
554 554
555 /* slave demod needs some time to wake up */
556 msleep(20);
557
555 /* check slave answers */558 /* check slave answers */
556 ret = rtl28xxu_ctrl_msg(d, &req_mn88472);559 ret = rtl28xxu_ctrl_msg(d, &req_mn88472);
557 if (ret == 0 && buf[0] == 0x02) {560 if (ret == 0 && buf[0] == 0x02) {
drivers/media/usb/dvb-usb/cxusb-analog.c+6−6
@@ -1223,7 +1223,7 @@ static int cxusb_medion_g_tuner(struct file *file, void *fh, · 1222 unmodified lines
1223 if (tuner->index != 0)1223 if (tuner->index != 0)
1224 return -EINVAL;1224 return -EINVAL;
1225 1225
1226 if (vdev->vfl_type == VFL_TYPE_GRABBER)1226 if (vdev->vfl_type == VFL_TYPE_VIDEO)
1227 tuner->type = V4L2_TUNER_ANALOG_TV;1227 tuner->type = V4L2_TUNER_ANALOG_TV;
1228 else1228 else
1229 tuner->type = V4L2_TUNER_RADIO;1229 tuner->type = V4L2_TUNER_RADIO;
@@ -1259,7 +1259,7 @@ static int cxusb_medion_g_tuner(struct file *file, void *fh, · 29 unmodified lines
1259 if (ret != 0)1259 if (ret != 0)
1260 return ret;1260 return ret;
1261 1261
1262 if (vdev->vfl_type == VFL_TYPE_GRABBER)1262 if (vdev->vfl_type == VFL_TYPE_VIDEO)
1263 strscpy(tuner->name, "TV tuner", sizeof(tuner->name));1263 strscpy(tuner->name, "TV tuner", sizeof(tuner->name));
1264 else1264 else
1265 strscpy(tuner->name, "Radio tuner", sizeof(tuner->name));1265 strscpy(tuner->name, "Radio tuner", sizeof(tuner->name));
@@ -1292,7 +1292,7 @@ static int cxusb_medion_s_tuner(struct file *file, void *fh, · 26 unmodified lines
1292 * make sure that cx25840 is in a correct TV / radio mode,1292 * make sure that cx25840 is in a correct TV / radio mode,
1293 * since calls above may have changed it for tuner / IF demod1293 * since calls above may have changed it for tuner / IF demod
1294 */1294 */
1295 if (vdev->vfl_type == VFL_TYPE_GRABBER)1295 if (vdev->vfl_type == VFL_TYPE_VIDEO)
1296 v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm);1296 v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm);
1297 else1297 else
1298 v4l2_subdev_call(cxdev->cx25840, tuner, s_radio);1298 v4l2_subdev_call(cxdev->cx25840, tuner, s_radio);
@@ -1335,7 +1335,7 @@ static int cxusb_medion_s_frequency(struct file *file, void *fh, · 36 unmodified lines
1335 * make sure that cx25840 is in a correct TV / radio mode,1335 * make sure that cx25840 is in a correct TV / radio mode,
1336 * since calls above may have changed it for tuner / IF demod1336 * since calls above may have changed it for tuner / IF demod
1337 */1337 */
1338 if (vdev->vfl_type == VFL_TYPE_GRABBER)1338 if (vdev->vfl_type == VFL_TYPE_VIDEO)
1339 v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm);1339 v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm);
1340 else1340 else
1341 v4l2_subdev_call(cxdev->cx25840, tuner, s_radio);1341 v4l2_subdev_call(cxdev->cx25840, tuner, s_radio);
@@ -1564,7 +1564,7 @@ static int cxusb_videoradio_release(struct file *f) · 222 unmodified lines
1564 1564
1565 cxusb_vprintk(dvbdev, OPS, "got release\n");1565 cxusb_vprintk(dvbdev, OPS, "got release\n");
1566 1566
1567 if (vdev->vfl_type == VFL_TYPE_GRABBER)1567 if (vdev->vfl_type == VFL_TYPE_VIDEO)
1568 ret = vb2_fop_release(f);1568 ret = vb2_fop_release(f);
1569 else1569 else
1570 ret = v4l2_fh_release(f);1570 ret = v4l2_fh_release(f);
@@ -1663,7 +1663,7 @@ static int cxusb_medion_register_analog_video(struct dvb_usb_device *dvbdev) · 92 unmodified lines
1663 cxdev->videodev->lock = &cxdev->dev_lock;1663 cxdev->videodev->lock = &cxdev->dev_lock;
1664 video_set_drvdata(cxdev->videodev, dvbdev);1664 video_set_drvdata(cxdev->videodev, dvbdev);
1665 1665
1666 ret = video_register_device(cxdev->videodev, VFL_TYPE_GRABBER, -1);1666 ret = video_register_device(cxdev->videodev, VFL_TYPE_VIDEO, -1);
1667 if (ret) {1667 if (ret) {
1668 dev_err(&dvbdev->udev->dev,1668 dev_err(&dvbdev->udev->dev,
1669 "video device register failed, ret = %d\n", ret);1669 "video device register failed, ret = %d\n", ret);
drivers/media/usb/dvb-usb/dib0700_core.c+2−2
@@ -818,7 +818,7 @@ int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf) · 817 unmodified lines
818 818
819 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */819 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
820 820
821 if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1)821 if (intf->cur_altsetting->desc.bNumEndpoints < rc_ep + 1)
822 return -ENODEV;822 return -ENODEV;
823 823
824 purb = usb_alloc_urb(0, GFP_KERNEL);824 purb = usb_alloc_urb(0, GFP_KERNEL);
@@ -838,7 +838,7 @@ int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf) · 13 unmodified lines
838 * Some devices like the Hauppauge NovaTD model 52009 use an interrupt838 * Some devices like the Hauppauge NovaTD model 52009 use an interrupt
839 * endpoint, while others use a bulk one.839 * endpoint, while others use a bulk one.
840 */840 */
841 e = &intf->altsetting[0].endpoint[rc_ep].desc;841 e = &intf->cur_altsetting->endpoint[rc_ep].desc;
842 if (usb_endpoint_dir_in(e)) {842 if (usb_endpoint_dir_in(e)) {
843 if (usb_endpoint_xfer_bulk(e)) {843 if (usb_endpoint_xfer_bulk(e)) {
844 pipe = usb_rcvbulkpipe(d->udev, rc_ep);844 pipe = usb_rcvbulkpipe(d->udev, rc_ep);
drivers/media/usb/dvb-usb/dw2102.c+43−2
@@ -1524,6 +1524,29 @@ static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap) · 1523 unmodified lines
1524 return -EIO;1524 return -EIO;
1525}1525}
1526 1526
1527static int tt_s2_4600_frontend_attach_probe_demod(struct dvb_usb_device *d,
1528 const int probe_addr)
1529{
1530 struct dw2102_state *state = d->priv;
1531
1532 state->data[0] = 0x9;
1533 state->data[1] = 0x1;
1534 state->data[2] = 0x1;
1535 state->data[3] = probe_addr;
1536 state->data[4] = 0x0;
1537
1538 if (dvb_usb_generic_rw(d, state->data, 5, state->data, 2, 0) < 0) {
1539 err("i2c probe for address 0x%x failed.", probe_addr);
1540 return 0;
1541 }
1542
1543 if (state->data[0] != 8) /* fail(7) or error, no device at address */
1544 return 0;
1545
1546 /* probing successful */
1547 return 1;
1548}
1549
1527static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)1550static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
1528{1551{
1529 struct dvb_usb_device *d = adap->dev;1552 struct dvb_usb_device *d = adap->dev;
@@ -1533,6 +1556,7 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) · 3 unmodified lines
1533 struct i2c_board_info board_info;1556 struct i2c_board_info board_info;
1534 struct m88ds3103_platform_data m88ds3103_pdata = {};1557 struct m88ds3103_platform_data m88ds3103_pdata = {};
1535 struct ts2020_config ts2020_config = {};1558 struct ts2020_config ts2020_config = {};
1559 int demod_addr;
1536 1560
1537 mutex_lock(&d->data_mutex);1561 mutex_lock(&d->data_mutex);
1538 1562
@@ -1570,8 +1594,22 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) · 31 unmodified lines
1570 if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)1594 if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
1571 err("command 0x51 transfer failed.");1595 err("command 0x51 transfer failed.");
1572 1596
1597 /* probe for demodulator i2c address */
1598 demod_addr = -1;
1599 if (tt_s2_4600_frontend_attach_probe_demod(d, 0x68))
1600 demod_addr = 0x68;
1601 else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x69))
1602 demod_addr = 0x69;
1603 else if (tt_s2_4600_frontend_attach_probe_demod(d, 0x6a))
1604 demod_addr = 0x6a;
1605
1573 mutex_unlock(&d->data_mutex);1606 mutex_unlock(&d->data_mutex);
1574 1607
1608 if (demod_addr < 0) {
1609 err("probing for demodulator failed. Is the external power switched on?");
1610 return -ENODEV;
1611 }
1612
1575 /* attach demod */1613 /* attach demod */
1576 m88ds3103_pdata.clk = 27000000;1614 m88ds3103_pdata.clk = 27000000;
1577 m88ds3103_pdata.i2c_wr_max = 33;1615 m88ds3103_pdata.i2c_wr_max = 33;
@@ -1586,8 +1624,11 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) · 8 unmodified lines
1586 m88ds3103_pdata.lnb_hv_pol = 1;1624 m88ds3103_pdata.lnb_hv_pol = 1;
1587 m88ds3103_pdata.lnb_en_pol = 0;1625 m88ds3103_pdata.lnb_en_pol = 0;
1588 memset(&board_info, 0, sizeof(board_info));1626 memset(&board_info, 0, sizeof(board_info));
1589 strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);1627 if (demod_addr == 0x6a)
1590 board_info.addr = 0x68;1628 strscpy(board_info.type, "m88ds3103b", I2C_NAME_SIZE);
1629 else
1630 strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
1631 board_info.addr = demod_addr;
1591 board_info.platform_data = &m88ds3103_pdata;1632 board_info.platform_data = &m88ds3103_pdata;
1592 request_module("m88ds3103");1633 request_module("m88ds3103");
1593 client = i2c_new_client_device(&d->i2c_adap, &board_info);1634 client = i2c_new_client_device(&d->i2c_adap, &board_info);
drivers/media/usb/em28xx/em28xx-cards.c+18−0
@@ -2397,6 +2397,20 @@ const struct em28xx_board em28xx_boards[] = { · 2396 unmodified lines
2397 .has_dvb = 1,2397 .has_dvb = 1,
2398 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,2398 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
2399 },2399 },
2400 /*
2401 * 2013:0259 PCTV DVB-S2 Stick (461e_v2)
2402 * Empia EM28178, Montage M88DS3103b, Montage M88TS2022, Allegro A8293
2403 */
2404 [EM28178_BOARD_PCTV_461E_V2] = {
2405 .def_i2c_bus = 1,
2406 .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
2407 EM28XX_I2C_FREQ_400_KHZ,
2408 .name = "PCTV DVB-S2 Stick (461e v2)",
2409 .tuner_type = TUNER_ABSENT,
2410 .tuner_gpio = pctv_461e,
2411 .has_dvb = 1,
2412 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
2413 },
2400 /*2414 /*
2401 * 2013:025f PCTV tripleStick (292e).2415 * 2013:025f PCTV tripleStick (292e).
2402 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si21572416 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157
@@ -2696,6 +2710,10 @@ struct usb_device_id em28xx_id_table[] = { · 293 unmodified lines
2696 .driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },2710 .driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE },
2697 { USB_DEVICE(0x2013, 0x0258),2711 { USB_DEVICE(0x2013, 0x0258),
2698 .driver_info = EM28178_BOARD_PCTV_461E },2712 .driver_info = EM28178_BOARD_PCTV_461E },
2713 { USB_DEVICE(0x2013, 0x0461),
2714 .driver_info = EM28178_BOARD_PCTV_461E_V2 },
2715 { USB_DEVICE(0x2013, 0x0259),
2716 .driver_info = EM28178_BOARD_PCTV_461E_V2 },
2699 { USB_DEVICE(0x2013, 0x025f),2717 { USB_DEVICE(0x2013, 0x025f),
2700 .driver_info = EM28178_BOARD_PCTV_292E },2718 .driver_info = EM28178_BOARD_PCTV_292E },
2701 { USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */2719 { USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */
drivers/media/usb/em28xx/em28xx-dvb.c+60−0
@@ -1219,6 +1219,61 @@ static int em28178_dvb_init_pctv_461e(struct em28xx *dev) · 1218 unmodified lines
1219 return 0;1219 return 0;
1220}1220}
1221 1221
1222static int em28178_dvb_init_pctv_461e_v2(struct em28xx *dev)
1223{
1224 struct em28xx_dvb *dvb = dev->dvb;
1225 struct i2c_adapter *i2c_adapter;
1226 struct m88ds3103_platform_data m88ds3103_pdata = {};
1227 struct ts2020_config ts2020_config = {};
1228 struct a8293_platform_data a8293_pdata = {};
1229
1230 /* attach demod */
1231 m88ds3103_pdata.clk = 27000000;
1232 m88ds3103_pdata.i2c_wr_max = 33;
1233 m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL;
1234 m88ds3103_pdata.ts_clk = 16000;
1235 m88ds3103_pdata.ts_clk_pol = 0;
1236 m88ds3103_pdata.agc = 0x99;
1237 m88ds3103_pdata.agc_inv = 0;
1238 m88ds3103_pdata.spec_inv = 0;
1239 dvb->i2c_client_demod = dvb_module_probe("m88ds3103", "m88ds3103b",
1240 &dev->i2c_adap[dev->def_i2c_bus],
1241 0x6a, &m88ds3103_pdata);
1242
1243 if (!dvb->i2c_client_demod)
1244 return -ENODEV;
1245
1246 dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(dvb->i2c_client_demod);
1247 i2c_adapter = m88ds3103_pdata.get_i2c_adapter(dvb->i2c_client_demod);
1248
1249 /* attach tuner */
1250 ts2020_config.fe = dvb->fe[0];
1251 dvb->i2c_client_tuner = dvb_module_probe("ts2020", "ts2022",
1252 i2c_adapter,
1253 0x60, &ts2020_config);
1254 if (!dvb->i2c_client_tuner) {
1255 dvb_module_release(dvb->i2c_client_demod);
1256 return -ENODEV;
1257 }
1258
1259 /* delegate signal strength measurement to tuner */
1260 dvb->fe[0]->ops.read_signal_strength =
1261 dvb->fe[0]->ops.tuner_ops.get_rf_strength;
1262
1263 /* attach SEC */
1264 a8293_pdata.dvb_frontend = dvb->fe[0];
1265 dvb->i2c_client_sec = dvb_module_probe("a8293", NULL,
1266 &dev->i2c_adap[dev->def_i2c_bus],
1267 0x08, &a8293_pdata);
1268 if (!dvb->i2c_client_sec) {
1269 dvb_module_release(dvb->i2c_client_tuner);
1270 dvb_module_release(dvb->i2c_client_demod);
1271 return -ENODEV;
1272 }
1273
1274 return 0;
1275}
1276
1222static int em28178_dvb_init_pctv_292e(struct em28xx *dev)1277static int em28178_dvb_init_pctv_292e(struct em28xx *dev)
1223{1278{
1224 struct em28xx_dvb *dvb = dev->dvb;1279 struct em28xx_dvb *dvb = dev->dvb;
@@ -1860,6 +1915,11 @@ static int em28xx_dvb_init(struct em28xx *dev) · 635 unmodified lines
1860 if (result)1915 if (result)
1861 goto out_free;1916 goto out_free;
1862 break;1917 break;
1918 case EM28178_BOARD_PCTV_461E_V2:
1919 result = em28178_dvb_init_pctv_461e_v2(dev);
1920 if (result)
1921 goto out_free;
1922 break;
1863 case EM28178_BOARD_PCTV_292E:1923 case EM28178_BOARD_PCTV_292E:
1864 result = em28178_dvb_init_pctv_292e(dev);1924 result = em28178_dvb_init_pctv_292e(dev);
1865 if (result)1925 if (result)
drivers/media/usb/em28xx/em28xx-video.c+2−2
@@ -2141,7 +2141,7 @@ static int em28xx_v4l2_open(struct file *filp) · 2140 unmodified lines
2141 int ret;2141 int ret;
2142 2142
2143 switch (vdev->vfl_type) {2143 switch (vdev->vfl_type) {
2144 case VFL_TYPE_GRABBER:2144 case VFL_TYPE_VIDEO:
2145 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;2145 fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2146 break;2146 break;
2147 case VFL_TYPE_VBI:2147 case VFL_TYPE_VBI:
@@ -2789,7 +2789,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) · 641 unmodified lines
2789 }2789 }
2790 2790
2791 /* register v4l2 video video_device */2791 /* register v4l2 video video_device */
2792 ret = video_register_device(&v4l2->vdev, VFL_TYPE_GRABBER,2792 ret = video_register_device(&v4l2->vdev, VFL_TYPE_VIDEO,
2793 video_nr[dev->devno]);2793 video_nr[dev->devno]);
2794 if (ret) {2794 if (ret) {
2795 dev_err(&dev->intf->dev,2795 dev_err(&dev->intf->dev,
drivers/media/usb/em28xx/em28xx.h+1−0
@@ -150,6 +150,7 @@ · 149 unmodified lines
150#define EM2884_BOARD_TERRATEC_H6 101150#define EM2884_BOARD_TERRATEC_H6 101
151#define EM2882_BOARD_ZOLID_HYBRID_TV_STICK 102151#define EM2882_BOARD_ZOLID_HYBRID_TV_STICK 102
152#define EM2861_BOARD_MAGIX_VIDEOWANDLER2 103152#define EM2861_BOARD_MAGIX_VIDEOWANDLER2 103
153#define EM28178_BOARD_PCTV_461E_V2 104
153 154
154/* Limits minimum and default number of buffers */155/* Limits minimum and default number of buffers */
155#define EM28XX_MIN_BUF 4156#define EM28XX_MIN_BUF 4
drivers/media/usb/go7007/go7007-usb.c+3−1
@@ -1044,6 +1044,7 @@ static int go7007_usb_probe(struct usb_interface *intf, · 1043 unmodified lines
1044 struct go7007_usb *usb;1044 struct go7007_usb *usb;
1045 const struct go7007_usb_board *board;1045 const struct go7007_usb_board *board;
1046 struct usb_device *usbdev = interface_to_usbdev(intf);1046 struct usb_device *usbdev = interface_to_usbdev(intf);
1047 struct usb_host_endpoint *ep;
1047 unsigned num_i2c_devs;1048 unsigned num_i2c_devs;
1048 char *name;1049 char *name;
1049 int video_pipe, i, v_urb_len;1050 int video_pipe, i, v_urb_len;
@@ -1140,7 +1141,8 @@ static int go7007_usb_probe(struct usb_interface *intf, · 90 unmodified lines
1140 if (usb->intr_urb->transfer_buffer == NULL)1141 if (usb->intr_urb->transfer_buffer == NULL)
1141 goto allocfail;1142 goto allocfail;
1142 1143
1143 if (go->board_id == GO7007_BOARDID_SENSORAY_2250)1144 ep = usb->usbdev->ep_in[4];
1145 if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK)
1144 usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,1146 usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
1145 usb_rcvbulkpipe(usb->usbdev, 4),1147 usb_rcvbulkpipe(usb->usbdev, 4),
1146 usb->intr_urb->transfer_buffer, 2*sizeof(u16),1148 usb->intr_urb->transfer_buffer, 2*sizeof(u16),
drivers/media/usb/go7007/go7007-v4l2.c+1−1
@@ -1138,7 +1138,7 @@ int go7007_v4l2_init(struct go7007 *go) · 1137 unmodified lines
1138 go7007_s_input(go);1138 go7007_s_input(go);
1139 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)1139 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1140 go7007_s_std(go);1140 go7007_s_std(go);
1141 rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1141 rv = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1142 if (rv < 0)1142 if (rv < 0)
1143 return rv;1143 return rv;
1144 dev_info(go->dev, "registered device %s [v4l2]\n",1144 dev_info(go->dev, "registered device %s [v4l2]\n",
drivers/media/usb/gspca/gspca.c+1−1
@@ -1555,7 +1555,7 @@ int gspca_dev_probe2(struct usb_interface *intf, · 1554 unmodified lines
1555 1555
1556 /* init video stuff */1556 /* init video stuff */
1557 ret = video_register_device(&gspca_dev->vdev,1557 ret = video_register_device(&gspca_dev->vdev,
1558 VFL_TYPE_GRABBER,1558 VFL_TYPE_VIDEO,
1559 -1);1559 -1);
1560 if (ret < 0) {1560 if (ret < 0) {
1561 pr_err("video_register_device err %d\n", ret);1561 pr_err("video_register_device err %d\n", ret);
drivers/media/usb/gspca/ov519.c+10−0
@@ -3477,6 +3477,11 @@ static void ov511_mode_init_regs(struct sd *sd) · 3476 unmodified lines
3477 return;3477 return;
3478 }3478 }
3479 3479
3480 if (alt->desc.bNumEndpoints < 1) {
3481 sd->gspca_dev.usb_err = -ENODEV;
3482 return;
3483 }
3484
3480 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);3485 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3481 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);3486 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3482 3487
@@ -3603,6 +3608,11 @@ static void ov518_mode_init_regs(struct sd *sd) · 120 unmodified lines
3603 return;3608 return;
3604 }3609 }
3605 3610
3611 if (alt->desc.bNumEndpoints < 1) {
3612 sd->gspca_dev.usb_err = -ENODEV;
3613 return;
3614 }
3615
3606 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);3616 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3607 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);3617 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
3608 3618
drivers/media/usb/gspca/stv06xx/stv06xx.c+18−1
@@ -282,6 +282,9 @@ static int stv06xx_start(struct gspca_dev *gspca_dev) · 281 unmodified lines
282 return -EIO;282 return -EIO;
283 }283 }
284 284
285 if (alt->desc.bNumEndpoints < 1)
286 return -ENODEV;
287
285 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);288 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
286 err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);289 err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
287 if (err < 0)290 if (err < 0)
@@ -306,11 +309,21 @@ out: · 18 unmodified lines
306 309
307static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)310static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
308{311{
312 struct usb_interface_cache *intfc;
309 struct usb_host_interface *alt;313 struct usb_host_interface *alt;
310 struct sd *sd = (struct sd *) gspca_dev;314 struct sd *sd = (struct sd *) gspca_dev;
311 315
316 intfc = gspca_dev->dev->actconfig->intf_cache[0];
317
318 if (intfc->num_altsetting < 2)
319 return -ENODEV;
320
321 alt = &intfc->altsetting[1];
322
323 if (alt->desc.bNumEndpoints < 1)
324 return -ENODEV;
325
312 /* Start isoc bandwidth "negotiation" at max isoc bandwidth */326 /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
313 alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
314 alt->endpoint[0].desc.wMaxPacketSize =327 alt->endpoint[0].desc.wMaxPacketSize =
315 cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);328 cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
316 329
@@ -323,6 +336,10 @@ static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) · 6 unmodified lines
323 struct usb_host_interface *alt;336 struct usb_host_interface *alt;
324 struct sd *sd = (struct sd *) gspca_dev;337 struct sd *sd = (struct sd *) gspca_dev;
325 338
339 /*
340 * Existence of altsetting and endpoint was verified in
341 * stv06xx_isoc_init()
342 */
326 alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];343 alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
327 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);344 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
328 min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];345 min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c+4−0
@@ -185,6 +185,10 @@ static int pb0100_start(struct sd *sd) · 184 unmodified lines
185 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);185 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
186 if (!alt)186 if (!alt)
187 return -ENODEV;187 return -ENODEV;
188
189 if (alt->desc.bNumEndpoints < 1)
190 return -ENODEV;
191
188 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);192 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
189 193
190 /* If we don't have enough bandwidth use a lower framerate */194 /* If we don't have enough bandwidth use a lower framerate */
drivers/media/usb/gspca/xirlink_cit.c+17−1
@@ -1442,6 +1442,9 @@ static int cit_get_packet_size(struct gspca_dev *gspca_dev) · 1441 unmodified lines
1442 return -EIO;1442 return -EIO;
1443 }1443 }
1444 1444
1445 if (alt->desc.bNumEndpoints < 1)
1446 return -ENODEV;
1447
1445 return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);1448 return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
1446}1449}
1447 1450
@@ -2626,6 +2629,7 @@ static int sd_start(struct gspca_dev *gspca_dev) · 1178 unmodified lines
2626 2629
2627static int sd_isoc_init(struct gspca_dev *gspca_dev)2630static int sd_isoc_init(struct gspca_dev *gspca_dev)
2628{2631{
2632 struct usb_interface_cache *intfc;
2629 struct usb_host_interface *alt;2633 struct usb_host_interface *alt;
2630 int max_packet_size;2634 int max_packet_size;
2631 2635
@@ -2641,8 +2645,17 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) · 9 unmodified lines
2641 break;2645 break;
2642 }2646 }
2643 2647
2648 intfc = gspca_dev->dev->actconfig->intf_cache[0];
2649
2650 if (intfc->num_altsetting < 2)
2651 return -ENODEV;
2652
2653 alt = &intfc->altsetting[1];
2654
2655 if (alt->desc.bNumEndpoints < 1)
2656 return -ENODEV;
2657
2644 /* Start isoc bandwidth "negotiation" at max isoc bandwidth */2658 /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
2645 alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
2646 alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);2659 alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
2647 2660
2648 return 0;2661 return 0;
@@ -2665,6 +2678,9 @@ static int sd_isoc_nego(struct gspca_dev *gspca_dev) · 16 unmodified lines
2665 break;2678 break;
2666 }2679 }
2667 2680
2681 /*
2682 * Existence of altsetting and endpoint was verified in sd_isoc_init()
2683 */
2668 alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];2684 alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
2669 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);2685 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
2670 if (packet_size <= min_packet_size)2686 if (packet_size <= min_packet_size)
drivers/media/usb/hdpvr/hdpvr-video.c+1−1
@@ -1238,7 +1238,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, · 1237 unmodified lines
1238 dev->video_dev.v4l2_dev = &dev->v4l2_dev;1238 dev->video_dev.v4l2_dev = &dev->v4l2_dev;
1239 video_set_drvdata(&dev->video_dev, dev);1239 video_set_drvdata(&dev->video_dev, dev);
1240 1240
1241 res = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, devnum);1241 res = video_register_device(&dev->video_dev, VFL_TYPE_VIDEO, devnum);
1242 if (res < 0) {1242 if (res < 0) {
1243 v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");1243 v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
1244 goto error;1244 goto error;
drivers/media/usb/pvrusb2/pvrusb2-v4l2.c+2−2
@@ -1196,7 +1196,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, · 1195 unmodified lines
1196 hdw = vp->channel.mc_head->hdw;1196 hdw = vp->channel.mc_head->hdw;
1197 dip->v4l_type = v4l_type;1197 dip->v4l_type = v4l_type;
1198 switch (v4l_type) {1198 switch (v4l_type) {
1199 case VFL_TYPE_GRABBER:1199 case VFL_TYPE_VIDEO:
1200 dip->stream = &vp->channel.mc_head->video_stream;1200 dip->stream = &vp->channel.mc_head->video_stream;
1201 dip->config = pvr2_config_mpeg;1201 dip->config = pvr2_config_mpeg;
1202 dip->minor_type = pvr2_v4l_type_video;1202 dip->minor_type = pvr2_v4l_type_video;
@@ -1276,7 +1276,7 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) · 73 unmodified lines
1276 /* register streams */1276 /* register streams */
1277 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);1277 vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1278 if (!vp->dev_video) goto fail;1278 if (!vp->dev_video) goto fail;
1279 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);1279 pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_VIDEO);
1280 if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &1280 if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1281 (1 << PVR2_CVAL_INPUT_RADIO)) {1281 (1 << PVR2_CVAL_INPUT_RADIO)) {
1282 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);1282 vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
drivers/media/usb/pwc/pwc-if.c+1−1
@@ -1116,7 +1116,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id · 1115 unmodified lines
1116 pdev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |1116 pdev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1117 V4L2_CAP_READWRITE;1117 V4L2_CAP_READWRITE;
1118 1118
1119 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);1119 rc = video_register_device(&pdev->vdev, VFL_TYPE_VIDEO, -1);
1120 if (rc < 0) {1120 if (rc < 0) {
1121 PWC_ERROR("Failed to register as video device (%d).\n", rc);1121 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1122 goto err_unregister_v4l2_dev;1122 goto err_unregister_v4l2_dev;
drivers/media/usb/s2255/s2255drv.c+2−2
@@ -1649,11 +1649,11 @@ static int s2255_probe_v4l(struct s2255_dev *dev) · 1648 unmodified lines
1649 video_set_drvdata(&vc->vdev, vc);1649 video_set_drvdata(&vc->vdev, vc);
1650 if (video_nr == -1)1650 if (video_nr == -1)
1651 ret = video_register_device(&vc->vdev,1651 ret = video_register_device(&vc->vdev,
1652 VFL_TYPE_GRABBER,1652 VFL_TYPE_VIDEO,
1653 video_nr);1653 video_nr);
1654 else1654 else
1655 ret = video_register_device(&vc->vdev,1655 ret = video_register_device(&vc->vdev,
1656 VFL_TYPE_GRABBER,1656 VFL_TYPE_VIDEO,
1657 cur_nr + i);1657 cur_nr + i);
1658 1658
1659 if (ret) {1659 if (ret) {
drivers/media/usb/stk1160/stk1160-v4l.c+1−1
@@ -830,7 +830,7 @@ int stk1160_video_register(struct stk1160 *dev) · 829 unmodified lines
830 dev->norm);830 dev->norm);
831 831
832 video_set_drvdata(&dev->vdev, dev);832 video_set_drvdata(&dev->vdev, dev);
833 rc = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);833 rc = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1);
834 if (rc < 0) {834 if (rc < 0) {
835 stk1160_err("video_register_device failed (%d)\n", rc);835 stk1160_err("video_register_device failed (%d)\n", rc);
836 return rc;836 return rc;
drivers/media/usb/stkwebcam/stk-webcam.c+1−1
@@ -1254,7 +1254,7 @@ static int stk_register_video_device(struct stk_camera *dev) · 1253 unmodified lines
1254 dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |1254 dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
1255 V4L2_CAP_STREAMING;1255 V4L2_CAP_STREAMING;
1256 video_set_drvdata(&dev->vdev, dev);1256 video_set_drvdata(&dev->vdev, dev);
1257 err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);1257 err = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1);
1258 if (err)1258 if (err)
1259 pr_err("v4l registration failed\n");1259 pr_err("v4l registration failed\n");
1260 else1260 else
drivers/media/usb/tm6000/tm6000-video.c+2−2
@@ -1300,7 +1300,7 @@ static int __tm6000_open(struct file *file) · 1299 unmodified lines
1300 video_device_node_name(vdev));1300 video_device_node_name(vdev));
1301 1301
1302 switch (vdev->vfl_type) {1302 switch (vdev->vfl_type) {
1303 case VFL_TYPE_GRABBER:1303 case VFL_TYPE_VIDEO:
1304 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;1304 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1305 break;1305 break;
1306 case VFL_TYPE_VBI:1306 case VFL_TYPE_VBI:
@@ -1639,7 +1639,7 @@ int tm6000_v4l2_register(struct tm6000_core *dev) · 332 unmodified lines
1639 INIT_LIST_HEAD(&dev->vidq.active);1639 INIT_LIST_HEAD(&dev->vidq.active);
1640 INIT_LIST_HEAD(&dev->vidq.queued);1640 INIT_LIST_HEAD(&dev->vidq.queued);
1641 1641
1642 ret = video_register_device(&dev->vfd, VFL_TYPE_GRABBER, video_nr);1642 ret = video_register_device(&dev->vfd, VFL_TYPE_VIDEO, video_nr);
1643 1643
1644 if (ret < 0) {1644 if (ret < 0) {
1645 printk(KERN_INFO "%s: can't register video device\n",1645 printk(KERN_INFO "%s: can't register video device\n",
drivers/media/usb/usbtv/usbtv-core.c+1−1
@@ -56,7 +56,7 @@ int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size) · 55 unmodified lines
56 56
57 ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,57 ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
58 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,58 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
59 value, index, NULL, 0, 0);59 value, index, NULL, 0, USB_CTRL_GET_TIMEOUT);
60 if (ret < 0)60 if (ret < 0)
61 return ret;61 return ret;
62 }62 }
drivers/media/usb/usbtv/usbtv-video.c+4−3
@@ -800,7 +800,8 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) · 799 unmodified lines
800 ret = usb_control_msg(usbtv->udev,800 ret = usb_control_msg(usbtv->udev,
801 usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG,801 usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG,
802 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,802 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
803 0, USBTV_BASE + 0x0244, (void *)data, 3, 0);803 0, USBTV_BASE + 0x0244, (void *)data, 3,
804 USB_CTRL_GET_TIMEOUT);
804 if (ret < 0)805 if (ret < 0)
805 goto error;806 goto error;
806 }807 }
@@ -851,7 +852,7 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) · 44 unmodified lines
851 ret = usb_control_msg(usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0),852 ret = usb_control_msg(usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0),
852 USBTV_CONTROL_REG,853 USBTV_CONTROL_REG,
853 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,854 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
854 0, index, (void *)data, size, 0);855 0, index, (void *)data, size, USB_CTRL_SET_TIMEOUT);
855 856
856error:857error:
857 if (ret < 0)858 if (ret < 0)
@@ -940,7 +941,7 @@ int usbtv_video_init(struct usbtv *usbtv) · 82 unmodified lines
940 usbtv->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |941 usbtv->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
941 V4L2_CAP_STREAMING;942 V4L2_CAP_STREAMING;
942 video_set_drvdata(&usbtv->vdev, usbtv);943 video_set_drvdata(&usbtv->vdev, usbtv);
943 ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);944 ret = video_register_device(&usbtv->vdev, VFL_TYPE_VIDEO, -1);
944 if (ret < 0) {945 if (ret < 0) {
945 dev_warn(usbtv->dev, "Could not register video device\n");946 dev_warn(usbtv->dev, "Could not register video device\n");
946 goto vdev_fail;947 goto vdev_fail;
drivers/media/usb/uvc/uvc_driver.c+1−1
@@ -2014,7 +2014,7 @@ int uvc_register_video_device(struct uvc_device *dev, · 2013 unmodified lines
2014 */2014 */
2015 video_set_drvdata(vdev, stream);2015 video_set_drvdata(vdev, stream);
2016 2016
2017 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);2017 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
2018 if (ret < 0) {2018 if (ret < 0) {
2019 uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",2019 uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
2020 v4l2_type_names[type], ret);2020 v4l2_type_names[type], ret);
drivers/media/usb/zr364xx/zr364xx.c+1−1
@@ -1516,7 +1516,7 @@ static int zr364xx_probe(struct usb_interface *intf, · 1515 unmodified lines
1516 V4L2_FIELD_NONE,1516 V4L2_FIELD_NONE,
1517 sizeof(struct zr364xx_buffer), cam, &cam->lock);1517 sizeof(struct zr364xx_buffer), cam, &cam->lock);
1518 1518
1519 err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);1519 err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
1520 if (err) {1520 if (err) {
1521 dev_err(&udev->dev, "video_register_device failed\n");1521 dev_err(&udev->dev, "video_register_device failed\n");
1522 goto fail;1522 goto fail;
drivers/media/v4l2-core/v4l2-ctrls.c+9−2
@@ -4296,10 +4296,17 @@ void v4l2_ctrl_request_complete(struct media_request *req, · 4295 unmodified lines
4296 continue;4296 continue;
4297 4297
4298 v4l2_ctrl_lock(ctrl);4298 v4l2_ctrl_lock(ctrl);
4299 if (ref->req)4299 if (ref->req) {
4300 ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req);4300 ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req);
4301 else4301 } else {
4302 ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req);4302 ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req);
4303 /*
4304 * Set ref->req to ensure that when userspace wants to
4305 * obtain the controls of this request it will take
4306 * this value and not the current value of the control.
4307 */
4308 ref->req = ref;
4309 }
4303 v4l2_ctrl_unlock(ctrl);4310 v4l2_ctrl_unlock(ctrl);
4304 }4311 }
4305 4312
drivers/media/v4l2-core/v4l2-dev.c+5−5
@@ -542,13 +542,13 @@ static void determine_valid_ioctls(struct video_device *vdev) · 541 unmodified lines
542 V4L2_CAP_META_OUTPUT;542 V4L2_CAP_META_OUTPUT;
543 DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);543 DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
544 const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;544 const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
545 bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER &&545 bool is_vid = vdev->vfl_type == VFL_TYPE_VIDEO &&
546 (vdev->device_caps & vid_caps);546 (vdev->device_caps & vid_caps);
547 bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;547 bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
548 bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;548 bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
549 bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;549 bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
550 bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;550 bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
551 bool is_meta = vdev->vfl_type == VFL_TYPE_GRABBER &&551 bool is_meta = vdev->vfl_type == VFL_TYPE_VIDEO &&
552 (vdev->device_caps & meta_caps);552 (vdev->device_caps & meta_caps);
553 bool is_rx = vdev->vfl_dir != VFL_DIR_TX;553 bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
554 bool is_tx = vdev->vfl_dir != VFL_DIR_RX;554 bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
@@ -783,7 +783,7 @@ static int video_register_media_controller(struct video_device *vdev) · 228 unmodified lines
783 vdev->entity.function = MEDIA_ENT_F_UNKNOWN;783 vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
784 784
785 switch (vdev->vfl_type) {785 switch (vdev->vfl_type) {
786 case VFL_TYPE_GRABBER:786 case VFL_TYPE_VIDEO:
787 intf_type = MEDIA_INTF_T_V4L_VIDEO;787 intf_type = MEDIA_INTF_T_V4L_VIDEO;
788 vdev->entity.function = MEDIA_ENT_F_IO_V4L;788 vdev->entity.function = MEDIA_ENT_F_IO_V4L;
789 break;789 break;
@@ -891,7 +891,7 @@ int __video_register_device(struct video_device *vdev, · 101 unmodified lines
891 891
892 /* Part 1: check device type */892 /* Part 1: check device type */
893 switch (type) {893 switch (type) {
894 case VFL_TYPE_GRABBER:894 case VFL_TYPE_VIDEO:
895 name_base = "video";895 name_base = "video";
896 break;896 break;
897 case VFL_TYPE_VBI:897 case VFL_TYPE_VBI:
@@ -935,7 +935,7 @@ int __video_register_device(struct video_device *vdev, · 37 unmodified lines
935 * of 128-191 and just pick the first free minor there935 * of 128-191 and just pick the first free minor there
936 * (new style). */936 * (new style). */
937 switch (type) {937 switch (type) {
938 case VFL_TYPE_GRABBER:938 case VFL_TYPE_VIDEO:
939 minor_offset = 0;939 minor_offset = 0;
940 minor_cnt = 64;940 minor_cnt = 64;
941 break;941 break;
drivers/media/v4l2-core/v4l2-device.c+3−5
@@ -111,9 +111,6 @@ EXPORT_SYMBOL_GPL(v4l2_device_unregister); · 110 unmodified lines
111int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,111int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
112 struct v4l2_subdev *sd)112 struct v4l2_subdev *sd)
113{113{
114#if defined(CONFIG_MEDIA_CONTROLLER)
115 struct media_entity *entity = &sd->entity;
116#endif
117 int err;114 int err;
118 115
119 /* Check for valid input */116 /* Check for valid input */
@@ -143,7 +140,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, · 23 unmodified lines
143#if defined(CONFIG_MEDIA_CONTROLLER)140#if defined(CONFIG_MEDIA_CONTROLLER)
144 /* Register the entity. */141 /* Register the entity. */
145 if (v4l2_dev->mdev) {142 if (v4l2_dev->mdev) {
146 err = media_device_register_entity(v4l2_dev->mdev, entity);143 err = media_device_register_entity(v4l2_dev->mdev, &sd->entity);
147 if (err < 0)144 if (err < 0)
148 goto error_module;145 goto error_module;
149 }146 }
@@ -163,7 +160,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, · 13 unmodified lines
163 160
164error_unregister:161error_unregister:
165#if defined(CONFIG_MEDIA_CONTROLLER)162#if defined(CONFIG_MEDIA_CONTROLLER)
166 media_device_unregister_entity(entity);163 media_device_unregister_entity(&sd->entity);
167#endif164#endif
168error_module:165error_module:
169 if (!sd->owner_v4l2_dev)166 if (!sd->owner_v4l2_dev)
@@ -179,6 +176,7 @@ static void v4l2_subdev_release(struct v4l2_subdev *sd) · 9 unmodified lines
179 176
180 if (sd->internal_ops && sd->internal_ops->release)177 if (sd->internal_ops && sd->internal_ops->release)
181 sd->internal_ops->release(sd);178 sd->internal_ops->release(sd);
179 sd->devnode = NULL;
182 module_put(owner);180 module_put(owner);
183}181}
184 182
drivers/media/v4l2-core/v4l2-fwnode.c+176−16
@@ -557,33 +557,28 @@ int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode, · 556 unmodified lines
557}557}
558EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);558EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
559 559
560int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,560int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
561 struct v4l2_fwnode_link *link)561 struct v4l2_fwnode_link *link)
562{562{
563 const char *port_prop = is_of_node(__fwnode) ? "reg" : "port";563 struct fwnode_endpoint fwep;
564 struct fwnode_handle *fwnode;
565 564
566 memset(link, 0, sizeof(*link));565 memset(link, 0, sizeof(*link));
567 566
568 fwnode = fwnode_get_parent(__fwnode);567 fwnode_graph_parse_endpoint(fwnode, &fwep);
569 fwnode_property_read_u32(fwnode, port_prop, &link->local_port);568 link->local_id = fwep.id;
570 fwnode = fwnode_get_next_parent(fwnode);569 link->local_port = fwep.port;
571 if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports"))570 link->local_node = fwnode_graph_get_port_parent(fwnode);
572 fwnode = fwnode_get_next_parent(fwnode);
573 link->local_node = fwnode;
574 571
575 fwnode = fwnode_graph_get_remote_endpoint(__fwnode);572 fwnode = fwnode_graph_get_remote_endpoint(fwnode);
576 if (!fwnode) {573 if (!fwnode) {
577 fwnode_handle_put(fwnode);574 fwnode_handle_put(fwnode);
578 return -ENOLINK;575 return -ENOLINK;
579 }576 }
580 577
581 fwnode = fwnode_get_parent(fwnode);578 fwnode_graph_parse_endpoint(fwnode, &fwep);
582 fwnode_property_read_u32(fwnode, port_prop, &link->remote_port);579 link->remote_id = fwep.id;
583 fwnode = fwnode_get_next_parent(fwnode);580 link->remote_port = fwep.port;
584 if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports"))581 link->remote_node = fwnode_graph_get_port_parent(fwnode);
585 fwnode = fwnode_get_next_parent(fwnode);
586 link->remote_node = fwnode;
587 582
588 return 0;583 return 0;
589}584}
@@ -596,6 +591,171 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link) · 6 unmodified lines
596}591}
597EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);592EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
598 593
594static const struct v4l2_fwnode_connector_conv {
595 enum v4l2_connector_type type;
596 const char *compatible;
597} connectors[] = {
598 {
599 .type = V4L2_CONN_COMPOSITE,
600 .compatible = "composite-video-connector",
601 }, {
602 .type = V4L2_CONN_SVIDEO,
603 .compatible = "svideo-connector",
604 },
605};
606
607static enum v4l2_connector_type
608v4l2_fwnode_string_to_connector_type(const char *con_str)
609{
610 unsigned int i;
611
612 for (i = 0; i < ARRAY_SIZE(connectors); i++)
613 if (!strcmp(con_str, connectors[i].compatible))
614 return connectors[i].type;
615
616 return V4L2_CONN_UNKNOWN;
617}
618
619static void
620v4l2_fwnode_connector_parse_analog(struct fwnode_handle *fwnode,
621 struct v4l2_fwnode_connector *vc)
622{
623 u32 stds;
624 int ret;
625
626 ret = fwnode_property_read_u32(fwnode, "sdtv-standards", &stds);
627
628 /* The property is optional. */
629 vc->connector.analog.sdtv_stds = ret ? V4L2_STD_ALL : stds;
630}
631
632void v4l2_fwnode_connector_free(struct v4l2_fwnode_connector *connector)
633{
634 struct v4l2_connector_link *link, *tmp;
635
636 if (IS_ERR_OR_NULL(connector) || connector->type == V4L2_CONN_UNKNOWN)
637 return;
638
639 list_for_each_entry_safe(link, tmp, &connector->links, head) {
640 v4l2_fwnode_put_link(&link->fwnode_link);
641 list_del(&link->head);
642 kfree(link);
643 }
644
645 kfree(connector->label);
646 connector->label = NULL;
647 connector->type = V4L2_CONN_UNKNOWN;
648}
649EXPORT_SYMBOL_GPL(v4l2_fwnode_connector_free);
650
651static enum v4l2_connector_type
652v4l2_fwnode_get_connector_type(struct fwnode_handle *fwnode)
653{
654 const char *type_name;
655 int err;
656
657 if (!fwnode)
658 return V4L2_CONN_UNKNOWN;
659
660 /* The connector-type is stored within the compatible string. */
661 err = fwnode_property_read_string(fwnode, "compatible", &type_name);
662 if (err)
663 return V4L2_CONN_UNKNOWN;
664
665 return v4l2_fwnode_string_to_connector_type(type_name);
666}
667
668int v4l2_fwnode_connector_parse(struct fwnode_handle *fwnode,
669 struct v4l2_fwnode_connector *connector)
670{
671 struct fwnode_handle *connector_node;
672 enum v4l2_connector_type connector_type;
673 const char *label;
674 int err;
675
676 if (!fwnode)
677 return -EINVAL;
678
679 memset(connector, 0, sizeof(*connector));
680
681 INIT_LIST_HEAD(&connector->links);
682
683 connector_node = fwnode_graph_get_port_parent(fwnode);
684 connector_type = v4l2_fwnode_get_connector_type(connector_node);
685 if (connector_type == V4L2_CONN_UNKNOWN) {
686 fwnode_handle_put(connector_node);
687 connector_node = fwnode_graph_get_remote_port_parent(fwnode);
688 connector_type = v4l2_fwnode_get_connector_type(connector_node);
689 }
690
691 if (connector_type == V4L2_CONN_UNKNOWN) {
692 pr_err("Unknown connector type\n");
693 err = -ENOTCONN;
694 goto out;
695 }
696
697 connector->type = connector_type;
698 connector->name = fwnode_get_name(connector_node);
699 err = fwnode_property_read_string(connector_node, "label", &label);
700 connector->label = err ? NULL : kstrdup_const(label, GFP_KERNEL);
701
702 /* Parse the connector specific properties. */
703 switch (connector->type) {
704 case V4L2_CONN_COMPOSITE:
705 case V4L2_CONN_SVIDEO:
706 v4l2_fwnode_connector_parse_analog(connector_node, connector);
707 break;
708 /* Avoid compiler warnings */
709 case V4L2_CONN_UNKNOWN:
710 break;
711 }
712
713out:
714 fwnode_handle_put(connector_node);
715
716 return err;
717}
718EXPORT_SYMBOL_GPL(v4l2_fwnode_connector_parse);
719
720int v4l2_fwnode_connector_add_link(struct fwnode_handle *fwnode,
721 struct v4l2_fwnode_connector *connector)
722{
723 struct fwnode_handle *connector_ep;
724 struct v4l2_connector_link *link;
725 int err;
726
727 if (!fwnode || !connector || connector->type == V4L2_CONN_UNKNOWN)
728 return -EINVAL;
729
730 connector_ep = fwnode_graph_get_remote_endpoint(fwnode);
731 if (!connector_ep)
732 return -ENOTCONN;
733
734 link = kzalloc(sizeof(*link), GFP_KERNEL);
735 if (!link) {
736 err = -ENOMEM;
737 goto err;
738 }
739
740 err = v4l2_fwnode_parse_link(connector_ep, &link->fwnode_link);
741 if (err)
742 goto err;
743
744 fwnode_handle_put(connector_ep);
745
746 list_add(&link->head, &connector->links);
747 connector->nr_of_links++;
748
749 return 0;
750
751err:
752 kfree(link);
753 fwnode_handle_put(connector_ep);
754
755 return err;
756}
757EXPORT_SYMBOL_GPL(v4l2_fwnode_connector_add_link);
758
599static int759static int
600v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,760v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
601 struct v4l2_async_notifier *notifier,761 struct v4l2_async_notifier *notifier,
drivers/media/v4l2-core/v4l2-i2c.c+5−5
@@ -74,10 +74,10 @@ struct v4l2_subdev · 73 unmodified lines
74 74
75 /* Create the i2c client */75 /* Create the i2c client */
76 if (info->addr == 0 && probe_addrs)76 if (info->addr == 0 && probe_addrs)
77 client = i2c_new_probed_device(adapter, info, probe_addrs,77 client = i2c_new_scanned_device(adapter, info, probe_addrs,
78 NULL);78 NULL);
79 else79 else
80 client = i2c_new_device(adapter, info);80 client = i2c_new_client_device(adapter, info);
81 81
82 /*82 /*
83 * Note: by loading the module first we are certain that c->driver83 * Note: by loading the module first we are certain that c->driver
@@ -88,7 +88,7 @@ struct v4l2_subdev · 4 unmodified lines
88 * want to use the i2c device, so explicitly loading the module88 * want to use the i2c device, so explicitly loading the module
89 * is the best alternative.89 * is the best alternative.
90 */90 */
91 if (!client || !client->dev.driver)91 if (!i2c_client_has_driver(client))
92 goto error;92 goto error;
93 93
94 /* Lock the module so we can safely get the v4l2_subdev pointer */94 /* Lock the module so we can safely get the v4l2_subdev pointer */
@@ -110,7 +110,7 @@ error: · 15 unmodified lines
110 * If we have a client but no subdev, then something went wrong and110 * If we have a client but no subdev, then something went wrong and
111 * we must unregister the client.111 * we must unregister the client.
112 */112 */
113 if (client && !sd)113 if (!IS_ERR(client) && !sd)
114 i2c_unregister_device(client);114 i2c_unregister_device(client);
115 return sd;115 return sd;
116}116}
drivers/media/v4l2-core/v4l2-ioctl.c+7−2
@@ -941,12 +941,12 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) · 940 unmodified lines
941 V4L2_CAP_META_OUTPUT;941 V4L2_CAP_META_OUTPUT;
942 struct video_device *vfd = video_devdata(file);942 struct video_device *vfd = video_devdata(file);
943 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;943 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
944 bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER &&944 bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO &&
945 (vfd->device_caps & vid_caps);945 (vfd->device_caps & vid_caps);
946 bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;946 bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
947 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;947 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
948 bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;948 bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
949 bool is_meta = vfd->vfl_type == VFL_TYPE_GRABBER &&949 bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
950 (vfd->device_caps & meta_caps);950 (vfd->device_caps & meta_caps);
951 bool is_rx = vfd->vfl_dir != VFL_DIR_TX;951 bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
952 bool is_tx = vfd->vfl_dir != VFL_DIR_RX;952 bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
@@ -1222,6 +1222,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) · 269 unmodified lines
1222 case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;1222 case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;
1223 case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break;1223 case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break;
1224 case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break;1224 case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break;
1225 case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break;
1225 case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break;1226 case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break;
1226 case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;1227 case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;
1227 case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;1228 case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
@@ -1306,6 +1307,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) · 78 unmodified lines
1306 case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;1307 case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1307 case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;1308 case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1308 case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break;1309 case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1310 case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break;
1311 case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break;
1312 case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break;
1313 case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break;
1309 case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break;1314 case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break;
1310 case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;1315 case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;
1311 case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;1316 case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;
drivers/media/v4l2-core/v4l2-mc.c+15−3
@@ -321,7 +321,7 @@ EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_source); · 320 unmodified lines
321 * use_count field stores the total number of users of all video device nodes321 * use_count field stores the total number of users of all video device nodes
322 * in the pipeline.322 * in the pipeline.
323 *323 *
324 * The v4l2_pipeline_pm_use() function must be called in the open() and324 * The v4l2_pipeline_pm_{get, put}() functions must be called in the open() and
325 * close() handlers of video device nodes. It increments or decrements the use325 * close() handlers of video device nodes. It increments or decrements the use
326 * count of all subdev entities in the pipeline.326 * count of all subdev entities in the pipeline.
327 *327 *
@@ -423,7 +423,7 @@ static int pipeline_pm_power(struct media_entity *entity, int change, · 95 unmodified lines
423 return ret;423 return ret;
424}424}
425 425
426int v4l2_pipeline_pm_use(struct media_entity *entity, int use)426static int v4l2_pipeline_pm_use(struct media_entity *entity, unsigned int use)
427{427{
428 struct media_device *mdev = entity->graph_obj.mdev;428 struct media_device *mdev = entity->graph_obj.mdev;
429 int change = use ? 1 : -1;429 int change = use ? 1 : -1;
@@ -444,7 +444,19 @@ int v4l2_pipeline_pm_use(struct media_entity *entity, int use) · 14 unmodified lines
444 444
445 return ret;445 return ret;
446}446}
447EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_use);447
448int v4l2_pipeline_pm_get(struct media_entity *entity)
449{
450 return v4l2_pipeline_pm_use(entity, 1);
451}
452EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_get);
453
454void v4l2_pipeline_pm_put(struct media_entity *entity)
455{
456 /* Powering off entities shouldn't fail. */
457 WARN_ON(v4l2_pipeline_pm_use(entity, 0));
458}
459EXPORT_SYMBOL_GPL(v4l2_pipeline_pm_put);
448 460
449int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,461int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
450 unsigned int notification)462 unsigned int notification)
drivers/media/v4l2-core/v4l2-mem2mem.c+219−2
@@ -340,6 +340,11 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev, · 339 unmodified lines
340 m2m_ctx->new_frame = !dst->vb2_buf.copied_timestamp ||340 m2m_ctx->new_frame = !dst->vb2_buf.copied_timestamp ||
341 dst->vb2_buf.timestamp != src->vb2_buf.timestamp;341 dst->vb2_buf.timestamp != src->vb2_buf.timestamp;
342 342
343 if (m2m_ctx->has_stopped) {
344 dprintk("Device has stopped\n");
345 goto job_unlock;
346 }
347
343 if (m2m_dev->m2m_ops->job_ready348 if (m2m_dev->m2m_ops->job_ready
344 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {349 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
345 dprintk("Driver not ready\n");350 dprintk("Driver not ready\n");
@@ -556,6 +561,140 @@ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, · 210 unmodified lines
556}561}
557EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);562EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
558 563
564/*
565 * This will add the LAST flag and mark the buffer management
566 * state as stopped.
567 * This is called when the last capture buffer must be flagged as LAST
568 * in draining mode from the encoder/decoder driver buf_queue() callback
569 * or from v4l2_update_last_buf_state() when a capture buffer is available.
570 */
571void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx,
572 struct vb2_v4l2_buffer *vbuf)
573{
574 vbuf->flags |= V4L2_BUF_FLAG_LAST;
575 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
576
577 v4l2_m2m_mark_stopped(m2m_ctx);
578}
579EXPORT_SYMBOL_GPL(v4l2_m2m_last_buffer_done);
580
581/* When stop command is issued, update buffer management state */
582static int v4l2_update_last_buf_state(struct v4l2_m2m_ctx *m2m_ctx)
583{
584 struct vb2_v4l2_buffer *next_dst_buf;
585
586 if (m2m_ctx->is_draining)
587 return -EBUSY;
588
589 if (m2m_ctx->has_stopped)
590 return 0;
591
592 m2m_ctx->last_src_buf = v4l2_m2m_last_src_buf(m2m_ctx);
593 m2m_ctx->is_draining = true;
594
595 /*
596 * The processing of the last output buffer queued before
597 * the STOP command is expected to mark the buffer management
598 * state as stopped with v4l2_m2m_mark_stopped().
599 */
600 if (m2m_ctx->last_src_buf)
601 return 0;
602
603 /*
604 * In case the output queue is empty, try to mark the last capture
605 * buffer as LAST.
606 */
607 next_dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx);
608 if (!next_dst_buf) {
609 /*
610 * Wait for the next queued one in encoder/decoder driver
611 * buf_queue() callback using the v4l2_m2m_dst_buf_is_last()
612 * helper or in v4l2_m2m_qbuf() if encoder/decoder is not yet
613 * streaming.
614 */
615 m2m_ctx->next_buf_last = true;
616 return 0;
617 }
618
619 v4l2_m2m_last_buffer_done(m2m_ctx, next_dst_buf);
620
621 return 0;
622}
623
624/*
625 * Updates the encoding/decoding buffer management state, should
626 * be called from encoder/decoder drivers start_streaming()
627 */
628void v4l2_m2m_update_start_streaming_state(struct v4l2_m2m_ctx *m2m_ctx,
629 struct vb2_queue *q)
630{
631 /* If start streaming again, untag the last output buffer */
632 if (V4L2_TYPE_IS_OUTPUT(q->type))
633 m2m_ctx->last_src_buf = NULL;
634}
635EXPORT_SYMBOL_GPL(v4l2_m2m_update_start_streaming_state);
636
637/*
638 * Updates the encoding/decoding buffer management state, should
639 * be called from encoder/decoder driver stop_streaming()
640 */
641void v4l2_m2m_update_stop_streaming_state(struct v4l2_m2m_ctx *m2m_ctx,
642 struct vb2_queue *q)
643{
644 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
645 /*
646 * If in draining state, either mark next dst buffer as
647 * done or flag next one to be marked as done either
648 * in encoder/decoder driver buf_queue() callback using
649 * the v4l2_m2m_dst_buf_is_last() helper or in v4l2_m2m_qbuf()
650 * if encoder/decoder is not yet streaming
651 */
652 if (m2m_ctx->is_draining) {
653 struct vb2_v4l2_buffer *next_dst_buf;
654
655 m2m_ctx->last_src_buf = NULL;
656 next_dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx);
657 if (!next_dst_buf)
658 m2m_ctx->next_buf_last = true;
659 else
660 v4l2_m2m_last_buffer_done(m2m_ctx,
661 next_dst_buf);
662 }
663 } else {
664 v4l2_m2m_clear_state(m2m_ctx);
665 }
666}
667EXPORT_SYMBOL_GPL(v4l2_m2m_update_stop_streaming_state);
668
669static void v4l2_m2m_force_last_buf_done(struct v4l2_m2m_ctx *m2m_ctx,
670 struct vb2_queue *q)
671{
672 struct vb2_buffer *vb;
673 struct vb2_v4l2_buffer *vbuf;
674 unsigned int i;
675
676 if (WARN_ON(q->is_output))
677 return;
678 if (list_empty(&q->queued_list))
679 return;
680
681 vb = list_first_entry(&q->queued_list, struct vb2_buffer, queued_entry);
682 for (i = 0; i < vb->num_planes; i++)
683 vb2_set_plane_payload(vb, i, 0);
684
685 /*
686 * Since the buffer hasn't been queued to the ready queue,
687 * mark is active and owned before marking it LAST and DONE
688 */
689 vb->state = VB2_BUF_STATE_ACTIVE;
690 atomic_inc(&q->owned_by_drv_count);
691
692 vbuf = to_vb2_v4l2_buffer(vb);
693 vbuf->field = V4L2_FIELD_NONE;
694
695 v4l2_m2m_last_buffer_done(m2m_ctx, vbuf);
696}
697
559int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,698int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
560 struct v4l2_buffer *buf)699 struct v4l2_buffer *buf)
561{700{
@@ -570,11 +709,25 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, · 8 unmodified lines
570 __func__);709 __func__);
571 return -EPERM;710 return -EPERM;
572 }711 }
712
573 ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf);713 ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf);
574 if (!ret && !(buf->flags & V4L2_BUF_FLAG_IN_REQUEST))714 if (ret)
715 return ret;
716
717 /*
718 * If the capture queue is streaming, but streaming hasn't started
719 * on the device, but was asked to stop, mark the previously queued
720 * buffer as DONE with LAST flag since it won't be queued on the
721 * device.
722 */
723 if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&
724 vb2_is_streaming(vq) && !vb2_start_streaming_called(vq) &&
725 (v4l2_m2m_has_stopped(m2m_ctx) || v4l2_m2m_dst_buf_is_last(m2m_ctx)))
726 v4l2_m2m_force_last_buf_done(m2m_ctx, vq);
727 else if (!(buf->flags & V4L2_BUF_FLAG_IN_REQUEST))
575 v4l2_m2m_try_schedule(m2m_ctx);728 v4l2_m2m_try_schedule(m2m_ctx);
576 729
577 return ret;730 return 0;
578}731}
579EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);732EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);
580 733
@@ -1225,6 +1378,70 @@ int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh, · 644 unmodified lines
1225}1378}
1226EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_try_decoder_cmd);1379EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_try_decoder_cmd);
1227 1380
1381/*
1382 * Updates the encoding state on ENC_CMD_STOP/ENC_CMD_START
1383 * Should be called from the encoder driver encoder_cmd() callback
1384 */
1385int v4l2_m2m_encoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
1386 struct v4l2_encoder_cmd *ec)
1387{
1388 if (ec->cmd != V4L2_ENC_CMD_STOP && ec->cmd != V4L2_ENC_CMD_START)
1389 return -EINVAL;
1390
1391 if (ec->cmd == V4L2_ENC_CMD_STOP)
1392 return v4l2_update_last_buf_state(m2m_ctx);
1393
1394 if (m2m_ctx->is_draining)
1395 return -EBUSY;
1396
1397 if (m2m_ctx->has_stopped)
1398 m2m_ctx->has_stopped = false;
1399
1400 return 0;
1401}
1402EXPORT_SYMBOL_GPL(v4l2_m2m_encoder_cmd);
1403
1404/*
1405 * Updates the decoding state on DEC_CMD_STOP/DEC_CMD_START
1406 * Should be called from the decoder driver decoder_cmd() callback
1407 */
1408int v4l2_m2m_decoder_cmd(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
1409 struct v4l2_decoder_cmd *dc)
1410{
1411 if (dc->cmd != V4L2_DEC_CMD_STOP && dc->cmd != V4L2_DEC_CMD_START)
1412 return -EINVAL;
1413
1414 if (dc->cmd == V4L2_DEC_CMD_STOP)
1415 return v4l2_update_last_buf_state(m2m_ctx);
1416
1417 if (m2m_ctx->is_draining)
1418 return -EBUSY;
1419
1420 if (m2m_ctx->has_stopped)
1421 m2m_ctx->has_stopped = false;
1422
1423 return 0;
1424}
1425EXPORT_SYMBOL_GPL(v4l2_m2m_decoder_cmd);
1426
1427int v4l2_m2m_ioctl_encoder_cmd(struct file *file, void *priv,
1428 struct v4l2_encoder_cmd *ec)
1429{
1430 struct v4l2_fh *fh = file->private_data;
1431
1432 return v4l2_m2m_encoder_cmd(file, fh->m2m_ctx, ec);
1433}
1434EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_encoder_cmd);
1435
1436int v4l2_m2m_ioctl_decoder_cmd(struct file *file, void *priv,
1437 struct v4l2_decoder_cmd *dc)
1438{
1439 struct v4l2_fh *fh = file->private_data;
1440
1441 return v4l2_m2m_decoder_cmd(file, fh->m2m_ctx, dc);
1442}
1443EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_decoder_cmd);
1444
1228int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh,1445int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh,
1229 struct v4l2_decoder_cmd *dc)1446 struct v4l2_decoder_cmd *dc)
1230{1447{
drivers/staging/media/Kconfig+4−0
@@ -42,4 +42,8 @@ source "drivers/staging/media/phy-rockchip-dphy-rx0/Kconfig" · 41 unmodified lines
42 42
43source "drivers/staging/media/rkisp1/Kconfig"43source "drivers/staging/media/rkisp1/Kconfig"
44 44
45if MEDIA_ANALOG_TV_SUPPORT
46source "drivers/staging/media/usbvision/Kconfig"
47endif
48
45endif49endif
drivers/staging/media/Makefile+1−0
@@ -10,3 +10,4 @@ obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ · 9 unmodified lines
10obj-$(CONFIG_SOC_CAMERA) += soc_camera/10obj-$(CONFIG_SOC_CAMERA) += soc_camera/
11obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0/11obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0/
12obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rkisp1/12obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rkisp1/
13obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
drivers/staging/media/allegro-dvt/Makefile+1−1
@@ -1,5 +1,5 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2 2
3allegro-objs := allegro-core.o nal-h264.o3allegro-objs := allegro-core.o nal-h264.o allegro-mail.o
4 4
5obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o5obj-$(CONFIG_VIDEO_ALLEGRO_DVT) += allegro.o
drivers/staging/media/allegro-dvt/allegro-core.c+540−390
@@ -5,7 +5,9 @@ · 4 unmodified lines
5 * Allegro DVT video encoder driver5 * Allegro DVT video encoder driver
6 */6 */
7 7
8#include <linux/bits.h>
8#include <linux/firmware.h>9#include <linux/firmware.h>
10#include <linux/gcd.h>
9#include <linux/interrupt.h>11#include <linux/interrupt.h>
10#include <linux/io.h>12#include <linux/io.h>
11#include <linux/kernel.h>13#include <linux/kernel.h>
@@ -26,6 +28,7 @@ · 14 unmodified lines
26#include <media/videobuf2-dma-contig.h>28#include <media/videobuf2-dma-contig.h>
27#include <media/videobuf2-v4l2.h>29#include <media/videobuf2-v4l2.h>
28 30
31#include "allegro-mail.h"
29#include "nal-h264.h"32#include "nal-h264.h"
30 33
31/*34/*
@@ -40,6 +43,8 @@ · 8 unmodified lines
40#define ALLEGRO_HEIGHT_DEFAULT 108043#define ALLEGRO_HEIGHT_DEFAULT 1080
41#define ALLEGRO_HEIGHT_MAX 216044#define ALLEGRO_HEIGHT_MAX 2160
42 45
46#define ALLEGRO_FRAMERATE_DEFAULT ((struct v4l2_fract) { 30, 1 })
47
43#define ALLEGRO_GOP_SIZE_DEFAULT 2548#define ALLEGRO_GOP_SIZE_DEFAULT 25
44#define ALLEGRO_GOP_SIZE_MAX 100049#define ALLEGRO_GOP_SIZE_MAX 1000
45 50
@@ -176,6 +181,7 @@ struct allegro_channel { · 130 unmodified lines
176 unsigned int width;181 unsigned int width;
177 unsigned int height;182 unsigned int height;
178 unsigned int stride;183 unsigned int stride;
184 struct v4l2_fract framerate;
179 185
180 enum v4l2_colorspace colorspace;186 enum v4l2_colorspace colorspace;
181 enum v4l2_ycbcr_encoding ycbcr_enc;187 enum v4l2_ycbcr_encoding ycbcr_enc;
@@ -192,7 +198,7 @@ struct allegro_channel { · 10 unmodified lines
192 unsigned int sizeimage_encoded;198 unsigned int sizeimage_encoded;
193 unsigned int csequence;199 unsigned int csequence;
194 200
195 enum v4l2_mpeg_video_bitrate_mode bitrate_mode;201 bool frame_rc_enable;
196 unsigned int bitrate;202 unsigned int bitrate;
197 unsigned int bitrate_peak;203 unsigned int bitrate_peak;
198 unsigned int cpb_size;204 unsigned int cpb_size;
@@ -200,9 +206,17 @@ struct allegro_channel { · 1 unmodified line
200 206
201 struct v4l2_ctrl *mpeg_video_h264_profile;207 struct v4l2_ctrl *mpeg_video_h264_profile;
202 struct v4l2_ctrl *mpeg_video_h264_level;208 struct v4l2_ctrl *mpeg_video_h264_level;
203 struct v4l2_ctrl *mpeg_video_bitrate_mode;209 struct v4l2_ctrl *mpeg_video_h264_i_frame_qp;
204 struct v4l2_ctrl *mpeg_video_bitrate;210 struct v4l2_ctrl *mpeg_video_h264_max_qp;
205 struct v4l2_ctrl *mpeg_video_bitrate_peak;211 struct v4l2_ctrl *mpeg_video_h264_min_qp;
212 struct v4l2_ctrl *mpeg_video_h264_p_frame_qp;
213 struct v4l2_ctrl *mpeg_video_h264_b_frame_qp;
214 struct v4l2_ctrl *mpeg_video_frame_rc_enable;
215 struct { /* video bitrate mode control cluster */
216 struct v4l2_ctrl *mpeg_video_bitrate_mode;
217 struct v4l2_ctrl *mpeg_video_bitrate;
218 struct v4l2_ctrl *mpeg_video_bitrate_peak;
219 };
206 struct v4l2_ctrl *mpeg_video_cpb_size;220 struct v4l2_ctrl *mpeg_video_cpb_size;
207 struct v4l2_ctrl *mpeg_video_gop_size;221 struct v4l2_ctrl *mpeg_video_gop_size;
208 222
@@ -215,6 +229,11 @@ struct allegro_channel { · 6 unmodified lines
215 struct list_head buffers_reference;229 struct list_head buffers_reference;
216 struct list_head buffers_intermediate;230 struct list_head buffers_intermediate;
217 231
232 struct list_head source_shadow_list;
233 struct list_head stream_shadow_list;
234 /* protect shadow lists of buffers passed to firmware */
235 struct mutex shadow_list_lock;
236
218 struct list_head list;237 struct list_head list;
219 struct completion completion;238 struct completion completion;
220 239
@@ -236,6 +255,14 @@ allegro_get_state(struct allegro_channel *channel) · 15 unmodified lines
236 return channel->state;255 return channel->state;
237}256}
238 257
258struct allegro_m2m_buffer {
259 struct v4l2_m2m_buffer buf;
260 struct list_head head;
261};
262
263#define to_allegro_m2m_buffer(__buf) \
264 container_of(__buf, struct allegro_m2m_buffer, buf)
265
239struct fw_info {266struct fw_info {
240 unsigned int id;267 unsigned int id;
241 unsigned int id_codec;268 unsigned int id_codec;
@@ -258,276 +285,33 @@ static const struct fw_info supported_firmware[] = { · 16 unmodified lines
258 },285 },
259};286};
260 287
261enum mcu_msg_type {288static inline u32 to_mcu_addr(struct allegro_dev *dev, dma_addr_t phys)
262 MCU_MSG_TYPE_INIT = 0x0000,289{
263 MCU_MSG_TYPE_CREATE_CHANNEL = 0x0005,290 if (upper_32_bits(phys) || (lower_32_bits(phys) & MCU_CACHE_OFFSET))
264 MCU_MSG_TYPE_DESTROY_CHANNEL = 0x0006,291 v4l2_warn(&dev->v4l2_dev,
265 MCU_MSG_TYPE_ENCODE_FRAME = 0x0007,292 "address %pad is outside mcu window\n", &phys);
266 MCU_MSG_TYPE_PUT_STREAM_BUFFER = 0x0012,293
267 MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE = 0x000e,294 return lower_32_bits(phys) | MCU_CACHE_OFFSET;
268 MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE = 0x000f,295}
269};
270 296
271static const char *msg_type_name(enum mcu_msg_type type)297static inline u32 to_mcu_size(struct allegro_dev *dev, size_t size)
272{298{
273 static char buf[9];299 return lower_32_bits(size);
300}
274 301
275 switch (type) {302static inline u32 to_codec_addr(struct allegro_dev *dev, dma_addr_t phys)
276 case MCU_MSG_TYPE_INIT:303{
277 return "INIT";304 if (upper_32_bits(phys))
278 case MCU_MSG_TYPE_CREATE_CHANNEL:305 v4l2_warn(&dev->v4l2_dev,
279 return "CREATE_CHANNEL";306 "address %pad cannot be used by codec\n", &phys);
280 case MCU_MSG_TYPE_DESTROY_CHANNEL:
281 return "DESTROY_CHANNEL";
282 case MCU_MSG_TYPE_ENCODE_FRAME:
283 return "ENCODE_FRAME";
284 case MCU_MSG_TYPE_PUT_STREAM_BUFFER:
285 return "PUT_STREAM_BUFFER";
286 case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE:
287 return "PUSH_BUFFER_INTERMEDIATE";
288 case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE:
289 return "PUSH_BUFFER_REFERENCE";
290 default:
291 snprintf(buf, sizeof(buf), "(0x%04x)", type);
292 return buf;
293 }
294}
295
296struct mcu_msg_header {
297 u16 length; /* length of the body in bytes */
298 u16 type;
299} __attribute__ ((__packed__));
300
301struct mcu_msg_init_request {
302 struct mcu_msg_header header;
303 u32 reserved0; /* maybe a unused channel id */
304 u32 suballoc_dma;
305 u32 suballoc_size;
306 s32 l2_cache[3];
307} __attribute__ ((__packed__));
308
309struct mcu_msg_init_response {
310 struct mcu_msg_header header;
311 u32 reserved0;
312} __attribute__ ((__packed__));
313
314struct mcu_msg_create_channel {
315 struct mcu_msg_header header;
316 u32 user_id;
317 u16 width;
318 u16 height;
319 u32 format;
320 u32 colorspace;
321 u32 src_mode;
322 u8 profile;
323 u16 constraint_set_flags;
324 s8 codec;
325 u16 level;
326 u16 tier;
327 u32 sps_param;
328 u32 pps_param;
329
330 u32 enc_option;
331#define AL_OPT_WPP BIT(0)
332#define AL_OPT_TILE BIT(1)
333#define AL_OPT_LF BIT(2)
334#define AL_OPT_LF_X_SLICE BIT(3)
335#define AL_OPT_LF_X_TILE BIT(4)
336#define AL_OPT_SCL_LST BIT(5)
337#define AL_OPT_CONST_INTRA_PRED BIT(6)
338#define AL_OPT_QP_TAB_RELATIVE BIT(7)
339#define AL_OPT_FIX_PREDICTOR BIT(8)
340#define AL_OPT_CUSTOM_LDA BIT(9)
341#define AL_OPT_ENABLE_AUTO_QP BIT(10)
342#define AL_OPT_ADAPT_AUTO_QP BIT(11)
343#define AL_OPT_TRANSFO_SKIP BIT(13)
344#define AL_OPT_FORCE_REC BIT(15)
345#define AL_OPT_FORCE_MV_OUT BIT(16)
346#define AL_OPT_FORCE_MV_CLIP BIT(17)
347#define AL_OPT_LOWLAT_SYNC BIT(18)
348#define AL_OPT_LOWLAT_INT BIT(19)
349#define AL_OPT_RDO_COST_MODE BIT(20)
350
351 s8 beta_offset;
352 s8 tc_offset;
353 u16 reserved10;
354 u32 unknown11;
355 u32 unknown12;
356 u16 num_slices;
357 u16 prefetch_auto;
358 u32 prefetch_mem_offset;
359 u32 prefetch_mem_size;
360 u16 clip_hrz_range;
361 u16 clip_vrt_range;
362 u16 me_range[4];
363 u8 max_cu_size;
364 u8 min_cu_size;
365 u8 max_tu_size;
366 u8 min_tu_size;
367 u8 max_transfo_depth_inter;
368 u8 max_transfo_depth_intra;
369 u16 reserved20;
370 u32 entropy_mode;
371 u32 wp_mode;
372
373 /* rate control param */
374 u32 rate_control_mode;
375 u32 initial_rem_delay;
376 u32 cpb_size;
377 u16 framerate;
378 u16 clk_ratio;
379 u32 target_bitrate;
380 u32 max_bitrate;
381 u16 initial_qp;
382 u16 min_qp;
383 u16 max_qp;
384 s16 ip_delta;
385 s16 pb_delta;
386 u16 golden_ref;
387 u16 golden_delta;
388 u16 golden_ref_frequency;
389 u32 rate_control_option;
390
391 /* gop param */
392 u32 gop_ctrl_mode;
393 u32 freq_ird;
394 u32 freq_lt;
395 u32 gdr_mode;
396 u32 gop_length;
397 u32 unknown39;
398
399 u32 subframe_latency;
400 u32 lda_control_mode;
401} __attribute__ ((__packed__));
402
403struct mcu_msg_create_channel_response {
404 struct mcu_msg_header header;
405 u32 channel_id;
406 u32 user_id;
407 u32 options;
408 u32 num_core;
409 u32 pps_param;
410 u32 int_buffers_count;
411 u32 int_buffers_size;
412 u32 rec_buffers_count;
413 u32 rec_buffers_size;
414 u32 reserved;
415 u32 error_code;
416} __attribute__ ((__packed__));
417
418struct mcu_msg_destroy_channel {
419 struct mcu_msg_header header;
420 u32 channel_id;
421} __attribute__ ((__packed__));
422
423struct mcu_msg_destroy_channel_response {
424 struct mcu_msg_header header;
425 u32 channel_id;
426} __attribute__ ((__packed__));
427
428struct mcu_msg_push_buffers_internal_buffer {
429 u32 dma_addr;
430 u32 mcu_addr;
431 u32 size;
432} __attribute__ ((__packed__));
433
434struct mcu_msg_push_buffers_internal {
435 struct mcu_msg_header header;
436 u32 channel_id;
437 struct mcu_msg_push_buffers_internal_buffer buffer[0];
438} __attribute__ ((__packed__));
439
440struct mcu_msg_put_stream_buffer {
441 struct mcu_msg_header header;
442 u32 channel_id;
443 u32 dma_addr;
444 u32 mcu_addr;
445 u32 size;
446 u32 offset;
447 u64 stream_id;
448} __attribute__ ((__packed__));
449
450struct mcu_msg_encode_frame {
451 struct mcu_msg_header header;
452 u32 channel_id;
453 u32 reserved;
454
455 u32 encoding_options;
456#define AL_OPT_USE_QP_TABLE BIT(0)
457#define AL_OPT_FORCE_LOAD BIT(1)
458#define AL_OPT_USE_L2 BIT(2)
459#define AL_OPT_DISABLE_INTRA BIT(3)
460#define AL_OPT_DEPENDENT_SLICES BIT(4)
461
462 s16 pps_qp;
463 u16 padding;
464 u64 user_param;
465 u64 src_handle;
466 307
467 u32 request_options;308 return lower_32_bits(phys);
468#define AL_OPT_SCENE_CHANGE BIT(0)309}
469#define AL_OPT_RESTART_GOP BIT(1)310
470#define AL_OPT_USE_LONG_TERM BIT(2)311static inline u64 ptr_to_u64(const void *ptr)
471#define AL_OPT_UPDATE_PARAMS BIT(3)312{
472 313 return (uintptr_t)ptr;
473 /* u32 scene_change_delay (optional) */314}
474 /* rate control param (optional) */
475 /* gop param (optional) */
476 u32 src_y;
477 u32 src_uv;
478 u32 stride;
479 u32 ep2;
480 u64 ep2_v;
481} __attribute__ ((__packed__));
482
483struct mcu_msg_encode_frame_response {
484 struct mcu_msg_header header;
485 u32 channel_id;
486 u64 stream_id; /* see mcu_msg_put_stream_buffer */
487 u64 user_param; /* see mcu_msg_encode_frame */
488 u64 src_handle; /* see mcu_msg_encode_frame */
489 u16 skip;
490 u16 is_ref;
491 u32 initial_removal_delay;
492 u32 dpb_output_delay;
493 u32 size;
494 u32 frame_tag_size;
495 s32 stuffing;
496 s32 filler;
497 u16 num_column;
498 u16 num_row;
499 u16 qp;
500 u8 num_ref_idx_l0;
501 u8 num_ref_idx_l1;
502 u32 partition_table_offset;
503 s32 partition_table_size;
504 u32 sum_complex;
505 s32 tile_width[4];
506 s32 tile_height[22];
507 u32 error_code;
508
509 u32 slice_type;
510#define AL_ENC_SLICE_TYPE_B 0
511#define AL_ENC_SLICE_TYPE_P 1
512#define AL_ENC_SLICE_TYPE_I 2
513
514 u32 pic_struct;
515 u8 is_idr;
516 u8 is_first_slice;
517 u8 is_last_slice;
518 u8 reserved;
519 u16 pps_qp;
520 u16 reserved1;
521 u32 reserved2;
522} __attribute__ ((__packed__));
523
524union mcu_msg_response {
525 struct mcu_msg_header header;
526 struct mcu_msg_init_response init;
527 struct mcu_msg_create_channel_response create_channel;
528 struct mcu_msg_destroy_channel_response destroy_channel;
529 struct mcu_msg_encode_frame_response encode_frame;
530};
531 315
532/* Helper functions for channel and user operations */316/* Helper functions for channel and user operations */
533 317
@@ -572,6 +356,56 @@ static inline bool channel_exists(struct allegro_channel *channel) · 38 unmodified lines
572 return channel->mcu_channel_id != -1;356 return channel->mcu_channel_id != -1;
573}357}
574 358
359#define AL_ERROR 0x80
360#define AL_ERR_INIT_FAILED 0x81
361#define AL_ERR_NO_FRAME_DECODED 0x82
362#define AL_ERR_RESOLUTION_CHANGE 0x85
363#define AL_ERR_NO_MEMORY 0x87
364#define AL_ERR_STREAM_OVERFLOW 0x88
365#define AL_ERR_TOO_MANY_SLICES 0x89
366#define AL_ERR_BUF_NOT_READY 0x8c
367#define AL_ERR_NO_CHANNEL_AVAILABLE 0x8d
368#define AL_ERR_RESOURCE_UNAVAILABLE 0x8e
369#define AL_ERR_NOT_ENOUGH_CORES 0x8f
370#define AL_ERR_REQUEST_MALFORMED 0x90
371#define AL_ERR_CMD_NOT_ALLOWED 0x91
372#define AL_ERR_INVALID_CMD_VALUE 0x92
373
374static inline const char *allegro_err_to_string(unsigned int err)
375{
376 switch (err) {
377 case AL_ERR_INIT_FAILED:
378 return "initialization failed";
379 case AL_ERR_NO_FRAME_DECODED:
380 return "no frame decoded";
381 case AL_ERR_RESOLUTION_CHANGE:
382 return "resolution change";
383 case AL_ERR_NO_MEMORY:
384 return "out of memory";
385 case AL_ERR_STREAM_OVERFLOW:
386 return "stream buffer overflow";
387 case AL_ERR_TOO_MANY_SLICES:
388 return "too many slices";
389 case AL_ERR_BUF_NOT_READY:
390 return "buffer not ready";
391 case AL_ERR_NO_CHANNEL_AVAILABLE:
392 return "no channel available";
393 case AL_ERR_RESOURCE_UNAVAILABLE:
394 return "resource unavailable";
395 case AL_ERR_NOT_ENOUGH_CORES:
396 return "not enough cores";
397 case AL_ERR_REQUEST_MALFORMED:
398 return "request malformed";
399 case AL_ERR_CMD_NOT_ALLOWED:
400 return "command not allowed";
401 case AL_ERR_INVALID_CMD_VALUE:
402 return "invalid command value";
403 case AL_ERROR:
404 default:
405 return "unknown error";
406 }
407}
408
575static unsigned int estimate_stream_size(unsigned int width,409static unsigned int estimate_stream_size(unsigned int width,
576 unsigned int height)410 unsigned int height)
577{411{
@@ -781,7 +615,7 @@ static int allegro_mbox_write(struct allegro_dev *dev, · 203 unmodified lines
781 615
782 if (size > mbox->size) {616 if (size > mbox->size) {
783 v4l2_err(&dev->v4l2_dev,617 v4l2_err(&dev->v4l2_dev,
784 "message (%zu bytes) to large for mailbox (%zu bytes)\n",618 "message (%zu bytes) too large for mailbox (%zu bytes)\n",
785 size, mbox->size);619 size, mbox->size);
786 return -EINVAL;620 return -EINVAL;
787 }621 }
@@ -894,8 +728,8 @@ static void allegro_mcu_send_init(struct allegro_dev *dev, · 106 unmodified lines
894 msg.header.type = MCU_MSG_TYPE_INIT;728 msg.header.type = MCU_MSG_TYPE_INIT;
895 msg.header.length = sizeof(msg) - sizeof(msg.header);729 msg.header.length = sizeof(msg) - sizeof(msg.header);
896 730
897 msg.suballoc_dma = lower_32_bits(suballoc_dma) | MCU_CACHE_OFFSET;731 msg.suballoc_dma = to_mcu_addr(dev, suballoc_dma);
898 msg.suballoc_size = suballoc_size;732 msg.suballoc_size = to_mcu_size(dev, suballoc_size);
899 733
900 /* disable L2 cache */734 /* disable L2 cache */
901 msg.l2_cache[0] = -1;735 msg.l2_cache[0] = -1;
@@ -1001,6 +835,103 @@ v4l2_bitrate_mode_to_mcu_mode(enum v4l2_mpeg_video_bitrate_mode mode) · 99 unmodified lines
1001 }835 }
1002}836}
1003 837
838static u32 v4l2_cpb_size_to_mcu(unsigned int cpb_size, unsigned int bitrate)
839{
840 unsigned int cpb_size_kbit;
841 unsigned int bitrate_kbps;
842
843 /*
844 * The mcu expects the CPB size in units of a 90 kHz clock, but the
845 * channel follows the V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE and stores
846 * the CPB size in kilobytes.
847 */
848 cpb_size_kbit = cpb_size * BITS_PER_BYTE;
849 bitrate_kbps = bitrate / 1000;
850
851 return (cpb_size_kbit * 90000) / bitrate_kbps;
852}
853
854static s16 get_qp_delta(int minuend, int subtrahend)
855{
856 if (minuend == subtrahend)
857 return -1;
858 else
859 return minuend - subtrahend;
860}
861
862static int fill_create_channel_param(struct allegro_channel *channel,
863 struct create_channel_param *param)
864{
865 int i_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_i_frame_qp);
866 int p_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_p_frame_qp);
867 int b_frame_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_b_frame_qp);
868 int bitrate_mode = v4l2_ctrl_g_ctrl(channel->mpeg_video_bitrate_mode);
869
870 param->width = channel->width;
871 param->height = channel->height;
872 param->format = v4l2_pixelformat_to_mcu_format(channel->pixelformat);
873 param->colorspace =
874 v4l2_colorspace_to_mcu_colorspace(channel->colorspace);
875 param->src_mode = 0x0;
876 param->profile = v4l2_profile_to_mcu_profile(channel->profile);
877 param->constraint_set_flags = BIT(1);
878 param->codec = v4l2_pixelformat_to_mcu_codec(channel->codec);
879 param->level = v4l2_level_to_mcu_level(channel->level);
880 param->tier = 0;
881 param->sps_param = BIT(20) | 0x4a;
882 param->pps_param = BIT(2);
883 param->enc_option = AL_OPT_RDO_COST_MODE | AL_OPT_LF_X_TILE |
884 AL_OPT_LF_X_SLICE | AL_OPT_LF;
885 param->beta_offset = -1;
886 param->tc_offset = -1;
887 param->num_slices = 1;
888 param->me_range[0] = 8;
889 param->me_range[1] = 8;
890 param->me_range[2] = 16;
891 param->me_range[3] = 16;
892 param->max_cu_size = ilog2(SIZE_MACROBLOCK);
893 param->min_cu_size = ilog2(8);
894 param->max_tu_size = 2;
895 param->min_tu_size = 2;
896 param->max_transfo_depth_intra = 1;
897 param->max_transfo_depth_inter = 1;
898
899 param->prefetch_auto = 0;
900 param->prefetch_mem_offset = 0;
901 param->prefetch_mem_size = 0;
902
903 param->rate_control_mode = channel->frame_rc_enable ?
904 v4l2_bitrate_mode_to_mcu_mode(bitrate_mode) : 0;
905
906 param->cpb_size = v4l2_cpb_size_to_mcu(channel->cpb_size,
907 channel->bitrate_peak);
908 /* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */
909 param->initial_rem_delay = param->cpb_size;
910 param->framerate = DIV_ROUND_UP(channel->framerate.numerator,
911 channel->framerate.denominator);
912 param->clk_ratio = channel->framerate.denominator == 1001 ? 1001 : 1000;
913 param->target_bitrate = channel->bitrate;
914 param->max_bitrate = channel->bitrate_peak;
915 param->initial_qp = i_frame_qp;
916 param->min_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_min_qp);
917 param->max_qp = v4l2_ctrl_g_ctrl(channel->mpeg_video_h264_max_qp);
918 param->ip_delta = get_qp_delta(i_frame_qp, p_frame_qp);
919 param->pb_delta = get_qp_delta(p_frame_qp, b_frame_qp);
920 param->golden_ref = 0;
921 param->golden_delta = 2;
922 param->golden_ref_frequency = 10;
923 param->rate_control_option = 0x00000000;
924
925 param->gop_ctrl_mode = 0x00000000;
926 param->freq_idr = channel->gop_size;
927 param->freq_lt = 0;
928 param->gdr_mode = 0x00000000;
929 param->gop_length = channel->gop_size;
930 param->subframe_latency = 0x00000000;
931
932 return 0;
933}
934
1004static int allegro_mcu_send_create_channel(struct allegro_dev *dev,935static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
1005 struct allegro_channel *channel)936 struct allegro_channel *channel)
1006{937{
@@ -1012,63 +943,8 @@ static int allegro_mcu_send_create_channel(struct allegro_dev *dev, · 5 unmodified lines
1012 msg.header.length = sizeof(msg) - sizeof(msg.header);943 msg.header.length = sizeof(msg) - sizeof(msg.header);
1013 944
1014 msg.user_id = channel->user_id;945 msg.user_id = channel->user_id;
1015 msg.width = channel->width;946
1016 msg.height = channel->height;947 fill_create_channel_param(channel, &msg.param);
1017 msg.format = v4l2_pixelformat_to_mcu_format(channel->pixelformat);
1018 msg.colorspace = v4l2_colorspace_to_mcu_colorspace(channel->colorspace);
1019 msg.src_mode = 0x0;
1020 msg.profile = v4l2_profile_to_mcu_profile(channel->profile);
1021 msg.constraint_set_flags = BIT(1);
1022 msg.codec = v4l2_pixelformat_to_mcu_codec(channel->codec);
1023 msg.level = v4l2_level_to_mcu_level(channel->level);
1024 msg.tier = 0;
1025 msg.sps_param = BIT(20) | 0x4a;
1026 msg.pps_param = BIT(2);
1027 msg.enc_option = AL_OPT_RDO_COST_MODE | AL_OPT_LF_X_TILE |
1028 AL_OPT_LF_X_SLICE | AL_OPT_LF;
1029 msg.beta_offset = -1;
1030 msg.tc_offset = -1;
1031 msg.num_slices = 1;
1032 msg.me_range[0] = 8;
1033 msg.me_range[1] = 8;
1034 msg.me_range[2] = 16;
1035 msg.me_range[3] = 16;
1036 msg.max_cu_size = ilog2(SIZE_MACROBLOCK);
1037 msg.min_cu_size = ilog2(8);
1038 msg.max_tu_size = 2;
1039 msg.min_tu_size = 2;
1040 msg.max_transfo_depth_intra = 1;
1041 msg.max_transfo_depth_inter = 1;
1042
1043 msg.rate_control_mode =
1044 v4l2_bitrate_mode_to_mcu_mode(channel->bitrate_mode);
1045 /* Shall be ]0;cpb_size in 90 kHz units]. Use maximum value. */
1046 msg.initial_rem_delay =
1047 ((channel->cpb_size * 1000) / channel->bitrate_peak) * 90000;
1048 /* Encoder expects cpb_size in units of a 90 kHz clock. */
1049 msg.cpb_size =
1050 ((channel->cpb_size * 1000) / channel->bitrate_peak) * 90000;
1051 msg.framerate = 25;
1052 msg.clk_ratio = 1000;
1053 msg.target_bitrate = channel->bitrate;
1054 msg.max_bitrate = channel->bitrate_peak;
1055 msg.initial_qp = 25;
1056 msg.min_qp = 10;
1057 msg.max_qp = 51;
1058 msg.ip_delta = -1;
1059 msg.pb_delta = -1;
1060 msg.golden_ref = 0;
1061 msg.golden_delta = 2;
1062 msg.golden_ref_frequency = 10;
1063 msg.rate_control_option = 0x00000000;
1064
1065 msg.gop_ctrl_mode = 0x00000000;
1066 msg.freq_ird = 0x7fffffff;
1067 msg.freq_lt = 0;
1068 msg.gdr_mode = 0x00000000;
1069 msg.gop_length = channel->gop_size;
1070 msg.subframe_latency = 0x00000000;
1071 msg.lda_control_mode = 0x700d0000;
1072 948
1073 allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));949 allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));
1074 allegro_mcu_interrupt(dev);950 allegro_mcu_interrupt(dev);
@@ -1097,7 +973,8 @@ static int allegro_mcu_send_destroy_channel(struct allegro_dev *dev, · 22 unmodified lines
1097static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,973static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
1098 struct allegro_channel *channel,974 struct allegro_channel *channel,
1099 dma_addr_t paddr,975 dma_addr_t paddr,
1100 unsigned long size)976 unsigned long size,
977 u64 stream_id)
1101{978{
1102 struct mcu_msg_put_stream_buffer msg;979 struct mcu_msg_put_stream_buffer msg;
1103 980
@@ -1107,11 +984,12 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev, · 3 unmodified lines
1107 msg.header.length = sizeof(msg) - sizeof(msg.header);984 msg.header.length = sizeof(msg) - sizeof(msg.header);
1108 985
1109 msg.channel_id = channel->mcu_channel_id;986 msg.channel_id = channel->mcu_channel_id;
1110 msg.dma_addr = paddr;987 msg.dma_addr = to_codec_addr(dev, paddr);
1111 msg.mcu_addr = paddr | MCU_CACHE_OFFSET;988 msg.mcu_addr = to_mcu_addr(dev, paddr);
1112 msg.size = size;989 msg.size = size;
1113 msg.offset = ENCODER_STREAM_OFFSET;990 msg.offset = ENCODER_STREAM_OFFSET;
1114 msg.stream_id = 0; /* copied to mcu_msg_encode_frame_response */991 /* copied to mcu_msg_encode_frame_response */
992 msg.stream_id = stream_id;
1115 993
1116 allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));994 allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));
1117 allegro_mcu_interrupt(dev);995 allegro_mcu_interrupt(dev);
@@ -1121,7 +999,8 @@ static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev, · 3 unmodified lines
1121 999
1122static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,1000static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,
1123 struct allegro_channel *channel,1001 struct allegro_channel *channel,
1124 dma_addr_t src_y, dma_addr_t src_uv)1002 dma_addr_t src_y, dma_addr_t src_uv,
1003 u64 src_handle)
1125{1004{
1126 struct mcu_msg_encode_frame msg;1005 struct mcu_msg_encode_frame msg;
1127 1006
@@ -1134,12 +1013,13 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev, · 6 unmodified lines
1134 msg.encoding_options = AL_OPT_FORCE_LOAD;1013 msg.encoding_options = AL_OPT_FORCE_LOAD;
1135 msg.pps_qp = 26; /* qp are relative to 26 */1014 msg.pps_qp = 26; /* qp are relative to 26 */
1136 msg.user_param = 0; /* copied to mcu_msg_encode_frame_response */1015 msg.user_param = 0; /* copied to mcu_msg_encode_frame_response */
1137 msg.src_handle = 0; /* copied to mcu_msg_encode_frame_response */1016 /* src_handle is copied to mcu_msg_encode_frame_response */
1138 msg.src_y = src_y;1017 msg.src_handle = src_handle;
1139 msg.src_uv = src_uv;1018 msg.src_y = to_codec_addr(dev, src_y);
1019 msg.src_uv = to_codec_addr(dev, src_uv);
1140 msg.stride = channel->stride;1020 msg.stride = channel->stride;
1141 msg.ep2 = 0x0;1021 msg.ep2 = 0x0;
1142 msg.ep2_v = msg.ep2 | MCU_CACHE_OFFSET;1022 msg.ep2_v = to_mcu_addr(dev, msg.ep2);
1143 1023
1144 allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));1024 allegro_mbox_write(dev, &dev->mbox_command, &msg, sizeof(msg));
1145 allegro_mcu_interrupt(dev);1025 allegro_mcu_interrupt(dev);
@@ -1198,10 +1078,9 @@ static int allegro_mcu_push_buffer_internal(struct allegro_channel *channel, · 52 unmodified lines
1198 1078
1199 buffer = msg->buffer;1079 buffer = msg->buffer;
1200 list_for_each_entry(al_buffer, list, head) {1080 list_for_each_entry(al_buffer, list, head) {
1201 buffer->dma_addr = lower_32_bits(al_buffer->paddr);1081 buffer->dma_addr = to_codec_addr(dev, al_buffer->paddr);
1202 buffer->mcu_addr =1082 buffer->mcu_addr = to_mcu_addr(dev, al_buffer->paddr);
1203 lower_32_bits(al_buffer->paddr) | MCU_CACHE_OFFSET;1083 buffer->size = to_mcu_size(dev, al_buffer->size);
1204 buffer->size = al_buffer->size;
1205 buffer++;1084 buffer++;
1206 }1085 }
1207 1086
@@ -1360,9 +1239,11 @@ static ssize_t allegro_h264_write_sps(struct allegro_channel *channel, · 152 unmodified lines
1360 sps->vui.chroma_loc_info_present_flag = 1;1239 sps->vui.chroma_loc_info_present_flag = 1;
1361 sps->vui.chroma_sample_loc_type_top_field = 0;1240 sps->vui.chroma_sample_loc_type_top_field = 0;
1362 sps->vui.chroma_sample_loc_type_bottom_field = 0;1241 sps->vui.chroma_sample_loc_type_bottom_field = 0;
1242
1363 sps->vui.timing_info_present_flag = 1;1243 sps->vui.timing_info_present_flag = 1;
1364 sps->vui.num_units_in_tick = 1;1244 sps->vui.num_units_in_tick = channel->framerate.denominator;
1365 sps->vui.time_scale = 50;1245 sps->vui.time_scale = 2 * channel->framerate.numerator;
1246
1366 sps->vui.fixed_frame_rate_flag = 1;1247 sps->vui.fixed_frame_rate_flag = 1;
1367 sps->vui.nal_hrd_parameters_present_flag = 0;1248 sps->vui.nal_hrd_parameters_present_flag = 0;
1368 sps->vui.vcl_hrd_parameters_present_flag = 1;1249 sps->vui.vcl_hrd_parameters_present_flag = 1;
@@ -1375,7 +1256,8 @@ static ssize_t allegro_h264_write_sps(struct allegro_channel *channel, · 6 unmodified lines
1375 /* See Rec. ITU-T H.264 (04/2017) p. 410 E-54 */1256 /* See Rec. ITU-T H.264 (04/2017) p. 410 E-54 */
1376 sps->vui.vcl_hrd_parameters.cpb_size_value_minus1[0] =1257 sps->vui.vcl_hrd_parameters.cpb_size_value_minus1[0] =
1377 (channel->cpb_size * 1000) / (1 << (4 + sps->vui.vcl_hrd_parameters.cpb_size_scale)) - 1;1258 (channel->cpb_size * 1000) / (1 << (4 + sps->vui.vcl_hrd_parameters.cpb_size_scale)) - 1;
1378 sps->vui.vcl_hrd_parameters.cbr_flag[0] = 1;1259 sps->vui.vcl_hrd_parameters.cbr_flag[0] =
1260 !v4l2_ctrl_g_ctrl(channel->mpeg_video_frame_rc_enable);
1379 sps->vui.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 = 31;1261 sps->vui.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 = 31;
1380 sps->vui.vcl_hrd_parameters.cpb_removal_delay_length_minus1 = 31;1262 sps->vui.vcl_hrd_parameters.cpb_removal_delay_length_minus1 = 31;
1381 sps->vui.vcl_hrd_parameters.dpb_output_delay_length_minus1 = 31;1263 sps->vui.vcl_hrd_parameters.dpb_output_delay_length_minus1 = 31;
@@ -1438,8 +1320,11 @@ static bool allegro_channel_is_at_eos(struct allegro_channel *channel) · 56 unmodified lines
1438 break;1320 break;
1439 case ALLEGRO_STATE_DRAIN:1321 case ALLEGRO_STATE_DRAIN:
1440 case ALLEGRO_STATE_WAIT_FOR_BUFFER:1322 case ALLEGRO_STATE_WAIT_FOR_BUFFER:
1441 if (v4l2_m2m_num_src_bufs_ready(channel->fh.m2m_ctx) == 0)1323 mutex_lock(&channel->shadow_list_lock);
1324 if (v4l2_m2m_num_src_bufs_ready(channel->fh.m2m_ctx) == 0 &&
1325 list_empty(&channel->source_shadow_list))
1442 is_at_eos = true;1326 is_at_eos = true;
1327 mutex_unlock(&channel->shadow_list_lock);
1443 break;1328 break;
1444 default:1329 default:
1445 break;1330 break;
@@ -1466,6 +1351,41 @@ static void allegro_channel_buf_done(struct allegro_channel *channel, · 20 unmodified lines
1466 v4l2_m2m_buf_done(buf, state);1351 v4l2_m2m_buf_done(buf, state);
1467}1352}
1468 1353
1354static u64 allegro_put_buffer(struct allegro_channel *channel,
1355 struct list_head *list,
1356 struct vb2_v4l2_buffer *buffer)
1357{
1358 struct v4l2_m2m_buffer *b = container_of(buffer,
1359 struct v4l2_m2m_buffer, vb);
1360 struct allegro_m2m_buffer *shadow = to_allegro_m2m_buffer(b);
1361
1362 mutex_lock(&channel->shadow_list_lock);
1363 list_add_tail(&shadow->head, list);
1364 mutex_unlock(&channel->shadow_list_lock);
1365
1366 return ptr_to_u64(buffer);
1367}
1368
1369static struct vb2_v4l2_buffer *
1370allegro_get_buffer(struct allegro_channel *channel,
1371 struct list_head *list, u64 handle)
1372{
1373 struct allegro_m2m_buffer *shadow, *tmp;
1374 struct vb2_v4l2_buffer *buffer = NULL;
1375
1376 mutex_lock(&channel->shadow_list_lock);
1377 list_for_each_entry_safe(shadow, tmp, list, head) {
1378 if (handle == ptr_to_u64(&shadow->buf.vb)) {
1379 buffer = &shadow->buf.vb;
1380 list_del_init(&shadow->head);
1381 break;
1382 }
1383 }
1384 mutex_unlock(&channel->shadow_list_lock);
1385
1386 return buffer;
1387}
1388
1469static void allegro_channel_finish_frame(struct allegro_channel *channel,1389static void allegro_channel_finish_frame(struct allegro_channel *channel,
1470 struct mcu_msg_encode_frame_response *msg)1390 struct mcu_msg_encode_frame_response *msg)
1471{1391{
@@ -1481,15 +1401,31 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel, · 9 unmodified lines
1481 ssize_t len;1401 ssize_t len;
1482 ssize_t free;1402 ssize_t free;
1483 1403
1484 src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx);1404 src_buf = allegro_get_buffer(channel, &channel->source_shadow_list,
1405 msg->src_handle);
1406 if (!src_buf)
1407 v4l2_warn(&dev->v4l2_dev,
1408 "channel %d: invalid source buffer\n",
1409 channel->mcu_channel_id);
1410
1411 dst_buf = allegro_get_buffer(channel, &channel->stream_shadow_list,
1412 msg->stream_id);
1413 if (!dst_buf)
1414 v4l2_warn(&dev->v4l2_dev,
1415 "channel %d: invalid stream buffer\n",
1416 channel->mcu_channel_id);
1417
1418 if (!src_buf || !dst_buf)
1419 goto err;
1485 1420
1486 dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
1487 dst_buf->sequence = channel->csequence++;1421 dst_buf->sequence = channel->csequence++;
1488 1422
1489 if (msg->error_code) {1423 if (msg->error_code & AL_ERROR) {
1490 v4l2_err(&dev->v4l2_dev,1424 v4l2_err(&dev->v4l2_dev,
1491 "channel %d: error while encoding frame: %x\n",1425 "channel %d: failed to encode frame: %s (%x)\n",
1492 channel->mcu_channel_id, msg->error_code);1426 channel->mcu_channel_id,
1427 allegro_err_to_string(msg->error_code),
1428 msg->error_code);
1493 goto err;1429 goto err;
1494 }1430 }
1495 1431
@@ -1562,17 +1498,22 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel, · 66 unmodified lines
1562 channel->mcu_channel_id, len);1498 channel->mcu_channel_id, len);
1563 }1499 }
1564 1500
1565 len = nal_h264_write_filler(&dev->plat_dev->dev, curr, free);1501 if (msg->slice_type != AL_ENC_SLICE_TYPE_I && !msg->is_idr) {
1566 if (len < 0) {1502 dst_buf->vb2_buf.planes[0].data_offset = free;
1567 v4l2_err(&dev->v4l2_dev,1503 free = 0;
1568 "failed to write %zd filler data\n", free);1504 } else {
1569 goto err;1505 len = nal_h264_write_filler(&dev->plat_dev->dev, curr, free);
1506 if (len < 0) {
1507 v4l2_err(&dev->v4l2_dev,
1508 "failed to write %zd filler data\n", free);
1509 goto err;
1510 }
1511 curr += len;
1512 free -= len;
1513 v4l2_dbg(2, debug, &dev->v4l2_dev,
1514 "channel %d: wrote %zd bytes filler nal unit\n",
1515 channel->mcu_channel_id, len);
1570 }1516 }
1571 curr += len;
1572 free -= len;
1573 v4l2_dbg(2, debug, &dev->v4l2_dev,
1574 "channel %d: wrote %zd bytes filler nal unit\n",
1575 channel->mcu_channel_id, len);
1576 1517
1577 if (free != 0) {1518 if (free != 0) {
1578 v4l2_err(&dev->v4l2_dev,1519 v4l2_err(&dev->v4l2_dev,
@@ -1590,20 +1531,20 @@ static void allegro_channel_finish_frame(struct allegro_channel *channel, · 11 unmodified lines
1590 dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;1531 dst_buf->flags |= V4L2_BUF_FLAG_PFRAME;
1591 1532
1592 v4l2_dbg(1, debug, &dev->v4l2_dev,1533 v4l2_dbg(1, debug, &dev->v4l2_dev,
1593 "channel %d: encoded frame #%03d (%s%s, %d bytes)\n",1534 "channel %d: encoded frame #%03d (%s%s, QP %d, %d bytes)\n",
1594 channel->mcu_channel_id,1535 channel->mcu_channel_id,
1595 dst_buf->sequence,1536 dst_buf->sequence,
1596 msg->is_idr ? "IDR, " : "",1537 msg->is_idr ? "IDR, " : "",
1597 msg->slice_type == AL_ENC_SLICE_TYPE_I ? "I slice" :1538 msg->slice_type == AL_ENC_SLICE_TYPE_I ? "I slice" :
1598 msg->slice_type == AL_ENC_SLICE_TYPE_P ? "P slice" : "unknown",1539 msg->slice_type == AL_ENC_SLICE_TYPE_P ? "P slice" : "unknown",
1599 partition->size);1540 msg->qp, partition->size);
1600 1541
1601err:1542err:
1602 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);1543 if (src_buf)
1603 1544 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1604 allegro_channel_buf_done(channel, dst_buf, state);
1605 1545
1606 v4l2_m2m_job_finish(dev->m2m_dev, channel->fh.m2m_ctx);1546 if (dst_buf)
1547 allegro_channel_buf_done(channel, dst_buf, state);
1607}1548}
1608 1549
1609static int allegro_handle_init(struct allegro_dev *dev,1550static int allegro_handle_init(struct allegro_dev *dev,
@@ -1621,6 +1562,12 @@ allegro_handle_create_channel(struct allegro_dev *dev, · 11 unmodified lines
1621 struct allegro_channel *channel;1562 struct allegro_channel *channel;
1622 int err = 0;1563 int err = 0;
1623 1564
1565 if (msg->header.length != sizeof(*msg) - sizeof(msg->header))
1566 v4l2_warn(&dev->v4l2_dev,
1567 "received message has %d bytes, but expected %zu\n",
1568 msg->header.length,
1569 sizeof(*msg) - sizeof(msg->header));
1570
1624 channel = allegro_find_channel_by_user_id(dev, msg->user_id);1571 channel = allegro_find_channel_by_user_id(dev, msg->user_id);
1625 if (IS_ERR(channel)) {1572 if (IS_ERR(channel)) {
1626 v4l2_warn(&dev->v4l2_dev,1573 v4l2_warn(&dev->v4l2_dev,
@@ -1632,8 +1579,10 @@ allegro_handle_create_channel(struct allegro_dev *dev, · 5 unmodified lines
1632 1579
1633 if (msg->error_code) {1580 if (msg->error_code) {
1634 v4l2_err(&dev->v4l2_dev,1581 v4l2_err(&dev->v4l2_dev,
1635 "user %d: mcu failed to create channel: error %x\n",1582 "user %d: mcu failed to create channel: %s (%x)\n",
1636 channel->user_id, msg->error_code);1583 channel->user_id,
1584 allegro_err_to_string(msg->error_code),
1585 msg->error_code);
1637 err = -EIO;1586 err = -EIO;
1638 goto out;1587 goto out;
1639 }1588 }
@@ -1712,6 +1661,12 @@ allegro_handle_encode_frame(struct allegro_dev *dev, · 72 unmodified lines
1712{1661{
1713 struct allegro_channel *channel;1662 struct allegro_channel *channel;
1714 1663
1664 if (msg->header.length != sizeof(*msg) - sizeof(msg->header))
1665 v4l2_warn(&dev->v4l2_dev,
1666 "received message has %d bytes, but expected %zu\n",
1667 msg->header.length,
1668 sizeof(*msg) - sizeof(msg->header));
1669
1715 channel = allegro_find_channel_by_channel_id(dev, msg->channel_id);1670 channel = allegro_find_channel_by_channel_id(dev, msg->channel_id);
1716 if (IS_ERR(channel)) {1671 if (IS_ERR(channel)) {
1717 v4l2_err(&dev->v4l2_dev,1672 v4l2_err(&dev->v4l2_dev,
@@ -1920,6 +1875,14 @@ static int allegro_mcu_reset(struct allegro_dev *dev) · 202 unmodified lines
1920{1875{
1921 int err;1876 int err;
1922 1877
1878 /*
1879 * Ensure that the AL5_MCU_WAKEUP bit is set to 0 otherwise the mcu
1880 * does not go to sleep after the reset.
1881 */
1882 err = regmap_write(dev->regmap, AL5_MCU_WAKEUP, 0);
1883 if (err)
1884 return err;
1885
1923 err = regmap_write(dev->regmap,1886 err = regmap_write(dev->regmap,
1924 AL5_MCU_RESET_MODE, AL5_MCU_RESET_MODE_SLEEP);1887 AL5_MCU_RESET_MODE, AL5_MCU_RESET_MODE_SLEEP);
1925 if (err < 0)1888 if (err < 0)
@@ -1955,6 +1918,12 @@ static void allegro_destroy_channel(struct allegro_channel *channel) · 29 unmodified lines
1955 1918
1956 v4l2_ctrl_grab(channel->mpeg_video_h264_profile, false);1919 v4l2_ctrl_grab(channel->mpeg_video_h264_profile, false);
1957 v4l2_ctrl_grab(channel->mpeg_video_h264_level, false);1920 v4l2_ctrl_grab(channel->mpeg_video_h264_level, false);
1921 v4l2_ctrl_grab(channel->mpeg_video_h264_i_frame_qp, false);
1922 v4l2_ctrl_grab(channel->mpeg_video_h264_max_qp, false);
1923 v4l2_ctrl_grab(channel->mpeg_video_h264_min_qp, false);
1924 v4l2_ctrl_grab(channel->mpeg_video_h264_p_frame_qp, false);
1925 v4l2_ctrl_grab(channel->mpeg_video_h264_b_frame_qp, false);
1926 v4l2_ctrl_grab(channel->mpeg_video_frame_rc_enable, false);
1958 v4l2_ctrl_grab(channel->mpeg_video_bitrate_mode, false);1927 v4l2_ctrl_grab(channel->mpeg_video_bitrate_mode, false);
1959 v4l2_ctrl_grab(channel->mpeg_video_bitrate, false);1928 v4l2_ctrl_grab(channel->mpeg_video_bitrate, false);
1960 v4l2_ctrl_grab(channel->mpeg_video_bitrate_peak, false);1929 v4l2_ctrl_grab(channel->mpeg_video_bitrate_peak, false);
@@ -2000,7 +1969,9 @@ static int allegro_create_channel(struct allegro_channel *channel) · 39 unmodified lines
2000 v4l2_dbg(1, debug, &dev->v4l2_dev,1969 v4l2_dbg(1, debug, &dev->v4l2_dev,
2001 "user %d: creating channel (%4.4s, %dx%d@%d)\n",1970 "user %d: creating channel (%4.4s, %dx%d@%d)\n",
2002 channel->user_id,1971 channel->user_id,
2003 (char *)&channel->codec, channel->width, channel->height, 25);1972 (char *)&channel->codec, channel->width, channel->height,
1973 DIV_ROUND_UP(channel->framerate.numerator,
1974 channel->framerate.denominator));
2004 1975
2005 min_level = select_minimum_h264_level(channel->width, channel->height);1976 min_level = select_minimum_h264_level(channel->width, channel->height);
2006 if (channel->level < min_level) {1977 if (channel->level < min_level) {
@@ -2014,6 +1985,12 @@ static int allegro_create_channel(struct allegro_channel *channel) · 7 unmodified lines
2014 1985
2015 v4l2_ctrl_grab(channel->mpeg_video_h264_profile, true);1986 v4l2_ctrl_grab(channel->mpeg_video_h264_profile, true);
2016 v4l2_ctrl_grab(channel->mpeg_video_h264_level, true);1987 v4l2_ctrl_grab(channel->mpeg_video_h264_level, true);
1988 v4l2_ctrl_grab(channel->mpeg_video_h264_i_frame_qp, true);
1989 v4l2_ctrl_grab(channel->mpeg_video_h264_max_qp, true);
1990 v4l2_ctrl_grab(channel->mpeg_video_h264_min_qp, true);
1991 v4l2_ctrl_grab(channel->mpeg_video_h264_p_frame_qp, true);
1992 v4l2_ctrl_grab(channel->mpeg_video_h264_b_frame_qp, true);
1993 v4l2_ctrl_grab(channel->mpeg_video_frame_rc_enable, true);
2017 v4l2_ctrl_grab(channel->mpeg_video_bitrate_mode, true);1994 v4l2_ctrl_grab(channel->mpeg_video_bitrate_mode, true);
2018 v4l2_ctrl_grab(channel->mpeg_video_bitrate, true);1995 v4l2_ctrl_grab(channel->mpeg_video_bitrate, true);
2019 v4l2_ctrl_grab(channel->mpeg_video_bitrate_peak, true);1996 v4l2_ctrl_grab(channel->mpeg_video_bitrate_peak, true);
@@ -2046,6 +2023,7 @@ static void allegro_set_default_params(struct allegro_channel *channel) · 26 unmodified lines
2046 channel->width = ALLEGRO_WIDTH_DEFAULT;2023 channel->width = ALLEGRO_WIDTH_DEFAULT;
2047 channel->height = ALLEGRO_HEIGHT_DEFAULT;2024 channel->height = ALLEGRO_HEIGHT_DEFAULT;
2048 channel->stride = round_up(channel->width, 32);2025 channel->stride = round_up(channel->width, 32);
2026 channel->framerate = ALLEGRO_FRAMERATE_DEFAULT;
2049 2027
2050 channel->colorspace = V4L2_COLORSPACE_REC709;2028 channel->colorspace = V4L2_COLORSPACE_REC709;
2051 channel->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;2029 channel->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
@@ -2062,7 +2040,6 @@ static void allegro_set_default_params(struct allegro_channel *channel) · 10 unmodified lines
2062 channel->sizeimage_encoded =2040 channel->sizeimage_encoded =
2063 estimate_stream_size(channel->width, channel->height);2041 estimate_stream_size(channel->width, channel->height);
2064 2042
2065 channel->bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
2066 channel->bitrate = maximum_bitrate(channel->level);2043 channel->bitrate = maximum_bitrate(channel->level);
2067 channel->bitrate_peak = maximum_bitrate(channel->level);2044 channel->bitrate_peak = maximum_bitrate(channel->level);
2068 channel->cpb_size = maximum_cpb_size(channel->level);2045 channel->cpb_size = maximum_cpb_size(channel->level);
@@ -2163,16 +2140,33 @@ static void allegro_stop_streaming(struct vb2_queue *q) · 94 unmodified lines
2163 struct allegro_channel *channel = vb2_get_drv_priv(q);2140 struct allegro_channel *channel = vb2_get_drv_priv(q);
2164 struct allegro_dev *dev = channel->dev;2141 struct allegro_dev *dev = channel->dev;
2165 struct vb2_v4l2_buffer *buffer;2142 struct vb2_v4l2_buffer *buffer;
2143 struct allegro_m2m_buffer *shadow, *tmp;
2166 2144
2167 v4l2_dbg(2, debug, &dev->v4l2_dev,2145 v4l2_dbg(2, debug, &dev->v4l2_dev,
2168 "%s: stop streaming\n",2146 "%s: stop streaming\n",
2169 V4L2_TYPE_IS_OUTPUT(q->type) ? "output" : "capture");2147 V4L2_TYPE_IS_OUTPUT(q->type) ? "output" : "capture");
2170 2148
2171 if (V4L2_TYPE_IS_OUTPUT(q->type)) {2149 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
2150 mutex_lock(&channel->shadow_list_lock);
2151 list_for_each_entry_safe(shadow, tmp,
2152 &channel->source_shadow_list, head) {
2153 list_del(&shadow->head);
2154 v4l2_m2m_buf_done(&shadow->buf.vb, VB2_BUF_STATE_ERROR);
2155 }
2156 mutex_unlock(&channel->shadow_list_lock);
2157
2172 allegro_set_state(channel, ALLEGRO_STATE_STOPPED);2158 allegro_set_state(channel, ALLEGRO_STATE_STOPPED);
2173 while ((buffer = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx)))2159 while ((buffer = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx)))
2174 v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_ERROR);2160 v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_ERROR);
2175 } else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {2161 } else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2162 mutex_lock(&channel->shadow_list_lock);
2163 list_for_each_entry_safe(shadow, tmp,
2164 &channel->stream_shadow_list, head) {
2165 list_del(&shadow->head);
2166 v4l2_m2m_buf_done(&shadow->buf.vb, VB2_BUF_STATE_ERROR);
2167 }
2168 mutex_unlock(&channel->shadow_list_lock);
2169
2176 allegro_destroy_channel(channel);2170 allegro_destroy_channel(channel);
2177 while ((buffer = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx)))2171 while ((buffer = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx)))
2178 v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_ERROR);2172 v4l2_m2m_buf_done(buffer, VB2_BUF_STATE_ERROR);
@@ -2203,7 +2197,7 @@ static int allegro_queue_init(void *priv, · 24 unmodified lines
2203 src_vq->drv_priv = channel;2197 src_vq->drv_priv = channel;
2204 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;2198 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2205 src_vq->ops = &allegro_queue_ops;2199 src_vq->ops = &allegro_queue_ops;
2206 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);2200 src_vq->buf_struct_size = sizeof(struct allegro_m2m_buffer);
2207 src_vq->lock = &channel->dev->lock;2201 src_vq->lock = &channel->dev->lock;
2208 err = vb2_queue_init(src_vq);2202 err = vb2_queue_init(src_vq);
2209 if (err)2203 if (err)
@@ -2216,7 +2210,7 @@ static int allegro_queue_init(void *priv, · 6 unmodified lines
2216 dst_vq->drv_priv = channel;2210 dst_vq->drv_priv = channel;
2217 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;2211 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2218 dst_vq->ops = &allegro_queue_ops;2212 dst_vq->ops = &allegro_queue_ops;
2219 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);2213 dst_vq->buf_struct_size = sizeof(struct allegro_m2m_buffer);
2220 dst_vq->lock = &channel->dev->lock;2214 dst_vq->lock = &channel->dev->lock;
2221 err = vb2_queue_init(dst_vq);2215 err = vb2_queue_init(dst_vq);
2222 if (err)2216 if (err)
@@ -2225,6 +2219,52 @@ static int allegro_queue_init(void *priv, · 2 unmodified lines
2225 return 0;2219 return 0;
2226}2220}
2227 2221
2222static int allegro_clamp_qp(struct allegro_channel *channel,
2223 struct v4l2_ctrl *ctrl)
2224{
2225 struct v4l2_ctrl *next_ctrl;
2226
2227 if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP)
2228 next_ctrl = channel->mpeg_video_h264_p_frame_qp;
2229 else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP)
2230 next_ctrl = channel->mpeg_video_h264_b_frame_qp;
2231 else
2232 return 0;
2233
2234 /* Modify range automatically updates the value */
2235 __v4l2_ctrl_modify_range(next_ctrl, ctrl->val, 51, 1, ctrl->val);
2236
2237 return allegro_clamp_qp(channel, next_ctrl);
2238}
2239
2240static int allegro_clamp_bitrate(struct allegro_channel *channel,
2241 struct v4l2_ctrl *ctrl)
2242{
2243 struct v4l2_ctrl *ctrl_bitrate = channel->mpeg_video_bitrate;
2244 struct v4l2_ctrl *ctrl_bitrate_peak = channel->mpeg_video_bitrate_peak;
2245
2246 if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
2247 ctrl_bitrate_peak->val < ctrl_bitrate->val)
2248 ctrl_bitrate_peak->val = ctrl_bitrate->val;
2249
2250 return 0;
2251}
2252
2253static int allegro_try_ctrl(struct v4l2_ctrl *ctrl)
2254{
2255 struct allegro_channel *channel = container_of(ctrl->handler,
2256 struct allegro_channel,
2257 ctrl_handler);
2258
2259 switch (ctrl->id) {
2260 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
2261 allegro_clamp_bitrate(channel, ctrl);
2262 break;
2263 }
2264
2265 return 0;
2266}
2267
2228static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)2268static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
2229{2269{
2230 struct allegro_channel *channel = container_of(ctrl->handler,2270 struct allegro_channel *channel = container_of(ctrl->handler,
@@ -2239,14 +2279,14 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl) · 8 unmodified lines
2239 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:2279 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
2240 channel->level = ctrl->val;2280 channel->level = ctrl->val;
2241 break;2281 break;
2242 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:2282 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
2243 channel->bitrate_mode = ctrl->val;2283 channel->frame_rc_enable = ctrl->val;
2244 break;
2245 case V4L2_CID_MPEG_VIDEO_BITRATE:
2246 channel->bitrate = ctrl->val;
2247 break;2284 break;
2248 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:2285 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
2249 channel->bitrate_peak = ctrl->val;2286 channel->bitrate = channel->mpeg_video_bitrate->val;
2287 channel->bitrate_peak = channel->mpeg_video_bitrate_peak->val;
2288 v4l2_ctrl_activate(channel->mpeg_video_bitrate_peak,
2289 ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
2250 break;2290 break;
2251 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:2291 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
2252 channel->cpb_size = ctrl->val;2292 channel->cpb_size = ctrl->val;
@@ -2254,12 +2294,18 @@ static int allegro_s_ctrl(struct v4l2_ctrl *ctrl) · 1 unmodified line
2254 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:2294 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
2255 channel->gop_size = ctrl->val;2295 channel->gop_size = ctrl->val;
2256 break;2296 break;
2297 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
2298 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
2299 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
2300 allegro_clamp_qp(channel, ctrl);
2301 break;
2257 }2302 }
2258 2303
2259 return 0;2304 return 0;
2260}2305}
2261 2306
2262static const struct v4l2_ctrl_ops allegro_ctrl_ops = {2307static const struct v4l2_ctrl_ops allegro_ctrl_ops = {
2308 .try_ctrl = allegro_try_ctrl,
2263 .s_ctrl = allegro_s_ctrl,2309 .s_ctrl = allegro_s_ctrl,
2264};2310};
2265 2311
@@ -2270,16 +2316,18 @@ static int allegro_open(struct file *file) · 4 unmodified lines
2270 struct allegro_channel *channel = NULL;2316 struct allegro_channel *channel = NULL;
2271 struct v4l2_ctrl_handler *handler;2317 struct v4l2_ctrl_handler *handler;
2272 u64 mask;2318 u64 mask;
2319 int ret;
2273 2320
2274 channel = kzalloc(sizeof(*channel), GFP_KERNEL);2321 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
2275 if (!channel)2322 if (!channel)
2276 return -ENOMEM;2323 return -ENOMEM;
2277 2324
2278 v4l2_fh_init(&channel->fh, vdev);2325 v4l2_fh_init(&channel->fh, vdev);
2279 file->private_data = &channel->fh;
2280 v4l2_fh_add(&channel->fh);
2281 2326
2282 init_completion(&channel->completion);2327 init_completion(&channel->completion);
2328 INIT_LIST_HEAD(&channel->source_shadow_list);
2329 INIT_LIST_HEAD(&channel->stream_shadow_list);
2330 mutex_init(&channel->shadow_list_lock);
2283 2331
2284 channel->dev = dev;2332 channel->dev = dev;
2285 2333
@@ -2298,11 +2346,42 @@ static int allegro_open(struct file *file) · 12 unmodified lines
2298 V4L2_CID_MPEG_VIDEO_H264_LEVEL,2346 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
2299 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, mask,2347 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, mask,
2300 V4L2_MPEG_VIDEO_H264_LEVEL_5_1);2348 V4L2_MPEG_VIDEO_H264_LEVEL_5_1);
2349 channel->mpeg_video_h264_i_frame_qp =
2350 v4l2_ctrl_new_std(handler,
2351 &allegro_ctrl_ops,
2352 V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
2353 0, 51, 1, 30);
2354 channel->mpeg_video_h264_max_qp =
2355 v4l2_ctrl_new_std(handler,
2356 &allegro_ctrl_ops,
2357 V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
2358 0, 51, 1, 51);
2359 channel->mpeg_video_h264_min_qp =
2360 v4l2_ctrl_new_std(handler,
2361 &allegro_ctrl_ops,
2362 V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
2363 0, 51, 1, 0);
2364 channel->mpeg_video_h264_p_frame_qp =
2365 v4l2_ctrl_new_std(handler,
2366 &allegro_ctrl_ops,
2367 V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
2368 0, 51, 1, 30);
2369 channel->mpeg_video_h264_b_frame_qp =
2370 v4l2_ctrl_new_std(handler,
2371 &allegro_ctrl_ops,
2372 V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
2373 0, 51, 1, 30);
2374 channel->mpeg_video_frame_rc_enable =
2375 v4l2_ctrl_new_std(handler,
2376 &allegro_ctrl_ops,
2377 V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
2378 false, 0x1,
2379 true, false);
2301 channel->mpeg_video_bitrate_mode = v4l2_ctrl_new_std_menu(handler,2380 channel->mpeg_video_bitrate_mode = v4l2_ctrl_new_std_menu(handler,
2302 &allegro_ctrl_ops,2381 &allegro_ctrl_ops,
2303 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,2382 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
2304 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,2383 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
2305 channel->bitrate_mode);2384 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
2306 channel->mpeg_video_bitrate = v4l2_ctrl_new_std(handler,2385 channel->mpeg_video_bitrate = v4l2_ctrl_new_std(handler,
2307 &allegro_ctrl_ops,2386 &allegro_ctrl_ops,
2308 V4L2_CID_MPEG_VIDEO_BITRATE,2387 V4L2_CID_MPEG_VIDEO_BITRATE,
@@ -2328,8 +2407,15 @@ static int allegro_open(struct file *file) · 19 unmodified lines
2328 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,2407 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
2329 1, 32,2408 1, 32,
2330 1, 1);2409 1, 1);
2410 if (handler->error != 0) {
2411 ret = handler->error;
2412 goto error;
2413 }
2414
2331 channel->fh.ctrl_handler = handler;2415 channel->fh.ctrl_handler = handler;
2332 2416
2417 v4l2_ctrl_cluster(3, &channel->mpeg_video_bitrate_mode);
2418
2333 channel->mcu_channel_id = -1;2419 channel->mcu_channel_id = -1;
2334 channel->user_id = -1;2420 channel->user_id = -1;
2335 2421
@@ -2341,7 +2427,20 @@ static int allegro_open(struct file *file) · 5 unmodified lines
2341 channel->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, channel,2427 channel->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, channel,
2342 allegro_queue_init);2428 allegro_queue_init);
2343 2429
2430 if (IS_ERR(channel->fh.m2m_ctx)) {
2431 ret = PTR_ERR(channel->fh.m2m_ctx);
2432 goto error;
2433 }
2434
2435 file->private_data = &channel->fh;
2436 v4l2_fh_add(&channel->fh);
2437
2344 return 0;2438 return 0;
2439
2440error:
2441 v4l2_ctrl_handler_free(handler);
2442 kfree(channel);
2443 return ret;
2345}2444}
2346 2445
2347static int allegro_release(struct file *file)2446static int allegro_release(struct file *file)
@@ -2636,6 +2735,46 @@ static int allegro_ioctl_streamon(struct file *file, void *priv, · 288 unmodified lines
2636 return v4l2_m2m_streamon(file, fh->m2m_ctx, type);2735 return v4l2_m2m_streamon(file, fh->m2m_ctx, type);
2637}2736}
2638 2737
2738static int allegro_g_parm(struct file *file, void *fh,
2739 struct v4l2_streamparm *a)
2740{
2741 struct allegro_channel *channel = fh_to_channel(fh);
2742 struct v4l2_fract *timeperframe;
2743
2744 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
2745 return -EINVAL;
2746
2747 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
2748 timeperframe = &a->parm.output.timeperframe;
2749 timeperframe->numerator = channel->framerate.denominator;
2750 timeperframe->denominator = channel->framerate.numerator;
2751
2752 return 0;
2753}
2754
2755static int allegro_s_parm(struct file *file, void *fh,
2756 struct v4l2_streamparm *a)
2757{
2758 struct allegro_channel *channel = fh_to_channel(fh);
2759 struct v4l2_fract *timeperframe;
2760 int div;
2761
2762 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
2763 return -EINVAL;
2764
2765 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
2766 timeperframe = &a->parm.output.timeperframe;
2767
2768 if (timeperframe->numerator == 0 || timeperframe->denominator == 0)
2769 return allegro_g_parm(file, fh, a);
2770
2771 div = gcd(timeperframe->denominator, timeperframe->numerator);
2772 channel->framerate.numerator = timeperframe->denominator / div;
2773 channel->framerate.denominator = timeperframe->numerator / div;
2774
2775 return 0;
2776}
2777
2639static int allegro_subscribe_event(struct v4l2_fh *fh,2778static int allegro_subscribe_event(struct v4l2_fh *fh,
2640 const struct v4l2_event_subscription *sub)2779 const struct v4l2_event_subscription *sub)
2641{2780{
@@ -2674,6 +2813,9 @@ static const struct v4l2_ioctl_ops allegro_ioctl_ops = { · 32 unmodified lines
2674 .vidioc_encoder_cmd = allegro_encoder_cmd,2813 .vidioc_encoder_cmd = allegro_encoder_cmd,
2675 .vidioc_enum_framesizes = allegro_enum_framesizes,2814 .vidioc_enum_framesizes = allegro_enum_framesizes,
2676 2815
2816 .vidioc_g_parm = allegro_g_parm,
2817 .vidioc_s_parm = allegro_s_parm,
2818
2677 .vidioc_subscribe_event = allegro_subscribe_event,2819 .vidioc_subscribe_event = allegro_subscribe_event,
2678 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,2820 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2679};2821};
@@ -2701,7 +2843,7 @@ static int allegro_register_device(struct allegro_dev *dev) · 21 unmodified lines
2701 video_dev->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;2843 video_dev->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
2702 video_set_drvdata(video_dev, dev);2844 video_set_drvdata(video_dev, dev);
2703 2845
2704 return video_register_device(video_dev, VFL_TYPE_GRABBER, 0);2846 return video_register_device(video_dev, VFL_TYPE_VIDEO, 0);
2705}2847}
2706 2848
2707static void allegro_device_run(void *priv)2849static void allegro_device_run(void *priv)
@@ -2714,18 +2856,26 @@ static void allegro_device_run(void *priv) · 6 unmodified lines
2714 dma_addr_t src_uv;2856 dma_addr_t src_uv;
2715 dma_addr_t dst_addr;2857 dma_addr_t dst_addr;
2716 unsigned long dst_size;2858 unsigned long dst_size;
2859 u64 src_handle;
2860 u64 dst_handle;
2717 2861
2718 dst_buf = v4l2_m2m_next_dst_buf(channel->fh.m2m_ctx);2862 dst_buf = v4l2_m2m_dst_buf_remove(channel->fh.m2m_ctx);
2719 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);2863 dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
2720 dst_size = vb2_plane_size(&dst_buf->vb2_buf, 0);2864 dst_size = vb2_plane_size(&dst_buf->vb2_buf, 0);
2721 allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size);2865 dst_handle = allegro_put_buffer(channel, &channel->stream_shadow_list,
2866 dst_buf);
2867 allegro_mcu_send_put_stream_buffer(dev, channel, dst_addr, dst_size,
2868 dst_handle);
2722 2869
2723 src_buf = v4l2_m2m_next_src_buf(channel->fh.m2m_ctx);2870 src_buf = v4l2_m2m_src_buf_remove(channel->fh.m2m_ctx);
2724 src_buf->sequence = channel->osequence++;2871 src_buf->sequence = channel->osequence++;
2725
2726 src_y = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);2872 src_y = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
2727 src_uv = src_y + (channel->stride * channel->height);2873 src_uv = src_y + (channel->stride * channel->height);
2728 allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv);2874 src_handle = allegro_put_buffer(channel, &channel->source_shadow_list,
2875 src_buf);
2876 allegro_mcu_send_encode_frame(dev, channel, src_y, src_uv, src_handle);
2877
2878 v4l2_m2m_job_finish(dev->m2m_dev, channel->fh.m2m_ctx);
2729}2879}
2730 2880
2731static const struct v4l2_m2m_ops allegro_m2m_ops = {2881static const struct v4l2_m2m_ops allegro_m2m_ops = {
drivers/staging/media/allegro-dvt/allegro-mail.c+37−0
@@ -0,0 +1,37 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de>
4 *
5 * Helper functions for handling messages that are send via mailbox to the
6 * Allegro VCU firmware.
7 */
8
9#include <linux/export.h>
10
11#include "allegro-mail.h"
12
13const char *msg_type_name(enum mcu_msg_type type)
14{
15 static char buf[9];
16
17 switch (type) {
18 case MCU_MSG_TYPE_INIT:
19 return "INIT";
20 case MCU_MSG_TYPE_CREATE_CHANNEL:
21 return "CREATE_CHANNEL";
22 case MCU_MSG_TYPE_DESTROY_CHANNEL:
23 return "DESTROY_CHANNEL";
24 case MCU_MSG_TYPE_ENCODE_FRAME:
25 return "ENCODE_FRAME";
26 case MCU_MSG_TYPE_PUT_STREAM_BUFFER:
27 return "PUT_STREAM_BUFFER";
28 case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE:
29 return "PUSH_BUFFER_INTERMEDIATE";
30 case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE:
31 return "PUSH_BUFFER_REFERENCE";
32 default:
33 snprintf(buf, sizeof(buf), "(0x%04x)", type);
34 return buf;
35 }
36}
37EXPORT_SYMBOL(msg_type_name);
drivers/staging/media/allegro-dvt/allegro-mail.h+267−0
@@ -0,0 +1,267 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de>
4 *
5 * Allegro VCU firmware mailbox mail definitions
6 */
7
8#ifndef ALLEGRO_MAIL_H
9#define ALLEGRO_MAIL_H
10
11#include <linux/kernel.h>
12
13enum mcu_msg_type {
14 MCU_MSG_TYPE_INIT = 0x0000,
15 MCU_MSG_TYPE_CREATE_CHANNEL = 0x0005,
16 MCU_MSG_TYPE_DESTROY_CHANNEL = 0x0006,
17 MCU_MSG_TYPE_ENCODE_FRAME = 0x0007,
18 MCU_MSG_TYPE_PUT_STREAM_BUFFER = 0x0012,
19 MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE = 0x000e,
20 MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE = 0x000f,
21};
22
23const char *msg_type_name(enum mcu_msg_type type);
24
25struct mcu_msg_header {
26 u16 length; /* length of the body in bytes */
27 u16 type;
28} __attribute__ ((__packed__));
29
30struct mcu_msg_init_request {
31 struct mcu_msg_header header;
32 u32 reserved0; /* maybe a unused channel id */
33 u32 suballoc_dma;
34 u32 suballoc_size;
35 s32 l2_cache[3];
36} __attribute__ ((__packed__));
37
38struct mcu_msg_init_response {
39 struct mcu_msg_header header;
40 u32 reserved0;
41} __attribute__ ((__packed__));
42
43struct create_channel_param {
44 u16 width;
45 u16 height;
46 u32 format;
47 u32 colorspace;
48 u32 src_mode;
49 u8 profile;
50 u16 constraint_set_flags;
51 s8 codec;
52 u16 level;
53 u16 tier;
54 u32 sps_param;
55 u32 pps_param;
56
57 u32 enc_option;
58#define AL_OPT_WPP BIT(0)
59#define AL_OPT_TILE BIT(1)
60#define AL_OPT_LF BIT(2)
61#define AL_OPT_LF_X_SLICE BIT(3)
62#define AL_OPT_LF_X_TILE BIT(4)
63#define AL_OPT_SCL_LST BIT(5)
64#define AL_OPT_CONST_INTRA_PRED BIT(6)
65#define AL_OPT_QP_TAB_RELATIVE BIT(7)
66#define AL_OPT_FIX_PREDICTOR BIT(8)
67#define AL_OPT_CUSTOM_LDA BIT(9)
68#define AL_OPT_ENABLE_AUTO_QP BIT(10)
69#define AL_OPT_ADAPT_AUTO_QP BIT(11)
70#define AL_OPT_TRANSFO_SKIP BIT(13)
71#define AL_OPT_FORCE_REC BIT(15)
72#define AL_OPT_FORCE_MV_OUT BIT(16)
73#define AL_OPT_FORCE_MV_CLIP BIT(17)
74#define AL_OPT_LOWLAT_SYNC BIT(18)
75#define AL_OPT_LOWLAT_INT BIT(19)
76#define AL_OPT_RDO_COST_MODE BIT(20)
77
78 s8 beta_offset;
79 s8 tc_offset;
80 u16 reserved10;
81 u32 unknown11;
82 u32 unknown12;
83 u16 num_slices;
84 u16 prefetch_auto;
85 u32 prefetch_mem_offset;
86 u32 prefetch_mem_size;
87 u16 clip_hrz_range;
88 u16 clip_vrt_range;
89 u16 me_range[4];
90 u8 max_cu_size;
91 u8 min_cu_size;
92 u8 max_tu_size;
93 u8 min_tu_size;
94 u8 max_transfo_depth_inter;
95 u8 max_transfo_depth_intra;
96 u16 reserved20;
97 u32 entropy_mode;
98 u32 wp_mode;
99
100 /* rate control param */
101 u32 rate_control_mode;
102 u32 initial_rem_delay;
103 u32 cpb_size;
104 u16 framerate;
105 u16 clk_ratio;
106 u32 target_bitrate;
107 u32 max_bitrate;
108 u16 initial_qp;
109 u16 min_qp;
110 u16 max_qp;
111 s16 ip_delta;
112 s16 pb_delta;
113 u16 golden_ref;
114 u16 golden_delta;
115 u16 golden_ref_frequency;
116 u32 rate_control_option;
117
118 /* gop param */
119 u32 gop_ctrl_mode;
120 u32 freq_idr;
121 u32 freq_lt;
122 u32 gdr_mode;
123 u16 gop_length;
124 u8 num_b;
125 u8 freq_golden_ref;
126
127 u32 subframe_latency;
128 u32 lda_control_mode;
129 u32 unknown41;
130} __attribute__ ((__packed__));
131
132struct mcu_msg_create_channel {
133 struct mcu_msg_header header;
134 u32 user_id;
135 struct create_channel_param param;
136} __attribute__ ((__packed__));
137
138struct mcu_msg_create_channel_response {
139 struct mcu_msg_header header;
140 u32 channel_id;
141 u32 user_id;
142 u32 options;
143 u32 num_core;
144 u32 pps_param;
145 u32 int_buffers_count;
146 u32 int_buffers_size;
147 u32 rec_buffers_count;
148 u32 rec_buffers_size;
149 u32 reserved;
150 u32 error_code;
151} __attribute__ ((__packed__));
152
153struct mcu_msg_destroy_channel {
154 struct mcu_msg_header header;
155 u32 channel_id;
156} __attribute__ ((__packed__));
157
158struct mcu_msg_destroy_channel_response {
159 struct mcu_msg_header header;
160 u32 channel_id;
161} __attribute__ ((__packed__));
162
163struct mcu_msg_push_buffers_internal_buffer {
164 u32 dma_addr;
165 u32 mcu_addr;
166 u32 size;
167} __attribute__ ((__packed__));
168
169struct mcu_msg_push_buffers_internal {
170 struct mcu_msg_header header;
171 u32 channel_id;
172 struct mcu_msg_push_buffers_internal_buffer buffer[0];
173} __attribute__ ((__packed__));
174
175struct mcu_msg_put_stream_buffer {
176 struct mcu_msg_header header;
177 u32 channel_id;
178 u32 dma_addr;
179 u32 mcu_addr;
180 u32 size;
181 u32 offset;
182 u64 stream_id;
183} __attribute__ ((__packed__));
184
185struct mcu_msg_encode_frame {
186 struct mcu_msg_header header;
187 u32 channel_id;
188 u32 reserved;
189
190 u32 encoding_options;
191#define AL_OPT_USE_QP_TABLE BIT(0)
192#define AL_OPT_FORCE_LOAD BIT(1)
193#define AL_OPT_USE_L2 BIT(2)
194#define AL_OPT_DISABLE_INTRA BIT(3)
195#define AL_OPT_DEPENDENT_SLICES BIT(4)
196
197 s16 pps_qp;
198 u16 padding;
199 u64 user_param;
200 u64 src_handle;
201
202 u32 request_options;
203#define AL_OPT_SCENE_CHANGE BIT(0)
204#define AL_OPT_RESTART_GOP BIT(1)
205#define AL_OPT_USE_LONG_TERM BIT(2)
206#define AL_OPT_UPDATE_PARAMS BIT(3)
207
208 /* u32 scene_change_delay (optional) */
209 /* rate control param (optional) */
210 /* gop param (optional) */
211 u32 src_y;
212 u32 src_uv;
213 u32 stride;
214 u32 ep2;
215 u64 ep2_v;
216} __attribute__ ((__packed__));
217
218struct mcu_msg_encode_frame_response {
219 struct mcu_msg_header header;
220 u32 channel_id;
221 u64 stream_id; /* see mcu_msg_put_stream_buffer */
222 u64 user_param; /* see mcu_msg_encode_frame */
223 u64 src_handle; /* see mcu_msg_encode_frame */
224 u16 skip;
225 u16 is_ref;
226 u32 initial_removal_delay;
227 u32 dpb_output_delay;
228 u32 size;
229 u32 frame_tag_size;
230 s32 stuffing;
231 s32 filler;
232 u16 num_column;
233 u16 num_row;
234 u16 qp;
235 u8 num_ref_idx_l0;
236 u8 num_ref_idx_l1;
237 u32 partition_table_offset;
238 s32 partition_table_size;
239 u32 sum_complex;
240 s32 tile_width[4];
241 s32 tile_height[22];
242 u32 error_code;
243
244 u32 slice_type;
245#define AL_ENC_SLICE_TYPE_B 0
246#define AL_ENC_SLICE_TYPE_P 1
247#define AL_ENC_SLICE_TYPE_I 2
248
249 u32 pic_struct;
250 u8 is_idr;
251 u8 is_first_slice;
252 u8 is_last_slice;
253 u8 reserved;
254 u16 pps_qp;
255 u16 reserved1;
256 u32 reserved2;
257} __attribute__ ((__packed__));
258
259union mcu_msg_response {
260 struct mcu_msg_header header;
261 struct mcu_msg_init_response init;
262 struct mcu_msg_create_channel_response create_channel;
263 struct mcu_msg_destroy_channel_response destroy_channel;
264 struct mcu_msg_encode_frame_response encode_frame;
265};
266
267#endif
drivers/staging/media/hantro/Kconfig+12−4
@@ -1,19 +1,27 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2config VIDEO_HANTRO2config VIDEO_HANTRO
3 tristate "Hantro VPU driver"3 tristate "Hantro VPU driver"
4 depends on ARCH_ROCKCHIP || COMPILE_TEST4 depends on ARCH_MXC || ARCH_ROCKCHIP || COMPILE_TEST
5 depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER5 depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER
6 depends on MEDIA_CONTROLLER_REQUEST_API6 depends on MEDIA_CONTROLLER_REQUEST_API
7 select VIDEOBUF2_DMA_CONTIG7 select VIDEOBUF2_DMA_CONTIG
8 select VIDEOBUF2_VMALLOC8 select VIDEOBUF2_VMALLOC
9 select V4L2_MEM2MEM_DEV9 select V4L2_MEM2MEM_DEV
10 help10 help
11 Support for the Hantro IP based Video Processing Unit present on11 Support for the Hantro IP based Video Processing Units present on
12 Rockchip SoC, which accelerates video and image encoding and12 Rockchip and NXP i.MX8M SoCs, which accelerate video and image
13 decoding.13 encoding and decoding.
14 To compile this driver as a module, choose M here: the module14 To compile this driver as a module, choose M here: the module
15 will be called hantro-vpu.15 will be called hantro-vpu.
16 16
17config VIDEO_HANTRO_IMX8M
18 bool "Hantro VPU i.MX8M support"
19 depends on VIDEO_HANTRO
20 depends on ARCH_MXC || COMPILE_TEST
21 default y
22 help
23 Enable support for i.MX8M SoCs.
24
17config VIDEO_HANTRO_ROCKCHIP25config VIDEO_HANTRO_ROCKCHIP
18 bool "Hantro VPU Rockchip support"26 bool "Hantro VPU Rockchip support"
19 depends on VIDEO_HANTRO27 depends on VIDEO_HANTRO
drivers/staging/media/hantro/Makefile+3−0
@@ -16,6 +16,9 @@ hantro-vpu-y += \ · 15 unmodified lines
16 hantro_mpeg2.o \16 hantro_mpeg2.o \
17 hantro_vp8.o17 hantro_vp8.o
18 18
19hantro-vpu-$(CONFIG_VIDEO_HANTRO_IMX8M) += \
20 imx8m_vpu_hw.o
21
19hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \22hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \
20 rk3288_vpu_hw.o \23 rk3288_vpu_hw.o \
21 rk3399_vpu_hw.o24 rk3399_vpu_hw.o
drivers/staging/media/hantro/hantro.h+1−1
@@ -423,7 +423,7 @@ hantro_get_dst_buf(struct hantro_ctx *ctx) · 422 unmodified lines
423static inline bool423static inline bool
424hantro_needs_postproc(struct hantro_ctx *ctx, const struct hantro_fmt *fmt)424hantro_needs_postproc(struct hantro_ctx *ctx, const struct hantro_fmt *fmt)
425{425{
426 return fmt->fourcc != V4L2_PIX_FMT_NV12;426 return !hantro_is_encoder_ctx(ctx) && fmt->fourcc != V4L2_PIX_FMT_NV12;
427}427}
428 428
429static inline dma_addr_t429static inline dma_addr_t
drivers/staging/media/hantro/hantro_drv.c+14−1
@@ -361,6 +361,16 @@ static const struct hantro_ctrl controls[] = { · 360 unmodified lines
361 .def = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,361 .def = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
362 .max = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,362 .max = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
363 },363 },
364 }, {
365 .codec = HANTRO_H264_DECODER,
366 .cfg = {
367 .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
368 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
369 .max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
370 .menu_skip_mask =
371 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
372 .def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
373 }
364 }, {374 }, {
365 },375 },
366};376};
@@ -488,6 +498,9 @@ static const struct of_device_id of_hantro_match[] = { · 121 unmodified lines
488 { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },498 { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
489 { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, },499 { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, },
490 { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, },500 { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, },
501#endif
502#ifdef CONFIG_VIDEO_HANTRO_IMX8M
503 { .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },
491#endif504#endif
492 { /* sentinel */ }505 { /* sentinel */ }
493};506};
@@ -664,7 +677,7 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid) · 170 unmodified lines
664 677
665 video_set_drvdata(vfd, vpu);678 video_set_drvdata(vfd, vpu);
666 679
667 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);680 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
668 if (ret) {681 if (ret) {
669 v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n");682 v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n");
670 return ret;683 return ret;
drivers/staging/media/hantro/hantro_h1_jpeg_enc.c+15−4
@@ -67,12 +67,23 @@ hantro_h1_jpeg_enc_set_qtable(struct hantro_dev *vpu, · 66 unmodified lines
67 unsigned char *chroma_qtable)67 unsigned char *chroma_qtable)
68{68{
69 u32 reg, i;69 u32 reg, i;
70 __be32 *luma_qtable_p;
71 __be32 *chroma_qtable_p;
70 72
73 luma_qtable_p = (__be32 *)luma_qtable;
74 chroma_qtable_p = (__be32 *)chroma_qtable;
75
76 /*
77 * Quantization table registers must be written in contiguous blocks.
78 * DO NOT collapse the below two "for" loops into one.
79 */
71 for (i = 0; i < H1_JPEG_QUANT_TABLE_COUNT; i++) {80 for (i = 0; i < H1_JPEG_QUANT_TABLE_COUNT; i++) {
72 reg = get_unaligned_be32(&luma_qtable[i]);81 reg = get_unaligned_be32(&luma_qtable_p[i]);
73 vepu_write_relaxed(vpu, reg, H1_REG_JPEG_LUMA_QUAT(i));82 vepu_write_relaxed(vpu, reg, H1_REG_JPEG_LUMA_QUAT(i));
83 }
74 84
75 reg = get_unaligned_be32(&chroma_qtable[i]);85 for (i = 0; i < H1_JPEG_QUANT_TABLE_COUNT; i++) {
86 reg = get_unaligned_be32(&chroma_qtable_p[i]);
76 vepu_write_relaxed(vpu, reg, H1_REG_JPEG_CHROMA_QUAT(i));87 vepu_write_relaxed(vpu, reg, H1_REG_JPEG_CHROMA_QUAT(i));
77 }88 }
78}89}
@@ -103,8 +114,8 @@ void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx) · 24 unmodified lines
103 hantro_h1_set_src_img_ctrl(vpu, ctx);114 hantro_h1_set_src_img_ctrl(vpu, ctx);
104 hantro_h1_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf);115 hantro_h1_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf);
105 hantro_h1_jpeg_enc_set_qtable(vpu,116 hantro_h1_jpeg_enc_set_qtable(vpu,
106 hantro_jpeg_get_qtable(&jpeg_ctx, 0),117 hantro_jpeg_get_qtable(0),
107 hantro_jpeg_get_qtable(&jpeg_ctx, 1));118 hantro_jpeg_get_qtable(1));
108 119
109 reg = H1_REG_AXI_CTRL_OUTPUT_SWAP16120 reg = H1_REG_AXI_CTRL_OUTPUT_SWAP16
110 | H1_REG_AXI_CTRL_INPUT_SWAP16121 | H1_REG_AXI_CTRL_INPUT_SWAP16
drivers/staging/media/hantro/hantro_hw.h+1−0
@@ -151,6 +151,7 @@ enum hantro_enc_fmt { · 150 unmodified lines
151extern const struct hantro_variant rk3399_vpu_variant;151extern const struct hantro_variant rk3399_vpu_variant;
152extern const struct hantro_variant rk3328_vpu_variant;152extern const struct hantro_variant rk3328_vpu_variant;
153extern const struct hantro_variant rk3288_vpu_variant;153extern const struct hantro_variant rk3288_vpu_variant;
154extern const struct hantro_variant imx8mq_vpu_variant;
154 155
155extern const struct hantro_postproc_regs hantro_g1_postproc_regs;156extern const struct hantro_postproc_regs hantro_g1_postproc_regs;
156 157
drivers/staging/media/hantro/hantro_jpeg.c+56−20
@@ -23,19 +23,21 @@ · 22 unmodified lines
23#define HUFF_CHROMA_AC_OFF 40923#define HUFF_CHROMA_AC_OFF 409
24 24
25/* Default tables from JPEG ITU-T.8125/* Default tables from JPEG ITU-T.81
26 * (ISO/IEC 10918-1) Annex K.3, I26 * (ISO/IEC 10918-1) Annex K, tables K.1 and K.2
27 */27 */
28static const unsigned char luma_q_table[] = {28static const unsigned char luma_q_table[] = {
29 0x10, 0x0b, 0x0a, 0x10, 0x7c, 0x8c, 0x97, 0xa1,29 0x10, 0x0b, 0x0a, 0x10, 0x18, 0x28, 0x33, 0x3d,
30 0x0c, 0x0c, 0x0e, 0x13, 0x7e, 0x9e, 0xa0, 0x9b,30 0x0c, 0x0c, 0x0e, 0x13, 0x1a, 0x3a, 0x3c, 0x37,
31 0x0e, 0x0d, 0x10, 0x18, 0x8c, 0x9d, 0xa9, 0x9c,31 0x0e, 0x0d, 0x10, 0x18, 0x28, 0x39, 0x45, 0x38,
32 0x0e, 0x11, 0x16, 0x1d, 0x97, 0xbb, 0xb4, 0xa2,32 0x0e, 0x11, 0x16, 0x1d, 0x33, 0x57, 0x50, 0x3e,
33 0x12, 0x16, 0x25, 0x38, 0xa8, 0x6d, 0x67, 0xb1,33 0x12, 0x16, 0x25, 0x38, 0x44, 0x6d, 0x67, 0x4d,
34 0x18, 0x23, 0x37, 0x40, 0xb5, 0x68, 0x71, 0xc0,34 0x18, 0x23, 0x37, 0x40, 0x51, 0x68, 0x71, 0x5c,
35 0x31, 0x40, 0x4e, 0x57, 0x67, 0x79, 0x78, 0x65,35 0x31, 0x40, 0x4e, 0x57, 0x67, 0x79, 0x78, 0x65,
36 0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0xc7,36 0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0x63
37};37};
38 38
39static unsigned char luma_q_table_reordered[ARRAY_SIZE(luma_q_table)];
40
39static const unsigned char chroma_q_table[] = {41static const unsigned char chroma_q_table[] = {
40 0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63,42 0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63,
41 0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63,43 0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63,
@@ -47,6 +49,30 @@ static const unsigned char chroma_q_table[] = { · 5 unmodified lines
47 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x6349 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
48};50};
49 51
52static unsigned char chroma_q_table_reordered[ARRAY_SIZE(chroma_q_table)];
53
54static const unsigned char zigzag[64] = {
55 0, 1, 8, 16, 9, 2, 3, 10,
56 17, 24, 32, 25, 18, 11, 4, 5,
57 12, 19, 26, 33, 40, 48, 41, 34,
58 27, 20, 13, 6, 7, 14, 21, 28,
59 35, 42, 49, 56, 57, 50, 43, 36,
60 29, 22, 15, 23, 30, 37, 44, 51,
61 58, 59, 52, 45, 38, 31, 39, 46,
62 53, 60, 61, 54, 47, 55, 62, 63
63};
64
65static const u32 hw_reorder[64] = {
66 0, 8, 16, 24, 1, 9, 17, 25,
67 32, 40, 48, 56, 33, 41, 49, 57,
68 2, 10, 18, 26, 3, 11, 19, 27,
69 34, 42, 50, 58, 35, 43, 51, 59,
70 4, 12, 20, 28, 5, 13, 21, 29,
71 36, 44, 52, 60, 37, 45, 53, 61,
72 6, 14, 22, 30, 7, 15, 23, 31,
73 38, 46, 54, 62, 39, 47, 55, 63
74};
75
50/* Huffman tables are shared with CODA */76/* Huffman tables are shared with CODA */
51static const unsigned char luma_dc_table[] = {77static const unsigned char luma_dc_table[] = {
52 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,78 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
@@ -225,20 +251,29 @@ static const unsigned char hantro_jpeg_header[JPEG_HEADER_SIZE] = { · 172 unmodified lines
225 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,251 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
226};252};
227 253
254static unsigned char jpeg_scale_qp(const unsigned char qp, int scale)
255{
256 unsigned int temp;
257
258 temp = DIV_ROUND_CLOSEST((unsigned int)qp * scale, 100);
259 if (temp <= 0)
260 temp = 1;
261 if (temp > 255)
262 temp = 255;
263
264 return (unsigned char)temp;
265}
266
228static void267static void
229jpeg_scale_quant_table(unsigned char *q_tab,268jpeg_scale_quant_table(unsigned char *file_q_tab,
269 unsigned char *reordered_q_tab,
230 const unsigned char *tab, int scale)270 const unsigned char *tab, int scale)
231{271{
232 unsigned int temp;
233 int i;272 int i;
234 273
235 for (i = 0; i < 64; i++) {274 for (i = 0; i < 64; i++) {
236 temp = DIV_ROUND_CLOSEST((unsigned int)tab[i] * scale, 100);275 file_q_tab[i] = jpeg_scale_qp(tab[zigzag[i]], scale);
237 if (temp <= 0)276 reordered_q_tab[i] = jpeg_scale_qp(tab[hw_reorder[i]], scale);
238 temp = 1;
239 if (temp > 255)
240 temp = 255;
241 q_tab[i] = (unsigned char)temp;
242 }277 }
243}278}
244 279
@@ -256,17 +291,18 @@ static void jpeg_set_quality(unsigned char *buffer, int quality) · 11 unmodified lines
256 scale = 200 - 2 * quality;291 scale = 200 - 2 * quality;
257 292
258 jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF,293 jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF,
294 luma_q_table_reordered,
259 luma_q_table, scale);295 luma_q_table, scale);
260 jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF,296 jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF,
297 chroma_q_table_reordered,
261 chroma_q_table, scale);298 chroma_q_table, scale);
262}299}
263 300
264unsigned char *301unsigned char *hantro_jpeg_get_qtable(int index)
265hantro_jpeg_get_qtable(struct hantro_jpeg_ctx *ctx, int index)
266{302{
267 if (index == 0)303 if (index == 0)
268 return ctx->buffer + LUMA_QUANT_OFF;304 return luma_q_table_reordered;
269 return ctx->buffer + CHROMA_QUANT_OFF;305 return chroma_q_table_reordered;
270}306}
271 307
272void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)308void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)
drivers/staging/media/hantro/hantro_jpeg.h+1−1
@@ -9,5 +9,5 @@ struct hantro_jpeg_ctx { · 8 unmodified lines
9 unsigned char *buffer;9 unsigned char *buffer;
10};10};
11 11
12unsigned char *hantro_jpeg_get_qtable(struct hantro_jpeg_ctx *ctx, int index);12unsigned char *hantro_jpeg_get_qtable(int index);
13void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx);13void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx);
drivers/staging/media/hantro/hantro_v4l2.c+1−1
@@ -295,7 +295,7 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f, · 294 unmodified lines
295 * +---------------------------+295 * +---------------------------+
296 */296 */
297 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE &&297 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE &&
298 !hantro_needs_postproc(ctx, ctx->vpu_dst_fmt))298 !hantro_needs_postproc(ctx, fmt))
299 pix_mp->plane_fmt[0].sizeimage +=299 pix_mp->plane_fmt[0].sizeimage +=
300 64 * MB_WIDTH(pix_mp->width) *300 64 * MB_WIDTH(pix_mp->width) *
301 MB_WIDTH(pix_mp->height) + 32;301 MB_WIDTH(pix_mp->height) + 32;
drivers/staging/media/hantro/imx8m_vpu_hw.c+220−0
@@ -0,0 +1,220 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Hantro VPU codec driver
4 *
5 * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
6 */
7
8#include <linux/clk.h>
9#include <linux/delay.h>
10
11#include "hantro.h"
12#include "hantro_jpeg.h"
13#include "hantro_g1_regs.h"
14
15#define CTRL_SOFT_RESET 0x00
16#define RESET_G1 BIT(1)
17#define RESET_G2 BIT(0)
18
19#define CTRL_CLOCK_ENABLE 0x04
20#define CLOCK_G1 BIT(1)
21#define CLOCK_G2 BIT(0)
22
23#define CTRL_G1_DEC_FUSE 0x08
24#define CTRL_G1_PP_FUSE 0x0c
25#define CTRL_G2_DEC_FUSE 0x10
26
27static void imx8m_soft_reset(struct hantro_dev *vpu, u32 reset_bits)
28{
29 u32 val;
30
31 /* Assert */
32 val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
33 val &= ~reset_bits;
34 writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
35
36 udelay(2);
37
38 /* Release */
39 val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);
40 val |= reset_bits;
41 writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);
42}
43
44static void imx8m_clk_enable(struct hantro_dev *vpu, u32 clock_bits)
45{
46 u32 val;
47
48 val = readl(vpu->ctrl_base + CTRL_CLOCK_ENABLE);
49 val |= clock_bits;
50 writel(val, vpu->ctrl_base + CTRL_CLOCK_ENABLE);
51}
52
53static int imx8mq_runtime_resume(struct hantro_dev *vpu)
54{
55 int ret;
56
57 ret = clk_bulk_prepare_enable(vpu->variant->num_clocks, vpu->clocks);
58 if (ret) {
59 dev_err(vpu->dev, "Failed to enable clocks\n");
60 return ret;
61 }
62
63 imx8m_soft_reset(vpu, RESET_G1 | RESET_G2);
64 imx8m_clk_enable(vpu, CLOCK_G1 | CLOCK_G2);
65
66 /* Set values of the fuse registers */
67 writel(0xffffffff, vpu->ctrl_base + CTRL_G1_DEC_FUSE);
68 writel(0xffffffff, vpu->ctrl_base + CTRL_G1_PP_FUSE);
69 writel(0xffffffff, vpu->ctrl_base + CTRL_G2_DEC_FUSE);
70
71 clk_bulk_disable_unprepare(vpu->variant->num_clocks, vpu->clocks);
72
73 return 0;
74}
75
76/*
77 * Supported formats.
78 */
79
80static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {
81 {
82 .fourcc = V4L2_PIX_FMT_YUYV,
83 .codec_mode = HANTRO_MODE_NONE,
84 },
85};
86
87static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
88 {
89 .fourcc = V4L2_PIX_FMT_NV12,
90 .codec_mode = HANTRO_MODE_NONE,
91 },
92 {
93 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
94 .codec_mode = HANTRO_MODE_MPEG2_DEC,
95 .max_depth = 2,
96 .frmsize = {
97 .min_width = 48,
98 .max_width = 1920,
99 .step_width = MB_DIM,
100 .min_height = 48,
101 .max_height = 1088,
102 .step_height = MB_DIM,
103 },
104 },
105 {
106 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
107 .codec_mode = HANTRO_MODE_VP8_DEC,
108 .max_depth = 2,
109 .frmsize = {
110 .min_width = 48,
111 .max_width = 3840,
112 .step_width = 16,
113 .min_height = 48,
114 .max_height = 2160,
115 .step_height = 16,
116 },
117 },
118 {
119 .fourcc = V4L2_PIX_FMT_H264_SLICE,
120 .codec_mode = HANTRO_MODE_H264_DEC,
121 .max_depth = 2,
122 .frmsize = {
123 .min_width = 48,
124 .max_width = 3840,
125 .step_width = MB_DIM,
126 .min_height = 48,
127 .max_height = 2160,
128 .step_height = MB_DIM,
129 },
130 },
131};
132
133static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
134{
135 struct hantro_dev *vpu = dev_id;
136 enum vb2_buffer_state state;
137 u32 status;
138
139 status = vdpu_read(vpu, G1_REG_INTERRUPT);
140 state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?
141 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
142
143 vdpu_write(vpu, 0, G1_REG_INTERRUPT);
144 vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
145
146 hantro_irq_done(vpu, 0, state);
147
148 return IRQ_HANDLED;
149}
150
151static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)
152{
153 vpu->dec_base = vpu->reg_bases[0];
154 vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];
155
156 return 0;
157}
158
159static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
160{
161 struct hantro_dev *vpu = ctx->dev;
162
163 imx8m_soft_reset(vpu, RESET_G1);
164}
165
166/*
167 * Supported codec ops.
168 */
169
170static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {
171 [HANTRO_MODE_MPEG2_DEC] = {
172 .run = hantro_g1_mpeg2_dec_run,
173 .reset = imx8m_vpu_g1_reset,
174 .init = hantro_mpeg2_dec_init,
175 .exit = hantro_mpeg2_dec_exit,
176 },
177 [HANTRO_MODE_VP8_DEC] = {
178 .run = hantro_g1_vp8_dec_run,
179 .reset = imx8m_vpu_g1_reset,
180 .init = hantro_vp8_dec_init,
181 .exit = hantro_vp8_dec_exit,
182 },
183 [HANTRO_MODE_H264_DEC] = {
184 .run = hantro_g1_h264_dec_run,
185 .reset = imx8m_vpu_g1_reset,
186 .init = hantro_h264_dec_init,
187 .exit = hantro_h264_dec_exit,
188 },
189};
190
191/*
192 * VPU variants.
193 */
194
195static const struct hantro_irq imx8mq_irqs[] = {
196 { "g1", imx8m_vpu_g1_irq },
197 { "g2", NULL /* TODO: imx8m_vpu_g2_irq */ },
198};
199
200static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };
201static const char * const imx8mq_reg_names[] = { "g1", "g2", "ctrl" };
202
203const struct hantro_variant imx8mq_vpu_variant = {
204 .dec_fmts = imx8m_vpu_dec_fmts,
205 .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
206 .postproc_fmts = imx8m_vpu_postproc_fmts,
207 .num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
208 .postproc_regs = &hantro_g1_postproc_regs,
209 .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
210 HANTRO_H264_DECODER,
211 .codec_ops = imx8mq_vpu_codec_ops,
212 .init = imx8mq_vpu_hw_init,
213 .runtime_resume = imx8mq_runtime_resume,
214 .irqs = imx8mq_irqs,
215 .num_irqs = ARRAY_SIZE(imx8mq_irqs),
216 .clk_names = imx8mq_clk_names,
217 .num_clocks = ARRAY_SIZE(imx8mq_clk_names),
218 .reg_names = imx8mq_reg_names,
219 .num_regs = ARRAY_SIZE(imx8mq_reg_names)
220};
drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c+17−7
@@ -18,9 +18,8 @@ · 17 unmodified lines
18 *18 *
19 * Quantization luma table values are written to registers19 * Quantization luma table values are written to registers
20 * VEPU_swreg_0-VEPU_swreg_15, and chroma table values to20 * VEPU_swreg_0-VEPU_swreg_15, and chroma table values to
21 * VEPU_swreg_16-VEPU_swreg_31.21 * VEPU_swreg_16-VEPU_swreg_31. A special order is needed, neither
22 *22 * zigzag, nor linear.
23 * JPEG zigzag order is expected on the quantization tables.
24 */23 */
25 24
26#include <asm/unaligned.h>25#include <asm/unaligned.h>
@@ -98,12 +97,23 @@ rk3399_vpu_jpeg_enc_set_qtable(struct hantro_dev *vpu, · 71 unmodified lines
98 unsigned char *chroma_qtable)97 unsigned char *chroma_qtable)
99{98{
100 u32 reg, i;99 u32 reg, i;
100 __be32 *luma_qtable_p;
101 __be32 *chroma_qtable_p;
102
103 luma_qtable_p = (__be32 *)luma_qtable;
104 chroma_qtable_p = (__be32 *)chroma_qtable;
101 105
106 /*
107 * Quantization table registers must be written in contiguous blocks.
108 * DO NOT collapse the below two "for" loops into one.
109 */
102 for (i = 0; i < VEPU_JPEG_QUANT_TABLE_COUNT; i++) {110 for (i = 0; i < VEPU_JPEG_QUANT_TABLE_COUNT; i++) {
103 reg = get_unaligned_be32(&luma_qtable[i]);111 reg = get_unaligned_be32(&luma_qtable_p[i]);
104 vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_LUMA_QUAT(i));112 vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_LUMA_QUAT(i));
113 }
105 114
106 reg = get_unaligned_be32(&chroma_qtable[i]);115 for (i = 0; i < VEPU_JPEG_QUANT_TABLE_COUNT; i++) {
116 reg = get_unaligned_be32(&chroma_qtable_p[i]);
107 vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_CHROMA_QUAT(i));117 vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_CHROMA_QUAT(i));
108 }118 }
109}119}
@@ -134,8 +144,8 @@ void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx) · 24 unmodified lines
134 rk3399_vpu_set_src_img_ctrl(vpu, ctx);144 rk3399_vpu_set_src_img_ctrl(vpu, ctx);
135 rk3399_vpu_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf);145 rk3399_vpu_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf);
136 rk3399_vpu_jpeg_enc_set_qtable(vpu,146 rk3399_vpu_jpeg_enc_set_qtable(vpu,
137 hantro_jpeg_get_qtable(&jpeg_ctx, 0),147 hantro_jpeg_get_qtable(0),
138 hantro_jpeg_get_qtable(&jpeg_ctx, 1));148 hantro_jpeg_get_qtable(1));
139 149
140 reg = VEPU_REG_OUTPUT_SWAP32150 reg = VEPU_REG_OUTPUT_SWAP32
141 | VEPU_REG_OUTPUT_SWAP16151 | VEPU_REG_OUTPUT_SWAP16
drivers/staging/media/imx/imx-media-capture.c+4−4
@@ -643,7 +643,7 @@ static int capture_open(struct file *file) · 642 unmodified lines
643 if (ret)643 if (ret)
644 v4l2_err(priv->src_sd, "v4l2_fh_open failed\n");644 v4l2_err(priv->src_sd, "v4l2_fh_open failed\n");
645 645
646 ret = v4l2_pipeline_pm_use(&vfd->entity, 1);646 ret = v4l2_pipeline_pm_get(&vfd->entity);
647 if (ret)647 if (ret)
648 v4l2_fh_release(file);648 v4l2_fh_release(file);
649 649
@@ -664,7 +664,7 @@ static int capture_release(struct file *file) · 14 unmodified lines
664 vq->owner = NULL;664 vq->owner = NULL;
665 }665 }
666 666
667 v4l2_pipeline_pm_use(&vfd->entity, 0);667 v4l2_pipeline_pm_put(&vfd->entity);
668 668
669 v4l2_fh_release(file);669 v4l2_fh_release(file);
670 mutex_unlock(&priv->mutex);670 mutex_unlock(&priv->mutex);
@@ -742,7 +742,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev) · 71 unmodified lines
742 742
743 vfd->v4l2_dev = v4l2_dev;743 vfd->v4l2_dev = v4l2_dev;
744 744
745 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);745 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
746 if (ret) {746 if (ret) {
747 v4l2_err(sd, "Failed to register video device\n");747 v4l2_err(sd, "Failed to register video device\n");
748 return ret;748 return ret;
@@ -778,7 +778,7 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev) · 29 unmodified lines
778 /* setup default format */778 /* setup default format */
779 fmt_src.pad = priv->src_sd_pad;779 fmt_src.pad = priv->src_sd_pad;
780 fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;780 fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
781 v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt_src);781 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt_src);
782 if (ret) {782 if (ret) {
783 v4l2_err(sd, "failed to get src_sd format\n");783 v4l2_err(sd, "failed to get src_sd format\n");
784 goto unreg;784 goto unreg;
drivers/staging/media/imx/imx-media-csc-scaler.c+1−1
@@ -849,7 +849,7 @@ int imx_media_csc_scaler_device_register(struct imx_media_video_dev *vdev) · 848 unmodified lines
849 849
850 vfd->v4l2_dev = &priv->md->v4l2_dev;850 vfd->v4l2_dev = &priv->md->v4l2_dev;
851 851
852 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);852 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
853 if (ret) {853 if (ret) {
854 v4l2_err(vfd->v4l2_dev, "Failed to register video device\n");854 v4l2_err(vfd->v4l2_dev, "Failed to register video device\n");
855 return ret;855 return ret;
drivers/staging/media/imx/imx-media-csi.c+4−1
@@ -457,7 +457,8 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) · 456 unmodified lines
457 case V4L2_PIX_FMT_SGBRG16:457 case V4L2_PIX_FMT_SGBRG16:
458 case V4L2_PIX_FMT_SGRBG16:458 case V4L2_PIX_FMT_SGRBG16:
459 case V4L2_PIX_FMT_SRGGB16:459 case V4L2_PIX_FMT_SRGGB16:
460 case V4L2_PIX_FMT_Y16:460 case V4L2_PIX_FMT_Y10:
461 case V4L2_PIX_FMT_Y12:
461 burst_size = 8;462 burst_size = 8;
462 passthrough_bits = 16;463 passthrough_bits = 16;
463 break;464 break;
@@ -1459,6 +1460,8 @@ static void csi_try_fmt(struct csi_priv *priv, · 995 unmodified lines
1459 /* propagate colorimetry from sink */1460 /* propagate colorimetry from sink */
1460 sdformat->format.colorspace = infmt->colorspace;1461 sdformat->format.colorspace = infmt->colorspace;
1461 sdformat->format.xfer_func = infmt->xfer_func;1462 sdformat->format.xfer_func = infmt->xfer_func;
1463 sdformat->format.quantization = infmt->quantization;
1464 sdformat->format.ycbcr_enc = infmt->ycbcr_enc;
1462 1465
1463 break;1466 break;
1464 case CSI_SINK_PAD:1467 case CSI_SINK_PAD:
drivers/staging/media/imx/imx-media-utils.c+13−6
@@ -161,17 +161,24 @@ static const struct imx_media_pixfmt rgb_formats[] = { · 160 unmodified lines
161 .bayer = true,161 .bayer = true,
162 }, {162 }, {
163 .fourcc = V4L2_PIX_FMT_GREY,163 .fourcc = V4L2_PIX_FMT_GREY,
164 .codes = {MEDIA_BUS_FMT_Y8_1X8},
165 .cs = IPUV3_COLORSPACE_RGB,
166 .bpp = 8,
167 .bayer = true,
168 }, {
169 .fourcc = V4L2_PIX_FMT_Y16,
170 .codes = {164 .codes = {
165 MEDIA_BUS_FMT_Y8_1X8,
171 MEDIA_BUS_FMT_Y10_1X10,166 MEDIA_BUS_FMT_Y10_1X10,
172 MEDIA_BUS_FMT_Y12_1X12,167 MEDIA_BUS_FMT_Y12_1X12,
173 },168 },
174 .cs = IPUV3_COLORSPACE_RGB,169 .cs = IPUV3_COLORSPACE_RGB,
170 .bpp = 8,
171 .bayer = true,
172 }, {
173 .fourcc = V4L2_PIX_FMT_Y10,
174 .codes = {MEDIA_BUS_FMT_Y10_1X10},
175 .cs = IPUV3_COLORSPACE_RGB,
176 .bpp = 16,
177 .bayer = true,
178 }, {
179 .fourcc = V4L2_PIX_FMT_Y12,
180 .codes = {MEDIA_BUS_FMT_Y12_1X12},
181 .cs = IPUV3_COLORSPACE_RGB,
175 .bpp = 16,182 .bpp = 16,
176 .bayer = true,183 .bayer = true,
177 },184 },
drivers/staging/media/imx/imx7-media-csi.c+23−1
@@ -292,7 +292,7 @@ static void imx7_csi_hw_disable(struct imx7_csi *csi) · 291 unmodified lines
292 292
293static void imx7_csi_dma_reflash(struct imx7_csi *csi)293static void imx7_csi_dma_reflash(struct imx7_csi *csi)
294{294{
295 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR18);295 u32 cr3;
296 296
297 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);297 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
298 cr3 |= BIT_DMA_REFLASH_RFF;298 cr3 |= BIT_DMA_REFLASH_RFF;
@@ -804,6 +804,22 @@ static int imx7_csi_configure(struct imx7_csi *csi) · 505 unmodified lines
804 case V4L2_PIX_FMT_YUYV:804 case V4L2_PIX_FMT_YUYV:
805 cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B;805 cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B;
806 break;806 break;
807 case V4L2_PIX_FMT_GREY:
808 if (in_code == MEDIA_BUS_FMT_Y8_1X8)
809 cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
810 else if (in_code == MEDIA_BUS_FMT_Y10_1X10)
811 cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
812 else
813 cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
814 break;
815 case V4L2_PIX_FMT_Y10:
816 cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
817 cr1 |= BIT_PIXEL_BIT;
818 break;
819 case V4L2_PIX_FMT_Y12:
820 cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
821 cr1 |= BIT_PIXEL_BIT;
822 break;
807 case V4L2_PIX_FMT_SBGGR8:823 case V4L2_PIX_FMT_SBGGR8:
808 cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;824 cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
809 break;825 break;
@@ -1009,10 +1025,13 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi, · 199 unmodified lines
1009 sdformat->format.width = in_fmt->width;1025 sdformat->format.width = in_fmt->width;
1010 sdformat->format.height = in_fmt->height;1026 sdformat->format.height = in_fmt->height;
1011 sdformat->format.code = in_fmt->code;1027 sdformat->format.code = in_fmt->code;
1028 sdformat->format.field = in_fmt->field;
1012 *cc = in_cc;1029 *cc = in_cc;
1013 1030
1014 sdformat->format.colorspace = in_fmt->colorspace;1031 sdformat->format.colorspace = in_fmt->colorspace;
1015 sdformat->format.xfer_func = in_fmt->xfer_func;1032 sdformat->format.xfer_func = in_fmt->xfer_func;
1033 sdformat->format.quantization = in_fmt->quantization;
1034 sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc;
1016 break;1035 break;
1017 case IMX7_CSI_PAD_SINK:1036 case IMX7_CSI_PAD_SINK:
1018 *cc = imx_media_find_mbus_format(sdformat->format.code,1037 *cc = imx_media_find_mbus_format(sdformat->format.code,
@@ -1023,6 +1042,9 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi, · 4 unmodified lines
1023 false);1042 false);
1024 sdformat->format.code = (*cc)->codes[0];1043 sdformat->format.code = (*cc)->codes[0];
1025 }1044 }
1045
1046 if (sdformat->format.field != V4L2_FIELD_INTERLACED)
1047 sdformat->format.field = V4L2_FIELD_NONE;
1026 break;1048 break;
1027 default:1049 default:
1028 return -EINVAL;1050 return -EINVAL;
drivers/staging/media/imx/imx7-mipi-csis.c+15−1
@@ -280,6 +280,18 @@ static const struct csis_pix_format mipi_csis_formats[] = { · 279 unmodified lines
280 .code = MEDIA_BUS_FMT_YUYV8_2X8,280 .code = MEDIA_BUS_FMT_YUYV8_2X8,
281 .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,281 .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT,
282 .data_alignment = 16,282 .data_alignment = 16,
283 }, {
284 .code = MEDIA_BUS_FMT_Y8_1X8,
285 .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8,
286 .data_alignment = 8,
287 }, {
288 .code = MEDIA_BUS_FMT_Y10_1X10,
289 .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10,
290 .data_alignment = 16,
291 }, {
292 .code = MEDIA_BUS_FMT_Y12_1X12,
293 .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12,
294 .data_alignment = 16,
283 }295 }
284};296};
285 297
@@ -301,6 +313,7 @@ static int mipi_csis_dump_regs(struct csi_state *state) · 15 unmodified lines
301 { 0x20, "DPHYSTS" },313 { 0x20, "DPHYSTS" },
302 { 0x10, "INTMSK" },314 { 0x10, "INTMSK" },
303 { 0x40, "CONFIG_CH0" },315 { 0x40, "CONFIG_CH0" },
316 { 0x44, "RESOL_CH0" },
304 { 0xC0, "DBG_CONFIG" },317 { 0xC0, "DBG_CONFIG" },
305 { 0x38, "DPHYSLAVE_L" },318 { 0x38, "DPHYSLAVE_L" },
306 { 0x3C, "DPHYSLAVE_H" },319 { 0x3C, "DPHYSLAVE_H" },
@@ -417,6 +430,7 @@ static void mipi_csis_set_params(struct csi_state *state) · 110 unmodified lines
417 val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL);430 val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL);
418 val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK;431 val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK;
419 val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET;432 val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET;
433 val |= MIPI_CSIS_CMN_CTRL_INTER_MODE;
420 mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val);434 mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val);
421 435
422 __mipi_csis_set_format(state);436 __mipi_csis_set_format(state);
@@ -577,7 +591,7 @@ static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) · 154 unmodified lines
577 state->flags |= ST_STREAMING;591 state->flags |= ST_STREAMING;
578 } else {592 } else {
579 v4l2_subdev_call(state->src_sd, video, s_stream, 0);593 v4l2_subdev_call(state->src_sd, video, s_stream, 0);
580 ret = v4l2_subdev_call(state->src_sd, core, s_power, 1);594 ret = v4l2_subdev_call(state->src_sd, core, s_power, 0);
581 mipi_csis_stop_stream(state);595 mipi_csis_stop_stream(state);
582 state->flags &= ~ST_STREAMING;596 state->flags &= ~ST_STREAMING;
583 if (state->debug)597 if (state->debug)
drivers/staging/media/ipu3/TODO+0−2
@@ -13,8 +13,6 @@ staging directory. · 12 unmodified lines
13- Elaborate the functionality of different selection rectangles in driver13- Elaborate the functionality of different selection rectangles in driver
14 documentation. This may require driver changes as well.14 documentation. This may require driver changes as well.
15 15
16- More detailed documentation on calculating BDS, GCD etc. sizes needed.
17
18- Document different operation modes, and which buffer queues are relevant16- Document different operation modes, and which buffer queues are relevant
19 in each mode. To process an image, which queues require a buffer an in17 in each mode. To process an image, which queues require a buffer an in
20 which ones is it optional?18 which ones is it optional?
drivers/staging/media/ipu3/ipu3-css.c+3−3
@@ -210,12 +210,12 @@ static int imgu_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp) · 209 unmodified lines
210 210
211/* Initialize the IPU3 CSS hardware and associated h/w blocks */211/* Initialize the IPU3 CSS hardware and associated h/w blocks */
212 212
213int imgu_css_set_powerup(struct device *dev, void __iomem *base)213int imgu_css_set_powerup(struct device *dev, void __iomem *base,
214 unsigned int freq)
214{215{
215 static const unsigned int freq = 450;
216 u32 pm_ctrl, state, val;216 u32 pm_ctrl, state, val;
217 217
218 dev_dbg(dev, "%s\n", __func__);218 dev_dbg(dev, "%s with freq %u\n", __func__, freq);
219 /* Clear the CSS busy signal */219 /* Clear the CSS busy signal */
220 readl(base + IMGU_REG_GP_BUSY);220 readl(base + IMGU_REG_GP_BUSY);
221 writel(0, base + IMGU_REG_GP_BUSY);221 writel(0, base + IMGU_REG_GP_BUSY);
drivers/staging/media/ipu3/ipu3-css.h+2−1
@@ -187,7 +187,8 @@ bool imgu_css_is_streaming(struct imgu_css *css); · 186 unmodified lines
187bool imgu_css_pipe_queue_empty(struct imgu_css *css, unsigned int pipe);187bool imgu_css_pipe_queue_empty(struct imgu_css *css, unsigned int pipe);
188 188
189/******************* css hw *******************/189/******************* css hw *******************/
190int imgu_css_set_powerup(struct device *dev, void __iomem *base);190int imgu_css_set_powerup(struct device *dev, void __iomem *base,
191 unsigned int freq);
191void imgu_css_set_powerdown(struct device *dev, void __iomem *base);192void imgu_css_set_powerdown(struct device *dev, void __iomem *base);
192int imgu_css_irq_ack(struct imgu_css *css);193int imgu_css_irq_ack(struct imgu_css *css);
193 194
drivers/staging/media/ipu3/ipu3-mmu.c+2−2
@@ -130,7 +130,7 @@ static u32 *imgu_mmu_alloc_page_table(u32 pteval) · 129 unmodified lines
130 for (pte = 0; pte < IPU3_PT_PTES; pte++)130 for (pte = 0; pte < IPU3_PT_PTES; pte++)
131 pt[pte] = pteval;131 pt[pte] = pteval;
132 132
133 set_memory_uc((unsigned long int)pt, IPU3_PT_ORDER);133 set_memory_uc((unsigned long)pt, IPU3_PT_ORDER);
134 134
135 return pt;135 return pt;
136}136}
@@ -141,7 +141,7 @@ static u32 *imgu_mmu_alloc_page_table(u32 pteval) · 4 unmodified lines
141 */141 */
142static void imgu_mmu_free_page_table(u32 *pt)142static void imgu_mmu_free_page_table(u32 *pt)
143{143{
144 set_memory_wb((unsigned long int)pt, IPU3_PT_ORDER);144 set_memory_wb((unsigned long)pt, IPU3_PT_ORDER);
145 free_page((unsigned long)pt);145 free_page((unsigned long)pt);
146}146}
147 147
drivers/staging/media/ipu3/ipu3-v4l2.c+1−1
@@ -1245,7 +1245,7 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, · 1244 unmodified lines
1245 vdev->queue = &node->vbq;1245 vdev->queue = &node->vbq;
1246 vdev->vfl_dir = node->output ? VFL_DIR_TX : VFL_DIR_RX;1246 vdev->vfl_dir = node->output ? VFL_DIR_TX : VFL_DIR_RX;
1247 video_set_drvdata(vdev, imgu);1247 video_set_drvdata(vdev, imgu);
1248 r = video_register_device(vdev, VFL_TYPE_GRABBER, -1);1248 r = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
1249 if (r) {1249 if (r) {
1250 dev_err(dev, "failed to register video device (%d)", r);1250 dev_err(dev, "failed to register video device (%d)", r);
1251 media_entity_cleanup(&vdev->entity);1251 media_entity_cleanup(&vdev->entity);
drivers/staging/media/ipu3/ipu3.c+14−2
@@ -345,8 +345,20 @@ failed: · 344 unmodified lines
345static int imgu_powerup(struct imgu_device *imgu)345static int imgu_powerup(struct imgu_device *imgu)
346{346{
347 int r;347 int r;
348 unsigned int pipe;
349 unsigned int freq = 200;
350 struct v4l2_mbus_framefmt *fmt;
351
352 /* input larger than 2048*1152, ask imgu to work on high freq */
353 for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) {
354 fmt = &imgu->imgu_pipe[pipe].nodes[IMGU_NODE_IN].pad_fmt;
355 dev_dbg(&imgu->pci_dev->dev, "pipe %u input format = %ux%u",
356 pipe, fmt->width, fmt->height);
357 if ((fmt->width * fmt->height) >= (2048 * 1152))
358 freq = 450;
359 }
348 360
349 r = imgu_css_set_powerup(&imgu->pci_dev->dev, imgu->base);361 r = imgu_css_set_powerup(&imgu->pci_dev->dev, imgu->base, freq);
350 if (r)362 if (r)
351 return r;363 return r;
352 364
@@ -666,7 +678,7 @@ static int imgu_pci_probe(struct pci_dev *pci_dev, · 313 unmodified lines
666 atomic_set(&imgu->qbuf_barrier, 0);678 atomic_set(&imgu->qbuf_barrier, 0);
667 init_waitqueue_head(&imgu->buf_drain_wq);679 init_waitqueue_head(&imgu->buf_drain_wq);
668 680
669 r = imgu_css_set_powerup(&pci_dev->dev, imgu->base);681 r = imgu_css_set_powerup(&pci_dev->dev, imgu->base, 200);
670 if (r) {682 if (r) {
671 dev_err(&pci_dev->dev,683 dev_err(&pci_dev->dev,
672 "failed to power up CSS (%d)\n", r);684 "failed to power up CSS (%d)\n", r);
drivers/staging/media/meson/vdec/Makefile+2−2
@@ -2,7 +2,7 @@ · 1 unmodified line
2# Makefile for Amlogic meson video decoder driver2# Makefile for Amlogic meson video decoder driver
3 3
4meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o4meson-vdec-objs = esparser.o vdec.o vdec_helpers.o vdec_platform.o
5meson-vdec-objs += vdec_1.o5meson-vdec-objs += vdec_1.o vdec_hevc.o
6meson-vdec-objs += codec_mpeg12.o6meson-vdec-objs += codec_mpeg12.o codec_h264.o codec_hevc_common.o codec_vp9.o
7 7
8obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o8obj-$(CONFIG_VIDEO_MESON_VDEC) += meson-vdec.o
drivers/staging/media/meson/vdec/codec_h264.c+485−0
@@ -0,0 +1,485 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 BayLibre, SAS
4 * Author: Maxime Jourdan <mjourdan@baylibre.com>
5 */
6
7#include <media/v4l2-mem2mem.h>
8#include <media/videobuf2-dma-contig.h>
9
10#include "vdec_helpers.h"
11#include "dos_regs.h"
12#include "codec_h264.h"
13
14#define SIZE_EXT_FW (20 * SZ_1K)
15#define SIZE_WORKSPACE 0x1ee000
16#define SIZE_SEI (8 * SZ_1K)
17
18/*
19 * Offset added by the firmware which must be substracted
20 * from the workspace phyaddr
21 */
22#define WORKSPACE_BUF_OFFSET 0x1000000
23
24/* ISR status */
25#define CMD_MASK GENMASK(7, 0)
26#define CMD_SRC_CHANGE 1
27#define CMD_FRAMES_READY 2
28#define CMD_FATAL_ERROR 6
29#define CMD_BAD_WIDTH 7
30#define CMD_BAD_HEIGHT 8
31
32#define SEI_DATA_READY BIT(15)
33
34/* Picture type */
35#define PIC_TOP_BOT 5
36#define PIC_BOT_TOP 6
37
38/* Size of Motion Vector per macroblock */
39#define MB_MV_SIZE 96
40
41/* Frame status data */
42#define PIC_STRUCT_BIT 5
43#define PIC_STRUCT_MASK GENMASK(2, 0)
44#define BUF_IDX_MASK GENMASK(4, 0)
45#define ERROR_FLAG BIT(9)
46#define OFFSET_BIT 16
47#define OFFSET_MASK GENMASK(15, 0)
48
49/* Bitstream parsed data */
50#define MB_TOTAL_BIT 8
51#define MB_TOTAL_MASK GENMASK(15, 0)
52#define MB_WIDTH_MASK GENMASK(7, 0)
53#define MAX_REF_BIT 24
54#define MAX_REF_MASK GENMASK(6, 0)
55#define AR_IDC_BIT 16
56#define AR_IDC_MASK GENMASK(7, 0)
57#define AR_PRESENT_FLAG BIT(0)
58#define AR_EXTEND 0xff
59
60/*
61 * Buffer to send to the ESPARSER to signal End Of Stream for H.264.
62 * This is a 16x16 encoded picture that will trigger drain firmware-side.
63 * There is no known alternative.
64 */
65static const u8 eos_sequence[SZ_4K] = {
66 0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xe4, 0xdc, 0x45, 0xe9, 0xbd,
67 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef,
68 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20,
69 0x36, 0x37, 0x20, 0x72, 0x31, 0x31, 0x33, 0x30, 0x20, 0x38, 0x34, 0x37,
70 0x35, 0x39, 0x37, 0x37, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34,
71 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20,
72 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
73 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30,
74 0x30, 0x39, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
75 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e,
76 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
77 0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
78 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d, 0x31, 0x20, 0x72, 0x65,
79 0x66, 0x3d, 0x31, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3d,
80 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73,
81 0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20,
82 0x6d, 0x65, 0x3d, 0x68, 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65,
83 0x3d, 0x36, 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e,
84 0x30, 0x3a, 0x30, 0x2e, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f,
85 0x72, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e,
86 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61,
87 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
88 0x73, 0x3d, 0x30, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30,
89 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a,
90 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x63, 0x68,
91 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73,
92 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64,
93 0x73, 0x3d, 0x31, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63,
94 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x6d, 0x62, 0x61, 0x66,
95 0x66, 0x3d, 0x30, 0x20, 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d,
96 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
97 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d,
98 0x32, 0x35, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x63, 0x75, 0x74, 0x3d,
99 0x34, 0x30, 0x20, 0x72, 0x63, 0x3d, 0x61, 0x62, 0x72, 0x20, 0x62, 0x69,
100 0x74, 0x72, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x30, 0x20, 0x72, 0x61, 0x74,
101 0x65, 0x74, 0x6f, 0x6c, 0x3d, 0x31, 0x2e, 0x30, 0x20, 0x71, 0x63, 0x6f,
102 0x6d, 0x70, 0x3d, 0x30, 0x2e, 0x36, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x69,
103 0x6e, 0x3d, 0x31, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x61, 0x78, 0x3d, 0x35,
104 0x31, 0x20, 0x71, 0x70, 0x73, 0x74, 0x65, 0x70, 0x3d, 0x34, 0x20, 0x69,
105 0x70, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x31, 0x2e, 0x34, 0x30,
106 0x20, 0x61, 0x71, 0x3d, 0x31, 0x3a, 0x31, 0x2e, 0x30, 0x30, 0x00, 0x80,
107 0x00, 0x00, 0x00, 0x01, 0x67, 0x4d, 0x40, 0x0a, 0x9a, 0x74, 0xf4, 0x20,
108 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x06, 0x51, 0xe2, 0x44, 0xd4,
109 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x00, 0x01,
110 0x65, 0x88, 0x80, 0x20, 0x00, 0x08, 0x7f, 0xea, 0x6a, 0xe2, 0x99, 0xb6,
111 0x57, 0xae, 0x49, 0x30, 0xf5, 0xfe, 0x5e, 0x46, 0x0b, 0x72, 0x44, 0xc4,
112 0xe1, 0xfc, 0x62, 0xda, 0xf1, 0xfb, 0xa2, 0xdb, 0xd6, 0xbe, 0x5c, 0xd7,
113 0x24, 0xa3, 0xf5, 0xb9, 0x2f, 0x57, 0x16, 0x49, 0x75, 0x47, 0x77, 0x09,
114 0x5c, 0xa1, 0xb4, 0xc3, 0x4f, 0x60, 0x2b, 0xb0, 0x0c, 0xc8, 0xd6, 0x66,
115 0xba, 0x9b, 0x82, 0x29, 0x33, 0x92, 0x26, 0x99, 0x31, 0x1c, 0x7f, 0x9b,
116 0x00, 0x00, 0x01, 0x0ff,
117};
118
119static const u8 *codec_h264_eos_sequence(u32 *len)
120{
121 *len = ARRAY_SIZE(eos_sequence);
122 return eos_sequence;
123}
124
125struct codec_h264 {
126 /* H.264 decoder requires an extended firmware */
127 void *ext_fw_vaddr;
128 dma_addr_t ext_fw_paddr;
129
130 /* Buffer for the H.264 Workspace */
131 void *workspace_vaddr;
132 dma_addr_t workspace_paddr;
133
134 /* Buffer for the H.264 references MV */
135 void *ref_vaddr;
136 dma_addr_t ref_paddr;
137 u32 ref_size;
138
139 /* Buffer for parsed SEI data */
140 void *sei_vaddr;
141 dma_addr_t sei_paddr;
142
143 u32 mb_width;
144 u32 mb_height;
145 u32 max_refs;
146};
147
148static int codec_h264_can_recycle(struct amvdec_core *core)
149{
150 return !amvdec_read_dos(core, AV_SCRATCH_7) ||
151 !amvdec_read_dos(core, AV_SCRATCH_8);
152}
153
154static void codec_h264_recycle(struct amvdec_core *core, u32 buf_idx)
155{
156 /*
157 * Tell the firmware it can recycle this buffer.
158 * AV_SCRATCH_8 serves the same purpose.
159 */
160 if (!amvdec_read_dos(core, AV_SCRATCH_7))
161 amvdec_write_dos(core, AV_SCRATCH_7, buf_idx + 1);
162 else
163 amvdec_write_dos(core, AV_SCRATCH_8, buf_idx + 1);
164}
165
166static int codec_h264_start(struct amvdec_session *sess)
167{
168 u32 workspace_offset;
169 struct amvdec_core *core = sess->core;
170 struct codec_h264 *h264 = sess->priv;
171
172 /* Allocate some memory for the H.264 decoder's state */
173 h264->workspace_vaddr =
174 dma_alloc_coherent(core->dev, SIZE_WORKSPACE,
175 &h264->workspace_paddr, GFP_KERNEL);
176 if (!h264->workspace_vaddr)
177 return -ENOMEM;
178
179 /* Allocate some memory for the H.264 SEI dump */
180 h264->sei_vaddr = dma_alloc_coherent(core->dev, SIZE_SEI,
181 &h264->sei_paddr, GFP_KERNEL);
182 if (!h264->sei_vaddr)
183 return -ENOMEM;
184
185 amvdec_write_dos_bits(core, POWER_CTL_VLD, BIT(9) | BIT(6));
186
187 workspace_offset = h264->workspace_paddr - WORKSPACE_BUF_OFFSET;
188 amvdec_write_dos(core, AV_SCRATCH_1, workspace_offset);
189 amvdec_write_dos(core, AV_SCRATCH_G, h264->ext_fw_paddr);
190 amvdec_write_dos(core, AV_SCRATCH_I, h264->sei_paddr -
191 workspace_offset);
192
193 /* Enable "error correction" */
194 amvdec_write_dos(core, AV_SCRATCH_F,
195 (amvdec_read_dos(core, AV_SCRATCH_F) & 0xffffffc3) |
196 BIT(4) | BIT(7));
197
198 amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa);
199
200 return 0;
201}
202
203static int codec_h264_stop(struct amvdec_session *sess)
204{
205 struct codec_h264 *h264 = sess->priv;
206 struct amvdec_core *core = sess->core;
207
208 if (h264->ext_fw_vaddr)
209 dma_free_coherent(core->dev, SIZE_EXT_FW,
210 h264->ext_fw_vaddr, h264->ext_fw_paddr);
211
212 if (h264->workspace_vaddr)
213 dma_free_coherent(core->dev, SIZE_WORKSPACE,
214 h264->workspace_vaddr, h264->workspace_paddr);
215
216 if (h264->ref_vaddr)
217 dma_free_coherent(core->dev, h264->ref_size,
218 h264->ref_vaddr, h264->ref_paddr);
219
220 if (h264->sei_vaddr)
221 dma_free_coherent(core->dev, SIZE_SEI,
222 h264->sei_vaddr, h264->sei_paddr);
223
224 return 0;
225}
226
227static int codec_h264_load_extended_firmware(struct amvdec_session *sess,
228 const u8 *data, u32 len)
229{
230 struct codec_h264 *h264;
231 struct amvdec_core *core = sess->core;
232
233 if (len < SIZE_EXT_FW)
234 return -EINVAL;
235
236 h264 = kzalloc(sizeof(*h264), GFP_KERNEL);
237 if (!h264)
238 return -ENOMEM;
239
240 h264->ext_fw_vaddr = dma_alloc_coherent(core->dev, SIZE_EXT_FW,
241 &h264->ext_fw_paddr,
242 GFP_KERNEL);
243 if (!h264->ext_fw_vaddr) {
244 kfree(h264);
245 return -ENOMEM;
246 }
247
248 memcpy(h264->ext_fw_vaddr, data, SIZE_EXT_FW);
249 sess->priv = h264;
250
251 return 0;
252}
253
254static const struct v4l2_fract par_table[] = {
255 { 1, 1 }, { 1, 1 }, { 12, 11 }, { 10, 11 },
256 { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
257 { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
258 { 64, 33 }, { 160, 99 }, { 4, 3 }, { 3, 2 },
259 { 2, 1 }
260};
261
262static void codec_h264_set_par(struct amvdec_session *sess)
263{
264 struct amvdec_core *core = sess->core;
265 u32 seq_info = amvdec_read_dos(core, AV_SCRATCH_2);
266 u32 ar_idc = (seq_info >> AR_IDC_BIT) & AR_IDC_MASK;
267
268 if (!(seq_info & AR_PRESENT_FLAG))
269 return;
270
271 if (ar_idc == AR_EXTEND) {
272 u32 ar_info = amvdec_read_dos(core, AV_SCRATCH_3);
273
274 sess->pixelaspect.numerator = ar_info & 0xffff;
275 sess->pixelaspect.denominator = (ar_info >> 16) & 0xffff;
276 return;
277 }
278
279 if (ar_idc >= ARRAY_SIZE(par_table))
280 return;
281
282 sess->pixelaspect = par_table[ar_idc];
283}
284
285static void codec_h264_resume(struct amvdec_session *sess)
286{
287 struct amvdec_core *core = sess->core;
288 struct codec_h264 *h264 = sess->priv;
289 u32 mb_width, mb_height, mb_total;
290
291 amvdec_set_canvases(sess,
292 (u32[]){ ANC0_CANVAS_ADDR, 0 },
293 (u32[]){ 24, 0 });
294
295 dev_dbg(core->dev, "max_refs = %u; actual_dpb_size = %u\n",
296 h264->max_refs, sess->num_dst_bufs);
297
298 /* Align to a multiple of 4 macroblocks */
299 mb_width = ALIGN(h264->mb_width, 4);
300 mb_height = ALIGN(h264->mb_height, 4);
301 mb_total = mb_width * mb_height;
302
303 h264->ref_size = mb_total * MB_MV_SIZE * h264->max_refs;
304 h264->ref_vaddr = dma_alloc_coherent(core->dev, h264->ref_size,
305 &h264->ref_paddr, GFP_KERNEL);
306 if (!h264->ref_vaddr) {
307 amvdec_abort(sess);
308 return;
309 }
310
311 /* Address to store the references' MVs */
312 amvdec_write_dos(core, AV_SCRATCH_1, h264->ref_paddr);
313 /* End of ref MV */
314 amvdec_write_dos(core, AV_SCRATCH_4, h264->ref_paddr + h264->ref_size);
315
316 amvdec_write_dos(core, AV_SCRATCH_0, (h264->max_refs << 24) |
317 (sess->num_dst_bufs << 16) |
318 ((h264->max_refs - 1) << 8));
319}
320
321/*
322 * Configure the H.264 decoder when the parser detected a parameter set change
323 */
324static void codec_h264_src_change(struct amvdec_session *sess)
325{
326 struct amvdec_core *core = sess->core;
327 struct codec_h264 *h264 = sess->priv;
328 u32 parsed_info, mb_total;
329 u32 crop_infor, crop_bottom, crop_right;
330 u32 frame_width, frame_height;
331
332 sess->keyframe_found = 1;
333
334 parsed_info = amvdec_read_dos(core, AV_SCRATCH_1);
335
336 /* Total number of 16x16 macroblocks */
337 mb_total = (parsed_info >> MB_TOTAL_BIT) & MB_TOTAL_MASK;
338 /* Number of macroblocks per line */
339 h264->mb_width = parsed_info & MB_WIDTH_MASK;
340 /* Number of macroblock lines */
341 h264->mb_height = mb_total / h264->mb_width;
342
343 h264->max_refs = ((parsed_info >> MAX_REF_BIT) & MAX_REF_MASK) + 1;
344
345 crop_infor = amvdec_read_dos(core, AV_SCRATCH_6);
346 crop_bottom = (crop_infor & 0xff);
347 crop_right = (crop_infor >> 16) & 0xff;
348
349 frame_width = h264->mb_width * 16 - crop_right;
350 frame_height = h264->mb_height * 16 - crop_bottom;
351
352 dev_dbg(core->dev, "frame: %ux%u; crop: %u %u\n",
353 frame_width, frame_height, crop_right, crop_bottom);
354
355 codec_h264_set_par(sess);
356 amvdec_src_change(sess, frame_width, frame_height, h264->max_refs + 5);
357}
358
359/*
360 * The bitstream offset is split in half in 2 different registers.
361 * Fetch its MSB here, which location depends on the frame number.
362 */
363static u32 get_offset_msb(struct amvdec_core *core, int frame_num)
364{
365 int take_msb = frame_num % 2;
366 int reg_offset = (frame_num / 2) * 4;
367 u32 offset_msb = amvdec_read_dos(core, AV_SCRATCH_A + reg_offset);
368
369 if (take_msb)
370 return offset_msb & 0xffff0000;
371
372 return (offset_msb & 0x0000ffff) << 16;
373}
374
375static void codec_h264_frames_ready(struct amvdec_session *sess, u32 status)
376{
377 struct amvdec_core *core = sess->core;
378 int error_count;
379 int num_frames;
380 int i;
381
382 error_count = amvdec_read_dos(core, AV_SCRATCH_D);
383 num_frames = (status >> 8) & 0xff;
384 if (error_count) {
385 dev_warn(core->dev,
386 "decoder error(s) happened, count %d\n", error_count);
387 amvdec_write_dos(core, AV_SCRATCH_D, 0);
388 }
389
390 for (i = 0; i < num_frames; i++) {
391 u32 frame_status = amvdec_read_dos(core, AV_SCRATCH_1 + i * 4);
392 u32 buffer_index = frame_status & BUF_IDX_MASK;
393 u32 pic_struct = (frame_status >> PIC_STRUCT_BIT) &
394 PIC_STRUCT_MASK;
395 u32 offset = (frame_status >> OFFSET_BIT) & OFFSET_MASK;
396 u32 field = V4L2_FIELD_NONE;
397
398 /*
399 * A buffer decode error means it was decoded,
400 * but part of the picture will have artifacts.
401 * Typical reason is a temporarily corrupted bitstream
402 */
403 if (frame_status & ERROR_FLAG)
404 dev_dbg(core->dev, "Buffer %d decode error\n",
405 buffer_index);
406
407 if (pic_struct == PIC_TOP_BOT)
408 field = V4L2_FIELD_INTERLACED_TB;
409 else if (pic_struct == PIC_BOT_TOP)
410 field = V4L2_FIELD_INTERLACED_BT;
411
412 offset |= get_offset_msb(core, i);
413 amvdec_dst_buf_done_idx(sess, buffer_index, offset, field);
414 }
415}
416
417static irqreturn_t codec_h264_threaded_isr(struct amvdec_session *sess)
418{
419 struct amvdec_core *core = sess->core;
420 u32 status;
421 u32 size;
422 u8 cmd;
423
424 status = amvdec_read_dos(core, AV_SCRATCH_0);
425 cmd = status & CMD_MASK;
426
427 switch (cmd) {
428 case CMD_SRC_CHANGE:
429 codec_h264_src_change(sess);
430 break;
431 case CMD_FRAMES_READY:
432 codec_h264_frames_ready(sess, status);
433 break;
434 case CMD_FATAL_ERROR:
435 dev_err(core->dev, "H.264 decoder fatal error\n");
436 goto abort;
437 case CMD_BAD_WIDTH:
438 size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16;
439 dev_err(core->dev, "Unsupported video width: %u\n", size);
440 goto abort;
441 case CMD_BAD_HEIGHT:
442 size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16;
443 dev_err(core->dev, "Unsupported video height: %u\n", size);
444 goto abort;
445 case 0: /* Unused but not worth printing for */
446 case 9:
447 break;
448 default:
449 dev_info(core->dev, "Unexpected H264 ISR: %08X\n", cmd);
450 break;
451 }
452
453 if (cmd && cmd != CMD_SRC_CHANGE)
454 amvdec_write_dos(core, AV_SCRATCH_0, 0);
455
456 /* Decoder has some SEI data for us ; ignore */
457 if (amvdec_read_dos(core, AV_SCRATCH_J) & SEI_DATA_READY)
458 amvdec_write_dos(core, AV_SCRATCH_J, 0);
459
460 return IRQ_HANDLED;
461abort:
462 amvdec_abort(sess);
463 return IRQ_HANDLED;
464}
465
466static irqreturn_t codec_h264_isr(struct amvdec_session *sess)
467{
468 struct amvdec_core *core = sess->core;
469
470 amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1);
471
472 return IRQ_WAKE_THREAD;
473}
474
475struct amvdec_codec_ops codec_h264_ops = {
476 .start = codec_h264_start,
477 .stop = codec_h264_stop,
478 .load_extended_firmware = codec_h264_load_extended_firmware,
479 .isr = codec_h264_isr,
480 .threaded_isr = codec_h264_threaded_isr,
481 .can_recycle = codec_h264_can_recycle,
482 .recycle = codec_h264_recycle,
483 .eos_sequence = codec_h264_eos_sequence,
484 .resume = codec_h264_resume,
485};
drivers/staging/media/meson/vdec/codec_h264.h+14−0
@@ -0,0 +1,14 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2019 BayLibre, SAS
4 * Author: Maxime Jourdan <mjourdan@baylibre.com>
5 */
6
7#ifndef __MESON_VDEC_CODEC_H264_H_
8#define __MESON_VDEC_CODEC_H264_H_
9
10#include "vdec.h"
11
12extern struct amvdec_codec_ops codec_h264_ops;
13
14#endif
drivers/staging/media/meson/vdec/codec_hevc_common.c+297−0
@@ -0,0 +1,297 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018 Maxime Jourdan <mjourdan@baylibre.com>
4 */
5
6#include <media/v4l2-mem2mem.h>
7#include <media/videobuf2-dma-contig.h>
8
9#include "codec_hevc_common.h"
10#include "vdec_helpers.h"
11#include "hevc_regs.h"
12
13#define MMU_COMPRESS_HEADER_SIZE 0x48000
14#define MMU_MAP_SIZE 0x4800
15
16const u16 vdec_hevc_parser_cmd[] = {
17 0x0401, 0x8401, 0x0800, 0x0402,
18 0x9002, 0x1423, 0x8CC3, 0x1423,
19 0x8804, 0x9825, 0x0800, 0x04FE,
20 0x8406, 0x8411, 0x1800, 0x8408,
21 0x8409, 0x8C2A, 0x9C2B, 0x1C00,
22 0x840F, 0x8407, 0x8000, 0x8408,
23 0x2000, 0xA800, 0x8410, 0x04DE,
24 0x840C, 0x840D, 0xAC00, 0xA000,
25 0x08C0, 0x08E0, 0xA40E, 0xFC00,
26 0x7C00
27};
28
29/* Configure decode head read mode */
30void codec_hevc_setup_decode_head(struct amvdec_session *sess, int is_10bit)
31{
32 struct amvdec_core *core = sess->core;
33 u32 body_size = amvdec_am21c_body_size(sess->width, sess->height);
34 u32 head_size = amvdec_am21c_head_size(sess->width, sess->height);
35
36 if (!codec_hevc_use_fbc(sess->pixfmt_cap, is_10bit)) {
37 /* Enable 2-plane reference read mode */
38 amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, BIT(31));
39 return;
40 }
41
42 if (codec_hevc_use_mmu(core->platform->revision,
43 sess->pixfmt_cap, is_10bit))
44 amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, BIT(4));
45 else
46 amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL1, 0);
47
48 if (core->platform->revision < VDEC_REVISION_SM1)
49 amvdec_write_dos(core, HEVCD_MPP_DECOMP_CTL2, body_size / 32);
50 amvdec_write_dos(core, HEVC_CM_BODY_LENGTH, body_size);
51 amvdec_write_dos(core, HEVC_CM_HEADER_OFFSET, body_size);
52 amvdec_write_dos(core, HEVC_CM_HEADER_LENGTH, head_size);
53}
54EXPORT_SYMBOL_GPL(codec_hevc_setup_decode_head);
55
56static void codec_hevc_setup_buffers_gxbb(struct amvdec_session *sess,
57 struct codec_hevc_common *comm,
58 int is_10bit)
59{
60 struct amvdec_core *core = sess->core;
61 struct v4l2_m2m_buffer *buf;
62 u32 buf_num = v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx);
63 dma_addr_t buf_y_paddr = 0;
64 dma_addr_t buf_uv_paddr = 0;
65 u32 idx = 0;
66 u32 val;
67 int i;
68
69 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0);
70
71 v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) {
72 struct vb2_buffer *vb = &buf->vb.vb2_buf;
73
74 idx = vb->index;
75
76 if (codec_hevc_use_downsample(sess->pixfmt_cap, is_10bit))
77 buf_y_paddr = comm->fbc_buffer_paddr[idx];
78 else
79 buf_y_paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
80
81 if (codec_hevc_use_fbc(sess->pixfmt_cap, is_10bit)) {
82 val = buf_y_paddr | (idx << 8) | 1;
83 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
84 val);
85 } else {
86 buf_uv_paddr = vb2_dma_contig_plane_dma_addr(vb, 1);
87 val = buf_y_paddr | ((idx * 2) << 8) | 1;
88 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
89 val);
90 val = buf_uv_paddr | ((idx * 2 + 1) << 8) | 1;
91 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
92 val);
93 }
94 }
95
96 if (codec_hevc_use_fbc(sess->pixfmt_cap, is_10bit))
97 val = buf_y_paddr | (idx << 8) | 1;
98 else
99 val = buf_y_paddr | ((idx * 2) << 8) | 1;
100
101 /* Fill the remaining unused slots with the last buffer's Y addr */
102 for (i = buf_num; i < MAX_REF_PIC_NUM; ++i)
103 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR, val);
104
105 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 1);
106 amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1);
107 for (i = 0; i < 32; ++i)
108 amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
109}
110
111static void codec_hevc_setup_buffers_gxl(struct amvdec_session *sess,
112 struct codec_hevc_common *comm,
113 int is_10bit)
114{
115 struct amvdec_core *core = sess->core;
116 struct v4l2_m2m_buffer *buf;
117 u32 revision = core->platform->revision;
118 u32 pixfmt_cap = sess->pixfmt_cap;
119 int i;
120
121 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
122 BIT(2) | BIT(1));
123
124 v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) {
125 struct vb2_buffer *vb = &buf->vb.vb2_buf;
126 dma_addr_t buf_y_paddr = 0;
127 dma_addr_t buf_uv_paddr = 0;
128 u32 idx = vb->index;
129
130 if (codec_hevc_use_mmu(revision, pixfmt_cap, is_10bit))
131 buf_y_paddr = comm->mmu_header_paddr[idx];
132 else if (codec_hevc_use_downsample(pixfmt_cap, is_10bit))
133 buf_y_paddr = comm->fbc_buffer_paddr[idx];
134 else
135 buf_y_paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
136
137 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA,
138 buf_y_paddr >> 5);
139
140 if (!codec_hevc_use_fbc(pixfmt_cap, is_10bit)) {
141 buf_uv_paddr = vb2_dma_contig_plane_dma_addr(vb, 1);
142 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_DATA,
143 buf_uv_paddr >> 5);
144 }
145 }
146
147 amvdec_write_dos(core, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 1);
148 amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1);
149 for (i = 0; i < 32; ++i)
150 amvdec_write_dos(core, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
151}
152
153void codec_hevc_free_fbc_buffers(struct amvdec_session *sess,
154 struct codec_hevc_common *comm)
155{
156 struct device *dev = sess->core->dev;
157 u32 am21_size = amvdec_am21c_size(sess->width, sess->height);
158 int i;
159
160 for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
161 if (comm->fbc_buffer_vaddr[i]) {
162 dma_free_coherent(dev, am21_size,
163 comm->fbc_buffer_vaddr[i],
164 comm->fbc_buffer_paddr[i]);
165 comm->fbc_buffer_vaddr[i] = NULL;
166 }
167 }
168}
169EXPORT_SYMBOL_GPL(codec_hevc_free_fbc_buffers);
170
171static int codec_hevc_alloc_fbc_buffers(struct amvdec_session *sess,
172 struct codec_hevc_common *comm)
173{
174 struct device *dev = sess->core->dev;
175 struct v4l2_m2m_buffer *buf;
176 u32 am21_size = amvdec_am21c_size(sess->width, sess->height);
177
178 v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) {
179 u32 idx = buf->vb.vb2_buf.index;
180 dma_addr_t paddr;
181 void *vaddr = dma_alloc_coherent(dev, am21_size, &paddr,
182 GFP_KERNEL);
183 if (!vaddr) {
184 codec_hevc_free_fbc_buffers(sess, comm);
185 return -ENOMEM;
186 }
187
188 comm->fbc_buffer_vaddr[idx] = vaddr;
189 comm->fbc_buffer_paddr[idx] = paddr;
190 }
191
192 return 0;
193}

104 more lines aren’t shown here.

drivers/staging/media/meson/vdec/codec_hevc_common.h+71−0

This diff is large: its 72 lines aren’t shown here.

drivers/staging/media/meson/vdec/codec_vp9.c+2141−0

This diff is large: its 2142 lines aren’t shown here.

drivers/staging/media/meson/vdec/codec_vp9.h+13−0

This diff is large: its 14 lines aren’t shown here.

drivers/staging/media/meson/vdec/esparser.c+166−34

This diff is large: its 252 lines aren’t shown here.

drivers/staging/media/meson/vdec/hevc_regs.h+218−0

This diff is large: its 219 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec.c+68−39

This diff is large: its 275 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec.h+12−2

This diff is large: its 58 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec_helpers.c+75−48

This diff is large: its 240 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec_helpers.h+8−2

This diff is large: its 29 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec_hevc.c+231−0

This diff is large: its 232 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec_hevc.h+13−0

This diff is large: its 14 lines aren’t shown here.

drivers/staging/media/meson/vdec/vdec_platform.c+109−0

This diff is large: its 210 lines aren’t shown here.

drivers/staging/media/omap4iss/iss_video.c+4−4

This diff is large: its 36 lines aren’t shown here.

drivers/staging/media/rkisp1/TODO+0−1

This diff is large: its 5 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-capture.c+5−8

This diff is large: its 48 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-common.h+3−0

This diff is large: its 24 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-dev.c+9−11

This diff is large: its 61 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-isp.c+33−28

This diff is large: its 204 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-params.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-resizer.c+16−11

This diff is large: its 106 lines aren’t shown here.

drivers/staging/media/rkisp1/rkisp1-stats.c+2−3

This diff is large: its 19 lines aren’t shown here.

drivers/staging/media/soc_camera/soc_camera.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/media/sunxi/cedrus/cedrus.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/media/sunxi/cedrus/cedrus_h264.c+5−1

This diff is large: its 14 lines aren’t shown here.

drivers/staging/media/tegra-vde/vde.c+9−46

This diff is large: its 93 lines aren’t shown here.

drivers/staging/media/usbvision/Kconfigrenamed from drivers/media/usb/usbvision/Kconfig+7−2

This diff is large: its 21 lines aren’t shown here.

drivers/staging/media/usbvision/Makefilerenamed from drivers/media/usb/usbvision/Makefile+0−0

File renamed without changes.

drivers/staging/media/usbvision/TODO+11−0

This diff is large: its 12 lines aren’t shown here.

drivers/staging/media/usbvision/usbvision-cards.crenamed from drivers/media/usb/usbvision/usbvision-cards.c+0−0

File renamed without changes.

drivers/staging/media/usbvision/usbvision-cards.hrenamed from drivers/media/usb/usbvision/usbvision-cards.h+0−0

File renamed without changes.

drivers/staging/media/usbvision/usbvision-core.crenamed from drivers/media/usb/usbvision/usbvision-core.c+0−0

File renamed without changes.

drivers/staging/media/usbvision/usbvision-i2c.crenamed from drivers/media/usb/usbvision/usbvision-i2c.c+0−0

File renamed without changes.

drivers/staging/media/usbvision/usbvision-video.crenamed from drivers/media/usb/usbvision/usbvision-video.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/staging/media/usbvision/usbvision.hrenamed from drivers/media/usb/usbvision/usbvision.h+0−0

File renamed without changes.

drivers/staging/most/video/video.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/usb/gadget/function/f_uvc.c+1−1

This diff is large: its 9 lines aren’t shown here.

include/dt-bindings/display/sdtv-standards.h+76−0

This diff is large: its 77 lines aren’t shown here.

include/dt-bindings/media/tvp5150.h+0−2

This diff is large: its 9 lines aren’t shown here.

include/linux/atmel-isc-media.h+58−0

This diff is large: its 59 lines aren’t shown here.

include/media/cec-notifier.h+8−31

This diff is large: its 93 lines aren’t shown here.

include/media/h264-ctrls.h+2−0

This diff is large: its 9 lines aren’t shown here.

include/media/i2c/smiapp.h+0−63

This diff is large: its 64 lines aren’t shown here.

include/media/rc-core.h+4−4

This diff is large: its 25 lines aren’t shown here.

include/media/rc-map.h+3−2

This diff is large: its 22 lines aren’t shown here.

include/media/v4l2-dev.h+2−2

This diff is large: its 18 lines aren’t shown here.

include/media/v4l2-device.h+8−8

This diff is large: its 72 lines aren’t shown here.

include/media/v4l2-fwnode.h+143−0

This diff is large: its 170 lines aren’t shown here.

include/media/v4l2-mc.h+25−15

This diff is large: its 69 lines aren’t shown here.

include/media/v4l2-mem2mem.h+133−0

This diff is large: its 168 lines aren’t shown here.

include/media/v4l2-subdev.h+1−1

This diff is large: its 9 lines aren’t shown here.

include/media/videobuf2-core.h+5−2

This diff is large: its 14 lines aren’t shown here.

include/uapi/linux/media-bus-format.h+2−1

This diff is large: its 17 lines aren’t shown here.

include/uapi/linux/v4l2-controls.h+6−0

This diff is large: its 13 lines aren’t shown here.

include/uapi/linux/videodev2.h+9−0

This diff is large: its 30 lines aren’t shown here.

samples/v4l/v4l2-pci-skeleton.c+1−1

This diff is large: its 9 lines aren’t shown here.