History

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

Pull media updates from Mauro Carvalho Chehab: - Legacy soc_camera driver was removed from staging - New I2C sensor related drivers: dw9768, ch7322, max9271, rdacm20 - TI vpe driver code was re-organized and had new features added - Added Xilinx MIPI CSI-2 Rx Subsystem driver - Added support for Infrared Toy and IR Droid devices - Lots of random driver fixes, new features and cleanups * tag 'media/v5.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (318 commits) media: camss: fix memory leaks on error handling paths in probe media: davinci: vpif_capture: fix potential double free media: radio: remove redundant assignment to variable retval media: allegro: fix potential null dereference on header media: mtk-mdp: Fix a refcounting bug on error in init media: allegro: fix an error pointer vs NULL check media: meye: fix missing pm_mchip_mode field media: cafe-driver: use generic power management media: saa7164: use generic power management media: v4l2-dev/ioctl: Fix document for VIDIOC_QUERYCAP media: v4l2: Correct kernel-doc inconsistency media: v4l2: Correct kernel-doc inconsistency media: dvbdev.h: keep * together with the type media: v4l2-subdev.h: keep * together with the type media: videobuf2: Print videobuf2 buffer state by name media: colorspaces-details.rst: fix V4L2_COLORSPACE_JPEG description media: tw68: use generic power management media: meye: use generic power management media: cx88: use generic power management media: cx25821: use generic power management ...

Linus Torvalds committed 6 years ago

Commit fa73e212 parents 75dee3b f45882c268 files · +12785 −12116Browse files

Unified · Split

268 files
  1. Documentation/admin-guide/media/fimc.rst +3 −3
  2. Documentation/admin-guide/media/vivid.rst +9 −0
  3. Documentation/devicetree/bindings/media/i2c/chrontel,ch7322.yaml +67 −0
  4. Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml +100 −0
  5. Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml +159 −0
  6. Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml +366 −0
  7. Documentation/devicetree/bindings/media/renesas,fcp.txt +0 −34
  8. Documentation/devicetree/bindings/media/renesas,fcp.yaml +66 −0
  9. Documentation/devicetree/bindings/media/renesas,fdp1.txt +0 −37
  10. Documentation/devicetree/bindings/media/renesas,fdp1.yaml +69 −0
  11. Documentation/devicetree/bindings/media/renesas,vsp1.txt +0 −30
  12. Documentation/devicetree/bindings/media/renesas,vsp1.yaml +97 −0
  13. Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml +237 −0
  14. Documentation/devicetree/bindings/vendor-prefixes.yaml +2 −0
  15. Documentation/driver-api/media/drivers/pvrusb2.rst +1 −1
  16. Documentation/driver-api/media/drivers/tuners.rst +1 −1
  17. Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst +3 −0
  18. Documentation/userspace-api/media/dvb/fe-get-info.rst +1 −2
  19. Documentation/userspace-api/media/v4l/buffer.rst +40 −4
  20. Documentation/userspace-api/media/v4l/colorspaces-details.rst +2 −2
  21. Documentation/userspace-api/media/v4l/dev-decoder.rst +6 −4
  22. Documentation/userspace-api/media/v4l/dev-encoder.rst +753 −0
  23. Documentation/userspace-api/media/v4l/dev-mem2mem.rst +1 −0
  24. Documentation/userspace-api/media/v4l/dev-osd.rst +1 −1
  25. Documentation/userspace-api/media/v4l/dev-sdr.rst +1 −1
  26. Documentation/userspace-api/media/v4l/hist-v4l2.rst +2 −2
  27. Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst +14 −14
  28. Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst +5 −0
  29. Documentation/userspace-api/media/v4l/v4l2.rst +2 −0
  30. Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst +6 −1
  31. Documentation/userspace-api/media/v4l/vidioc-dqevent.rst +1 −1
  32. Documentation/userspace-api/media/v4l/vidioc-encoder-cmd.rst +31 −20
  33. Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst +25 −5
  34. Documentation/userspace-api/media/v4l/vidioc-g-parm.rst +32 −19
  35. Documentation/userspace-api/media/v4l/vidioc-querycap.rst +2 −2
  36. Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst +19 −2
  37. Documentation/userspace-api/media/videodev2.h.rst.exceptions +1 −0
  38. MAINTAINERS +54 −10
  39. arch/arm/configs/ezx_defconfig +0 −2
  40. arch/arm/configs/imote2_defconfig +0 −2
  41. arch/arm/configs/imx_v4_v5_defconfig +0 −1
  42. arch/arm/configs/imx_v6_v7_defconfig +0 −1
  43. arch/arm/configs/pxa_defconfig +0 −3
  44. arch/arm/configs/sama5_defconfig +0 −2
  45. arch/arm/mach-imx/mach-imx27_visstrim_m10.c +0 −31
  46. arch/arm/mach-omap1/board-ams-delta.c +0 −32
  47. arch/arm/mach-omap1/camera.h +0 −14
  48. arch/arm/mach-omap1/devices.c +0 −43
  49. arch/arm/mach-pxa/palmz72.c +0 −112
  50. arch/arm/mach-pxa/pcm990-baseboard.c +0 −157
  51. arch/sh/configs/ap325rxa_defconfig +0 −3
  52. arch/sh/configs/ecovec24_defconfig +0 −3
  53. arch/sh/configs/migor_defconfig +0 −3
  54. arch/sh/configs/se7724_defconfig +0 −2
  55. drivers/media/cec/Kconfig +1 −0
  56. drivers/media/cec/Makefile +1 −1
  57. drivers/media/cec/core/cec-adap.c +0 −4
  58. drivers/media/cec/core/cec-api.c +7 −1
  59. drivers/media/cec/core/cec-core.c +0 −1
  60. drivers/media/cec/core/cec-notifier.c +7 −4
  61. drivers/media/cec/i2c/Kconfig +14 −0
  62. drivers/media/cec/i2c/Makefile +5 −0
  63. drivers/media/cec/i2c/ch7322.c +604 −0
  64. drivers/media/cec/platform/cros-ec/cros-ec-cec.c +1 −5
  65. drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +33 −7
  66. drivers/media/common/videobuf2/videobuf2-core.c +225 −142
  67. drivers/media/common/videobuf2/videobuf2-dma-contig.c +38 −6
  68. drivers/media/common/videobuf2/videobuf2-dma-sg.c +30 −8
  69. drivers/media/common/videobuf2/videobuf2-v4l2.c +114 −33
  70. drivers/media/dvb-core/dvb_vb2.c +1 −1
  71. drivers/media/dvb-frontends/drxk_hard.c +0 −11
  72. drivers/media/dvb-frontends/rtl2832_sdr.c +1 −1
  73. drivers/media/firewire/firedtv-fw.c +2 −0
  74. drivers/media/i2c/Kconfig +39 −0
  75. drivers/media/i2c/Makefile +4 −0
  76. drivers/media/i2c/dw9768.c +554 −0
  77. drivers/media/i2c/imx290.c +343 −61
  78. drivers/media/i2c/max9271.c +341 −0
  79. drivers/media/i2c/max9271.h +224 −0
  80. drivers/media/i2c/max9286.c +1320 −0
  81. drivers/media/i2c/ov2740.c +146 −3
  82. drivers/media/i2c/ov9640.c +1 −1
  83. drivers/media/i2c/rdacm20.c +667 −0
  84. drivers/media/i2c/s5k6a3.c +1 −1
  85. drivers/media/i2c/smiapp/smiapp-core.c +2 −3
  86. drivers/media/i2c/tvp5150.c +6 −2
  87. drivers/media/mc/mc-request.c +17 −14
  88. drivers/media/pci/cx18/cx18-cards.c +1 −1
  89. drivers/media/pci/cx23885/cx23885-core.c +0 −3
  90. drivers/media/pci/cx23885/cx23888-ir.c +0 −20
  91. drivers/media/pci/cx25821/cx25821-core.c +0 −3
  92. drivers/media/pci/cx88/cx88-video.c +16 −44
  93. drivers/media/pci/dt3155/dt3155.c +1 −1
  94. drivers/media/pci/dt3155/dt3155.h +1 −1
  95. drivers/media/pci/ivtv/ivtv-cards.c +1 −1
  96. drivers/media/pci/meye/meye.c +5 −10
  97. drivers/media/pci/meye/meye.h +0 −2
  98. drivers/media/pci/saa7164/saa7164-core.c +0 −3
  99. drivers/media/pci/solo6x10/solo6x10-core.c +1 −1
  100. drivers/media/pci/solo6x10/solo6x10-disp.c +1 −1
  101. drivers/media/pci/solo6x10/solo6x10-eeprom.c +1 −1
  102. drivers/media/pci/solo6x10/solo6x10-enc.c +1 −1
  103. drivers/media/pci/solo6x10/solo6x10-g723.c +1 −1
  104. drivers/media/pci/solo6x10/solo6x10-gpio.c +1 −1
  105. drivers/media/pci/solo6x10/solo6x10-i2c.c +1 −1
  106. drivers/media/pci/solo6x10/solo6x10-jpeg.h +1 −1
  107. drivers/media/pci/solo6x10/solo6x10-offsets.h +1 −1
  108. drivers/media/pci/solo6x10/solo6x10-p2m.c +1 −1
  109. drivers/media/pci/solo6x10/solo6x10-regs.h +1 −1
  110. drivers/media/pci/solo6x10/solo6x10-tw28.c +1 −1
  111. drivers/media/pci/solo6x10/solo6x10-tw28.h +1 −1
  112. drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +1 −1
  113. drivers/media/pci/solo6x10/solo6x10-v4l2.c +1 −1
  114. drivers/media/pci/solo6x10/solo6x10.h +1 −1
  115. drivers/media/pci/sta2x11/sta2x11_vip.c +15 −48
  116. drivers/media/pci/ttpci/av7110.c +3 −2
  117. drivers/media/pci/ttpci/budget-core.c +8 −3
  118. drivers/media/pci/tw5864/tw5864-core.c +1 −1
  119. drivers/media/pci/tw68/tw68-core.c +12 −20
  120. drivers/media/platform/am437x/am437x-vpfe.c +3 −16
  121. drivers/media/platform/atmel/atmel-isc-base.c +24 −36
  122. drivers/media/platform/atmel/atmel-isc-regs.h +0 −2
  123. drivers/media/platform/atmel/atmel-isc.h +1 −1
  124. drivers/media/platform/atmel/atmel-sama5d2-isc.c +2 −0
  125. drivers/media/platform/coda/coda-common.c +2 −3
  126. drivers/media/platform/coda/coda-jpeg.c +4 −1
  127. drivers/media/platform/davinci/vpbe_display.c +1 −1
  128. drivers/media/platform/davinci/vpif.c +2 −1
  129. drivers/media/platform/davinci/vpif.h +1 −1
  130. drivers/media/platform/davinci/vpif_capture.c +0 −2
  131. drivers/media/platform/davinci/vpif_display.c +1 −1
  132. drivers/media/platform/davinci/vpif_display.h +1 −1
  133. drivers/media/platform/davinci/vpss.c +16 −4
  134. drivers/media/platform/exynos-gsc/gsc-core.c +1 −1
  135. drivers/media/platform/exynos-gsc/gsc-m2m.c +1 −1
  136. drivers/media/platform/exynos4-is/fimc-capture.c +6 −16
  137. drivers/media/platform/exynos4-is/fimc-is.c +1 −0
  138. drivers/media/platform/exynos4-is/fimc-isp-video.c +1 −0
  139. drivers/media/platform/exynos4-is/fimc-lite.c +3 −15
  140. drivers/media/platform/exynos4-is/media-dev.c +4 −1
  141. drivers/media/platform/marvell-ccic/cafe-driver.c +7 −24
  142. drivers/media/platform/marvell-ccic/mcam-core.c +2 −3
  143. drivers/media/platform/marvell-ccic/mcam-core.h +0 −2
  144. drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +1 −1
  145. drivers/media/platform/mtk-mdp/mtk_mdp_comp.c +19 −57
  146. drivers/media/platform/mtk-mdp/mtk_mdp_comp.h +4 −19
  147. drivers/media/platform/mtk-mdp/mtk_mdp_core.c +44 −25
  148. drivers/media/platform/mtk-mdp/mtk_mdp_core.h +8 −4
  149. drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +37 −60
  150. drivers/media/platform/omap3isp/isppreview.c +3 −1
  151. drivers/media/platform/pxa_camera.c +9 −12
  152. drivers/media/platform/qcom/camss/camss-csid.c +4 −2
  153. drivers/media/platform/qcom/camss/camss-csiphy.c +1 −1
  154. drivers/media/platform/qcom/camss/camss-ispif.c +4 −2
  155. drivers/media/platform/qcom/camss/camss-vfe.c +4 −6
  156. drivers/media/platform/qcom/camss/camss.c +20 −10
  157. drivers/media/platform/qcom/venus/pm_helpers.c +4 −0
  158. drivers/media/platform/qcom/venus/venc.c +1 −2
  159. drivers/media/platform/rcar-vin/rcar-csi2.c +8 −7
  160. drivers/media/platform/rcar-vin/rcar-dma.c +19 −2
  161. drivers/media/platform/rcar-vin/rcar-v4l2.c +12 −3
  162. drivers/media/platform/rcar_jpu.c +1 −1
  163. drivers/media/platform/rockchip/rga/rga-hw.c +16 −13
  164. drivers/media/platform/rockchip/rga/rga-hw.h +5 −0
  165. drivers/media/platform/s3c-camif/camif-core.c +1 −1
  166. drivers/media/platform/s5p-g2d/g2d.c +15 −13
  167. drivers/media/platform/s5p-jpeg/jpeg-core.c +2 −14
  168. drivers/media/platform/sti/hva/hva-v4l2.c +1 −1
  169. drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +2 −0
  170. drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c +1 −1
  171. drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c +2 −3
  172. drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +2 −0
  173. drivers/media/platform/ti-vpe/Makefile +1 −1
  174. drivers/media/platform/ti-vpe/cal-camerarx.c +649 −0
  175. drivers/media/platform/ti-vpe/cal-video.c +886 −0
  176. drivers/media/platform/ti-vpe/cal.c +489 −2034
  177. drivers/media/platform/ti-vpe/cal.h +267 −0
  178. drivers/media/platform/ti-vpe/cal_regs.h +36 −38
  179. drivers/media/platform/ti-vpe/vpe.c +1 −1
  180. drivers/media/platform/vsp1/vsp1_dl.c +2 −0
  181. drivers/media/platform/xilinx/Kconfig +7 −0
  182. drivers/media/platform/xilinx/Makefile +1 −0
  183. drivers/media/platform/xilinx/xilinx-csi2rxss.c +1111 −0
  184. drivers/media/radio/si4713/radio-usb-si4713.c +1 −1
  185. drivers/media/rc/Kconfig +11 −0
  186. drivers/media/rc/Makefile +1 −0
  187. drivers/media/rc/fintek-cir.c +0 −7
  188. drivers/media/rc/imon.c +1 −1
  189. drivers/media/rc/ir_toy.c +509 −0
  190. drivers/media/rc/nuvoton-cir.c +0 −32
  191. drivers/media/rc/rc-main.c +1 −1
  192. drivers/media/test-drivers/vicodec/vicodec-core.c +3 −3
  193. drivers/media/test-drivers/vimc/Kconfig +2 −0
  194. drivers/media/test-drivers/vimc/vimc-common.h +1 −0
  195. drivers/media/test-drivers/vimc/vimc-core.c +10 −0
  196. drivers/media/test-drivers/vimc/vimc-sensor.c +71 −0
  197. drivers/media/test-drivers/vivid/vivid-core.c +11 −2
  198. drivers/media/usb/cx231xx/cx231xx-417.c +1 −1
  199. drivers/media/usb/dvb-usb-v2/dvbsky.c +4 −4
  200. drivers/media/usb/dvb-usb/Kconfig +1 −0
  201. drivers/media/usb/go7007/go7007-usb.c +10 −1
  202. drivers/media/usb/gspca/gspca.c +1 −1
  203. drivers/media/usb/gspca/jl2005bcd.c +1 −1
  204. drivers/media/usb/gspca/ov534.c +1 −1
  205. drivers/media/usb/gspca/sn9c2028.c +1 −1
  206. drivers/media/v4l2-core/v4l2-async.c +75 −8
  207. drivers/media/v4l2-core/v4l2-compat-ioctl32.c +8 −2
  208. drivers/media/v4l2-core/v4l2-ioctl.c +11 −8
  209. drivers/media/v4l2-core/v4l2-mem2mem.c +3 −3
  210. drivers/staging/media/Kconfig +0 −2
  211. drivers/staging/media/Makefile +0 −1
  212. drivers/staging/media/allegro-dvt/allegro-core.c +228 −163
  213. drivers/staging/media/allegro-dvt/allegro-mail.c +506 −0
  214. drivers/staging/media/allegro-dvt/allegro-mail.h +69 −42
  215. drivers/staging/media/hantro/hantro.h +3 −10
  216. drivers/staging/media/hantro/hantro_drv.c +43 −51
  217. drivers/staging/media/hantro/hantro_h1_jpeg_enc.c +17 −0
  218. drivers/staging/media/hantro/hantro_h264.c +2 −4
  219. drivers/staging/media/hantro/hantro_hw.h +3 −2
  220. drivers/staging/media/hantro/hantro_v4l2.c +15 −15
  221. drivers/staging/media/hantro/imx8m_vpu_hw.c +1 −1
  222. drivers/staging/media/hantro/rk3288_vpu_hw.c +4 −4
  223. drivers/staging/media/hantro/rk3399_vpu_hw.c +3 −4
  224. drivers/staging/media/imx/imx-ic-prp.c +2 −2
  225. drivers/staging/media/imx/imx-ic-prpencvf.c +2 −2
  226. drivers/staging/media/imx/imx-media-csi.c +2 −2
  227. drivers/staging/media/imx/imx-media-vdic.c +2 −2
  228. drivers/staging/media/rkisp1/TODO +0 −1
  229. drivers/staging/media/rkisp1/rkisp1-capture.c +20 −36
  230. drivers/staging/media/rkisp1/rkisp1-common.h +15 −11
  231. drivers/staging/media/rkisp1/rkisp1-dev.c +8 −3
  232. drivers/staging/media/rkisp1/rkisp1-isp.c +38 −37
  233. drivers/staging/media/rkisp1/rkisp1-params.c +1 −1
  234. drivers/staging/media/rkisp1/rkisp1-regs.h +0 −1
  235. drivers/staging/media/rkisp1/rkisp1-resizer.c +9 −9
  236. drivers/staging/media/rkisp1/rkisp1-stats.c +17 −109
  237. drivers/staging/media/rkisp1/uapi/rkisp1-config.h +2 −2
  238. drivers/staging/media/rkvdec/rkvdec.c +28 −1
  239. drivers/staging/media/soc_camera/Kconfig +0 −51
  240. drivers/staging/media/soc_camera/Makefile +0 −7
  241. drivers/staging/media/soc_camera/TODO +0 −4
  242. drivers/staging/media/soc_camera/imx074.c +0 −492
  243. drivers/staging/media/soc_camera/mt9t031.c +0 −853
  244. drivers/staging/media/soc_camera/soc-camera.rst +0 −171
  245. drivers/staging/media/soc_camera/soc_camera.c +0 −2164
  246. drivers/staging/media/soc_camera/soc_mediabus.c +0 −529
  247. drivers/staging/media/soc_camera/soc_mt9v022.c +0 −1008
  248. drivers/staging/media/soc_camera/soc_ov5642.c +0 −1085
  249. drivers/staging/media/soc_camera/soc_ov9740.c +0 −992
  250. drivers/staging/media/tegra-vde/vde.c +27 −18
  251. drivers/usb/class/cdc-acm.c +6 −0
  252. include/linux/platform_data/media/omap1_camera.h +0 −32
  253. include/linux/property.h +5 −0
  254. include/media/cec.h +55 −2
  255. include/media/davinci/vpbe_display.h +1 −1
  256. include/media/drv-intf/soc_mediabus.h +0 −107
  257. include/media/dvbdev.h +3 −3
  258. include/media/media-device.h +1 −1
  259. include/media/media-devnode.h +1 −1
  260. include/media/media-entity.h +1 −1
  261. include/media/soc_camera.h +0 −397
  262. include/media/tpg/v4l2-tpg.h +2 −1
  263. include/media/v4l2-mc.h +4 −4
  264. include/media/v4l2-rect.h +20 −0
  265. include/media/v4l2-subdev.h +20 −19
  266. include/media/videobuf2-core.h +40 −11
  267. include/media/videobuf2-v4l2.h +13 −0
  268. include/uapi/linux/videodev2.h +15 −2
Documentation/admin-guide/media/fimc.rst+3−3
@@ -2,7 +2,7 @@ · 1 unmodified line
2 2
3.. include:: <isonum.txt>3.. include:: <isonum.txt>
4 4
5The Samsung S5P/EXYNOS4 FIMC driver5The Samsung S5P/Exynos4 FIMC driver
6===================================6===================================
7 7
8Copyright |copy| 2012 - 2013 Samsung Electronics Co., Ltd.8Copyright |copy| 2012 - 2013 Samsung Electronics Co., Ltd.
@@ -19,7 +19,7 @@ drivers/media/platform/exynos4-is directory. · 10 unmodified lines
19Supported SoCs19Supported SoCs
20--------------20--------------
21 21
22S5PC100 (mem-to-mem only), S5PV210, EXYNOS421022S5PC100 (mem-to-mem only), S5PV210, Exynos4210
23 23
24Supported features24Supported features
25------------------25------------------
@@ -45,7 +45,7 @@ Media device interface · 19 unmodified lines
45~~~~~~~~~~~~~~~~~~~~~~45~~~~~~~~~~~~~~~~~~~~~~
46 46
47The driver supports Media Controller API as defined at :ref:`media_controller`.47The driver supports Media Controller API as defined at :ref:`media_controller`.
48The media device driver name is "SAMSUNG S5P FIMC".48The media device driver name is "Samsung S5P FIMC".
49 49
50The purpose of this interface is to allow changing assignment of FIMC instances50The purpose of this interface is to allow changing assignment of FIMC instances
51to the SoC peripheral camera input at runtime and optionally to control internal51to the SoC peripheral camera input at runtime and optionally to control internal
Documentation/admin-guide/media/vivid.rst+9−0
@@ -293,6 +293,15 @@ all configurable using the following module options: · 292 unmodified lines
293 - 0: vmalloc293 - 0: vmalloc
294 - 1: dma-contig294 - 1: dma-contig
295 295
296- cache_hints:
297
298 specifies if the device should set queues' user-space cache and memory
299 consistency hint capability (V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS).
300 The hints are valid only when using MMAP streaming I/O. Default is 0.
301
302 - 0: forbid hints
303 - 1: allow hints
304
296Taken together, all these module options allow you to precisely customize305Taken together, all these module options allow you to precisely customize
297the driver behavior and test your application with all sorts of permutations.306the driver behavior and test your application with all sorts of permutations.
298It is also very suitable to emulate hardware that is not yet available, e.g.307It is also very suitable to emulate hardware that is not yet available, e.g.
Documentation/devicetree/bindings/media/i2c/chrontel,ch7322.yaml+67−0
@@ -0,0 +1,67 @@
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/chrontel,ch7322.yaml#"
5$schema: "http://devicetree.org/meta-schemas/core.yaml#"
6
7title: Chrontel HDMI-CEC Controller
8
9maintainers:
10 - Jeff Chase <jnchase@google.com>
11
12description:
13 The Chrontel CH7322 is a discrete HDMI-CEC controller. It is
14 programmable through I2C and drives a single CEC line.
15
16properties:
17 compatible:
18 const: chrontel,ch7322
19
20 reg:
21 description: I2C device address
22 maxItems: 1
23
24 clocks:
25 maxItems: 1
26
27 interrupts:
28 maxItems: 1
29
30 reset-gpios:
31 description:
32 Reference to the GPIO connected to the RESET pin, if any. This
33 pin is active-low.
34 maxItems: 1
35
36 standby-gpios:
37 description:
38 Reference to the GPIO connected to the OE pin, if any. When low
39 the device will respond to power status requests with "standby"
40 if in auto mode.
41 maxItems: 1
42
43 # see ../cec.txt
44 hdmi-phandle:
45 description: phandle to the HDMI controller
46
47required:
48 - compatible
49 - reg
50 - interrupts
51
52examples:
53 - |
54 #include <dt-bindings/gpio/gpio.h>
55 #include <dt-bindings/interrupt-controller/irq.h>
56 i2c {
57 #address-cells = <1>;
58 #size-cells = <0>;
59 ch7322@75 {
60 compatible = "chrontel,ch7322";
61 reg = <0x75>;
62 interrupts = <47 IRQ_TYPE_EDGE_RISING>;
63 standby-gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
64 reset-gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
65 hdmi-phandle = <&hdmi>;
66 };
67 };
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml+100−0
@@ -0,0 +1,100 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2# Copyright (c) 2020 MediaTek Inc.
3%YAML 1.2
4---
5$id: http://devicetree.org/schemas/media/i2c/dongwoon,dw9768.yaml#
6$schema: http://devicetree.org/meta-schemas/core.yaml#
7
8title: Dongwoon Anatech DW9768 Voice Coil Motor (VCM) Lens Device Tree Bindings
9
10maintainers:
11 - Dongchun Zhu <dongchun.zhu@mediatek.com>
12
13description: |-
14 The Dongwoon DW9768 is a single 10-bit digital-to-analog (DAC) converter
15 with 100 mA output current sink capability. VCM current is controlled with
16 a linear mode driver. The DAC is controlled via a 2-wire (I2C-compatible)
17 serial interface that operates at clock rates up to 1MHz. This chip
18 integrates Advanced Actuator Control (AAC) technology and is intended for
19 driving voice coil lenses in camera modules.
20
21properties:
22 compatible:
23 enum:
24 - dongwoon,dw9768 # for DW9768 VCM
25 - giantec,gt9769 # for GT9769 VCM
26
27 reg:
28 maxItems: 1
29
30 vin-supply:
31 description:
32 Definition of the regulator used as Digital I/O voltage supply.
33
34 vdd-supply:
35 description:
36 Definition of the regulator used as Digital core voltage supply.
37
38 dongwoon,aac-mode:
39 description:
40 Indication of AAC mode select.
41 allOf:
42 - $ref: "/schemas/types.yaml#/definitions/uint32"
43 - enum:
44 - 1 # AAC2 mode(operation time# 0.48 x Tvib)
45 - 2 # AAC3 mode(operation time# 0.70 x Tvib)
46 - 3 # AAC4 mode(operation time# 0.75 x Tvib)
47 - 5 # AAC8 mode(operation time# 1.13 x Tvib)
48 default: 2
49
50 dongwoon,aac-timing:
51 description:
52 Number of AAC Timing count that controlled by one 6-bit period of
53 vibration register AACT[5:0], the unit of which is 100 us.
54 allOf:
55 - $ref: "/schemas/types.yaml#/definitions/uint32"
56 - default: 0x20
57 minimum: 0x00
58 maximum: 0x3f
59
60 dongwoon,clock-presc:
61 description:
62 Indication of VCM internal clock dividing rate select, as one multiple
63 factor to calculate VCM ring periodic time Tvib.
64 allOf:
65 - $ref: "/schemas/types.yaml#/definitions/uint32"
66 - enum:
67 - 0 # Dividing Rate - 2
68 - 1 # Dividing Rate - 1
69 - 2 # Dividing Rate - 1/2
70 - 3 # Dividing Rate - 1/4
71 - 4 # Dividing Rate - 8
72 - 5 # Dividing Rate - 4
73 default: 1
74
75required:
76 - compatible
77 - reg
78 - vin-supply
79 - vdd-supply
80
81additionalProperties: false
82
83examples:
84 - |
85
86 i2c {
87 #address-cells = <1>;
88 #size-cells = <0>;
89
90 dw9768: camera-lens@c {
91 compatible = "dongwoon,dw9768";
92 reg = <0x0c>;
93
94 vin-supply = <&mt6358_vcamio_reg>;
95 vdd-supply = <&mt6358_vcama2_reg>;
96 dongwoon,aac-timing = <0x39>;
97 };
98 };
99
100...
Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml+159−0
@@ -0,0 +1,159 @@
1# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
2# Copyright (C) 2019 Renesas Electronics Corp.
3%YAML 1.2
4---
5$id: http://devicetree.org/schemas/media/i2c/imi,rdacm2x-gmsl.yaml#
6$schema: http://devicetree.org/meta-schemas/core.yaml#
7
8title: IMI D&D RDACM20 and RDACM21 Automotive Camera Platforms
9
10maintainers:
11 - Jacopo Mondi <jacopo+renesas@jmondi.org>
12 - Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
13 - Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
14 - Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
15
16description: -|
17 The IMI D&D RDACM20 and RDACM21 are GMSL-compatible camera designed for
18 automotive applications.
19
20 The RDACM20 camera module encloses a Maxim Integrated MAX9271 GMSL serializer,
21 coupled with an OV10635 image sensor and an embedded MCU. Both the MCU and
22 the image sensor are connected to the serializer local I2C bus and are
23 accessible by the host SoC by direct addressing.
24
25 The RDACM21 camera module encloses the same serializer, coupled with an
26 OV10640 image sensor and an OV490 ISP. Only the OV490 ISP is interfaced to
27 the serializer local I2C bus while the image sensor is not accessible from
28 the host SoC.
29
30 They both connect to a remote GMSL endpoint through a coaxial cable.
31
32 IMI RDACM20
33 +---------------+ +--------------------------------+
34 | GMSL | <- Video Stream | <- Video--------\ |
35 | |< === GMSL Link ====== >|MAX9271<- I2C bus-> <-->OV10635 |
36 | de-serializer | <- I2C messages -> | \<-->MCU |
37 +---------------+ +--------------------------------+
38
39 IMI RDACM21
40 +---------------+ +--------------------------------+
41 | GMSL | <- Video Stream | <- Video--------\ |
42 | |< === GMSL Link ====== >|MAX9271<- I2C bus-> <-->OV490 |
43 | | <- I2C messages -> | | |
44 | de-serializer | | OV10640 <-------| |
45 +---------------+ +--------------------------------+
46
47 Both camera modules serialize video data generated by the embedded camera
48 sensor on the GMSL serial channel to a remote GMSL de-serializer. They also
49 receive and transmit I2C messages encapsulated and transmitted on the GMSL
50 bidirectional control channel.
51
52 All I2C traffic received on the GMSL link not directed to the serializer is
53 propagated on the local I2C bus to the remote device there connected. All the
54 I2C traffic generated on the local I2C bus not directed to the serializer is
55 propagated to the remote de-serializer encapsulated in the GMSL control
56 channel.
57
58 The RDACM20 and RDACM21 DT node should be a direct child of the GMSL
59 deserializer's I2C bus corresponding to the GMSL link that the camera is
60 attached to.
61
62properties:
63 '#address-cells':
64 const: 1
65
66 '#size-cells':
67 const: 0
68
69 compatible:
70 enum:
71 - imi,rdacm20
72 - imi,rdacm21
73
74 reg:
75 description: -|
76 I2C device addresses, the first to be assigned to the serializer, the
77 following ones to be assigned to the remote devices.
78
79 For RDACM20 the second entry of the property is assigned to the
80 OV10635 image sensor and the optional third one to the embedded MCU.
81
82 For RDACM21 the second entry is assigned to the OV490 ISP and the optional
83 third one ignored.
84
85 minItems: 2
86 maxItems: 3
87
88 port:
89 type: object
90 additionalProperties: false
91 description: -|
92 Connection to the remote GMSL endpoint are modelled using the OF graph
93 bindings in accordance with the video interface bindings defined in
94 Documentation/devicetree/bindings/media/video-interfaces.txt.
95
96 The device node contains a single "port" child node with a single
97 "endpoint" sub-device.
98
99 properties:
100 endpoint:
101 type: object
102 additionalProperties: false
103
104 properties:
105 remote-endpoint:
106 description: -|
107 phandle to the remote GMSL endpoint sub-node in the remote node
108 port.
109 maxItems: 1
110
111 required:
112 - remote-endpoint
113
114 required:
115 - endpoint
116
117required:
118 - compatible
119 - reg
120 - port
121
122examples:
123 - |
124 i2c@e66d8000 {
125 #address-cells = <1>;
126 #size-cells = <0>;
127
128 reg = <0 0xe66d8000>;
129
130 camera@31 {
131 compatible = "imi,rdacm20";
132 reg = <0x31>, <0x41>, <0x51>;
133
134 port {
135 rdacm20_out0: endpoint {
136 remote-endpoint = <&max9286_in0>;
137 };
138 };
139 };
140 };
141
142 - |
143 i2c@e66d8000 {
144 #address-cells = <1>;
145 #size-cells = <0>;
146
147 reg = <0 0xe66d8000>;
148
149 camera@31 {
150 compatible = "imi,rdacm21";
151 reg = <0x31>, <0x41>;
152
153 port {
154 rdacm21_out0: endpoint {
155 remote-endpoint = <&max9286_in0>;
156 };
157 };
158 };
159 };
Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml+366−0
@@ -0,0 +1,366 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2# Copyright (C) 2019 Renesas Electronics Corp.
3%YAML 1.2
4---
5$id: http://devicetree.org/schemas/media/i2c/maxim,max9286.yaml#
6$schema: http://devicetree.org/meta-schemas/core.yaml#
7
8title: Maxim Integrated Quad GMSL Deserializer
9
10maintainers:
11 - Jacopo Mondi <jacopo+renesas@jmondi.org>
12 - Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
13 - Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
14 - Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
15
16description: |
17 The MAX9286 deserializer receives video data on up to 4 Gigabit Multimedia
18 Serial Links (GMSL) and outputs them on a CSI-2 D-PHY port using up to 4 data
19 lanes.
20
21 In addition to video data, the GMSL links carry a bidirectional control
22 channel that encapsulates I2C messages. The MAX9286 forwards all I2C traffic
23 not addressed to itself to the other side of the links, where a GMSL
24 serializer will output it on a local I2C bus. In the other direction all I2C
25 traffic received over GMSL by the MAX9286 is output on the local I2C bus.
26
27properties:
28 '#address-cells':
29 const: 1
30
31 '#size-cells':
32 const: 0
33
34 compatible:
35 const: maxim,max9286
36
37 reg:
38 description: I2C device address
39 maxItems: 1
40
41 poc-supply:
42 description: Regulator providing Power over Coax to the cameras
43 maxItems: 1
44
45 enable-gpios:
46 description: GPIO connected to the \#PWDN pin with inverted polarity
47 maxItems: 1
48
49 gpio-controller: true
50
51 '#gpio-cells':
52 const: 2
53
54 ports:
55 type: object
56 description: |
57 The connections to the MAX9286 GMSL and its endpoint nodes are modelled
58 using the OF graph bindings in accordance with the video interface
59 bindings defined in
60 Documentation/devicetree/bindings/media/video-interfaces.txt.
61
62 The following table lists the port number corresponding to each device
63 port.
64
65 Port Description
66 ----------------------------------------
67 Port 0 GMSL Input 0
68 Port 1 GMSL Input 1
69 Port 2 GMSL Input 2
70 Port 3 GMSL Input 3
71 Port 4 CSI-2 Output
72
73 properties:
74 '#address-cells':
75 const: 1
76
77 '#size-cells':
78 const: 0
79
80 port@[0-3]:
81 type: object
82 properties:
83 reg:
84 enum: [ 0, 1, 2, 3 ]
85
86 endpoint:
87 type: object
88
89 properties:
90 remote-endpoint:
91 description: |
92 phandle to the remote GMSL source endpoint subnode in the
93 remote node port.
94
95 required:
96 - remote-endpoint
97
98 required:
99 - reg
100 - endpoint
101
102 additionalProperties: false
103
104 port@4:
105 type: object
106 properties:
107 reg:
108 const: 4
109
110 endpoint:
111 type: object
112
113 properties:
114 remote-endpoint:
115 description: phandle to the remote CSI-2 sink endpoint.
116
117 data-lanes:
118 description: array of physical CSI-2 data lane indexes.
119
120 required:
121 - remote-endpoint
122 - data-lanes
123
124 required:
125 - reg
126 - endpoint
127
128 additionalProperties: false
129
130 required:
131 - port@4
132
133 i2c-mux:
134 type: object
135 description: |
136 Each GMSL link is modelled as a child bus of an i2c bus
137 multiplexer/switch, in accordance with bindings described in
138 Documentation/devicetree/bindings/i2c/i2c-mux.txt.
139
140 properties:
141 '#address-cells':
142 const: 1
143
144 '#size-cells':
145 const: 0
146
147 patternProperties:
148 "^i2c@[0-3]$":
149 type: object
150 description: |
151 Child node of the i2c bus multiplexer which represents a GMSL link.
152 Each serializer device on the GMSL link remote end is represented with
153 an i2c-mux child node. The MAX9286 chip supports up to 4 GMSL
154 channels.
155
156 properties:
157 '#address-cells':
158 const: 1
159
160 '#size-cells':
161 const: 0
162
163 reg:
164 description: The index of the GMSL channel.
165 maxItems: 1
166
167 patternProperties:
168 "^camera@[a-f0-9]+$":
169 type: object
170 description: |
171 The remote camera device, composed by a GMSL serializer and a
172 connected video source.
173
174 properties:
175 compatible:
176 description: The remote device compatible string.
177
178 reg:
179 minItems: 2
180 maxItems: 3
181 description: |
182 The I2C addresses to be assigned to the remote devices through
183 address reprogramming. The number of entries depends on the
184 requirements of the currently connected remote device.
185
186 port:
187 type: object
188
189 properties:
190 endpoint:
191 type: object
192
193 properties:
194 remote-endpoint:
195 description: phandle to the MAX9286 sink endpoint.
196
197 required:
198 - remote-endpoint
199
200 additionalProperties: false
201
202 required:
203 - endpoint
204
205 additionalProperties: false
206
207 required:
208 - compatible
209 - reg
210 - port
211
212 additionalProperties: false
213
214 additionalProperties: false
215
216 additionalProperties: false
217
218required:
219 - compatible
220 - reg
221 - ports
222 - i2c-mux
223 - gpio-controller
224
225additionalProperties: false
226
227examples:
228 - |
229 #include <dt-bindings/gpio/gpio.h>
230
231 i2c@e66d8000 {
232 #address-cells = <1>;
233 #size-cells = <0>;
234
235 reg = <0 0xe66d8000>;
236
237 gmsl-deserializer@2c {
238 compatible = "maxim,max9286";
239 reg = <0x2c>;
240 poc-supply = <&camera_poc_12v>;
241 enable-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
242
243 gpio-controller;
244 #gpio-cells = <2>;
245
246 ports {
247 #address-cells = <1>;
248 #size-cells = <0>;
249
250 port@0 {
251 reg = <0>;
252
253 max9286_in0: endpoint {
254 remote-endpoint = <&rdacm20_out0>;
255 };
256 };
257
258 port@1 {
259 reg = <1>;
260
261 max9286_in1: endpoint {
262 remote-endpoint = <&rdacm20_out1>;
263 };
264 };
265
266 port@2 {
267 reg = <2>;
268
269 max9286_in2: endpoint {
270 remote-endpoint = <&rdacm20_out2>;
271 };
272 };
273
274 port@3 {
275 reg = <3>;
276
277 max9286_in3: endpoint {
278 remote-endpoint = <&rdacm20_out3>;
279 };
280 };
281
282 port@4 {
283 reg = <4>;
284
285 max9286_out: endpoint {
286 data-lanes = <1 2 3 4>;
287 remote-endpoint = <&csi40_in>;
288 };
289 };
290 };
291
292 i2c-mux {
293 #address-cells = <1>;
294 #size-cells = <0>;
295
296 i2c@0 {
297 #address-cells = <1>;
298 #size-cells = <0>;
299 reg = <0>;
300
301 camera@51 {
302 compatible = "imi,rdacm20";
303 reg = <0x51>, <0x61>;
304
305 port {
306 rdacm20_out0: endpoint {
307 remote-endpoint = <&max9286_in0>;
308 };
309 };
310
311 };
312 };
313
314 i2c@1 {
315 #address-cells = <1>;
316 #size-cells = <0>;
317 reg = <1>;
318
319 camera@52 {
320 compatible = "imi,rdacm20";
321 reg = <0x52>, <0x62>;
322
323 port {
324 rdacm20_out1: endpoint {
325 remote-endpoint = <&max9286_in1>;
326 };
327 };
328 };
329 };
330
331 i2c@2 {
332 #address-cells = <1>;
333 #size-cells = <0>;
334 reg = <2>;
335
336 camera@53 {
337 compatible = "imi,rdacm20";
338 reg = <0x53>, <0x63>;
339
340 port {
341 rdacm20_out2: endpoint {
342 remote-endpoint = <&max9286_in2>;
343 };
344 };
345 };
346 };
347
348 i2c@3 {
349 #address-cells = <1>;
350 #size-cells = <0>;
351 reg = <3>;
352
353 camera@54 {
354 compatible = "imi,rdacm20";
355 reg = <0x54>, <0x64>;
356
357 port {
358 rdacm20_out3: endpoint {
359 remote-endpoint = <&max9286_in3>;
360 };
361 };
362 };
363 };
364 };
365 };
366 };
Documentation/devicetree/bindings/media/renesas,fcp.txt+0−34
@@ -1,34 +0,0 @@
1Renesas R-Car Frame Compression Processor (FCP)
2-----------------------------------------------
3
4The FCP is a companion module of video processing modules in the Renesas R-Car
5Gen3 and RZ/G2 SoCs. It provides data compression and decompression, data
6caching, and conversion of AXI transactions in order to reduce the memory
7bandwidth.
8
9There are three types of FCP: FCP for Codec (FCPC), FCP for VSP (FCPV) and FCP
10for FDP (FCPF). Their configuration and behaviour depend on the module they
11are paired with. These DT bindings currently support the FCPV and FCPF.
12
13 - compatible: Must be one or more of the following
14
15 - "renesas,fcpv" for generic compatible 'FCP for VSP'
16 - "renesas,fcpf" for generic compatible 'FCP for FDP'
17
18 - reg: the register base and size for the device registers
19 - clocks: Reference to the functional clock
20
21Optional properties:
22 - power-domains : power-domain property defined with a power domain specifier
23 to respective power domain.
24
25
26Device node example
27-------------------
28
29 fcpvd1: fcp@fea2f000 {
30 compatible = "renesas,fcpv";
31 reg = <0 0xfea2f000 0 0x200>;
32 clocks = <&cpg CPG_MOD 602>;
33 power-domains = <&sysc R8A7795_PD_A3VP>;
34 };
Documentation/devicetree/bindings/media/renesas,fcp.yaml+66−0
@@ -0,0 +1,66 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/media/renesas,fcp.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Renesas R-Car Frame Compression Processor (FCP)
8
9maintainers:
10 - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11
12description: |
13 The FCP is a companion module of video processing modules in the Renesas
14 R-Car Gen3 and RZ/G2 SoCs. It provides data compression and decompression,
15 data caching, and conversion of AXI transactions in order to reduce the
16 memory bandwidth.
17
18 There are three types of FCP: FCP for Codec (FCPC), FCP for VSP (FCPV) and
19 FCP for FDP (FCPF). Their configuration and behaviour depend on the module
20 they are paired with. These DT bindings currently support the FCPV and FCPF.
21
22properties:
23 compatible:
24 enum:
25 - renesas,fcpv # FCP for VSP
26 - renesas,fcpf # FCP for FDP
27
28 reg:
29 maxItems: 1
30
31 clocks:
32 maxItems: 1
33
34 iommus:
35 maxItems: 1
36
37 power-domains:
38 maxItems: 1
39
40 resets:
41 maxItems: 1
42
43required:
44 - compatible
45 - reg
46 - clocks
47 - power-domains
48 - resets
49
50additionalProperties: false
51
52examples:
53 # R8A7795 (R-Car H3) FCP for VSP-D1
54 - |
55 #include <dt-bindings/clock/renesas-cpg-mssr.h>
56 #include <dt-bindings/power/r8a7795-sysc.h>
57
58 fcp@fea2f000 {
59 compatible = "renesas,fcpv";
60 reg = <0xfea2f000 0x200>;
61 clocks = <&cpg CPG_MOD 602>;
62 power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
63 resets = <&cpg 602>;
64 iommus = <&ipmmu_vi0 9>;
65 };
66...
Documentation/devicetree/bindings/media/renesas,fdp1.txt+0−37
@@ -1,37 +0,0 @@
1Renesas R-Car Fine Display Processor (FDP1)
2-------------------------------------------
3
4The FDP1 is a de-interlacing module which converts interlaced video to
5progressive video. It is capable of performing pixel format conversion between
6YCbCr/YUV formats and RGB formats. Only YCbCr/YUV formats are supported as
7an input to the module.
8
9Required properties:
10
11 - compatible: must be "renesas,fdp1"
12 - reg: the register base and size for the device registers
13 - interrupts : interrupt specifier for the FDP1 instance
14 - clocks: reference to the functional clock
15
16Optional properties:
17
18 - power-domains: reference to the power domain that the FDP1 belongs to, if
19 any.
20 - renesas,fcp: a phandle referencing the FCP that handles memory accesses
21 for the FDP1. Not needed on Gen2, mandatory on Gen3.
22
23Please refer to the binding documentation for the clock and/or power domain
24providers for more details.
25
26
27Device node example
28-------------------
29
30 fdp1@fe940000 {
31 compatible = "renesas,fdp1";
32 reg = <0 0xfe940000 0 0x2400>;
33 interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
34 clocks = <&cpg CPG_MOD 119>;
35 power-domains = <&sysc R8A7795_PD_A3VP>;
36 renesas,fcp = <&fcpf0>;
37 };
Documentation/devicetree/bindings/media/renesas,fdp1.yaml+69−0
@@ -0,0 +1,69 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/media/renesas,fdp1.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Renesas R-Car Fine Display Processor (FDP1)
8
9maintainers:
10 - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11
12description:
13 The FDP1 is a de-interlacing module which converts interlaced video to
14 progressive video. It is capable of performing pixel format conversion
15 between YCbCr/YUV formats and RGB formats. Only YCbCr/YUV formats are
16 supported as an input to the module.
17
18properties:
19 compatible:
20 enum:
21 - renesas,fdp1
22
23 reg:
24 maxItems: 1
25
26 interrupts:
27 maxItems: 1
28
29 clocks:
30 maxItems: 1
31
32 power-domains:
33 maxItems: 1
34
35 resets:
36 maxItems: 1
37
38 renesas,fcp:
39 $ref: /schemas/types.yaml#/definitions/phandle
40 description:
41 A phandle referencing the FCP that handles memory accesses for the FDP1.
42 Not allowed on R-Car Gen2, mandatory on R-Car Gen3.
43
44required:
45 - compatible
46 - reg
47 - interrupts
48 - clocks
49 - power-domains
50 - resets
51
52additionalProperties: false
53
54examples:
55 - |
56 #include <dt-bindings/clock/renesas-cpg-mssr.h>
57 #include <dt-bindings/interrupt-controller/arm-gic.h>
58 #include <dt-bindings/power/r8a7795-sysc.h>
59
60 fdp1@fe940000 {
61 compatible = "renesas,fdp1";
62 reg = <0xfe940000 0x2400>;
63 interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
64 clocks = <&cpg CPG_MOD 119>;
65 power-domains = <&sysc R8A7795_PD_A3VP>;
66 resets = <&cpg 119>;
67 renesas,fcp = <&fcpf0>;
68 };
69...
Documentation/devicetree/bindings/media/renesas,vsp1.txt+0−30
@@ -1,30 +0,0 @@
1* Renesas VSP Video Processing Engine
2
3The VSP is a video processing engine that supports up-/down-scaling, alpha
4blending, color space conversion and various other image processing features.
5It can be found in the Renesas R-Car Gen2, R-Car Gen3, RZ/G1, and RZ/G2 SoCs.
6
7Required properties:
8
9 - compatible: Must contain one of the following values
10 - "renesas,vsp1" for the R-Car Gen2 and RZ/G1 VSP1
11 - "renesas,vsp2" for the R-Car Gen3 and RZ/G2 VSP2
12
13 - reg: Base address and length of the registers block for the VSP.
14 - interrupts: VSP interrupt specifier.
15 - clocks: A phandle + clock-specifier pair for the VSP functional clock.
16
17Optional properties:
18
19 - renesas,fcp: A phandle referencing the FCP that handles memory accesses
20 for the VSP. Not needed on Gen2, mandatory on Gen3.
21
22
23Example: R8A7790 (R-Car H2) VSP1-S node
24
25 vsp@fe928000 {
26 compatible = "renesas,vsp1";
27 reg = <0 0xfe928000 0 0x8000>;
28 interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
29 clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
30 };
Documentation/devicetree/bindings/media/renesas,vsp1.yaml+97−0
@@ -0,0 +1,97 @@
1# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/media/renesas,vsp1.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Renesas VSP Video Processing Engine
8
9maintainers:
10 - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11
12description:
13 The VSP is a video processing engine that supports up-/down-scaling, alpha
14 blending, color space conversion and various other image processing features.
15 It can be found in the Renesas R-Car Gen2, R-Car Gen3, RZ/G1, and RZ/G2 SoCs.
16
17properties:
18 compatible:
19 enum:
20 - renesas,vsp1 # R-Car Gen2 and RZ/G1
21 - renesas,vsp2 # R-Car Gen3 and RZ/G2
22
23 reg:
24 maxItems: 1
25
26 interrupts:
27 maxItems: 1
28
29 clocks:
30 maxItems: 1
31
32 power-domains:
33 maxItems: 1
34
35 resets:
36 maxItems: 1
37
38 renesas,fcp:
39 $ref: /schemas/types.yaml#/definitions/phandle
40 description:
41 A phandle referencing the FCP that handles memory accesses for the VSP.
42
43required:
44 - compatible
45 - reg
46 - interrupts
47 - clocks
48 - power-domains
49 - resets
50
51additionalProperties: false
52
53if:
54 properties:
55 compatible:
56 items:
57 - const: renesas,vsp1
58then:
59 properties:
60 renesas,fcp: false
61else:
62 required:
63 - renesas,fcp
64
65examples:
66 # R8A7790 (R-Car H2) VSP1-S
67 - |
68 #include <dt-bindings/clock/renesas-cpg-mssr.h>
69 #include <dt-bindings/interrupt-controller/arm-gic.h>
70 #include <dt-bindings/power/r8a7790-sysc.h>
71
72 vsp@fe928000 {
73 compatible = "renesas,vsp1";
74 reg = <0xfe928000 0x8000>;
75 interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
76 clocks = <&cpg CPG_MOD 131>;
77 power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
78 resets = <&cpg 131>;
79 };
80
81 # R8A77951 (R-Car H3) VSP2-BC
82 - |
83 #include <dt-bindings/clock/renesas-cpg-mssr.h>
84 #include <dt-bindings/interrupt-controller/arm-gic.h>
85 #include <dt-bindings/power/r8a7795-sysc.h>
86
87 vsp@fe920000 {
88 compatible = "renesas,vsp2";
89 reg = <0xfe920000 0x8000>;
90 interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
91 clocks = <&cpg CPG_MOD 624>;
92 power-domains = <&sysc R8A7795_PD_A3VP>;
93 resets = <&cpg 624>;
94
95 renesas,fcp = <&fcpvb1>;
96 };
97...
Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml+237−0
@@ -0,0 +1,237 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/media/xilinx/xlnx,csi2rxss.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Xilinx MIPI CSI-2 Receiver Subsystem
8
9maintainers:
10 - Vishal Sagar <vishal.sagar@xilinx.com>
11
12description: |
13 The Xilinx MIPI CSI-2 Receiver Subsystem is used to capture MIPI CSI-2
14 traffic from compliant camera sensors and send the output as AXI4 Stream
15 video data for image processing.
16 The subsystem consists of a MIPI D-PHY in slave mode which captures the
17 data packets. This is passed along the MIPI CSI-2 Rx IP which extracts the
18 packet data. The optional Video Format Bridge (VFB) converts this data to
19 AXI4 Stream video data.
20 For more details, please refer to PG232 Xilinx MIPI CSI-2 Receiver Subsystem.
21 Please note that this bindings includes only the MIPI CSI-2 Rx controller
22 and Video Format Bridge and not D-PHY.
23
24properties:
25 compatible:
26 items:
27 - enum:
28 - xlnx,mipi-csi2-rx-subsystem-5.0
29
30 reg:
31 maxItems: 1
32
33 interrupts:
34 maxItems: 1
35
36 clocks:
37 description: List of clock specifiers
38 items:
39 - description: AXI Lite clock
40 - description: Video clock
41
42 clock-names:
43 items:
44 - const: lite_aclk
45 - const: video_aclk
46
47 xlnx,csi-pxl-format:
48 description: |
49 This denotes the CSI Data type selected in hw design.
50 Packets other than this data type (except for RAW8 and
51 User defined data types) will be filtered out.
52 Possible values are as below -
53 0x1e - YUV4228B
54 0x1f - YUV42210B
55 0x20 - RGB444
56 0x21 - RGB555
57 0x22 - RGB565
58 0x23 - RGB666
59 0x24 - RGB888
60 0x28 - RAW6
61 0x29 - RAW7
62 0x2a - RAW8
63 0x2b - RAW10
64 0x2c - RAW12
65 0x2d - RAW14
66 0x2e - RAW16
67 0x2f - RAW20
68 allOf:
69 - $ref: /schemas/types.yaml#/definitions/uint32
70 - anyOf:
71 - minimum: 0x1e
72 - maximum: 0x24
73 - minimum: 0x28
74 - maximum: 0x2f
75
76 xlnx,vfb:
77 type: boolean
78 description: Present when Video Format Bridge is enabled in IP configuration
79
80 xlnx,en-csi-v2-0:
81 type: boolean
82 description: Present if CSI v2 is enabled in IP configuration.
83
84 xlnx,en-vcx:
85 type: boolean
86 description: |
87 When present, there are maximum 16 virtual channels, else only 4.
88
89 xlnx,en-active-lanes:
90 type: boolean
91 description: |
92 Present if the number of active lanes can be re-configured at
93 runtime in the Protocol Configuration Register. Otherwise all lanes,
94 as set in IP configuration, are always active.
95
96 video-reset-gpios:
97 description: Optional specifier for a GPIO that asserts video_aresetn.
98 maxItems: 1
99
100 ports:
101 type: object
102
103 properties:
104 port@0:
105 type: object
106 description: |
107 Input / sink port node, single endpoint describing the
108 CSI-2 transmitter.
109
110 properties:
111 reg:
112 const: 0
113
114 endpoint:
115 type: object
116
117 properties:
118
119 data-lanes:
120 description: |
121 This is required only in the sink port 0 endpoint which
122 connects to MIPI CSI-2 source like sensor.
123 The possible values are -
124 1 - For 1 lane enabled in IP.
125 1 2 - For 2 lanes enabled in IP.
126 1 2 3 - For 3 lanes enabled in IP.
127 1 2 3 4 - For 4 lanes enabled in IP.
128 items:
129 - const: 1
130 - const: 2
131 - const: 3
132 - const: 4
133
134 remote-endpoint: true
135
136 required:
137 - data-lanes
138 - remote-endpoint
139
140 additionalProperties: false
141
142 additionalProperties: false
143
144 port@1:
145 type: object
146 description: |
147 Output / source port node, endpoint describing modules
148 connected the CSI-2 receiver.
149
150 properties:
151
152 reg:
153 const: 1
154
155 endpoint:
156 type: object
157
158 properties:
159
160 remote-endpoint: true
161
162 required:
163 - remote-endpoint
164
165 additionalProperties: false
166
167 additionalProperties: false
168
169required:
170 - compatible
171 - reg
172 - interrupts
173 - clocks
174 - clock-names
175 - ports
176
177allOf:
178 - if:
179 required:
180 - xlnx,vfb
181 then:
182 required:
183 - xlnx,csi-pxl-format
184 else:
185 properties:
186 xlnx,csi-pxl-format: false
187
188 - if:
189 not:
190 required:
191 - xlnx,en-csi-v2-0
192 then:
193 properties:
194 xlnx,en-vcx: false
195
196additionalProperties: false
197
198examples:
199 - |
200 #include <dt-bindings/gpio/gpio.h>
201 xcsi2rxss_1: csi2rx@a0020000 {
202 compatible = "xlnx,mipi-csi2-rx-subsystem-5.0";
203 reg = <0xa0020000 0x10000>;
204 interrupt-parent = <&gic>;
205 interrupts = <0 95 4>;
206 xlnx,csi-pxl-format = <0x2a>;
207 xlnx,vfb;
208 xlnx,en-active-lanes;
209 xlnx,en-csi-v2-0;
210 xlnx,en-vcx;
211 clock-names = "lite_aclk", "video_aclk";
212 clocks = <&misc_clk_0>, <&misc_clk_1>;
213 video-reset-gpios = <&gpio 86 GPIO_ACTIVE_LOW>;
214
215 ports {
216 #address-cells = <1>;
217 #size-cells = <0>;
218
219 port@0 {
220 /* Sink port */
221 reg = <0>;
222 csiss_in: endpoint {
223 data-lanes = <1 2 3 4>;
224 /* MIPI CSI-2 Camera handle */
225 remote-endpoint = <&camera_out>;
226 };
227 };
228 port@1 {
229 /* Source port */
230 reg = <1>;
231 csiss_out: endpoint {
232 remote-endpoint = <&vproc_in>;
233 };
234 };
235 };
236 };
237...
Documentation/devicetree/bindings/vendor-prefixes.yaml+2−0
@@ -473,6 +473,8 @@ patternProperties: · 472 unmodified lines
473 description: ILI Technology Corporation (ILITEK)473 description: ILI Technology Corporation (ILITEK)
474 "^img,.*":474 "^img,.*":
475 description: Imagination Technologies Ltd.475 description: Imagination Technologies Ltd.
476 "^imi,.*":
477 description: Integrated Micro-Electronics Inc.
476 "^incircuit,.*":478 "^incircuit,.*":
477 description: In-Circuit GmbH479 description: In-Circuit GmbH
478 "^inet-tek,.*":480 "^inet-tek,.*":
Documentation/driver-api/media/drivers/pvrusb2.rst+1−1
@@ -20,7 +20,7 @@ last known snapshot and evolved the driver to the state it is in · 19 unmodified lines
20here.20here.
21 21
22More information on this driver can be found at:22More information on this driver can be found at:
23http://www.isely.net/pvrusb2.html23https://www.isely.net/pvrusb2.html
24 24
25 25
26This driver has a strong separation of layers. They are very26This driver has a strong separation of layers. They are very
Documentation/driver-api/media/drivers/tuners.rst+1−1
@@ -18,7 +18,7 @@ These differ mainly by the bandswitch byte. · 17 unmodified lines
18Tuner Manufacturers18Tuner Manufacturers
19-------------------19-------------------
20 20
21- SAMSUNG Tuner identification: (e.g. TCPM9091PD27)21- Samsung Tuner identification: (e.g. TCPM9091PD27)
22 22
23.. code-block:: none23.. code-block:: none
24 24
Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst+3−0
@@ -57,6 +57,9 @@ returns the information to the application. The ioctl never fails. · 56 unmodified lines
57 - ``name[32]``57 - ``name[32]``
58 - The name of this CEC adapter. The combination ``driver`` and58 - The name of this CEC adapter. The combination ``driver`` and
59 ``name`` must be unique.59 ``name`` must be unique.
60 * - __u32
61 - ``available_log_addrs``
62 - The maximum number of logical addresses that can be configured.
60 * - __u3263 * - __u32
61 - ``capabilities``64 - ``capabilities``
62 - The capabilities of the CEC adapter, see65 - The capabilities of the CEC adapter, see
Documentation/userspace-api/media/dvb/fe-get-info.rst+1−2
@@ -34,8 +34,7 @@ Arguments · 33 unmodified lines
34 File descriptor returned by :ref:`open() <frontend_f_open>`.34 File descriptor returned by :ref:`open() <frontend_f_open>`.
35 35
36``argp``36``argp``
37 pointer to struct struct37 pointer to struct :c:type:`dvb_frontend_info`
38 :c:type:`dvb_frontend_info`
39 38
40 39
41Description40Description
Documentation/userspace-api/media/v4l/buffer.rst+40−4
@@ -23,8 +23,8 @@ argument to the :ref:`VIDIOC_QUERYBUF`, · 22 unmodified lines
23:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` and23:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` and
24:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. In the multi-planar API,24:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. In the multi-planar API,
25some plane-specific members of struct :c:type:`v4l2_buffer`,25some plane-specific members of struct :c:type:`v4l2_buffer`,
26such as pointers and sizes for each plane, are stored in struct26such as pointers and sizes for each plane, are stored in
27struct :c:type:`v4l2_plane` instead. In that case, struct27struct :c:type:`v4l2_plane` instead. In that case,
28struct :c:type:`v4l2_buffer` contains an array of plane structures.28struct :c:type:`v4l2_buffer` contains an array of plane structures.
29 29
30Dequeued video buffers come with timestamps. The driver decides at which30Dequeued video buffers come with timestamps. The driver decides at which
@@ -577,7 +577,10 @@ Buffer Flags · 546 unmodified lines
577 applications shall use this flag if the data captured in the577 applications shall use this flag if the data captured in the
578 buffer is not going to be touched by the CPU, instead the buffer578 buffer is not going to be touched by the CPU, instead the buffer
579 will, probably, be passed on to a DMA-capable hardware unit for579 will, probably, be passed on to a DMA-capable hardware unit for
580 further processing or output.580 further processing or output. This flag is ignored unless the
581 queue is used for :ref:`memory mapping <mmap>` streaming I/O and
582 reports :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
583 <V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability.
581 * .. _`V4L2-BUF-FLAG-NO-CACHE-CLEAN`:584 * .. _`V4L2-BUF-FLAG-NO-CACHE-CLEAN`:
582 585
583 - ``V4L2_BUF_FLAG_NO_CACHE_CLEAN``586 - ``V4L2_BUF_FLAG_NO_CACHE_CLEAN``
@@ -585,7 +588,10 @@ Buffer Flags · 1 unmodified line
585 - Caches do not have to be cleaned for this buffer. Typically588 - Caches do not have to be cleaned for this buffer. Typically
586 applications shall use this flag for output buffers if the data in589 applications shall use this flag for output buffers if the data in
587 this buffer has not been created by the CPU but by some590 this buffer has not been created by the CPU but by some
588 DMA-capable unit, in which case caches have not been used.591 DMA-capable unit, in which case caches have not been used. This flag
592 is ignored unless the queue is used for :ref:`memory mapping <mmap>`
593 streaming I/O and reports :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
594 <V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability.
589 * .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`:595 * .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`:
590 596
591 - ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF``597 - ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF``
@@ -681,6 +687,36 @@ Buffer Flags · 89 unmodified lines
681 687
682 \normalsize688 \normalsize
683 689
690.. _memory-flags:
691
692Memory Consistency Flags
693========================
694
695.. tabularcolumns:: |p{7.0cm}|p{2.2cm}|p{8.3cm}|
696
697.. cssclass:: longtable
698
699.. flat-table::
700 :header-rows: 0
701 :stub-columns: 0
702 :widths: 3 1 4
703
704 * .. _`V4L2-FLAG-MEMORY-NON-CONSISTENT`:
705
706 - ``V4L2_FLAG_MEMORY_NON_CONSISTENT``
707 - 0x00000001
708 - A buffer is allocated either in consistent (it will be automatically
709 coherent between the CPU and the bus) or non-consistent memory. The
710 latter can provide performance gains, for instance the CPU cache
711 sync/flush operations can be avoided if the buffer is accessed by the
712 corresponding device only and the CPU does not read/write to/from that
713 buffer. However, this requires extra care from the driver -- it must
714 guarantee memory consistency by issuing a cache flush/sync when
715 consistency is needed. If this flag is set V4L2 will attempt to
716 allocate the buffer in non-consistent memory. The flag takes effect
717 only if the buffer is used for :ref:`memory mapping <mmap>` I/O and the
718 queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
719 <V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability.
684 720
685.. c:type:: v4l2_memory721.. c:type:: v4l2_memory
686 722
Documentation/userspace-api/media/v4l/colorspaces-details.rst+2−2
@@ -767,8 +767,8 @@ scaled to [-128…128] and then clipped to [-128…127]. · 766 unmodified lines
767 information. So if something other than sRGB is used, then the driver767 information. So if something other than sRGB is used, then the driver
768 will have to set that information explicitly. Effectively768 will have to set that information explicitly. Effectively
769 ``V4L2_COLORSPACE_JPEG`` can be considered to be an abbreviation for769 ``V4L2_COLORSPACE_JPEG`` can be considered to be an abbreviation for
770 ``V4L2_COLORSPACE_SRGB``, ``V4L2_YCBCR_ENC_601`` and770 ``V4L2_COLORSPACE_SRGB``, ``V4L2_XFER_FUNC_SRGB``, ``V4L2_YCBCR_ENC_601``
771 ``V4L2_QUANTIZATION_FULL_RANGE``.771 and ``V4L2_QUANTIZATION_FULL_RANGE``.
772 772
773***************************************773***************************************
774Detailed Transfer Function Descriptions774Detailed Transfer Function Descriptions
Documentation/userspace-api/media/v4l/dev-decoder.rst+6−4
@@ -247,7 +247,7 @@ Querying Capabilities · 246 unmodified lines
247Initialization247Initialization
248==============248==============
249 249
2501. Set the coded format on ``OUTPUT`` via :c:func:`VIDIOC_S_FMT`2501. Set the coded format on ``OUTPUT`` via :c:func:`VIDIOC_S_FMT`.
251 251
252 * **Required fields:**252 * **Required fields:**
253 253
@@ -803,7 +803,7 @@ it may be affected as per normal decoder operation. · 549 unmodified lines
803 * The decoder will drop all the pending ``OUTPUT`` buffers and they must be803 * The decoder will drop all the pending ``OUTPUT`` buffers and they must be
804 treated as returned to the client (following standard semantics).804 treated as returned to the client (following standard semantics).
805 805
8062. Restart the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`8062. Restart the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`.
807 807
808 * **Required fields:**808 * **Required fields:**
809 809
@@ -906,7 +906,9 @@ reflected by corresponding queries): · 96 unmodified lines
906 906
907* visible resolution (selection rectangles),907* visible resolution (selection rectangles),
908 908
909* the minimum number of buffers needed for decoding.909* the minimum number of buffers needed for decoding,
910
911* bit-depth of the bitstream has been changed.
910 912
911Whenever that happens, the decoder must proceed as follows:913Whenever that happens, the decoder must proceed as follows:
912 914
@@ -1059,7 +1061,7 @@ sequence was started. · 146 unmodified lines
1059 ``V4L2_DEC_CMD_STOP`` again while the drain sequence is in progress and they1061 ``V4L2_DEC_CMD_STOP`` again while the drain sequence is in progress and they
1060 will fail with -EBUSY error code if attempted.1062 will fail with -EBUSY error code if attempted.
1061 1063
1062 Although mandatory, the availability of decoder commands may be queried1064 Although not mandatory, the availability of decoder commands may be queried
1063 using :c:func:`VIDIOC_TRY_DECODER_CMD`.1065 using :c:func:`VIDIOC_TRY_DECODER_CMD`.
1064 1066
1065End of Stream1067End of Stream
Documentation/userspace-api/media/v4l/dev-encoder.rst+753−0
@@ -0,0 +1,753 @@
1.. This file is dual-licensed: you can use it either under the terms
2.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
3.. dual licensing only applies to this file, and not this project as a
4.. whole.
5..
6.. a) This file is free software; you can redistribute it and/or
7.. modify it under the terms of the GNU General Public License as
8.. published by the Free Software Foundation version 2 of
9.. the License.
10..
11.. This file is distributed in the hope that it will be useful,
12.. but WITHOUT ANY WARRANTY; without even the implied warranty of
13.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.. GNU General Public License for more details.
15..
16.. Or, alternatively,
17..
18.. b) Permission is granted to copy, distribute and/or modify this
19.. document under the terms of the GNU Free Documentation License,
20.. Version 1.1 or any later version published by the Free Software
21.. Foundation, with no Invariant Sections, no Front-Cover Texts
22.. and no Back-Cover Texts. A copy of the license is included at
23.. Documentation/userspace-api/media/fdl-appendix.rst.
24..
25.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
26
27.. _encoder:
28
29*************************************************
30Memory-to-Memory Stateful Video Encoder Interface
31*************************************************
32
33A stateful video encoder takes raw video frames in display order and encodes
34them into a bytestream. It generates complete chunks of the bytestream, including
35all metadata, headers, etc. The resulting bytestream does not require any
36further post-processing by the client.
37
38Performing software stream processing, header generation etc. in the driver
39in order to support this interface is strongly discouraged. In case such
40operations are needed, use of the Stateless Video Encoder Interface (in
41development) is strongly advised.
42
43Conventions and Notations Used in This Document
44===============================================
45
461. The general V4L2 API rules apply if not specified in this document
47 otherwise.
48
492. The meaning of words "must", "may", "should", etc. is as per `RFC
50 2119 <https://tools.ietf.org/html/rfc2119>`_.
51
523. All steps not marked "optional" are required.
53
544. :c:func:`VIDIOC_G_EXT_CTRLS` and :c:func:`VIDIOC_S_EXT_CTRLS` may be used
55 interchangeably with :c:func:`VIDIOC_G_CTRL` and :c:func:`VIDIOC_S_CTRL`,
56 unless specified otherwise.
57
585. Single-planar API (see :ref:`planar-apis`) and applicable structures may be
59 used interchangeably with multi-planar API, unless specified otherwise,
60 depending on encoder capabilities and following the general V4L2 guidelines.
61
626. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i =
63 [0..2]: i = 0, 1, 2.
64
657. Given an ``OUTPUT`` buffer A, then A' represents a buffer on the ``CAPTURE``
66 queue containing data that resulted from processing buffer A.
67
68Glossary
69========
70
71Refer to :ref:`decoder-glossary`.
72
73State Machine
74=============
75
76.. kernel-render:: DOT
77 :alt: DOT digraph of encoder state machine
78 :caption: Encoder State Machine
79
80 digraph encoder_state_machine {
81 node [shape = doublecircle, label="Encoding"] Encoding;
82
83 node [shape = circle, label="Initialization"] Initialization;
84 node [shape = circle, label="Stopped"] Stopped;
85 node [shape = circle, label="Drain"] Drain;
86 node [shape = circle, label="Reset"] Reset;
87
88 node [shape = point]; qi
89 qi -> Initialization [ label = "open()" ];
90
91 Initialization -> Encoding [ label = "Both queues streaming" ];
92
93 Encoding -> Drain [ label = "V4L2_ENC_CMD_STOP" ];
94 Encoding -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
95 Encoding -> Stopped [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
96 Encoding -> Encoding;
97
98 Drain -> Stopped [ label = "All CAPTURE\nbuffers dequeued\nor\nVIDIOC_STREAMOFF(OUTPUT)" ];
99 Drain -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
100
101 Reset -> Encoding [ label = "VIDIOC_STREAMON(CAPTURE)" ];
102 Reset -> Initialization [ label = "VIDIOC_REQBUFS(OUTPUT, 0)" ];
103
104 Stopped -> Encoding [ label = "V4L2_ENC_CMD_START\nor\nVIDIOC_STREAMON(OUTPUT)" ];
105 Stopped -> Reset [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
106 }
107
108Querying Capabilities
109=====================
110
1111. To enumerate the set of coded formats supported by the encoder, the
112 client may call :c:func:`VIDIOC_ENUM_FMT` on ``CAPTURE``.
113
114 * The full set of supported formats will be returned, regardless of the
115 format set on ``OUTPUT``.
116
1172. To enumerate the set of supported raw formats, the client may call
118 :c:func:`VIDIOC_ENUM_FMT` on ``OUTPUT``.
119
120 * Only the formats supported for the format currently active on ``CAPTURE``
121 will be returned.
122
123 * In order to enumerate raw formats supported by a given coded format,
124 the client must first set that coded format on ``CAPTURE`` and then
125 enumerate the formats on ``OUTPUT``.
126
1273. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
128 resolutions for a given format, passing the desired pixel format in
129 :c:type:`v4l2_frmsizeenum` ``pixel_format``.
130
131 * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a coded pixel
132 format will include all possible coded resolutions supported by the
133 encoder for the given coded pixel format.
134
135 * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a raw pixel format
136 will include all possible frame buffer resolutions supported by the
137 encoder for the given raw pixel format and coded format currently set on
138 ``CAPTURE``.
139
1404. The client may use :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` to detect supported
141 frame intervals for a given format and resolution, passing the desired pixel
142 format in :c:type:`v4l2_frmsizeenum` ``pixel_format`` and the resolution
143 in :c:type:`v4l2_frmsizeenum` ``width`` and :c:type:`v4l2_frmsizeenum`
144 ``height``.
145
146 * Values returned by :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` for a coded pixel
147 format and coded resolution will include all possible frame intervals
148 supported by the encoder for the given coded pixel format and resolution.
149
150 * Values returned by :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` for a raw pixel
151 format and resolution will include all possible frame intervals supported
152 by the encoder for the given raw pixel format and resolution and for the
153 coded format, coded resolution and coded frame interval currently set on
154 ``CAPTURE``.
155
156 * Support for :c:func:`VIDIOC_ENUM_FRAMEINTERVALS` is optional. If it is
157 not implemented, then there are no special restrictions other than the
158 limits of the codec itself.
159
1605. Supported profiles and levels for the coded format currently set on
161 ``CAPTURE``, if applicable, may be queried using their respective controls
162 via :c:func:`VIDIOC_QUERYCTRL`.
163
1646. Any additional encoder capabilities may be discovered by querying
165 their respective controls.
166
167Initialization
168==============
169
1701. Set the coded format on the ``CAPTURE`` queue via :c:func:`VIDIOC_S_FMT`.
171
172 * **Required fields:**
173
174 ``type``
175 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
176
177 ``pixelformat``
178 the coded format to be produced.
179
180 ``sizeimage``
181 desired size of ``CAPTURE`` buffers; the encoder may adjust it to
182 match hardware requirements.
183
184 ``width``, ``height``
185 ignored (read-only).
186
187 other fields
188 follow standard semantics.
189
190 * **Return fields:**
191
192 ``sizeimage``
193 adjusted size of ``CAPTURE`` buffers.
194
195 ``width``, ``height``
196 the coded size selected by the encoder based on current state, e.g.
197 ``OUTPUT`` format, selection rectangles, etc. (read-only).
198
199 .. important::
200
201 Changing the ``CAPTURE`` format may change the currently set ``OUTPUT``
202 format. How the new ``OUTPUT`` format is determined is up to the encoder
203 and the client must ensure it matches its needs afterwards.
204
2052. **Optional.** Enumerate supported ``OUTPUT`` formats (raw formats for
206 source) for the selected coded format via :c:func:`VIDIOC_ENUM_FMT`.
207
208 * **Required fields:**
209
210 ``type``
211 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
212
213 other fields
214 follow standard semantics.
215
216 * **Return fields:**
217
218 ``pixelformat``
219 raw format supported for the coded format currently selected on
220 the ``CAPTURE`` queue.
221
222 other fields
223 follow standard semantics.
224
2253. Set the raw source format on the ``OUTPUT`` queue via
226 :c:func:`VIDIOC_S_FMT`.
227
228 * **Required fields:**
229
230 ``type``
231 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
232
233 ``pixelformat``
234 raw format of the source.
235
236 ``width``, ``height``
237 source resolution.
238
239 other fields
240 follow standard semantics.
241
242 * **Return fields:**
243
244 ``width``, ``height``
245 may be adjusted to match encoder minimums, maximums and alignment
246 requirements, as required by the currently selected formats, as
247 reported by :c:func:`VIDIOC_ENUM_FRAMESIZES`.
248
249 other fields
250 follow standard semantics.
251
252 * Setting the ``OUTPUT`` format will reset the selection rectangles to their
253 default values, based on the new resolution, as described in the next
254 step.
255
2564. Set the raw frame interval on the ``OUTPUT`` queue via
257 :c:func:`VIDIOC_S_PARM`. This also sets the coded frame interval on the
258 ``CAPTURE`` queue to the same value.
259
260 * ** Required fields:**
261
262 ``type``
263 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
264
265 ``parm.output``
266 set all fields except ``parm.output.timeperframe`` to 0.
267
268 ``parm.output.timeperframe``
269 the desired frame interval; the encoder may adjust it to
270 match hardware requirements.
271
272 * **Return fields:**
273
274 ``parm.output.timeperframe``
275 the adjusted frame interval.
276
277 .. important::
278
279 Changing the ``OUTPUT`` frame interval *also* sets the framerate that
280 the encoder uses to encode the video. So setting the frame interval
281 to 1/24 (or 24 frames per second) will produce a coded video stream
282 that can be played back at that speed. The frame interval for the
283 ``OUTPUT`` queue is just a hint, the application may provide raw
284 frames at a different rate. It can be used by the driver to help
285 schedule multiple encoders running in parallel.
286
287 In the next step the ``CAPTURE`` frame interval can optionally be
288 changed to a different value. This is useful for off-line encoding
289 were the coded frame interval can be different from the rate at
290 which raw frames are supplied.
291
292 .. important::
293
294 ``timeperframe`` deals with *frames*, not fields. So for interlaced
295 formats this is the time per two fields, since a frame consists of
296 a top and a bottom field.
297
298 .. note::
299
300 It is due to historical reasons that changing the ``OUTPUT`` frame
301 interval also changes the coded frame interval on the ``CAPTURE``
302 queue. Ideally these would be independent settings, but that would
303 break the existing API.
304
3055. **Optional** Set the coded frame interval on the ``CAPTURE`` queue via
306 :c:func:`VIDIOC_S_PARM`. This is only necessary if the coded frame
307 interval is different from the raw frame interval, which is typically
308 the case for off-line encoding. Support for this feature is signalled
309 by the :ref:`V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL <fmtdesc-flags>` format flag.
310
311 * ** Required fields:**
312
313 ``type``
314 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
315
316 ``parm.capture``
317 set all fields except ``parm.capture.timeperframe`` to 0.
318
319 ``parm.capture.timeperframe``
320 the desired coded frame interval; the encoder may adjust it to
321 match hardware requirements.
322
323 * **Return fields:**
324
325 ``parm.capture.timeperframe``
326 the adjusted frame interval.
327
328 .. important::
329
330 Changing the ``CAPTURE`` frame interval sets the framerate for the
331 coded video. It does *not* set the rate at which buffers arrive on the
332 ``CAPTURE`` queue, that depends on how fast the encoder is and how
333 fast raw frames are queued on the ``OUTPUT`` queue.
334
335 .. important::
336
337 ``timeperframe`` deals with *frames*, not fields. So for interlaced
338 formats this is the time per two fields, since a frame consists of
339 a top and a bottom field.
340
341 .. note::
342
343 Not all drivers support this functionality, in that case just set
344 the desired coded frame interval for the ``OUTPUT`` queue.
345
346 However, drivers that can schedule multiple encoders based on the
347 ``OUTPUT`` frame interval must support this optional feature.
348
3496. **Optional.** Set the visible resolution for the stream metadata via
350 :c:func:`VIDIOC_S_SELECTION` on the ``OUTPUT`` queue if it is desired
351 to be different than the full OUTPUT resolution.
352
353 * **Required fields:**
354
355 ``type``
356 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
357
358 ``target``
359 set to ``V4L2_SEL_TGT_CROP``.
360
361 ``r.left``, ``r.top``, ``r.width``, ``r.height``
362 visible rectangle; this must fit within the `V4L2_SEL_TGT_CROP_BOUNDS`
363 rectangle and may be subject to adjustment to match codec and
364 hardware constraints.
365
366 * **Return fields:**
367
368 ``r.left``, ``r.top``, ``r.width``, ``r.height``
369 visible rectangle adjusted by the encoder.
370
371 * The following selection targets are supported on ``OUTPUT``:
372
373 ``V4L2_SEL_TGT_CROP_BOUNDS``
374 equal to the full source frame, matching the active ``OUTPUT``
375 format.
376
377 ``V4L2_SEL_TGT_CROP_DEFAULT``
378 equal to ``V4L2_SEL_TGT_CROP_BOUNDS``.
379
380 ``V4L2_SEL_TGT_CROP``
381 rectangle within the source buffer to be encoded into the
382 ``CAPTURE`` stream; defaults to ``V4L2_SEL_TGT_CROP_DEFAULT``.
383
384 .. note::
385
386 A common use case for this selection target is encoding a source
387 video with a resolution that is not a multiple of a macroblock,
388 e.g. the common 1920x1080 resolution may require the source
389 buffers to be aligned to 1920x1088 for codecs with 16x16 macroblock
390 size. To avoid encoding the padding, the client needs to explicitly
391 configure this selection target to 1920x1080.
392
393 .. warning::
394
395 The encoder may adjust the crop/compose rectangles to the nearest
396 supported ones to meet codec and hardware requirements. The client needs
397 to check the adjusted rectangle returned by :c:func:`VIDIOC_S_SELECTION`.
398
3997. Allocate buffers for both ``OUTPUT`` and ``CAPTURE`` via
400 :c:func:`VIDIOC_REQBUFS`. This may be performed in any order.
401
402 * **Required fields:**
403
404 ``count``
405 requested number of buffers to allocate; greater than zero.
406
407 ``type``
408 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT`` or
409 ``CAPTURE``.
410
411 other fields
412 follow standard semantics.
413
414 * **Return fields:**
415
416 ``count``
417 actual number of buffers allocated.
418
419 .. warning::
420
421 The actual number of allocated buffers may differ from the ``count``
422 given. The client must check the updated value of ``count`` after the
423 call returns.
424
425 .. note::
426
427 To allocate more than the minimum number of OUTPUT buffers (for pipeline
428 depth), the client may query the ``V4L2_CID_MIN_BUFFERS_FOR_OUTPUT``
429 control to get the minimum number of buffers required, and pass the
430 obtained value plus the number of additional buffers needed in the
431 ``count`` field to :c:func:`VIDIOC_REQBUFS`.
432
433 Alternatively, :c:func:`VIDIOC_CREATE_BUFS` can be used to have more
434 control over buffer allocation.
435
436 * **Required fields:**
437
438 ``count``
439 requested number of buffers to allocate; greater than zero.
440
441 ``type``
442 a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
443
444 other fields
445 follow standard semantics.
446
447 * **Return fields:**
448
449 ``count``
450 adjusted to the number of allocated buffers.
451
4528. Begin streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
453 :c:func:`VIDIOC_STREAMON`. This may be performed in any order. The actual
454 encoding process starts when both queues start streaming.
455
456.. note::
457
458 If the client stops the ``CAPTURE`` queue during the encode process and then
459 restarts it again, the encoder will begin generating a stream independent
460 from the stream generated before the stop. The exact constraints depend
461 on the coded format, but may include the following implications:
462
463 * encoded frames produced after the restart must not reference any
464 frames produced before the stop, e.g. no long term references for
465 H.264/HEVC,
466
467 * any headers that must be included in a standalone stream must be
468 produced again, e.g. SPS and PPS for H.264/HEVC.
469
470Encoding
471========
472
473This state is reached after the `Initialization` sequence finishes
474successfully. In this state, the client queues and dequeues buffers to both
475queues via :c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`, following the
476standard semantics.
477
478The content of encoded ``CAPTURE`` buffers depends on the active coded pixel
479format and may be affected by codec-specific extended controls, as stated
480in the documentation of each format.
481
482Both queues operate independently, following standard behavior of V4L2 buffer
483queues and memory-to-memory devices. In addition, the order of encoded frames
484dequeued from the ``CAPTURE`` queue may differ from the order of queuing raw
485frames to the ``OUTPUT`` queue, due to properties of the selected coded format,
486e.g. frame reordering.
487
488The client must not assume any direct relationship between ``CAPTURE`` and
489``OUTPUT`` buffers and any specific timing of buffers becoming
490available to dequeue. Specifically:
491
492* a buffer queued to ``OUTPUT`` may result in more than one buffer produced on
493 ``CAPTURE`` (for example, if returning an encoded frame allowed the encoder
494 to return a frame that preceded it in display, but succeeded it in the decode
495 order; however, there may be other reasons for this as well),
496
497* a buffer queued to ``OUTPUT`` may result in a buffer being produced on
498 ``CAPTURE`` later into encode process, and/or after processing further
499 ``OUTPUT`` buffers, or be returned out of order, e.g. if display
500 reordering is used,
501
502* buffers may become available on the ``CAPTURE`` queue without additional
503 buffers queued to ``OUTPUT`` (e.g. during drain or ``EOS``), because of the
504 ``OUTPUT`` buffers queued in the past whose encoding results are only
505 available at later time, due to specifics of the encoding process,
506
507* buffers queued to ``OUTPUT`` may not become available to dequeue instantly
508 after being encoded into a corresponding ``CAPTURE`` buffer, e.g. if the
509 encoder needs to use the frame as a reference for encoding further frames.
510
511.. note::
512
513 To allow matching encoded ``CAPTURE`` buffers with ``OUTPUT`` buffers they
514 originated from, the client can set the ``timestamp`` field of the
515 :c:type:`v4l2_buffer` struct when queuing an ``OUTPUT`` buffer. The
516 ``CAPTURE`` buffer(s), which resulted from encoding that ``OUTPUT`` buffer
517 will have their ``timestamp`` field set to the same value when dequeued.
518
519 In addition to the straightforward case of one ``OUTPUT`` buffer producing
520 one ``CAPTURE`` buffer, the following cases are defined:
521
522 * one ``OUTPUT`` buffer generates multiple ``CAPTURE`` buffers: the same
523 ``OUTPUT`` timestamp will be copied to multiple ``CAPTURE`` buffers,
524
525 * the encoding order differs from the presentation order (i.e. the
526 ``CAPTURE`` buffers are out-of-order compared to the ``OUTPUT`` buffers):
527 ``CAPTURE`` timestamps will not retain the order of ``OUTPUT`` timestamps.
528
529.. note::
530
531 To let the client distinguish between frame types (keyframes, intermediate
532 frames; the exact list of types depends on the coded format), the
533 ``CAPTURE`` buffers will have corresponding flag bits set in their
534 :c:type:`v4l2_buffer` struct when dequeued. See the documentation of
535 :c:type:`v4l2_buffer` and each coded pixel format for exact list of flags
536 and their meanings.
537
538Should an encoding error occur, it will be reported to the client with the level
539of details depending on the encoder capabilities. Specifically:
540
541* the ``CAPTURE`` buffer (if any) that contains the results of the failed encode
542 operation will be returned with the ``V4L2_BUF_FLAG_ERROR`` flag set,
543
544* if the encoder is able to precisely report the ``OUTPUT`` buffer(s) that triggered
545 the error, such buffer(s) will be returned with the ``V4L2_BUF_FLAG_ERROR`` flag
546 set.
547
548.. note::
549
550 If a ``CAPTURE`` buffer is too small then it is just returned with the
551 ``V4L2_BUF_FLAG_ERROR`` flag set. More work is needed to detect that this
552 error occurred because the buffer was too small, and to provide support to
553 free existing buffers that were too small.
554
555In case of a fatal failure that does not allow the encoding to continue, any
556further operations on corresponding encoder file handle will return the -EIO
557error code. The client may close the file handle and open a new one, or
558alternatively reinitialize the instance by stopping streaming on both queues,
559releasing all buffers and performing the Initialization sequence again.
560
561Encoding Parameter Changes
562==========================
563
564The client is allowed to use :c:func:`VIDIOC_S_CTRL` to change encoder
565parameters at any time. The availability of parameters is encoder-specific
566and the client must query the encoder to find the set of available controls.
567
568The ability to change each parameter during encoding is encoder-specific, as
569per the standard semantics of the V4L2 control interface. The client may
570attempt to set a control during encoding and if the operation fails with the
571-EBUSY error code, the ``CAPTURE`` queue needs to be stopped for the
572configuration change to be allowed. To do this, it may follow the `Drain`
573sequence to avoid losing the already queued/encoded frames.
574
575The timing of parameter updates is encoder-specific, as per the standard
576semantics of the V4L2 control interface. If the client needs to apply the
577parameters exactly at specific frame, using the Request API
578(:ref:`media-request-api`) should be considered, if supported by the encoder.
579
580Drain
581=====
582
583To ensure that all the queued ``OUTPUT`` buffers have been processed and the
584related ``CAPTURE`` buffers are given to the client, the client must follow the
585drain sequence described below. After the drain sequence ends, the client has
586received all encoded frames for all ``OUTPUT`` buffers queued before the
587sequence was started.
588
5891. Begin the drain sequence by issuing :c:func:`VIDIOC_ENCODER_CMD`.
590
591 * **Required fields:**
592
593 ``cmd``
594 set to ``V4L2_ENC_CMD_STOP``.
595
596 ``flags``
597 set to 0.
598
599 ``pts``
600 set to 0.
601
602 .. warning::
603
604 The sequence can be only initiated if both ``OUTPUT`` and ``CAPTURE``
605 queues are streaming. For compatibility reasons, the call to
606 :c:func:`VIDIOC_ENCODER_CMD` will not fail even if any of the queues is
607 not streaming, but at the same time it will not initiate the `Drain`
608 sequence and so the steps described below would not be applicable.
609
6102. Any ``OUTPUT`` buffers queued by the client before the
611 :c:func:`VIDIOC_ENCODER_CMD` was issued will be processed and encoded as
612 normal. The client must continue to handle both queues independently,
613 similarly to normal encode operation. This includes:
614
615 * queuing and dequeuing ``CAPTURE`` buffers, until a buffer marked with the
616 ``V4L2_BUF_FLAG_LAST`` flag is dequeued,
617
618 .. warning::
619
620 The last buffer may be empty (with :c:type:`v4l2_buffer`
621 ``bytesused`` = 0) and in that case it must be ignored by the client,
622 as it does not contain an encoded frame.
623
624 .. note::
625
626 Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer
627 marked with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
628 :c:func:`VIDIOC_DQBUF`.
629
630 * dequeuing processed ``OUTPUT`` buffers, until all the buffers queued
631 before the ``V4L2_ENC_CMD_STOP`` command are dequeued,
632
633 * dequeuing the ``V4L2_EVENT_EOS`` event, if the client subscribes to it.
634
635 .. note::
636
637 For backwards compatibility, the encoder will signal a ``V4L2_EVENT_EOS``
638 event when the last frame has been encoded and all frames are ready to be
639 dequeued. It is deprecated behavior and the client must not rely on it.
640 The ``V4L2_BUF_FLAG_LAST`` buffer flag should be used instead.
641
6423. Once all ``OUTPUT`` buffers queued before the ``V4L2_ENC_CMD_STOP`` call are
643 dequeued and the last ``CAPTURE`` buffer is dequeued, the encoder is stopped
644 and it will accept, but not process any newly queued ``OUTPUT`` buffers
645 until the client issues any of the following operations:
646
647 * ``V4L2_ENC_CMD_START`` - the encoder will not be reset and will resume
648 operation normally, with all the state from before the drain,
649
650 * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
651 ``CAPTURE`` queue - the encoder will be reset (see the `Reset` sequence)
652 and then resume encoding,
653
654 * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
655 ``OUTPUT`` queue - the encoder will resume operation normally, however any
656 source frames queued to the ``OUTPUT`` queue between ``V4L2_ENC_CMD_STOP``
657 and :c:func:`VIDIOC_STREAMOFF` will be discarded.
658
659.. note::
660
661 Once the drain sequence is initiated, the client needs to drive it to
662 completion, as described by the steps above, unless it aborts the process by
663 issuing :c:func:`VIDIOC_STREAMOFF` on any of the ``OUTPUT`` or ``CAPTURE``
664 queues. The client is not allowed to issue ``V4L2_ENC_CMD_START`` or
665 ``V4L2_ENC_CMD_STOP`` again while the drain sequence is in progress and they
666 will fail with -EBUSY error code if attempted.
667
668 For reference, handling of various corner cases is described below:
669
670 * In case of no buffer in the ``OUTPUT`` queue at the time the
671 ``V4L2_ENC_CMD_STOP`` command was issued, the drain sequence completes
672 immediately and the encoder returns an empty ``CAPTURE`` buffer with the
673 ``V4L2_BUF_FLAG_LAST`` flag set.
674
675 * In case of no buffer in the ``CAPTURE`` queue at the time the drain
676 sequence completes, the next time the client queues a ``CAPTURE`` buffer
677 it is returned at once as an empty buffer with the ``V4L2_BUF_FLAG_LAST``
678 flag set.
679
680 * If :c:func:`VIDIOC_STREAMOFF` is called on the ``CAPTURE`` queue in the
681 middle of the drain sequence, the drain sequence is canceled and all
682 ``CAPTURE`` buffers are implicitly returned to the client.
683
684 * If :c:func:`VIDIOC_STREAMOFF` is called on the ``OUTPUT`` queue in the
685 middle of the drain sequence, the drain sequence completes immediately and
686 next ``CAPTURE`` buffer will be returned empty with the
687 ``V4L2_BUF_FLAG_LAST`` flag set.
688
689 Although not mandatory, the availability of encoder commands may be queried
690 using :c:func:`VIDIOC_TRY_ENCODER_CMD`.
691
692Reset
693=====
694
695The client may want to request the encoder to reinitialize the encoding, so
696that the following stream data becomes independent from the stream data
697generated before. Depending on the coded format, that may imply that:
698
699* encoded frames produced after the restart must not reference any frames
700 produced before the stop, e.g. no long term references for H.264/HEVC,
701
702* any headers that must be included in a standalone stream must be produced
703 again, e.g. SPS and PPS for H.264/HEVC.
704
705This can be achieved by performing the reset sequence.
706
7071. Perform the `Drain` sequence to ensure all the in-flight encoding finishes
708 and respective buffers are dequeued.
709
7102. Stop streaming on the ``CAPTURE`` queue via :c:func:`VIDIOC_STREAMOFF`. This
711 will return all currently queued ``CAPTURE`` buffers to the client, without
712 valid frame data.
713
7143. Start streaming on the ``CAPTURE`` queue via :c:func:`VIDIOC_STREAMON` and
715 continue with regular encoding sequence. The encoded frames produced into
716 ``CAPTURE`` buffers from now on will contain a standalone stream that can be
717 decoded without the need for frames encoded before the reset sequence,
718 starting at the first ``OUTPUT`` buffer queued after issuing the
719 `V4L2_ENC_CMD_STOP` of the `Drain` sequence.
720
721This sequence may be also used to change encoding parameters for encoders
722without the ability to change the parameters on the fly.
723
724Commit Points
725=============
726
727Setting formats and allocating buffers triggers changes in the behavior of the
728encoder.
729
7301. Setting the format on the ``CAPTURE`` queue may change the set of formats
731 supported/advertised on the ``OUTPUT`` queue. In particular, it also means
732 that the ``OUTPUT`` format may be reset and the client must not rely on the
733 previously set format being preserved.
734
7352. Enumerating formats on the ``OUTPUT`` queue always returns only formats
736 supported for the current ``CAPTURE`` format.
737
7383. Setting the format on the ``OUTPUT`` queue does not change the list of
739 formats available on the ``CAPTURE`` queue. An attempt to set the ``OUTPUT``
740 format that is not supported for the currently selected ``CAPTURE`` format
741 will result in the encoder adjusting the requested ``OUTPUT`` format to a
742 supported one.
743
7444. Enumerating formats on the ``CAPTURE`` queue always returns the full set of
745 supported coded formats, irrespective of the current ``OUTPUT`` format.
746
7475. While buffers are allocated on any of the ``OUTPUT`` or ``CAPTURE`` queues,
748 the client must not change the format on the ``CAPTURE`` queue. Drivers will
749 return the -EBUSY error code for any such format change attempt.
750
751To summarize, setting formats and allocation must always start with the
752``CAPTURE`` queue and the ``CAPTURE`` queue is the master that governs the
753set of supported formats for the ``OUTPUT`` queue.
Documentation/userspace-api/media/v4l/dev-mem2mem.rst+1−0
@@ -46,4 +46,5 @@ devices are given in the following sections. · 45 unmodified lines
46 :maxdepth: 146 :maxdepth: 1
47 47
48 dev-decoder48 dev-decoder
49 dev-encoder
49 dev-stateless-decoder50 dev-stateless-decoder
Documentation/userspace-api/media/v4l/dev-osd.rst+1−1
@@ -51,7 +51,7 @@ other information, the physical address of the framebuffer in the · 50 unmodified lines
51``base`` field of struct :c:type:`v4l2_framebuffer`.51``base`` field of struct :c:type:`v4l2_framebuffer`.
52The framebuffer device ioctl ``FBIOGET_FSCREENINFO`` returns the same52The framebuffer device ioctl ``FBIOGET_FSCREENINFO`` returns the same
53address in the ``smem_start`` field of struct53address in the ``smem_start`` field of struct
54struct :c:type:`fb_fix_screeninfo`. The ``FBIOGET_FSCREENINFO``54:c:type:`fb_fix_screeninfo`. The ``FBIOGET_FSCREENINFO``
55ioctl and struct :c:type:`fb_fix_screeninfo` are defined in55ioctl and struct :c:type:`fb_fix_screeninfo` are defined in
56the ``linux/fb.h`` header file.56the ``linux/fb.h`` header file.
57 57
Documentation/userspace-api/media/v4l/dev-sdr.rst+1−1
@@ -78,7 +78,7 @@ field of a struct :c:type:`v4l2_format` to · 77 unmodified lines
78``V4L2_BUF_TYPE_SDR_CAPTURE`` or ``V4L2_BUF_TYPE_SDR_OUTPUT`` and use78``V4L2_BUF_TYPE_SDR_CAPTURE`` or ``V4L2_BUF_TYPE_SDR_OUTPUT`` and use
79the struct :c:type:`v4l2_sdr_format` ``sdr`` member79the struct :c:type:`v4l2_sdr_format` ``sdr`` member
80of the ``fmt`` union as needed per the desired operation. Currently80of the ``fmt`` union as needed per the desired operation. Currently
81there is two fields, ``pixelformat`` and ``buffersize``, of struct81there are two fields, ``pixelformat`` and ``buffersize``, of
82struct :c:type:`v4l2_sdr_format` which are used.82struct :c:type:`v4l2_sdr_format` which are used.
83Content of the ``pixelformat`` is V4L2 FourCC code of the data format.83Content of the ``pixelformat`` is V4L2 FourCC code of the data format.
84The ``buffersize`` field is maximum buffer size in bytes required for84The ``buffersize`` field is maximum buffer size in bytes required for
Documentation/userspace-api/media/v4l/hist-v4l2.rst+2−2
@@ -43,7 +43,7 @@ transmission arguments. · 42 unmodified lines
431998-09-28: Revamped video standard. Made video controls individually431998-09-28: Revamped video standard. Made video controls individually
44enumerable.44enumerable.
45 45
461998-10-02: The ``id`` field was removed from struct461998-10-02: The ``id`` field was removed from
47struct ``video_standard`` and the color subcarrier fields were47struct ``video_standard`` and the color subcarrier fields were
48renamed. The :ref:`VIDIOC_QUERYSTD` ioctl was48renamed. The :ref:`VIDIOC_QUERYSTD` ioctl was
49renamed to :ref:`VIDIOC_ENUMSTD`,49renamed to :ref:`VIDIOC_ENUMSTD`,
@@ -260,7 +260,7 @@ multiple tuners into account.) · 210 unmodified lines
260 260
2612000-09-18: ``V4L2_BUF_TYPE_VBI`` was added. This may *break2612000-09-18: ``V4L2_BUF_TYPE_VBI`` was added. This may *break
262compatibility* as the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and262compatibility* as the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and
263:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls may fail now if the struct263:ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls may fail now if the
264struct ``v4l2_fmt`` ``type`` field does not contain264struct ``v4l2_fmt`` ``type`` field does not contain
265``V4L2_BUF_TYPE_VBI``. In the documentation of the struct265``V4L2_BUF_TYPE_VBI``. In the documentation of the struct
266:c:type:`v4l2_vbi_format` ``offset`` field the266:c:type:`v4l2_vbi_format` ``offset`` field the
Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst+14−14
@@ -69,37 +69,37 @@ Each cell is one byte. · 68 unmodified lines
69 69
70 B\ :sub:`00low bits 5--0`\ (bits 5--0)70 B\ :sub:`00low bits 5--0`\ (bits 5--0)
71 71
72 - R\ :sub:`02low bits 3--0`\ (bits 7--4)72 - B\ :sub:`02low bits 3--0`\ (bits 7--4)
73 73
74 G\ :sub:`01low bits 5--2`\ (bits 3--0)74 G\ :sub:`01low bits 5--2`\ (bits 3--0)
75 75
76 - G\ :sub:`03low bits 5--0`\ (bits 7--2)76 - G\ :sub:`03low bits 5--0`\ (bits 7--2)
77 77
78 R\ :sub:`02low bits 5--4`\ (bits 1--0)78 B\ :sub:`02low bits 5--4`\ (bits 1--0)
79 79
80 - .. row 280 - .. row 2
81 81
82 - start + 782 - start + 7
83 83
84 - G\ :sub:`00high`84 - G\ :sub:`10high`
85 85
86 - R\ :sub:`01high`86 - R\ :sub:`11high`
87 87
88 - G\ :sub:`02high`88 - G\ :sub:`12high`
89 89
90 - R\ :sub:`03high`90 - R\ :sub:`13high`
91 91
92 - R\ :sub:`01low bits 1--0`\ (bits 7--6)92 - R\ :sub:`11low bits 1--0`\ (bits 7--6)
93 93
94 G\ :sub:`00low bits 5--0`\ (bits 5--0)94 G\ :sub:`10low bits 5--0`\ (bits 5--0)
95 95
96 - G\ :sub:`02low bits 3--0`\ (bits 7--4)96 - G\ :sub:`12low bits 3--0`\ (bits 7--4)
97 97
98 R\ :sub:`01low bits 5--2`\ (bits 3--0)98 R\ :sub:`11low bits 5--2`\ (bits 3--0)
99 99
100 - R\ :sub:`03low bits 5--0`\ (bits 7--2)100 - R\ :sub:`13low bits 5--0`\ (bits 7--2)
101 101
102 G\ :sub:`02low bits 5--4`\ (bits 1--0)102 G\ :sub:`12low bits 5--4`\ (bits 1--0)
103 103
104 - .. row 3104 - .. row 3
105 105
@@ -117,13 +117,13 @@ Each cell is one byte. · 11 unmodified lines
117 117
118 B\ :sub:`20low bits 5--0`\ (bits 5--0)118 B\ :sub:`20low bits 5--0`\ (bits 5--0)
119 119
120 - R\ :sub:`22low bits 3--0`\ (bits 7--4)120 - B\ :sub:`22low bits 3--0`\ (bits 7--4)
121 121
122 G\ :sub:`21low bits 5--2`\ (bits 3--0)122 G\ :sub:`21low bits 5--2`\ (bits 3--0)
123 123
124 - G\ :sub:`23low bits 5--0`\ (bits 7--2)124 - G\ :sub:`23low bits 5--0`\ (bits 7--2)
125 125
126 R\ :sub:`22low bits 5--4`\ (bits 1--0)126 B\ :sub:`22low bits 5--4`\ (bits 1--0)
127 127
128 - .. row 4128 - .. row 4
129 129
Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst+5−0
@@ -44,6 +44,11 @@ Single-planar format structure · 43 unmodified lines
44 inside the stream, when fed to a stateful mem2mem decoder, the fields44 inside the stream, when fed to a stateful mem2mem decoder, the fields
45 may be zero to rely on the decoder to detect the right values. For more45 may be zero to rely on the decoder to detect the right values. For more
46 details see :ref:`decoder` and format descriptions.46 details see :ref:`decoder` and format descriptions.
47
48 For compressed formats on the CAPTURE side of a stateful mem2mem
49 encoder, the fields must be zero, since the coded size is expected to
50 be calculated internally by the encoder itself, based on the OUTPUT
51 side. For more details see :ref:`encoder` and format descriptions.
47 * - __u3252 * - __u32
48 - ``pixelformat``53 - ``pixelformat``
49 - The pixel format or type of compression, set by the application.54 - The pixel format or type of compression, set by the application.
Documentation/userspace-api/media/v4l/v4l2.rst+2−0
@@ -63,6 +63,7 @@ Authors, in alphabetical order: · 62 unmodified lines
63- Figa, Tomasz <tfiga@chromium.org>63- Figa, Tomasz <tfiga@chromium.org>
64 64
65 - Documented the memory-to-memory decoder interface.65 - Documented the memory-to-memory decoder interface.
66 - Documented the memory-to-memory encoder interface.
66 67
67- H Schimek, Michael <mschimek@gmx.at>68- H Schimek, Michael <mschimek@gmx.at>
68 69
@@ -75,6 +76,7 @@ Authors, in alphabetical order: · 6 unmodified lines
75- Osciak, Pawel <posciak@chromium.org>76- Osciak, Pawel <posciak@chromium.org>
76 77
77 - Documented the memory-to-memory decoder interface.78 - Documented the memory-to-memory decoder interface.
79 - Documented the memory-to-memory encoder interface.
78 80
79- Osciak, Pawel <pawel@osciak.com>81- Osciak, Pawel <pawel@osciak.com>
80 82
Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst+6−1
@@ -121,7 +121,12 @@ than the number requested. · 120 unmodified lines
121 other changes, then set ``count`` to 0, ``memory`` to121 other changes, then set ``count`` to 0, ``memory`` to
122 ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type.122 ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type.
123 * - __u32123 * - __u32
124 - ``reserved``\ [7]124 - ``flags``
125 - Specifies additional buffer management attributes.
126 See :ref:`memory-flags`.
127
128 * - __u32
129 - ``reserved``\ [6]
125 - A place holder for future extensions. Drivers and applications130 - A place holder for future extensions. Drivers and applications
126 must set the array to zero.131 must set the array to zero.
127 132
Documentation/userspace-api/media/v4l/vidioc-dqevent.rst+1−1
@@ -260,7 +260,7 @@ call. · 259 unmodified lines
260 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.260 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.
261 * - __s32261 * - __s32
262 - ``default_value``262 - ``default_value``
263 - The default value value of the control. See struct263 - The default value of the control. See struct
264 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.264 :ref:`v4l2_queryctrl <v4l2-queryctrl>`.
265 265
266 266
Documentation/userspace-api/media/v4l/vidioc-encoder-cmd.rst+31−20
@@ -51,25 +51,26 @@ To send a command applications must initialize all fields of a struct · 50 unmodified lines
51``VIDIOC_ENCODER_CMD`` or ``VIDIOC_TRY_ENCODER_CMD`` with a pointer to51``VIDIOC_ENCODER_CMD`` or ``VIDIOC_TRY_ENCODER_CMD`` with a pointer to
52this structure.52this structure.
53 53
54The ``cmd`` field must contain the command code. The ``flags`` field is54The ``cmd`` field must contain the command code. Some commands use the
55currently only used by the STOP command and contains one bit: If the55``flags`` field for additional information.
56``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag is set, encoding will continue
57until the end of the current *Group Of Pictures*, otherwise it will stop
58immediately.
59 56
60A :ref:`read() <func-read>` or :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`57After a STOP command, :ref:`read() <func-read>` calls will read
61call sends an implicit START command to the encoder if it has not been
62started yet. After a STOP command, :ref:`read() <func-read>` calls will read
63the remaining data buffered by the driver. When the buffer is empty,58the remaining data buffered by the driver. When the buffer is empty,
64:ref:`read() <func-read>` will return zero and the next :ref:`read() <func-read>`59:ref:`read() <func-read>` will return zero and the next :ref:`read() <func-read>`
65call will restart the encoder.60call will restart the encoder.
66 61
62A :ref:`read() <func-read>` or :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`
63call sends an implicit START command to the encoder if it has not been
64started yet. Applies to both queues of mem2mem encoders.
65
67A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`66A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
68call of a streaming file descriptor sends an implicit immediate STOP to67call of a streaming file descriptor sends an implicit immediate STOP to
69the encoder, and all buffered data is discarded.68the encoder, and all buffered data is discarded. Applies to both queues of
69mem2mem encoders.
70 70
71These ioctls are optional, not all drivers may support them. They were71These ioctls are optional, not all drivers may support them. They were
72introduced in Linux 2.6.21.72introduced in Linux 2.6.21. They are, however, mandatory for stateful mem2mem
73encoders (as further documented in :ref:`encoder`).
73 74
74 75
75.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|76.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
@@ -109,21 +110,24 @@ introduced in Linux 2.6.21. · 33 unmodified lines
109 - 0110 - 0
110 - Start the encoder. When the encoder is already running or paused,111 - Start the encoder. When the encoder is already running or paused,
111 this command does nothing. No flags are defined for this command.112 this command does nothing. No flags are defined for this command.
113
114 For a device implementing the :ref:`encoder`, once the drain sequence
115 is initiated with the ``V4L2_ENC_CMD_STOP`` command, it must be driven
116 to completion before this command can be invoked. Any attempt to
117 invoke the command while the drain sequence is in progress will trigger
118 an ``EBUSY`` error code. See :ref:`encoder` for more details.
112 * - ``V4L2_ENC_CMD_STOP``119 * - ``V4L2_ENC_CMD_STOP``
113 - 1120 - 1
114 - Stop the encoder. When the ``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag121 - Stop the encoder. When the ``V4L2_ENC_CMD_STOP_AT_GOP_END`` flag
115 is set, encoding will continue until the end of the current *Group122 is set, encoding will continue until the end of the current *Group
116 Of Pictures*, otherwise encoding will stop immediately. When the123 Of Pictures*, otherwise encoding will stop immediately. When the
117 encoder is already stopped, this command does nothing. mem2mem124 encoder is already stopped, this command does nothing.
118 encoders will send a ``V4L2_EVENT_EOS`` event when the last frame125
119 has been encoded and all frames are ready to be dequeued and will126 For a device implementing the :ref:`encoder`, the command will initiate
120 set the ``V4L2_BUF_FLAG_LAST`` buffer flag on the last buffer of127 the drain sequence as documented in :ref:`encoder`. No flags or other
121 the capture queue to indicate there will be no new buffers128 arguments are accepted in this case. Any attempt to invoke the command
122 produced to dequeue. This buffer may be empty, indicated by the129 again before the sequence completes will trigger an ``EBUSY`` error
123 driver setting the ``bytesused`` field to 0. Once the130 code.
124 ``V4L2_BUF_FLAG_LAST`` flag was set, the
125 :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
126 but return an ``EPIPE`` error code.
127 * - ``V4L2_ENC_CMD_PAUSE``131 * - ``V4L2_ENC_CMD_PAUSE``
128 - 2132 - 2
129 - Pause the encoder. When the encoder has not been started yet, the133 - Pause the encoder. When the encoder has not been started yet, the
@@ -152,6 +156,8 @@ introduced in Linux 2.6.21. · 22 unmodified lines
152 - Stop encoding at the end of the current *Group Of Pictures*,156 - Stop encoding at the end of the current *Group Of Pictures*,
153 rather than immediately.157 rather than immediately.
154 158
159 Does not apply to :ref:`encoder`.
160
155 161
156Return Value162Return Value
157============163============
@@ -160,6 +166,11 @@ On success 0 is returned, on error -1 and the ``errno`` variable is set · 2 unmodified lines
160appropriately. The generic error codes are described at the166appropriately. The generic error codes are described at the
161:ref:`Generic Error Codes <gen-errors>` chapter.167:ref:`Generic Error Codes <gen-errors>` chapter.
162 168
169EBUSY
170 A drain sequence of a device implementing the :ref:`encoder` is still in
171 progress. It is not allowed to issue another encoder command until it
172 completes.
173
163EINVAL174EINVAL
164 The ``cmd`` field is invalid.175 The ``cmd`` field is invalid.
165 176
Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst+25−5
@@ -167,17 +167,37 @@ the ``mbus_code`` field is handled differently: · 166 unmodified lines
167 - The hardware decoder for this compressed bytestream format (aka coded167 - The hardware decoder for this compressed bytestream format (aka coded
168 format) is capable of parsing a continuous bytestream. Applications do168 format) is capable of parsing a continuous bytestream. Applications do
169 not need to parse the bytestream themselves to find the boundaries169 not need to parse the bytestream themselves to find the boundaries
170 between frames/fields. This flag can only be used in combination with170 between frames/fields.
171 the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to compressed171
172 This flag can only be used in combination with the
173 ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to compressed
172 formats only. This flag is valid for stateful decoders only.174 formats only. This flag is valid for stateful decoders only.
173 * - ``V4L2_FMT_FLAG_DYN_RESOLUTION``175 * - ``V4L2_FMT_FLAG_DYN_RESOLUTION``
174 - 0x0008176 - 0x0008
175 - Dynamic resolution switching is supported by the device for this177 - Dynamic resolution switching is supported by the device for this
176 compressed bytestream format (aka coded format). It will notify the user178 compressed bytestream format (aka coded format). It will notify the user
177 via the event ``V4L2_EVENT_SOURCE_CHANGE`` when changes in the video179 via the event ``V4L2_EVENT_SOURCE_CHANGE`` when changes in the video
178 parameters are detected. This flag can only be used in combination180 parameters are detected.
179 with the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to181
180 compressed formats only. It is also only applies to stateful codecs.182 This flag can only be used in combination with the
183 ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to
184 compressed formats only. This flag is valid for stateful codecs only.
185 * - ``V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL``
186 - 0x0010
187 - The hardware encoder supports setting the ``CAPTURE`` coded frame
188 interval separately from the ``OUTPUT`` raw frame interval.
189 Setting the ``OUTPUT`` raw frame interval with :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>`
190 also sets the ``CAPTURE`` coded frame interval to the same value.
191 If this flag is set, then the ``CAPTURE`` coded frame interval can be
192 set to a different value afterwards. This is typically used for
193 offline encoding where the ``OUTPUT`` raw frame interval is used as
194 a hint for reserving hardware encoder resources and the ``CAPTURE`` coded
195 frame interval is the actual frame rate embedded in the encoded video
196 stream.
197
198 This flag can only be used in combination with the
199 ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to
200 compressed formats only. This flag is valid for stateful encoders only.
181 201
182 202
183Return Value203Return Value
Documentation/userspace-api/media/v4l/vidioc-g-parm.rst+32−19
@@ -42,12 +42,13 @@ Arguments · 41 unmodified lines
42Description42Description
43===========43===========
44 44
45The current video standard determines a nominal number of frames per45Applications can request a different frame interval. The capture or
46second. If less than this number of frames is to be captured or output,46output device will be reconfigured to support the requested frame
47applications can request frame skipping or duplicating on the driver47interval if possible. Optionally drivers may choose to skip or
48side. This is especially useful when using the :ref:`read() <func-read>` or48repeat frames to achieve the requested frame interval.
49:ref:`write() <func-write>`, which are not augmented by timestamps or sequence49
50counters, and to avoid unnecessary data copying.50For stateful encoders (see :ref:`encoder`) this represents the
51frame interval that is typically embedded in the encoded video stream.
51 52
52Changing the frame interval shall never change the format. Changing the53Changing the frame interval shall never change the format. Changing the
53format, on the other hand, may change the frame interval.54format, on the other hand, may change the frame interval.
@@ -57,7 +58,8 @@ internally by a driver in read/write mode. For implications see the · 3 unmodified lines
57section discussing the :ref:`read() <func-read>` function.58section discussing the :ref:`read() <func-read>` function.
58 59
59To get and set the streaming parameters applications call the60To get and set the streaming parameters applications call the
60:ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and :ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl, respectively. They take a61:ref:`VIDIOC_G_PARM <VIDIOC_G_PARM>` and
62:ref:`VIDIOC_S_PARM <VIDIOC_G_PARM>` ioctl, respectively. They take a
61pointer to a struct :c:type:`v4l2_streamparm` which contains a63pointer to a struct :c:type:`v4l2_streamparm` which contains a
62union holding separate parameters for input and output devices.64union holding separate parameters for input and output devices.
63 65
@@ -113,14 +115,21 @@ union holding separate parameters for input and output devices. · 49 unmodified lines
113 * - struct :c:type:`v4l2_fract`115 * - struct :c:type:`v4l2_fract`
114 - ``timeperframe``116 - ``timeperframe``
115 - This is the desired period between successive frames captured by117 - This is the desired period between successive frames captured by
116 the driver, in seconds. The field is intended to skip frames on118 the driver, in seconds.
117 the driver side, saving I/O bandwidth.119 * - :cspan:`2`
120
121 This will configure the speed at which the video source (e.g. a sensor)
122 generates video frames. If the speed is fixed, then the driver may
123 choose to skip or repeat frames in order to achieve the requested
124 frame rate.
125
126 For stateful encoders (see :ref:`encoder`) this represents the
127 frame interval that is typically embedded in the encoded video stream.
118 128
119 Applications store here the desired frame period, drivers return129 Applications store here the desired frame period, drivers return
120 the actual frame period, which must be greater or equal to the130 the actual frame period.
121 nominal frame period determined by the current video standard131
122 (struct :c:type:`v4l2_standard` ``frameperiod``132 Changing the video standard (also implicitly by switching
123 field). Changing the video standard (also implicitly by switching
124 the video input) may reset this parameter to the nominal frame133 the video input) may reset this parameter to the nominal frame
125 period. To reset manually applications can just set this field to134 period. To reset manually applications can just set this field to
126 zero.135 zero.
@@ -173,11 +182,15 @@ union holding separate parameters for input and output devices. · 46 unmodified lines
173 :ref:`write() <func-write>` mode (in streaming mode timestamps182 :ref:`write() <func-write>` mode (in streaming mode timestamps
174 can be used to throttle the output), saving I/O bandwidth.183 can be used to throttle the output), saving I/O bandwidth.
175 184
185 For stateful encoders (see :ref:`encoder`) this represents the
186 frame interval that is typically embedded in the encoded video stream
187 and it provides a hint to the encoder of the speed at which raw
188 frames are queued up to the encoder.
189
176 Applications store here the desired frame period, drivers return190 Applications store here the desired frame period, drivers return
177 the actual frame period, which must be greater or equal to the191 the actual frame period.
178 nominal frame period determined by the current video standard192
179 (struct :c:type:`v4l2_standard` ``frameperiod``193 Changing the video standard (also implicitly by switching
180 field). Changing the video standard (also implicitly by switching
181 the video output) may reset this parameter to the nominal frame194 the video output) may reset this parameter to the nominal frame
182 period. To reset manually applications can just set this field to195 period. To reset manually applications can just set this field to
183 zero.196 zero.
@@ -216,8 +229,8 @@ union holding separate parameters for input and output devices. · 32 unmodified lines
216 229
217 * - ``V4L2_CAP_TIMEPERFRAME``230 * - ``V4L2_CAP_TIMEPERFRAME``
218 - 0x1000231 - 0x1000
219 - The frame skipping/repeating controlled by the ``timeperframe``232 - The frame period can be modified by setting the ``timeperframe``
220 field is supported.233 field.
221 234
222 235
223 236
Documentation/userspace-api/media/v4l/vidioc-querycap.rst+2−2
@@ -168,11 +168,11 @@ specification the ioctl returns an ``EINVAL`` error code. · 167 unmodified lines
168 - The device supports the :ref:`multi-planar API <planar-apis>`168 - The device supports the :ref:`multi-planar API <planar-apis>`
169 through the :ref:`Video Output <output>` interface.169 through the :ref:`Video Output <output>` interface.
170 * - ``V4L2_CAP_VIDEO_M2M``170 * - ``V4L2_CAP_VIDEO_M2M``
171 - 0x00004000171 - 0x00008000
172 - The device supports the single-planar API through the Video172 - The device supports the single-planar API through the Video
173 Memory-To-Memory interface.173 Memory-To-Memory interface.
174 * - ``V4L2_CAP_VIDEO_M2M_MPLANE``174 * - ``V4L2_CAP_VIDEO_M2M_MPLANE``
175 - 0x00008000175 - 0x00004000
176 - The device supports the :ref:`multi-planar API <planar-apis>`176 - The device supports the :ref:`multi-planar API <planar-apis>`
177 through the Video Memory-To-Memory interface.177 through the Video Memory-To-Memory interface.
178 * - ``V4L2_CAP_VIDEO_OVERLAY``178 * - ``V4L2_CAP_VIDEO_OVERLAY``
Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst+19−2
@@ -112,10 +112,17 @@ aborting or finishing any DMA in progress, an implicit · 111 unmodified lines
112 ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will112 ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will
113 free any previously allocated buffers, so this is typically something113 free any previously allocated buffers, so this is typically something
114 that will be done at the start of the application.114 that will be done at the start of the application.
115 * - union {
116 - (anonymous)
117 * - __u32
118 - ``flags``
119 - Specifies additional buffer management attributes.
120 See :ref:`memory-flags`.
115 * - __u32121 * - __u32
116 - ``reserved``\ [1]122 - ``reserved``\ [1]
117 - A place holder for future extensions. Drivers and applications123 - Kept for backwards compatibility. Use ``flags`` instead.
118 must set the array to zero.124 * - }
125 -
119 126
120.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|127.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}|
121 128
@@ -126,6 +133,7 @@ aborting or finishing any DMA in progress, an implicit · 4 unmodified lines
126.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:133.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
127.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:134.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
128.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:135.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:
136.. _V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS:
129 137
130.. cssclass:: longtable138.. cssclass:: longtable
131 139
@@ -156,6 +164,15 @@ aborting or finishing any DMA in progress, an implicit · 24 unmodified lines
156 - Only valid for stateless decoders. If set, then userspace can set the164 - Only valid for stateless decoders. If set, then userspace can set the
157 ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the165 ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the
158 capture buffer until the OUTPUT timestamp changes.166 capture buffer until the OUTPUT timestamp changes.
167 * - ``V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS``
168 - 0x00000040
169 - This capability is set by the driver to indicate that the queue supports
170 cache and memory management hints. However, it's only valid when the
171 queue is used for :ref:`memory mapping <mmap>` streaming I/O. See
172 :ref:`V4L2_FLAG_MEMORY_NON_CONSISTENT <V4L2-FLAG-MEMORY-NON-CONSISTENT>`,
173 :ref:`V4L2_BUF_FLAG_NO_CACHE_INVALIDATE <V4L2-BUF-FLAG-NO-CACHE-INVALIDATE>` and
174 :ref:`V4L2_BUF_FLAG_NO_CACHE_CLEAN <V4L2-BUF-FLAG-NO-CACHE-CLEAN>`.
175
159 176
160Return Value177Return Value
161============178============
Documentation/userspace-api/media/videodev2.h.rst.exceptions+1−0
@@ -187,6 +187,7 @@ replace define V4L2_FMT_FLAG_COMPRESSED fmtdesc-flags · 186 unmodified lines
187replace define V4L2_FMT_FLAG_EMULATED fmtdesc-flags187replace define V4L2_FMT_FLAG_EMULATED fmtdesc-flags
188replace define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM fmtdesc-flags188replace define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM fmtdesc-flags
189replace define V4L2_FMT_FLAG_DYN_RESOLUTION fmtdesc-flags189replace define V4L2_FMT_FLAG_DYN_RESOLUTION fmtdesc-flags
190replace define V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL fmtdesc-flags
190 191
191# V4L2 timecode types192# V4L2 timecode types
192replace define V4L2_TC_TYPE_24FPS timecode-type193replace define V4L2_TC_TYPE_24FPS timecode-type
MAINTAINERS+54−10
@@ -4141,6 +4141,14 @@ F: drivers/power/supply/cros_usbpd-charger.c · 4140 unmodified lines
4141N: cros_ec4141N: cros_ec
4142N: cros-ec4142N: cros-ec
4143 4143
4144CHRONTEL CH7322 CEC DRIVER
4145M: Jeff Chase <jnchase@google.com>
4146L: linux-media@vger.kernel.org
4147S: Maintained
4148T: git git://linuxtv.org/media_tree.git
4149F: Documentation/devicetree/bindings/media/i2c/chrontel,ch7322.yaml
4150F: drivers/media/cec/i2c/ch7322.c
4151
4144CIRRUS LOGIC AUDIO CODEC DRIVERS4152CIRRUS LOGIC AUDIO CODEC DRIVERS
4145M: James Schulman <james.schulman@cirrus.com>4153M: James Schulman <james.schulman@cirrus.com>
4146M: David Rhodes <david.rhodes@cirrus.com>4154M: David Rhodes <david.rhodes@cirrus.com>
@@ -5267,6 +5275,14 @@ T: git git://linuxtv.org/media_tree.git · 1120 unmodified lines
5267F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt5275F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt
5268F: drivers/media/i2c/dw9714.c5276F: drivers/media/i2c/dw9714.c
5269 5277
5278DONGWOON DW9768 LENS VOICE COIL DRIVER
5279M: Dongchun Zhu <dongchun.zhu@mediatek.com>
5280L: linux-media@vger.kernel.org
5281S: Maintained
5282T: git git://linuxtv.org/media_tree.git
5283F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml
5284F: drivers/media/i2c/dw9768.c
5285
5270DONGWOON DW9807 LENS VOICE COIL DRIVER5286DONGWOON DW9807 LENS VOICE COIL DRIVER
5271M: Sakari Ailus <sakari.ailus@linux.intel.com>5287M: Sakari Ailus <sakari.ailus@linux.intel.com>
5272L: linux-media@vger.kernel.org5288L: linux-media@vger.kernel.org
@@ -10507,6 +10523,16 @@ F: Documentation/hwmon/max6697.rst · 5234 unmodified lines
10507F: drivers/hwmon/max6697.c10523F: drivers/hwmon/max6697.c
10508F: include/linux/platform_data/max6697.h10524F: include/linux/platform_data/max6697.h
10509 10525
10526MAX9286 QUAD GMSL DESERIALIZER DRIVER
10527M: Jacopo Mondi <jacopo+renesas@jmondi.org>
10528M: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
10529M: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
10530M: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
10531L: linux-media@vger.kernel.org
10532S: Maintained
10533F: Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
10534F: drivers/media/i2c/max9286.c
10535
10510MAX9860 MONO AUDIO VOICE CODEC DRIVER10536MAX9860 MONO AUDIO VOICE CODEC DRIVER
10511M: Peter Rosin <peda@axentia.se>10537M: Peter Rosin <peda@axentia.se>
10512L: alsa-devel@alsa-project.org (moderated for non-subscribers)10538L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -10785,7 +10811,7 @@ L: linux-media@vger.kernel.org · 272 unmodified lines
10785L: linux-renesas-soc@vger.kernel.org10811L: linux-renesas-soc@vger.kernel.org
10786S: Supported10812S: Supported
10787T: git git://linuxtv.org/media_tree.git10813T: git git://linuxtv.org/media_tree.git
10788F: Documentation/devicetree/bindings/media/renesas,fcp.txt10814F: Documentation/devicetree/bindings/media/renesas,fcp.yaml
10789F: drivers/media/platform/rcar-fcp.c10815F: drivers/media/platform/rcar-fcp.c
10790F: include/media/rcar-fcp.h10816F: include/media/rcar-fcp.h
10791 10817
@@ -10795,7 +10821,7 @@ L: linux-media@vger.kernel.org · 3 unmodified lines
10795L: linux-renesas-soc@vger.kernel.org10821L: linux-renesas-soc@vger.kernel.org
10796S: Supported10822S: Supported
10797T: git git://linuxtv.org/media_tree.git10823T: git git://linuxtv.org/media_tree.git
10798F: Documentation/devicetree/bindings/media/renesas,fdp1.txt10824F: Documentation/devicetree/bindings/media/renesas,fdp1.yaml
10799F: drivers/media/platform/rcar_fdp1.c10825F: drivers/media/platform/rcar_fdp1.c
10800 10826
10801MEDIA DRIVERS FOR RENESAS - VIN10827MEDIA DRIVERS FOR RENESAS - VIN
@@ -10815,7 +10841,7 @@ L: linux-media@vger.kernel.org · 13 unmodified lines
10815L: linux-renesas-soc@vger.kernel.org10841L: linux-renesas-soc@vger.kernel.org
10816S: Supported10842S: Supported
10817T: git git://linuxtv.org/media_tree.git10843T: git git://linuxtv.org/media_tree.git
10818F: Documentation/devicetree/bindings/media/renesas,vsp1.txt10844F: Documentation/devicetree/bindings/media/renesas,vsp1.yaml
10819F: drivers/media/platform/vsp1/10845F: drivers/media/platform/vsp1/
10820 10846
10821MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs10847MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs
@@ -14483,6 +14509,19 @@ L: linux-wireless@vger.kernel.org · 3661 unmodified lines
14483S: Orphan14509S: Orphan
14484F: drivers/net/wireless/ray*14510F: drivers/net/wireless/ray*
14485 14511
14512RC-CORE / LIRC FRAMEWORK
14513M: Sean Young <sean@mess.org>
14514L: linux-media@vger.kernel.org
14515S: Maintained
14516W: http://linuxtv.org
14517T: git git://linuxtv.org/media_tree.git
14518F: Documentation/driver-api/media/rc-core.rst
14519F: Documentation/userspace-api/media/rc/
14520F: drivers/media/rc/
14521F: include/media/rc-map.h
14522F: include/media/rc-core.h
14523F: include/uapi/linux/lirc.h
14524
14486RCMM REMOTE CONTROLS DECODER14525RCMM REMOTE CONTROLS DECODER
14487M: Patrick Lerda <patrick9876@free.fr>14526M: Patrick Lerda <patrick9876@free.fr>
14488S: Maintained14527S: Maintained
@@ -14499,6 +14538,18 @@ S: Supported · 10 unmodified lines
14499T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev14538T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git dev
14500F: tools/testing/selftests/rcutorture14539F: tools/testing/selftests/rcutorture
14501 14540
14541RDACM20 Camera Sensor
14542M: Jacopo Mondi <jacopo+renesas@jmondi.org>
14543M: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
14544M: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
14545M: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
14546L: linux-media@vger.kernel.org
14547S: Maintained
14548F: Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml
14549F: drivers/media/i2c/rdacm20.c
14550F: drivers/media/i2c/max9271.c
14551F: drivers/media/i2c/max9271.h
14552
14502RDC R-321X SoC14553RDC R-321X SoC
14503M: Florian Fainelli <florian@openwrt.org>14554M: Florian Fainelli <florian@openwrt.org>
14504S: Maintained14555S: Maintained
@@ -15887,13 +15938,6 @@ L: netdev@vger.kernel.org · 1382 unmodified lines
15887S: Maintained15938S: Maintained
15888F: drivers/net/ethernet/smsc/smsc9420.*15939F: drivers/net/ethernet/smsc/smsc9420.*
15889 15940
15890SOC-CAMERA V4L2 SUBSYSTEM
15891L: linux-media@vger.kernel.org
15892S: Orphan
15893T: git git://linuxtv.org/media_tree.git
15894F: drivers/staging/media/soc_camera/
15895F: include/media/soc_camera.h
15896
15897SOCIONEXT (SNI) AVE NETWORK DRIVER15941SOCIONEXT (SNI) AVE NETWORK DRIVER
15898M: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>15942M: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
15899L: netdev@vger.kernel.org15943L: netdev@vger.kernel.org
arch/arm/configs/ezx_defconfig+0−2
@@ -236,8 +236,6 @@ CONFIG_MEDIA_TUNER_CUSTOMISE=y · 235 unmodified lines
236# CONFIG_MEDIA_TUNER_MXL5007T is not set236# CONFIG_MEDIA_TUNER_MXL5007T is not set
237# CONFIG_MEDIA_TUNER_MC44S803 is not set237# CONFIG_MEDIA_TUNER_MC44S803 is not set
238# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set238# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
239CONFIG_SOC_CAMERA=y
240CONFIG_SOC_CAMERA_MT9M111=y
241CONFIG_VIDEO_PXA27x=y239CONFIG_VIDEO_PXA27x=y
242# CONFIG_V4L_USB_DRIVERS is not set240# CONFIG_V4L_USB_DRIVERS is not set
243CONFIG_RADIO_TEA5764=y241CONFIG_RADIO_TEA5764=y
arch/arm/configs/imote2_defconfig+0−2
@@ -217,8 +217,6 @@ CONFIG_MEDIA_TUNER_CUSTOMISE=y · 216 unmodified lines
217# CONFIG_MEDIA_TUNER_MXL5007T is not set217# CONFIG_MEDIA_TUNER_MXL5007T is not set
218# CONFIG_MEDIA_TUNER_MC44S803 is not set218# CONFIG_MEDIA_TUNER_MC44S803 is not set
219# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set219# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
220CONFIG_SOC_CAMERA=y
221CONFIG_SOC_CAMERA_MT9M111=y
222CONFIG_VIDEO_PXA27x=y220CONFIG_VIDEO_PXA27x=y
223# CONFIG_V4L_USB_DRIVERS is not set221# CONFIG_V4L_USB_DRIVERS is not set
224# CONFIG_RADIO_ADAPTERS is not set222# CONFIG_RADIO_ADAPTERS is not set
arch/arm/configs/imx_v4_v5_defconfig+0−1
@@ -110,7 +110,6 @@ CONFIG_REGULATOR_MC13892=y · 109 unmodified lines
110CONFIG_MEDIA_SUPPORT=y110CONFIG_MEDIA_SUPPORT=y
111CONFIG_MEDIA_CAMERA_SUPPORT=y111CONFIG_MEDIA_CAMERA_SUPPORT=y
112CONFIG_V4L_PLATFORM_DRIVERS=y112CONFIG_V4L_PLATFORM_DRIVERS=y
113CONFIG_SOC_CAMERA=y
114CONFIG_V4L_MEM2MEM_DRIVERS=y113CONFIG_V4L_MEM2MEM_DRIVERS=y
115CONFIG_VIDEO_CODA=y114CONFIG_VIDEO_CODA=y
116CONFIG_FB=y115CONFIG_FB=y
arch/arm/configs/imx_v6_v7_defconfig+0−1
@@ -272,7 +272,6 @@ CONFIG_MEDIA_USB_SUPPORT=y · 271 unmodified lines
272CONFIG_USB_VIDEO_CLASS=m272CONFIG_USB_VIDEO_CLASS=m
273CONFIG_V4L_PLATFORM_DRIVERS=y273CONFIG_V4L_PLATFORM_DRIVERS=y
274CONFIG_VIDEO_MUX=y274CONFIG_VIDEO_MUX=y
275CONFIG_SOC_CAMERA=y
276CONFIG_V4L_MEM2MEM_DRIVERS=y275CONFIG_V4L_MEM2MEM_DRIVERS=y
277CONFIG_VIDEO_CODA=m276CONFIG_VIDEO_CODA=m
278CONFIG_VIDEO_IMX_PXP=y277CONFIG_VIDEO_IMX_PXP=y
arch/arm/configs/pxa_defconfig+0−3
@@ -447,11 +447,8 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y · 446 unmodified lines
447CONFIG_MEDIA_USB_SUPPORT=y447CONFIG_MEDIA_USB_SUPPORT=y
448CONFIG_USB_VIDEO_CLASS=m448CONFIG_USB_VIDEO_CLASS=m
449CONFIG_V4L_PLATFORM_DRIVERS=y449CONFIG_V4L_PLATFORM_DRIVERS=y
450CONFIG_SOC_CAMERA=m
451CONFIG_SOC_CAMERA_PLATFORM=m
452CONFIG_VIDEO_PXA27x=m450CONFIG_VIDEO_PXA27x=m
453CONFIG_V4L_MEM2MEM_DRIVERS=y451CONFIG_V4L_MEM2MEM_DRIVERS=y
454CONFIG_SOC_CAMERA_MT9M111=m
455CONFIG_DRM=m452CONFIG_DRM=m
456CONFIG_FIRMWARE_EDID=y453CONFIG_FIRMWARE_EDID=y
457CONFIG_FB_TILEBLITTING=y454CONFIG_FB_TILEBLITTING=y
arch/arm/configs/sama5_defconfig+0−2
@@ -155,9 +155,7 @@ CONFIG_REGULATOR_PWM=m · 154 unmodified lines
155CONFIG_MEDIA_SUPPORT=y155CONFIG_MEDIA_SUPPORT=y
156CONFIG_MEDIA_CAMERA_SUPPORT=y156CONFIG_MEDIA_CAMERA_SUPPORT=y
157CONFIG_V4L_PLATFORM_DRIVERS=y157CONFIG_V4L_PLATFORM_DRIVERS=y
158CONFIG_SOC_CAMERA=y
159CONFIG_VIDEO_ATMEL_ISI=y158CONFIG_VIDEO_ATMEL_ISI=y
160CONFIG_SOC_CAMERA_OV2640=m
161CONFIG_DRM=y159CONFIG_DRM=y
162CONFIG_DRM_ATMEL_HLCDC=y160CONFIG_DRM_ATMEL_HLCDC=y
163CONFIG_DRM_PANEL_SIMPLE=y161CONFIG_DRM_PANEL_SIMPLE=y
arch/arm/mach-imx/mach-imx27_visstrim_m10.c+0−31
@@ -19,7 +19,6 @@ · 18 unmodified lines
19#include <linux/dma-mapping.h>19#include <linux/dma-mapping.h>
20#include <linux/leds.h>20#include <linux/leds.h>
21#include <linux/platform_data/asoc-mx27vis.h>21#include <linux/platform_data/asoc-mx27vis.h>
22#include <media/soc_camera.h>
23#include <sound/tlv320aic32x4.h>22#include <sound/tlv320aic32x4.h>
24#include <asm/mach-types.h>23#include <asm/mach-types.h>
25#include <asm/mach/arch.h>24#include <asm/mach/arch.h>
@@ -191,34 +190,6 @@ static const struct gpio visstrim_m10_gpios[] __initconst = { · 165 unmodified lines
191};190};
192 191
193/* Camera */192/* Camera */
194static int visstrim_camera_power(struct device *dev, int on)
195{
196 gpio_set_value(TVP5150_PWDN, on);
197
198 return 0;
199};
200
201static int visstrim_camera_reset(struct device *dev)
202{
203 gpio_set_value(TVP5150_RSTN, 0);
204 ndelay(500);
205 gpio_set_value(TVP5150_RSTN, 1);
206
207 return 0;
208};
209
210static struct i2c_board_info visstrim_i2c_camera = {
211 I2C_BOARD_INFO("tvp5150", 0x5d),
212};
213
214static struct soc_camera_link iclink_tvp5150 = {
215 .bus_id = 0,
216 .board_info = &visstrim_i2c_camera,
217 .i2c_adapter_id = 0,
218 .power = visstrim_camera_power,
219 .reset = visstrim_camera_reset,
220};
221
222static struct mx2_camera_platform_data visstrim_camera = {193static struct mx2_camera_platform_data visstrim_camera = {
223 .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |194 .flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
224 MX2_CAMERA_PCLK_SAMPLE_RISING,195 MX2_CAMERA_PCLK_SAMPLE_RISING,
@@ -549,8 +520,6 @@ static void __init visstrim_m10_late_init(void) · 324 unmodified lines
549 520
550 imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,521 imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,
551 sizeof(snd_mx27vis_pdata));522 sizeof(snd_mx27vis_pdata));
552 platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
553 &iclink_tvp5150, sizeof(iclink_tvp5150));
554 523
555 gpio_led_register_device(0, &visstrim_m10_led_data);524 gpio_led_register_device(0, &visstrim_m10_led_data);
556 525
arch/arm/mach-omap1/board-ams-delta.c+0−32
@@ -29,8 +29,6 @@ · 28 unmodified lines
29#include <linux/io.h>29#include <linux/io.h>
30#include <linux/platform_data/gpio-omap.h>30#include <linux/platform_data/gpio-omap.h>
31 31
32#include <media/soc_camera.h>
33
34#include <asm/serial.h>32#include <asm/serial.h>
35#include <asm/mach-types.h>33#include <asm/mach-types.h>
36#include <asm/mach/arch.h>34#include <asm/mach/arch.h>
@@ -40,7 +38,6 @@ · 3 unmodified lines
40#include <mach/mux.h>38#include <mach/mux.h>
41 39
42#include <mach/hardware.h>40#include <mach/hardware.h>
43#include "camera.h"
44#include <mach/usb.h>41#include <mach/usb.h>
45 42
46#include "ams-delta-fiq.h"43#include "ams-delta-fiq.h"
@@ -459,12 +456,6 @@ static struct gpiod_lookup_table leds_gpio_table = { · 412 unmodified lines
459 },456 },
460};457};
461 458
462static struct i2c_board_info ams_delta_camera_board_info[] = {
463 {
464 I2C_BOARD_INFO("ov6650", 0x60),
465 },
466};
467
468#ifdef CONFIG_LEDS_TRIGGERS459#ifdef CONFIG_LEDS_TRIGGERS
469DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger);460DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger);
470 461
@@ -483,27 +474,6 @@ static int ams_delta_camera_power(struct device *dev, int power) · 12 unmodified lines
483#define ams_delta_camera_power NULL474#define ams_delta_camera_power NULL
484#endif475#endif
485 476
486static struct soc_camera_link ams_delta_iclink = {
487 .bus_id = 0, /* OMAP1 SoC camera bus */
488 .i2c_adapter_id = 1,
489 .board_info = &ams_delta_camera_board_info[0],
490 .module_name = "ov6650",
491 .power = ams_delta_camera_power,
492};
493
494static struct platform_device ams_delta_camera_device = {
495 .name = "soc-camera-pdrv",
496 .id = 0,
497 .dev = {
498 .platform_data = &ams_delta_iclink,
499 },
500};
501
502static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
503 .camexclk_khz = 12000, /* default 12MHz clock, no extra DPLL */
504 .lclk_khz_max = 1334, /* results in 5fps CIF, 10fps QCIF */
505};
506
507static struct platform_device ams_delta_audio_device = {477static struct platform_device ams_delta_audio_device = {
508 .name = "ams-delta-audio",478 .name = "ams-delta-audio",
509 .id = -1,479 .id = -1,
@@ -598,7 +568,6 @@ static struct platform_device *ams_delta_devices[] __initdata = { · 88 unmodified lines
598 &latch1_gpio_device,568 &latch1_gpio_device,
599 &latch2_gpio_device,569 &latch2_gpio_device,
600 &ams_delta_kp_device,570 &ams_delta_kp_device,
601 &ams_delta_camera_device,
602 &ams_delta_audio_device,571 &ams_delta_audio_device,
603 &ams_delta_serio_device,572 &ams_delta_serio_device,
604 &ams_delta_nand_device,573 &ams_delta_nand_device,
@@ -750,7 +719,6 @@ static void __init ams_delta_init(void) · 145 unmodified lines
750 omap_register_i2c_bus(1, 100, NULL, 0);719 omap_register_i2c_bus(1, 100, NULL, 0);
751 720
752 omap1_usb_init(&ams_delta_usb_config);721 omap1_usb_init(&ams_delta_usb_config);
753 omap1_set_camera_info(&ams_delta_camera_platform_data);
754#ifdef CONFIG_LEDS_TRIGGERS722#ifdef CONFIG_LEDS_TRIGGERS
755 led_trigger_register_simple("ams_delta_camera",723 led_trigger_register_simple("ams_delta_camera",
756 &ams_delta_camera_led_trigger);724 &ams_delta_camera_led_trigger);
arch/arm/mach-omap1/camera.h+0−14
@@ -1,14 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __ASM_ARCH_CAMERA_H_
3#define __ASM_ARCH_CAMERA_H_
4
5#include <linux/platform_data/media/omap1_camera.h>
6
7void omap1_camera_init(void *);
8
9static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info)
10{
11 omap1_camera_init(info);
12}
13
14#endif /* __ASM_ARCH_CAMERA_H_ */
arch/arm/mach-omap1/devices.c+0−43
@@ -21,7 +21,6 @@ · 20 unmodified lines
21#include <mach/mux.h>21#include <mach/mux.h>
22 22
23#include <mach/omap7xx.h>23#include <mach/omap7xx.h>
24#include "camera.h"
25#include <mach/hardware.h>24#include <mach/hardware.h>
26 25
27#include "common.h"26#include "common.h"
@@ -258,48 +257,6 @@ static inline void omap_init_spi100k(void) · 230 unmodified lines
258}257}
259#endif258#endif
260 259
261
262#define OMAP1_CAMERA_BASE 0xfffb6800
263#define OMAP1_CAMERA_IOSIZE 0x1c
264
265static struct resource omap1_camera_resources[] = {
266 [0] = {
267 .start = OMAP1_CAMERA_BASE,
268 .end = OMAP1_CAMERA_BASE + OMAP1_CAMERA_IOSIZE - 1,
269 .flags = IORESOURCE_MEM,
270 },
271 [1] = {
272 .start = INT_CAMERA,
273 .flags = IORESOURCE_IRQ,
274 },
275};
276
277static u64 omap1_camera_dma_mask = DMA_BIT_MASK(32);
278
279static struct platform_device omap1_camera_device = {
280 .name = "omap1-camera",
281 .id = 0, /* This is used to put cameras on this interface */
282 .dev = {
283 .dma_mask = &omap1_camera_dma_mask,
284 .coherent_dma_mask = DMA_BIT_MASK(32),
285 },
286 .num_resources = ARRAY_SIZE(omap1_camera_resources),
287 .resource = omap1_camera_resources,
288};
289
290void __init omap1_camera_init(void *info)
291{
292 struct platform_device *dev = &omap1_camera_device;
293 int ret;
294
295 dev->dev.platform_data = info;
296
297 ret = platform_device_register(dev);
298 if (ret)
299 dev_err(&dev->dev, "unable to register device: %d\n", ret);
300}
301
302
303/*-------------------------------------------------------------------------*/260/*-------------------------------------------------------------------------*/
304 261
305static inline void omap_init_sti(void) {}262static inline void omap_init_sti(void) {}
arch/arm/mach-pxa/palmz72.c+0−112
@@ -47,8 +47,6 @@ · 46 unmodified lines
47#include "pm.h"47#include "pm.h"
48#include <linux/platform_data/media/camera-pxa.h>48#include <linux/platform_data/media/camera-pxa.h>
49 49
50#include <media/soc_camera.h>
51
52#include "generic.h"50#include "generic.h"
53#include "devices.h"51#include "devices.h"
54 52
@@ -272,115 +270,6 @@ static int __init palmz72_pm_init(void) · 217 unmodified lines
272device_initcall(palmz72_pm_init);270device_initcall(palmz72_pm_init);
273#endif271#endif
274 272
275/******************************************************************************
276 * SoC Camera
277 ******************************************************************************/
278#if defined(CONFIG_SOC_CAMERA_OV9640) || \
279 defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
280static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
281 .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
282 PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
283 .mclk_10khz = 2600,
284};
285
286/* Board I2C devices. */
287static struct i2c_board_info palmz72_i2c_device[] = {
288 {
289 I2C_BOARD_INFO("ov9640", 0x30),
290 }
291};
292
293static int palmz72_camera_power(struct device *dev, int power)
294{
295 gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
296 mdelay(50);
297 return 0;
298}
299
300static int palmz72_camera_reset(struct device *dev)
301{
302 gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
303 mdelay(50);
304 gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
305 mdelay(50);
306 return 0;
307}
308
309static struct soc_camera_link palmz72_iclink = {
310 .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
311 .board_info = &palmz72_i2c_device[0],
312 .i2c_adapter_id = 0,
313 .module_name = "ov96xx",
314 .power = &palmz72_camera_power,
315 .reset = &palmz72_camera_reset,
316 .flags = SOCAM_DATAWIDTH_8,
317};
318
319static struct gpiod_lookup_table palmz72_i2c_gpiod_table = {
320 .dev_id = "i2c-gpio.0",
321 .table = {
322 GPIO_LOOKUP_IDX("gpio-pxa", 118, NULL, 0,
323 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
324 GPIO_LOOKUP_IDX("gpio-pxa", 117, NULL, 1,
325 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
326 },
327};
328
329static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
330 .udelay = 10,
331 .timeout = 100,
332};
333
334static struct platform_device palmz72_i2c_bus_device = {
335 .name = "i2c-gpio",
336 .id = 0, /* we use this as a replacement for i2c-pxa */
337 .dev = {
338 .platform_data = &palmz72_i2c_bus_data,
339 }
340};
341
342static struct platform_device palmz72_camera = {
343 .name = "soc-camera-pdrv",
344 .id = -1,
345 .dev = {
346 .platform_data = &palmz72_iclink,
347 },
348};
349
350/* Here we request the camera GPIOs and configure them. We power up the camera
351 * module, deassert the reset pin, but put it into powerdown (low to no power
352 * consumption) mode. This allows us to later bring the module up fast. */
353static struct gpio palmz72_camera_gpios[] = {
354 { GPIO_NR_PALMZ72_CAM_POWER, GPIOF_INIT_HIGH,"Camera DVDD" },
355 { GPIO_NR_PALMZ72_CAM_RESET, GPIOF_INIT_LOW, "Camera RESET" },
356 { GPIO_NR_PALMZ72_CAM_PWDN, GPIOF_INIT_LOW, "Camera PWDN" },
357};
358
359static inline void __init palmz72_cam_gpio_init(void)
360{
361 int ret;
362
363 ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
364 if (!ret)
365 gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
366 else
367 printk(KERN_ERR "Camera GPIO init failed!\n");
368
369 return;
370}
371
372static void __init palmz72_camera_init(void)
373{
374 palmz72_cam_gpio_init();
375 pxa_set_camera_info(&palmz72_pxacamera_platform_data);
376 gpiod_add_lookup_table(&palmz72_i2c_gpiod_table);
377 platform_device_register(&palmz72_i2c_bus_device);
378 platform_device_register(&palmz72_camera);
379}
380#else
381static inline void palmz72_camera_init(void) {}
382#endif
383
384static struct gpiod_lookup_table palmz72_mci_gpio_table = {273static struct gpiod_lookup_table palmz72_mci_gpio_table = {
385 .dev_id = "pxa2xx-mci.0",274 .dev_id = "pxa2xx-mci.0",
386 .table = {275 .table = {
@@ -416,7 +305,6 @@ static void __init palmz72_init(void) · 29 unmodified lines
416 palm27x_pmic_init();305 palm27x_pmic_init();
417 palmz72_kpc_init();306 palmz72_kpc_init();
418 palmz72_leds_init();307 palmz72_leds_init();
419 palmz72_camera_init();
420}308}
421 309
422MACHINE_START(PALMZ72, "Palm Zire72")310MACHINE_START(PALMZ72, "Palm Zire72")
arch/arm/mach-pxa/pcm990-baseboard.c+0−157
@@ -24,10 +24,6 @@ · 23 unmodified lines
24#include <linux/pwm.h>24#include <linux/pwm.h>
25#include <linux/pwm_backlight.h>25#include <linux/pwm_backlight.h>
26 26
27#include <media/i2c/mt9v022.h>
28#include <media/soc_camera.h>
29
30#include <linux/platform_data/media/camera-pxa.h>
31#include <asm/mach/map.h>27#include <asm/mach/map.h>
32#include "pxa27x.h"28#include "pxa27x.h"
33#include <mach/audio.h>29#include <mach/audio.h>
@@ -374,149 +370,6 @@ static struct pxaohci_platform_data pcm990_ohci_platform_data = { · 340 unmodified lines
374 .power_on_delay = 10,370 .power_on_delay = 10,
375};371};
376 372
377/*
378 * PXA27x Camera specific stuff
379 */
380#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
381static unsigned long pcm990_camera_pin_config[] = {
382 /* CIF */
383 GPIO98_CIF_DD_0,
384 GPIO105_CIF_DD_1,
385 GPIO104_CIF_DD_2,
386 GPIO103_CIF_DD_3,
387 GPIO95_CIF_DD_4,
388 GPIO94_CIF_DD_5,
389 GPIO93_CIF_DD_6,
390 GPIO108_CIF_DD_7,
391 GPIO107_CIF_DD_8,
392 GPIO106_CIF_DD_9,
393 GPIO42_CIF_MCLK,
394 GPIO45_CIF_PCLK,
395 GPIO43_CIF_FV,
396 GPIO44_CIF_LV,
397};
398
399/*
400 * CICR4: PCLK_EN: Pixel clock is supplied by the sensor
401 * MCLK_EN: Master clock is generated by PXA
402 * PCP: Data sampled on the falling edge of pixel clock
403 */
404struct pxacamera_platform_data pcm990_pxacamera_platform_data = {
405 .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_10 |
406 PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN/* | PXA_CAMERA_PCP*/,
407 .mclk_10khz = 1000,
408};
409
410#include <linux/platform_data/pca953x.h>
411
412static struct pca953x_platform_data pca9536_data = {
413 .gpio_base = PXA_NR_BUILTIN_GPIO,
414};
415
416static int gpio_bus_switch = -EINVAL;
417
418static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
419 unsigned long flags)
420{
421 if (gpio_bus_switch < 0) {
422 if (flags == SOCAM_DATAWIDTH_10)
423 return 0;
424 else
425 return -EINVAL;
426 }
427
428 if (flags & SOCAM_DATAWIDTH_8)
429 gpio_set_value_cansleep(gpio_bus_switch, 1);
430 else
431 gpio_set_value_cansleep(gpio_bus_switch, 0);
432
433 return 0;
434}
435
436static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
437{
438 int ret;
439
440 if (gpio_bus_switch < 0) {
441 ret = gpio_request(PXA_NR_BUILTIN_GPIO, "camera");
442 if (!ret) {
443 gpio_bus_switch = PXA_NR_BUILTIN_GPIO;
444 gpio_direction_output(gpio_bus_switch, 0);
445 }
446 }
447
448 if (gpio_bus_switch >= 0)
449 return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
450 else
451 return SOCAM_DATAWIDTH_10;
452}
453
454static void pcm990_camera_free_bus(struct soc_camera_link *link)
455{
456 if (gpio_bus_switch < 0)
457 return;
458
459 gpio_free(gpio_bus_switch);
460 gpio_bus_switch = -EINVAL;
461}
462
463/* Board I2C devices. */
464static struct i2c_board_info __initdata pcm990_i2c_devices[] = {
465 {
466 /* Must initialize before the camera(s) */
467 I2C_BOARD_INFO("pca9536", 0x41),
468 .platform_data = &pca9536_data,
469 },
470};
471
472static struct mt9v022_platform_data mt9v022_pdata = {
473 .y_skip_top = 1,
474};
475
476static struct i2c_board_info pcm990_camera_i2c[] = {
477 {
478 I2C_BOARD_INFO("mt9v022", 0x48),
479 }, {
480 I2C_BOARD_INFO("mt9m001", 0x5d),
481 },
482};
483
484static struct soc_camera_link iclink[] = {
485 {
486 .bus_id = 0, /* Must match with the camera ID */
487 .board_info = &pcm990_camera_i2c[0],
488 .priv = &mt9v022_pdata,
489 .i2c_adapter_id = 0,
490 .query_bus_param = pcm990_camera_query_bus_param,
491 .set_bus_param = pcm990_camera_set_bus_param,
492 .free_bus = pcm990_camera_free_bus,
493 }, {
494 .bus_id = 0, /* Must match with the camera ID */
495 .board_info = &pcm990_camera_i2c[1],
496 .i2c_adapter_id = 0,
497 .query_bus_param = pcm990_camera_query_bus_param,
498 .set_bus_param = pcm990_camera_set_bus_param,
499 .free_bus = pcm990_camera_free_bus,
500 },
501};
502
503static struct platform_device pcm990_camera[] = {
504 {
505 .name = "soc-camera-pdrv",
506 .id = 0,
507 .dev = {
508 .platform_data = &iclink[0],
509 },
510 }, {
511 .name = "soc-camera-pdrv",
512 .id = 1,
513 .dev = {
514 .platform_data = &iclink[1],
515 },
516 },
517};
518#endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */
519
520/*373/*
521 * system init for baseboard usage. Will be called by pcm027 init.374 * system init for baseboard usage. Will be called by pcm027 init.
522 *375 *
@@ -551,15 +404,5 @@ void __init pcm990_baseboard_init(void) · 28 unmodified lines
551 pxa_set_i2c_info(NULL);404 pxa_set_i2c_info(NULL);
552 pxa_set_ac97_info(NULL);405 pxa_set_ac97_info(NULL);
553 406
554#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
555 pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config));
556 pxa_set_camera_info(&pcm990_pxacamera_platform_data);
557
558 i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices));
559
560 platform_device_register(&pcm990_camera[0]);
561 platform_device_register(&pcm990_camera[1]);
562#endif
563
564 printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");407 printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
565}408}
arch/sh/configs/ap325rxa_defconfig+0−3
@@ -65,9 +65,6 @@ CONFIG_VIDEO_DEV=y · 64 unmodified lines
65# CONFIG_VIDEO_ALLOW_V4L1 is not set65# CONFIG_VIDEO_ALLOW_V4L1 is not set
66# CONFIG_MEDIA_TUNER_CUSTOMISE is not set66# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
67CONFIG_VIDEO_HELPER_CHIPS_AUTO=y67CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
68CONFIG_SOC_CAMERA=y
69CONFIG_SOC_CAMERA_PLATFORM=y
70CONFIG_SOC_CAMERA_OV772X=y
71CONFIG_VIDEO_SH_MOBILE_CEU=y68CONFIG_VIDEO_SH_MOBILE_CEU=y
72# CONFIG_RADIO_ADAPTERS is not set69# CONFIG_RADIO_ADAPTERS is not set
73CONFIG_FB=y70CONFIG_FB=y
arch/sh/configs/ecovec24_defconfig+0−3
@@ -72,9 +72,6 @@ CONFIG_MEDIA_SUPPORT=y · 71 unmodified lines
72CONFIG_VIDEO_DEV=y72CONFIG_VIDEO_DEV=y
73# CONFIG_MEDIA_TUNER_CUSTOMISE is not set73# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
74CONFIG_VIDEO_HELPER_CHIPS_AUTO=y74CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
75CONFIG_SOC_CAMERA=y
76CONFIG_SOC_CAMERA_MT9T112=y
77CONFIG_SOC_CAMERA_TW9910=y
78CONFIG_VIDEO_SH_MOBILE_CEU=y75CONFIG_VIDEO_SH_MOBILE_CEU=y
79# CONFIG_V4L_USB_DRIVERS is not set76# CONFIG_V4L_USB_DRIVERS is not set
80CONFIG_FB=y77CONFIG_FB=y
arch/sh/configs/migor_defconfig+0−3
@@ -62,9 +62,6 @@ CONFIG_VIDEO_DEV=y · 61 unmodified lines
62# CONFIG_VIDEO_ALLOW_V4L1 is not set62# CONFIG_VIDEO_ALLOW_V4L1 is not set
63# CONFIG_MEDIA_TUNER_CUSTOMISE is not set63# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
64CONFIG_VIDEO_HELPER_CHIPS_AUTO=y64CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
65CONFIG_SOC_CAMERA=y
66CONFIG_SOC_CAMERA_TW9910=y
67CONFIG_SOC_CAMERA_OV772X=y
68CONFIG_VIDEO_SH_MOBILE_CEU=y65CONFIG_VIDEO_SH_MOBILE_CEU=y
69# CONFIG_RADIO_ADAPTERS is not set66# CONFIG_RADIO_ADAPTERS is not set
70CONFIG_FB=y67CONFIG_FB=y
arch/sh/configs/se7724_defconfig+0−2
@@ -70,8 +70,6 @@ CONFIG_VIDEO_DEV=y · 69 unmodified lines
70CONFIG_DVB_CORE=m70CONFIG_DVB_CORE=m
71# CONFIG_MEDIA_TUNER_CUSTOMISE is not set71# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
72CONFIG_VIDEO_HELPER_CHIPS_AUTO=y72CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
73CONFIG_SOC_CAMERA=y
74CONFIG_SOC_CAMERA_OV772X=y
75CONFIG_VIDEO_SH_MOBILE_CEU=y73CONFIG_VIDEO_SH_MOBILE_CEU=y
76# CONFIG_RADIO_ADAPTERS is not set74# CONFIG_RADIO_ADAPTERS is not set
77# CONFIG_DVB_FE_CUSTOMISE is not set75# CONFIG_DVB_FE_CUSTOMISE is not set
drivers/media/cec/Kconfig+1−0
@@ -33,6 +33,7 @@ menuconfig MEDIA_CEC_SUPPORT · 32 unmodified lines
33 adapter that supports HDMI CEC.33 adapter that supports HDMI CEC.
34 34
35if MEDIA_CEC_SUPPORT35if MEDIA_CEC_SUPPORT
36source "drivers/media/cec/i2c/Kconfig"
36source "drivers/media/cec/platform/Kconfig"37source "drivers/media/cec/platform/Kconfig"
37source "drivers/media/cec/usb/Kconfig"38source "drivers/media/cec/usb/Kconfig"
38endif39endif
drivers/media/cec/Makefile+1−1
@@ -1,2 +1,2 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2obj-y += core/ platform/ usb/2obj-y += core/ i2c/ platform/ usb/
drivers/media/cec/core/cec-adap.c+0−4
@@ -1306,7 +1306,6 @@ static int cec_config_log_addr(struct cec_adapter *adap, · 1305 unmodified lines
1306 1306
1307 las->log_addr[idx] = log_addr;1307 las->log_addr[idx] = log_addr;
1308 las->log_addr_mask |= 1 << log_addr;1308 las->log_addr_mask |= 1 << log_addr;
1309 adap->phys_addrs[log_addr] = adap->phys_addr;
1310 return 1;1309 return 1;
1311}1310}
1312 1311
@@ -1324,7 +1323,6 @@ static void cec_adap_unconfigure(struct cec_adapter *adap) · 11 unmodified lines
1324 adap->log_addrs.log_addr_mask = 0;1323 adap->log_addrs.log_addr_mask = 0;
1325 adap->is_configuring = false;1324 adap->is_configuring = false;
1326 adap->is_configured = false;1325 adap->is_configured = false;
1327 memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
1328 cec_flush(adap);1326 cec_flush(adap);
1329 wake_up_interruptible(&adap->kthread_waitq);1327 wake_up_interruptible(&adap->kthread_waitq);
1330 cec_post_state_event(adap);1328 cec_post_state_event(adap);
@@ -1974,8 +1972,6 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, · 643 unmodified lines
1974 case CEC_MSG_REPORT_PHYSICAL_ADDR: {1972 case CEC_MSG_REPORT_PHYSICAL_ADDR: {
1975 u16 pa = (msg->msg[2] << 8) | msg->msg[3];1973 u16 pa = (msg->msg[2] << 8) | msg->msg[3];
1976 1974
1977 if (!from_unregistered)
1978 adap->phys_addrs[init_laddr] = pa;
1979 dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n",1975 dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n",
1980 cec_phys_addr_exp(pa), init_laddr);1976 cec_phys_addr_exp(pa), init_laddr);
1981 break;1977 break;
drivers/media/cec/core/cec-api.c+7−1
@@ -147,7 +147,13 @@ static long cec_adap_g_log_addrs(struct cec_adapter *adap, · 146 unmodified lines
147 struct cec_log_addrs log_addrs;147 struct cec_log_addrs log_addrs;
148 148
149 mutex_lock(&adap->lock);149 mutex_lock(&adap->lock);
150 log_addrs = adap->log_addrs;150 /*
151 * We use memcpy here instead of assignment since there is a
152 * hole at the end of struct cec_log_addrs that an assignment
153 * might ignore. So when we do copy_to_user() we could leak
154 * one byte of memory.
155 */
156 memcpy(&log_addrs, &adap->log_addrs, sizeof(log_addrs));
151 if (!adap->is_configured)157 if (!adap->is_configured)
152 memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID,158 memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID,
153 sizeof(log_addrs.log_addr));159 sizeof(log_addrs.log_addr));
drivers/media/cec/core/cec-core.c+0−1
@@ -265,7 +265,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, · 264 unmodified lines
265 adap->sequence = 0;265 adap->sequence = 0;
266 adap->ops = ops;266 adap->ops = ops;
267 adap->priv = priv;267 adap->priv = priv;
268 memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
269 mutex_init(&adap->lock);268 mutex_init(&adap->lock);
270 INIT_LIST_HEAD(&adap->transmit_queue);269 INIT_LIST_HEAD(&adap->transmit_queue);
271 INIT_LIST_HEAD(&adap->wait_queue);270 INIT_LIST_HEAD(&adap->wait_queue);
drivers/media/cec/core/cec-notifier.c+7−4
@@ -116,7 +116,8 @@ cec_notifier_conn_register(struct device *hdmi_dev, const char *port_name, · 115 unmodified lines
116 else116 else
117 memset(&n->conn_info, 0, sizeof(n->conn_info));117 memset(&n->conn_info, 0, sizeof(n->conn_info));
118 if (n->cec_adap) {118 if (n->cec_adap) {
119 cec_phys_addr_invalidate(n->cec_adap);119 if (!n->cec_adap->adap_controls_phys_addr)
120 cec_phys_addr_invalidate(n->cec_adap);
120 cec_s_conn_info(n->cec_adap, conn_info);121 cec_s_conn_info(n->cec_adap, conn_info);
121 }122 }
122 mutex_unlock(&n->lock);123 mutex_unlock(&n->lock);
@@ -133,7 +134,8 @@ void cec_notifier_conn_unregister(struct cec_notifier *n) · 10 unmodified lines
133 memset(&n->conn_info, 0, sizeof(n->conn_info));134 memset(&n->conn_info, 0, sizeof(n->conn_info));
134 n->phys_addr = CEC_PHYS_ADDR_INVALID;135 n->phys_addr = CEC_PHYS_ADDR_INVALID;
135 if (n->cec_adap) {136 if (n->cec_adap) {
136 cec_phys_addr_invalidate(n->cec_adap);137 if (!n->cec_adap->adap_controls_phys_addr)
138 cec_phys_addr_invalidate(n->cec_adap);
137 cec_s_conn_info(n->cec_adap, NULL);139 cec_s_conn_info(n->cec_adap, NULL);
138 }140 }
139 mutex_unlock(&n->lock);141 mutex_unlock(&n->lock);
@@ -158,7 +160,8 @@ cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *port_name, · 18 unmodified lines
158 n->cec_adap = adap;160 n->cec_adap = adap;
159 adap->conn_info = n->conn_info;161 adap->conn_info = n->conn_info;
160 adap->notifier = n;162 adap->notifier = n;
161 cec_s_phys_addr(adap, n->phys_addr, false);163 if (!adap->adap_controls_phys_addr)
164 cec_s_phys_addr(adap, n->phys_addr, false);
162 mutex_unlock(&n->lock);165 mutex_unlock(&n->lock);
163 return n;166 return n;
164}167}
@@ -185,7 +188,7 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa) · 20 unmodified lines
185 188
186 mutex_lock(&n->lock);189 mutex_lock(&n->lock);
187 n->phys_addr = pa;190 n->phys_addr = pa;
188 if (n->cec_adap)191 if (n->cec_adap && !n->cec_adap->adap_controls_phys_addr)
189 cec_s_phys_addr(n->cec_adap, n->phys_addr, false);192 cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
190 mutex_unlock(&n->lock);193 mutex_unlock(&n->lock);
191}194}
drivers/media/cec/i2c/Kconfig+14−0
@@ -0,0 +1,14 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# I2C drivers
4
5config CEC_CH7322
6 tristate "Chrontel CH7322 CEC controller"
7 depends on I2C
8 select REGMAP_I2C
9 select CEC_CORE
10 help
11 This is a driver for the Chrontel CH7322 CEC controller. It uses the
12 generic CEC framework interface.
13 CEC bus is present in the HDMI connector and enables communication
14 between compatible devices.
drivers/media/cec/i2c/Makefile+5−0
@@ -0,0 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Makefile for the CEC I2C device drivers.
4#
5obj-$(CONFIG_CEC_CH7322) += ch7322.o
drivers/media/cec/i2c/ch7322.c+604−0
@@ -0,0 +1,604 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for the Chrontel CH7322 CEC Controller
4 *
5 * Copyright 2020 Google LLC.
6 */
7
8/*
9 * Notes
10 *
11 * - This device powers on in Auto Mode which has limited functionality. This
12 * driver disables Auto Mode when it attaches.
13 *
14 */
15
16#include <linux/cec.h>
17#include <linux/dmi.h>
18#include <linux/i2c.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/mutex.h>
22#include <linux/pci.h>
23#include <linux/regmap.h>
24#include <media/cec.h>
25#include <media/cec-notifier.h>
26
27#define CH7322_WRITE 0x00
28#define CH7322_WRITE_MSENT 0x80
29#define CH7322_WRITE_BOK 0x40
30#define CH7322_WRITE_NMASK 0x0f
31
32/* Write buffer is 0x01-0x10 */
33#define CH7322_WRBUF 0x01
34#define CH7322_WRBUF_LEN 0x10
35
36#define CH7322_READ 0x40
37#define CH7322_READ_NRDT 0x80
38#define CH7322_READ_MSENT 0x20
39#define CH7322_READ_NMASK 0x0f
40
41/* Read buffer is 0x41-0x50 */
42#define CH7322_RDBUF 0x41
43#define CH7322_RDBUF_LEN 0x10
44
45#define CH7322_MODE 0x11
46#define CH7322_MODE_AUTO 0x78
47#define CH7322_MODE_SW 0xb5
48
49#define CH7322_RESET 0x12
50#define CH7322_RESET_RST 0x00
51
52#define CH7322_POWER 0x13
53#define CH7322_POWER_FPD 0x04
54
55#define CH7322_CFG0 0x17
56#define CH7322_CFG0_EOBEN 0x40
57#define CH7322_CFG0_PEOB 0x20
58#define CH7322_CFG0_CLRSPP 0x10
59#define CH7322_CFG0_FLOW 0x08
60
61#define CH7322_CFG1 0x1a
62#define CH7322_CFG1_STDBYO 0x04
63#define CH7322_CFG1_HPBP 0x02
64#define CH7322_CFG1_PIO 0x01
65
66#define CH7322_INTCTL 0x1b
67#define CH7322_INTCTL_INTPB 0x80
68#define CH7322_INTCTL_STDBY 0x40
69#define CH7322_INTCTL_HPDFALL 0x20
70#define CH7322_INTCTL_HPDRISE 0x10
71#define CH7322_INTCTL_RXMSG 0x08
72#define CH7322_INTCTL_TXMSG 0x04
73#define CH7322_INTCTL_NEWPHA 0x02
74#define CH7322_INTCTL_ERROR 0x01
75
76#define CH7322_DVCLKFNH 0x1d
77#define CH7322_DVCLKFNL 0x1e
78
79#define CH7322_CTL 0x31
80#define CH7322_CTL_FSTDBY 0x80
81#define CH7322_CTL_PLSEN 0x40
82#define CH7322_CTL_PLSPB 0x20
83#define CH7322_CTL_SPADL 0x10
84#define CH7322_CTL_HINIT 0x08
85#define CH7322_CTL_WPHYA 0x04
86#define CH7322_CTL_H1T 0x02
87#define CH7322_CTL_S1T 0x01
88
89#define CH7322_PAWH 0x32
90#define CH7322_PAWL 0x33
91
92#define CH7322_ADDLW 0x34
93#define CH7322_ADDLW_MASK 0xf0
94
95#define CH7322_ADDLR 0x3d
96#define CH7322_ADDLR_HPD 0x80
97#define CH7322_ADDLR_MASK 0x0f
98
99#define CH7322_INTDATA 0x3e
100#define CH7322_INTDATA_MODE 0x80
101#define CH7322_INTDATA_STDBY 0x40
102#define CH7322_INTDATA_HPDFALL 0x20
103#define CH7322_INTDATA_HPDRISE 0x10
104#define CH7322_INTDATA_RXMSG 0x08
105#define CH7322_INTDATA_TXMSG 0x04
106#define CH7322_INTDATA_NEWPHA 0x02
107#define CH7322_INTDATA_ERROR 0x01
108
109#define CH7322_EVENT 0x3f
110#define CH7322_EVENT_TXERR 0x80
111#define CH7322_EVENT_HRST 0x40
112#define CH7322_EVENT_HFST 0x20
113#define CH7322_EVENT_PHACHG 0x10
114#define CH7322_EVENT_ACTST 0x08
115#define CH7322_EVENT_PHARDY 0x04
116#define CH7322_EVENT_BSOK 0x02
117#define CH7322_EVENT_ERRADCF 0x01
118
119#define CH7322_DID 0x51
120#define CH7322_DID_CH7322 0x5b
121#define CH7322_DID_CH7323 0x5f
122
123#define CH7322_REVISIONID 0x52
124
125#define CH7322_PARH 0x53
126#define CH7322_PARL 0x54
127
128#define CH7322_IOCFG2 0x75
129#define CH7322_IOCFG_CIO 0x80
130#define CH7322_IOCFG_IOCFGMASK 0x78
131#define CH7322_IOCFG_AUDIO 0x04
132#define CH7322_IOCFG_SPAMST 0x02
133#define CH7322_IOCFG_SPAMSP 0x01
134
135#define CH7322_CTL3 0x7b
136#define CH7322_CTL3_SWENA 0x80
137#define CH7322_CTL3_FC_INIT 0x40
138#define CH7322_CTL3_SML_FL 0x20
139#define CH7322_CTL3_SM_RDST 0x10
140#define CH7322_CTL3_SPP_CIAH 0x08
141#define CH7322_CTL3_SPP_CIAL 0x04
142#define CH7322_CTL3_SPP_ACTH 0x02
143#define CH7322_CTL3_SPP_ACTL 0x01
144
145/* BOK status means NACK */
146#define CH7322_TX_FLAG_NACK BIT(0)
147/* Device will retry automatically */
148#define CH7322_TX_FLAG_RETRY BIT(1)
149
150struct ch7322 {
151 struct i2c_client *i2c;
152 struct regmap *regmap;
153 struct cec_adapter *cec;
154 struct mutex mutex; /* device access mutex */
155 u8 tx_flags;
156};
157
158static const struct regmap_config ch7322_regmap = {
159 .reg_bits = 8,
160 .val_bits = 8,
161 .max_register = 0x7f,
162 .disable_locking = true,
163};
164
165static int ch7322_send_message(struct ch7322 *ch7322, const struct cec_msg *msg)
166{
167 unsigned int val;
168 unsigned int len = msg->len;
169 int ret;
170 int i;
171
172 WARN_ON(!mutex_is_locked(&ch7322->mutex));
173
174 if (len > CH7322_WRBUF_LEN || len < 1)
175 return -EINVAL;
176
177 ret = regmap_read(ch7322->regmap, CH7322_WRITE, &val);
178 if (ret)
179 return ret;
180
181 /* Buffer not ready */
182 if (!(val & CH7322_WRITE_MSENT))
183 return -EBUSY;
184
185 if (cec_msg_opcode(msg) == -1 &&
186 cec_msg_initiator(msg) == cec_msg_destination(msg)) {
187 ch7322->tx_flags = CH7322_TX_FLAG_NACK | CH7322_TX_FLAG_RETRY;
188 } else if (cec_msg_is_broadcast(msg)) {
189 ch7322->tx_flags = CH7322_TX_FLAG_NACK;
190 } else {
191 ch7322->tx_flags = CH7322_TX_FLAG_RETRY;
192 }
193
194 ret = regmap_write(ch7322->regmap, CH7322_WRITE, len - 1);
195 if (ret)
196 return ret;
197
198 for (i = 0; i < len; i++) {
199 ret = regmap_write(ch7322->regmap,
200 CH7322_WRBUF + i, msg->msg[i]);
201 if (ret)
202 return ret;
203 }
204
205 return 0;
206}
207
208static int ch7322_receive_message(struct ch7322 *ch7322, struct cec_msg *msg)
209{
210 unsigned int val;
211 int ret = 0;
212 int i;
213
214 WARN_ON(!mutex_is_locked(&ch7322->mutex));
215
216 ret = regmap_read(ch7322->regmap, CH7322_READ, &val);
217 if (ret)
218 return ret;
219
220 /* Message not ready */
221 if (!(val & CH7322_READ_NRDT))
222 return -EIO;
223
224 msg->len = (val & CH7322_READ_NMASK) + 1;
225
226 /* Read entire RDBUF to clear state */
227 for (i = 0; i < CH7322_RDBUF_LEN; i++) {
228 ret = regmap_read(ch7322->regmap, CH7322_RDBUF + i, &val);
229 if (ret)
230 return ret;
231 msg->msg[i] = (u8)val;
232 }
233
234 return 0;
235}
236
237static void ch7322_tx_done(struct ch7322 *ch7322)
238{
239 int ret;
240 unsigned int val;
241 u8 status, flags;
242
243 mutex_lock(&ch7322->mutex);
244 ret = regmap_read(ch7322->regmap, CH7322_WRITE, &val);
245 flags = ch7322->tx_flags;
246 mutex_unlock(&ch7322->mutex);
247
248 /*
249 * The device returns a one-bit OK status which usually means ACK but
250 * actually means NACK when sending a logical address query or a
251 * broadcast.
252 */
253 if (ret)
254 status = CEC_TX_STATUS_ERROR;
255 else if ((val & CH7322_WRITE_BOK) && (flags & CH7322_TX_FLAG_NACK))
256 status = CEC_TX_STATUS_NACK;
257 else if (val & CH7322_WRITE_BOK)
258 status = CEC_TX_STATUS_OK;
259 else if (flags & CH7322_TX_FLAG_NACK)
260 status = CEC_TX_STATUS_OK;
261 else
262 status = CEC_TX_STATUS_NACK;
263
264 if (status == CEC_TX_STATUS_NACK && (flags & CH7322_TX_FLAG_RETRY))
265 status |= CEC_TX_STATUS_MAX_RETRIES;
266
267 cec_transmit_attempt_done(ch7322->cec, status);
268}
269
270static void ch7322_rx_done(struct ch7322 *ch7322)
271{
272 struct cec_msg msg;
273 int ret;
274
275 mutex_lock(&ch7322->mutex);
276 ret = ch7322_receive_message(ch7322, &msg);
277 mutex_unlock(&ch7322->mutex);
278
279 if (ret)
280 dev_err(&ch7322->i2c->dev, "cec receive error: %d\n", ret);
281 else
282 cec_received_msg(ch7322->cec, &msg);
283}
284
285/*
286 * This device can either monitor the DDC lines to obtain the physical address
287 * or it can allow the host to program it. This driver lets the device obtain
288 * it.
289 */
290static void ch7322_phys_addr(struct ch7322 *ch7322)
291{
292 unsigned int pah, pal;
293 int ret = 0;
294
295 mutex_lock(&ch7322->mutex);
296 ret |= regmap_read(ch7322->regmap, CH7322_PARH, &pah);
297 ret |= regmap_read(ch7322->regmap, CH7322_PARL, &pal);
298 mutex_unlock(&ch7322->mutex);
299
300 if (ret)
301 dev_err(&ch7322->i2c->dev, "phys addr error\n");
302 else
303 cec_s_phys_addr(ch7322->cec, pal | (pah << 8), false);
304}
305
306static irqreturn_t ch7322_irq(int irq, void *dev)
307{
308 struct ch7322 *ch7322 = dev;
309 unsigned int data = 0;
310
311 mutex_lock(&ch7322->mutex);
312 regmap_read(ch7322->regmap, CH7322_INTDATA, &data);
313 regmap_write(ch7322->regmap, CH7322_INTDATA, data);
314 mutex_unlock(&ch7322->mutex);
315
316 if (data & CH7322_INTDATA_HPDFALL)
317 cec_phys_addr_invalidate(ch7322->cec);
318
319 if (data & CH7322_INTDATA_TXMSG)
320 ch7322_tx_done(ch7322);
321
322 if (data & CH7322_INTDATA_RXMSG)
323 ch7322_rx_done(ch7322);
324
325 if (data & CH7322_INTDATA_NEWPHA)
326 ch7322_phys_addr(ch7322);
327
328 if (data & CH7322_INTDATA_ERROR)
329 dev_dbg(&ch7322->i2c->dev, "unknown error\n");
330
331 return IRQ_HANDLED;
332}
333
334/* This device is always enabled */
335static int ch7322_cec_adap_enable(struct cec_adapter *adap, bool enable)
336{
337 return 0;
338}
339
340static int ch7322_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
341{
342 struct ch7322 *ch7322 = cec_get_drvdata(adap);
343 int ret;
344
345 mutex_lock(&ch7322->mutex);
346 ret = regmap_update_bits(ch7322->regmap, CH7322_ADDLW,
347 CH7322_ADDLW_MASK, log_addr << 4);
348 mutex_unlock(&ch7322->mutex);
349
350 return ret;
351}
352
353static int ch7322_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
354 u32 signal_free_time, struct cec_msg *msg)
355{
356 struct ch7322 *ch7322 = cec_get_drvdata(adap);
357 int ret;
358
359 mutex_lock(&ch7322->mutex);
360 ret = ch7322_send_message(ch7322, msg);
361 mutex_unlock(&ch7322->mutex);
362
363 return ret;
364}
365
366static const struct cec_adap_ops ch7322_cec_adap_ops = {
367 .adap_enable = ch7322_cec_adap_enable,
368 .adap_log_addr = ch7322_cec_adap_log_addr,
369 .adap_transmit = ch7322_cec_adap_transmit,
370};
371
372#if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI)
373
374struct ch7322_conn_match {
375 const char *dev_name;
376 const char *pci_name;
377 const char *port_name;
378};
379
380static struct ch7322_conn_match google_endeavour[] = {
381 { "i2c-PRP0001:00", "0000:00:02.0", "Port B" },
382 { "i2c-PRP0001:01", "0000:00:02.0", "Port C" },
383 { },
384};
385
386static const struct dmi_system_id ch7322_dmi_table[] = {
387 {
388 .matches = {
389 DMI_MATCH(DMI_BOARD_VENDOR, "Google"),
390 DMI_MATCH(DMI_BOARD_NAME, "Endeavour"),
391 },
392 .driver_data = google_endeavour,
393 },
394 { },
395};
396
397/* Make a best-effort attempt to locate a matching HDMI port */
398static int ch7322_get_port(struct i2c_client *client,
399 struct device **dev,
400 const char **port)
401{
402 const struct dmi_system_id *system;
403 const struct ch7322_conn_match *conn;
404
405 *dev = NULL;
406 *port = NULL;
407
408 system = dmi_first_match(ch7322_dmi_table);
409 if (!system)
410 return 0;
411
412 for (conn = system->driver_data; conn->dev_name; conn++) {
413 if (!strcmp(dev_name(&client->dev), conn->dev_name)) {
414 struct device *d;
415
416 d = bus_find_device_by_name(&pci_bus_type, NULL,
417 conn->pci_name);
418 if (!d)
419 return -EPROBE_DEFER;
420
421 put_device(d);
422
423 *dev = d;
424 *port = conn->port_name;
425
426 return 0;
427 }
428 }
429
430 return 0;
431}
432
433#else
434
435static int ch7322_get_port(struct i2c_client *client,
436 struct device **dev,
437 const char **port)
438{
439 *dev = NULL;
440 *port = NULL;
441
442 return 0;
443}
444
445#endif
446
447static int ch7322_probe(struct i2c_client *client)
448{
449 struct device *hdmi_dev;
450 const char *port_name;
451 struct ch7322 *ch7322;
452 struct cec_notifier *notifier = NULL;
453 u32 caps = CEC_CAP_DEFAULTS;
454 int ret;
455 unsigned int val;
456
457 ret = ch7322_get_port(client, &hdmi_dev, &port_name);
458 if (ret)
459 return ret;
460
461 if (hdmi_dev)
462 caps |= CEC_CAP_CONNECTOR_INFO;
463
464 ch7322 = devm_kzalloc(&client->dev, sizeof(*ch7322), GFP_KERNEL);
465 if (!ch7322)
466 return -ENOMEM;
467
468 ch7322->regmap = devm_regmap_init_i2c(client, &ch7322_regmap);
469 if (IS_ERR(ch7322->regmap))
470 return PTR_ERR(ch7322->regmap);
471
472 ret = regmap_read(ch7322->regmap, CH7322_DID, &val);
473 if (ret)
474 return ret;
475
476 if (val != CH7322_DID_CH7322)
477 return -EOPNOTSUPP;
478
479 mutex_init(&ch7322->mutex);
480 ch7322->i2c = client;
481 ch7322->tx_flags = 0;
482
483 i2c_set_clientdata(client, ch7322);
484
485 /* Disable auto mode */
486 ret = regmap_write(ch7322->regmap, CH7322_MODE, CH7322_MODE_SW);
487 if (ret)
488 goto err_mutex;
489
490 /* Enable logical address register */
491 ret = regmap_update_bits(ch7322->regmap, CH7322_CTL,
492 CH7322_CTL_SPADL, CH7322_CTL_SPADL);
493 if (ret)
494 goto err_mutex;
495
496 ch7322->cec = cec_allocate_adapter(&ch7322_cec_adap_ops, ch7322,
497 dev_name(&client->dev),
498 caps, 1);
499
500 if (IS_ERR(ch7322->cec)) {
501 ret = PTR_ERR(ch7322->cec);
502 goto err_mutex;
503 }
504
505 ch7322->cec->adap_controls_phys_addr = true;
506
507 if (hdmi_dev) {
508 notifier = cec_notifier_cec_adap_register(hdmi_dev,
509 port_name,
510 ch7322->cec);
511 if (!notifier) {
512 ret = -ENOMEM;
513 goto err_cec;
514 }
515 }
516
517 /* Configure, mask, and clear interrupt */
518 ret = regmap_write(ch7322->regmap, CH7322_CFG1, 0);
519 if (ret)
520 goto err_notifier;
521 ret = regmap_write(ch7322->regmap, CH7322_INTCTL, CH7322_INTCTL_INTPB);
522 if (ret)
523 goto err_notifier;
524 ret = regmap_write(ch7322->regmap, CH7322_INTDATA, 0xff);
525 if (ret)
526 goto err_notifier;
527
528 /* If HPD is up read physical address */
529 ret = regmap_read(ch7322->regmap, CH7322_ADDLR, &val);
530 if (ret)
531 goto err_notifier;
532 if (val & CH7322_ADDLR_HPD)
533 ch7322_phys_addr(ch7322);
534
535 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
536 ch7322_irq,
537 IRQF_ONESHOT | IRQF_TRIGGER_RISING,
538 client->name, ch7322);
539 if (ret)
540 goto err_notifier;
541
542 /* Unmask interrupt */
543 mutex_lock(&ch7322->mutex);
544 ret = regmap_write(ch7322->regmap, CH7322_INTCTL, 0xff);
545 mutex_unlock(&ch7322->mutex);
546
547 if (ret)
548 goto err_notifier;
549
550 ret = cec_register_adapter(ch7322->cec, &client->dev);
551 if (ret)
552 goto err_notifier;
553
554 dev_info(&client->dev, "device registered\n");
555
556 return 0;
557
558err_notifier:
559 if (notifier)
560 cec_notifier_cec_adap_unregister(notifier, ch7322->cec);
561err_cec:
562 cec_delete_adapter(ch7322->cec);
563err_mutex:
564 mutex_destroy(&ch7322->mutex);
565 return ret;
566}
567
568static int ch7322_remove(struct i2c_client *client)
569{
570 struct ch7322 *ch7322 = i2c_get_clientdata(client);
571
572 /* Mask interrupt */
573 mutex_lock(&ch7322->mutex);
574 regmap_write(ch7322->regmap, CH7322_INTCTL, CH7322_INTCTL_INTPB);
575 mutex_unlock(&ch7322->mutex);
576
577 cec_unregister_adapter(ch7322->cec);
578 mutex_destroy(&ch7322->mutex);
579
580 dev_info(&client->dev, "device unregistered\n");
581
582 return 0;
583}
584
585static const struct of_device_id ch7322_of_match[] = {
586 { .compatible = "chrontel,ch7322", },
587 {},
588};
589MODULE_DEVICE_TABLE(of, ch7322_of_match);
590
591static struct i2c_driver ch7322_i2c_driver = {
592 .driver = {
593 .name = "ch7322",
594 .of_match_table = of_match_ptr(ch7322_of_match),
595 },
596 .probe_new = ch7322_probe,
597 .remove = ch7322_remove,
598};
599
600module_i2c_driver(ch7322_i2c_driver);
601
602MODULE_DESCRIPTION("Chrontel CH7322 CEC Controller Driver");
603MODULE_AUTHOR("Jeff Chase <jnchase@google.com>");
604MODULE_LICENSE("GPL");
drivers/media/cec/platform/cros-ec/cros-ec-cec.c+1−5
@@ -277,11 +277,7 @@ static int cros_ec_cec_probe(struct platform_device *pdev) · 276 unmodified lines
277 platform_set_drvdata(pdev, cros_ec_cec);277 platform_set_drvdata(pdev, cros_ec_cec);
278 cros_ec_cec->cros_ec = cros_ec;278 cros_ec_cec->cros_ec = cros_ec;
279 279
280 ret = device_init_wakeup(&pdev->dev, 1);280 device_init_wakeup(&pdev->dev, 1);
281 if (ret) {
282 dev_err(&pdev->dev, "failed to initialize wakeup\n");
283 return ret;
284 }
285 281
286 cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec,282 cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec,
287 DRV_NAME,283 DRV_NAME,
drivers/media/common/v4l2-tpg/v4l2-tpg-core.c+33−7
@@ -1927,44 +1927,46 @@ typedef struct { u16 __; u8 _; } __packed x24; · 1926 unmodified lines
1927 1927
1928static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],1928static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1929 unsigned p, unsigned first, unsigned div, unsigned step,1929 unsigned p, unsigned first, unsigned div, unsigned step,
1930 int y, int x, char *text, unsigned len)1930 int y, int x, const char *text, unsigned len)
1931{1931{
1932 PRINTSTR(u8);1932 PRINTSTR(u8);
1933}1933}
1934 1934
1935static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],1935static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1936 unsigned p, unsigned first, unsigned div, unsigned step,1936 unsigned p, unsigned first, unsigned div, unsigned step,
1937 int y, int x, char *text, unsigned len)1937 int y, int x, const char *text, unsigned len)
1938{1938{
1939 PRINTSTR(u16);1939 PRINTSTR(u16);
1940}1940}
1941 1941
1942static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],1942static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1943 unsigned p, unsigned first, unsigned div, unsigned step,1943 unsigned p, unsigned first, unsigned div, unsigned step,
1944 int y, int x, char *text, unsigned len)1944 int y, int x, const char *text, unsigned len)
1945{1945{
1946 PRINTSTR(x24);1946 PRINTSTR(x24);
1947}1947}
1948 1948
1949static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],1949static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1950 unsigned p, unsigned first, unsigned div, unsigned step,1950 unsigned p, unsigned first, unsigned div, unsigned step,
1951 int y, int x, char *text, unsigned len)1951 int y, int x, const char *text, unsigned len)
1952{1952{
1953 PRINTSTR(u32);1953 PRINTSTR(u32);
1954}1954}
1955 1955
1956void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],1956void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1957 int y, int x, char *text)1957 int y, int x, const char *text)
1958{1958{
1959 unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;1959 unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1960 unsigned div = step;1960 unsigned div = step;
1961 unsigned first = 0;1961 unsigned first = 0;
1962 unsigned len = strlen(text);1962 unsigned len;
1963 unsigned p;1963 unsigned p;
1964 1964
1965 if (font8x16 == NULL || basep == NULL)1965 if (font8x16 == NULL || basep == NULL || text == NULL)
1966 return;1966 return;
1967 1967
1968 len = strlen(text);
1969
1968 /* Checks if it is possible to show string */1970 /* Checks if it is possible to show string */
1969 if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)1971 if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1970 return;1972 return;
@@ -2006,6 +2008,30 @@ void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], · 35 unmodified lines
2006}2008}
2007EXPORT_SYMBOL_GPL(tpg_gen_text);2009EXPORT_SYMBOL_GPL(tpg_gen_text);
2008 2010
2011const char *tpg_g_color_order(const struct tpg_data *tpg)
2012{
2013 switch (tpg->pattern) {
2014 case TPG_PAT_75_COLORBAR:
2015 case TPG_PAT_100_COLORBAR:
2016 case TPG_PAT_CSC_COLORBAR:
2017 case TPG_PAT_100_HCOLORBAR:
2018 return "White, yellow, cyan, green, magenta, red, blue, black";
2019 case TPG_PAT_BLACK:
2020 return "Black";
2021 case TPG_PAT_WHITE:
2022 return "White";
2023 case TPG_PAT_RED:
2024 return "Red";
2025 case TPG_PAT_GREEN:
2026 return "Green";
2027 case TPG_PAT_BLUE:
2028 return "Blue";
2029 default:
2030 return NULL;
2031 }
2032}
2033EXPORT_SYMBOL_GPL(tpg_g_color_order);
2034
2009void tpg_update_mv_step(struct tpg_data *tpg)2035void tpg_update_mv_step(struct tpg_data *tpg)
2010{2036{
2011 int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;2037 int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
drivers/media/common/videobuf2/videobuf2-core.c+225−142
@@ -34,10 +34,11 @@ · 33 unmodified lines
34static int debug;34static int debug;
35module_param(debug, int, 0644);35module_param(debug, int, 0644);
36 36
37#define dprintk(level, fmt, arg...) \37#define dprintk(q, level, fmt, arg...) \
38 do { \38 do { \
39 if (debug >= level) \39 if (debug >= level) \
40 pr_info("%s: " fmt, __func__, ## arg); \40 pr_info("[%s] %s: " fmt, (q)->name, __func__, \
41 ## arg); \
41 } while (0)42 } while (0)
42 43
43#ifdef CONFIG_VIDEO_ADV_DEBUG44#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -51,8 +52,8 @@ module_param(debug, int, 0644); · 7 unmodified lines
51 */52 */
52 53
53#define log_memop(vb, op) \54#define log_memop(vb, op) \
54 dprintk(2, "call_memop(%p, %d, %s)%s\n", \55 dprintk((vb)->vb2_queue, 2, "call_memop(%d, %s)%s\n", \
55 (vb)->vb2_queue, (vb)->index, #op, \56 (vb)->index, #op, \
56 (vb)->vb2_queue->mem_ops->op ? "" : " (nop)")57 (vb)->vb2_queue->mem_ops->op ? "" : " (nop)")
57 58
58#define call_memop(vb, op, args...) \59#define call_memop(vb, op, args...) \
@@ -90,7 +91,7 @@ module_param(debug, int, 0644); · 31 unmodified lines
90})91})
91 92
92#define log_qop(q, op) \93#define log_qop(q, op) \
93 dprintk(2, "call_qop(%p, %s)%s\n", q, #op, \94 dprintk(q, 2, "call_qop(%s)%s\n", #op, \
94 (q)->ops->op ? "" : " (nop)")95 (q)->ops->op ? "" : " (nop)")
95 96
96#define call_qop(q, op, args...) \97#define call_qop(q, op, args...) \
@@ -113,8 +114,8 @@ module_param(debug, int, 0644); · 16 unmodified lines
113})114})
114 115
115#define log_vb_qop(vb, op, args...) \116#define log_vb_qop(vb, op, args...) \
116 dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \117 dprintk((vb)->vb2_queue, 2, "call_vb_qop(%d, %s)%s\n", \
117 (vb)->vb2_queue, (vb)->index, #op, \118 (vb)->index, #op, \
118 (vb)->vb2_queue->ops->op ? "" : " (nop)")119 (vb)->vb2_queue->ops->op ? "" : " (nop)")
119 120
120#define call_vb_qop(vb, op, args...) \121#define call_vb_qop(vb, op, args...) \
@@ -190,6 +191,23 @@ module_param(debug, int, 0644); · 69 unmodified lines
190static void __vb2_queue_cancel(struct vb2_queue *q);191static void __vb2_queue_cancel(struct vb2_queue *q);
191static void __enqueue_in_driver(struct vb2_buffer *vb);192static void __enqueue_in_driver(struct vb2_buffer *vb);
192 193
194static const char *vb2_state_name(enum vb2_buffer_state s)
195{
196 static const char * const state_names[] = {
197 [VB2_BUF_STATE_DEQUEUED] = "dequeued",
198 [VB2_BUF_STATE_IN_REQUEST] = "in request",
199 [VB2_BUF_STATE_PREPARING] = "preparing",
200 [VB2_BUF_STATE_QUEUED] = "queued",
201 [VB2_BUF_STATE_ACTIVE] = "active",
202 [VB2_BUF_STATE_DONE] = "done",
203 [VB2_BUF_STATE_ERROR] = "error",
204 };
205
206 if ((unsigned int)(s) < ARRAY_SIZE(state_names))
207 return state_names[s];
208 return "unknown";
209}
210
193/*211/*
194 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer212 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
195 */213 */
@@ -246,7 +264,8 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb) · 50 unmodified lines
246 for (plane = 0; plane < vb->num_planes; ++plane) {264 for (plane = 0; plane < vb->num_planes; ++plane) {
247 call_void_memop(vb, put, vb->planes[plane].mem_priv);265 call_void_memop(vb, put, vb->planes[plane].mem_priv);
248 vb->planes[plane].mem_priv = NULL;266 vb->planes[plane].mem_priv = NULL;
249 dprintk(3, "freed plane %d of buffer %d\n", plane, vb->index);267 dprintk(vb->vb2_queue, 3, "freed plane %d of buffer %d\n",
268 plane, vb->index);
250 }269 }
251}270}
252 271
@@ -296,6 +315,44 @@ static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb) · 43 unmodified lines
296 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);315 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
297}316}
298 317
318/*
319 * __vb2_buf_mem_prepare() - call ->prepare() on buffer's private memory
320 * to sync caches
321 */
322static void __vb2_buf_mem_prepare(struct vb2_buffer *vb)
323{
324 unsigned int plane;
325
326 if (vb->synced)
327 return;
328
329 if (vb->need_cache_sync_on_prepare) {
330 for (plane = 0; plane < vb->num_planes; ++plane)
331 call_void_memop(vb, prepare,
332 vb->planes[plane].mem_priv);
333 }
334 vb->synced = 1;
335}
336
337/*
338 * __vb2_buf_mem_finish() - call ->finish on buffer's private memory
339 * to sync caches
340 */
341static void __vb2_buf_mem_finish(struct vb2_buffer *vb)
342{
343 unsigned int plane;
344
345 if (!vb->synced)
346 return;
347
348 if (vb->need_cache_sync_on_finish) {
349 for (plane = 0; plane < vb->num_planes; ++plane)
350 call_void_memop(vb, finish,
351 vb->planes[plane].mem_priv);
352 }
353 vb->synced = 0;
354}
355
299/*356/*
300 * __setup_offsets() - setup unique offsets ("cookies") for every plane in357 * __setup_offsets() - setup unique offsets ("cookies") for every plane in
301 * the buffer.358 * the buffer.
@@ -316,7 +373,7 @@ static void __setup_offsets(struct vb2_buffer *vb) · 14 unmodified lines
316 for (plane = 0; plane < vb->num_planes; ++plane) {373 for (plane = 0; plane < vb->num_planes; ++plane) {
317 vb->planes[plane].m.offset = off;374 vb->planes[plane].m.offset = off;
318 375
319 dprintk(3, "buffer %d, plane %d offset 0x%08lx\n",376 dprintk(q, 3, "buffer %d, plane %d offset 0x%08lx\n",
320 vb->index, plane, off);377 vb->index, plane, off);
321 378
322 off += vb->planes[plane].length;379 off += vb->planes[plane].length;
@@ -347,7 +404,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, · 24 unmodified lines
347 /* Allocate videobuf buffer structures */404 /* Allocate videobuf buffer structures */
348 vb = kzalloc(q->buf_struct_size, GFP_KERNEL);405 vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
349 if (!vb) {406 if (!vb) {
350 dprintk(1, "memory alloc for buffer struct failed\n");407 dprintk(q, 1, "memory alloc for buffer struct failed\n");
351 break;408 break;
352 }409 }
353 410
@@ -369,7 +426,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, · 15 unmodified lines
369 if (memory == VB2_MEMORY_MMAP) {426 if (memory == VB2_MEMORY_MMAP) {
370 ret = __vb2_buf_mem_alloc(vb);427 ret = __vb2_buf_mem_alloc(vb);
371 if (ret) {428 if (ret) {
372 dprintk(1, "failed allocating memory for buffer %d\n",429 dprintk(q, 1, "failed allocating memory for buffer %d\n",
373 buffer);430 buffer);
374 q->bufs[vb->index] = NULL;431 q->bufs[vb->index] = NULL;
375 kfree(vb);432 kfree(vb);
@@ -383,7 +440,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, · 7 unmodified lines
383 */440 */
384 ret = call_vb_qop(vb, buf_init, vb);441 ret = call_vb_qop(vb, buf_init, vb);
385 if (ret) {442 if (ret) {
386 dprintk(1, "buffer %d %p initialization failed\n",443 dprintk(q, 1, "buffer %d %p initialization failed\n",
387 buffer, vb);444 buffer, vb);
388 __vb2_buf_mem_free(vb);445 __vb2_buf_mem_free(vb);
389 q->bufs[vb->index] = NULL;446 q->bufs[vb->index] = NULL;
@@ -393,7 +450,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, · 3 unmodified lines
393 }450 }
394 }451 }
395 452
396 dprintk(3, "allocated %d buffers, %d plane(s) each\n",453 dprintk(q, 3, "allocated %d buffers, %d plane(s) each\n",
397 buffer, num_planes);454 buffer, num_planes);
398 455
399 return buffer;456 return buffer;
@@ -445,7 +502,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) · 45 unmodified lines
445 if (q->bufs[buffer] == NULL)502 if (q->bufs[buffer] == NULL)
446 continue;503 continue;
447 if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {504 if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
448 dprintk(1, "preparing buffers, cannot free\n");505 dprintk(q, 1, "preparing buffers, cannot free\n");
449 return -EAGAIN;506 return -EAGAIN;
450 }507 }
451 }508 }
@@ -623,12 +680,12 @@ int vb2_verify_memory_type(struct vb2_queue *q, · 171 unmodified lines
623{680{
624 if (memory != VB2_MEMORY_MMAP && memory != VB2_MEMORY_USERPTR &&681 if (memory != VB2_MEMORY_MMAP && memory != VB2_MEMORY_USERPTR &&
625 memory != VB2_MEMORY_DMABUF) {682 memory != VB2_MEMORY_DMABUF) {
626 dprintk(1, "unsupported memory type\n");683 dprintk(q, 1, "unsupported memory type\n");
627 return -EINVAL;684 return -EINVAL;
628 }685 }
629 686
630 if (type != q->type) {687 if (type != q->type) {
631 dprintk(1, "requested type is incorrect\n");688 dprintk(q, 1, "requested type is incorrect\n");
632 return -EINVAL;689 return -EINVAL;
633 }690 }
634 691
@@ -637,17 +694,17 @@ int vb2_verify_memory_type(struct vb2_queue *q, · 2 unmodified lines
637 * are available.694 * are available.
638 */695 */
639 if (memory == VB2_MEMORY_MMAP && __verify_mmap_ops(q)) {696 if (memory == VB2_MEMORY_MMAP && __verify_mmap_ops(q)) {
640 dprintk(1, "MMAP for current setup unsupported\n");697 dprintk(q, 1, "MMAP for current setup unsupported\n");
641 return -EINVAL;698 return -EINVAL;
642 }699 }
643 700
644 if (memory == VB2_MEMORY_USERPTR && __verify_userptr_ops(q)) {701 if (memory == VB2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
645 dprintk(1, "USERPTR for current setup unsupported\n");702 dprintk(q, 1, "USERPTR for current setup unsupported\n");
646 return -EINVAL;703 return -EINVAL;
647 }704 }
648 705
649 if (memory == VB2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {706 if (memory == VB2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
650 dprintk(1, "DMABUF for current setup unsupported\n");707 dprintk(q, 1, "DMABUF for current setup unsupported\n");
651 return -EINVAL;708 return -EINVAL;
652 }709 }
653 710
@@ -657,33 +714,59 @@ int vb2_verify_memory_type(struct vb2_queue *q, · 3 unmodified lines
657 * do the memory and type validation.714 * do the memory and type validation.
658 */715 */
659 if (vb2_fileio_is_active(q)) {716 if (vb2_fileio_is_active(q)) {
660 dprintk(1, "file io in progress\n");717 dprintk(q, 1, "file io in progress\n");
661 return -EBUSY;718 return -EBUSY;
662 }719 }
663 return 0;720 return 0;
664}721}
665EXPORT_SYMBOL(vb2_verify_memory_type);722EXPORT_SYMBOL(vb2_verify_memory_type);
666 723
724static void set_queue_consistency(struct vb2_queue *q, bool consistent_mem)
725{
726 q->dma_attrs &= ~DMA_ATTR_NON_CONSISTENT;
727
728 if (!vb2_queue_allows_cache_hints(q))
729 return;
730 if (!consistent_mem)
731 q->dma_attrs |= DMA_ATTR_NON_CONSISTENT;
732}
733
734static bool verify_consistency_attr(struct vb2_queue *q, bool consistent_mem)
735{
736 bool queue_is_consistent = !(q->dma_attrs & DMA_ATTR_NON_CONSISTENT);
737
738 if (consistent_mem != queue_is_consistent) {
739 dprintk(q, 1, "memory consistency model mismatch\n");
740 return false;
741 }
742 return true;
743}
744
667int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,745int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
668 unsigned int *count)746 unsigned int flags, unsigned int *count)
669{747{
670 unsigned int num_buffers, allocated_buffers, num_planes = 0;748 unsigned int num_buffers, allocated_buffers, num_planes = 0;
671 unsigned plane_sizes[VB2_MAX_PLANES] = { };749 unsigned plane_sizes[VB2_MAX_PLANES] = { };
750 bool consistent_mem = true;
672 unsigned int i;751 unsigned int i;
673 int ret;752 int ret;
674 753
754 if (flags & V4L2_FLAG_MEMORY_NON_CONSISTENT)
755 consistent_mem = false;
756
675 if (q->streaming) {757 if (q->streaming) {
676 dprintk(1, "streaming active\n");758 dprintk(q, 1, "streaming active\n");
677 return -EBUSY;759 return -EBUSY;
678 }760 }
679 761
680 if (q->waiting_in_dqbuf && *count) {762 if (q->waiting_in_dqbuf && *count) {
681 dprintk(1, "another dup()ped fd is waiting for a buffer\n");763 dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
682 return -EBUSY;764 return -EBUSY;
683 }765 }
684 766
685 if (*count == 0 || q->num_buffers != 0 ||767 if (*count == 0 || q->num_buffers != 0 ||
686 (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) {768 (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory) ||
769 !verify_consistency_attr(q, consistent_mem)) {
687 /*770 /*
688 * We already have buffers allocated, so first check if they771 * We already have buffers allocated, so first check if they
689 * are not in use and can be freed.772 * are not in use and can be freed.
@@ -691,7 +774,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, · 1 unmodified line
691 mutex_lock(&q->mmap_lock);774 mutex_lock(&q->mmap_lock);
692 if (debug && q->memory == VB2_MEMORY_MMAP &&775 if (debug && q->memory == VB2_MEMORY_MMAP &&
693 __buffers_in_use(q))776 __buffers_in_use(q))
694 dprintk(1, "memory in use, orphaning buffers\n");777 dprintk(q, 1, "memory in use, orphaning buffers\n");
695 778
696 /*779 /*
697 * Call queue_cancel to clean up any buffers in the780 * Call queue_cancel to clean up any buffers in the
@@ -720,6 +803,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, · 22 unmodified lines
720 num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);803 num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);
721 memset(q->alloc_devs, 0, sizeof(q->alloc_devs));804 memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
722 q->memory = memory;805 q->memory = memory;
806 set_queue_consistency(q, consistent_mem);
723 807
724 /*808 /*
725 * Ask the driver how many buffers and planes per buffer it requires.809 * Ask the driver how many buffers and planes per buffer it requires.
@@ -742,7 +826,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, · 16 unmodified lines
742 allocated_buffers =826 allocated_buffers =
743 __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);827 __vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
744 if (allocated_buffers == 0) {828 if (allocated_buffers == 0) {
745 dprintk(1, "memory allocation failed\n");829 dprintk(q, 1, "memory allocation failed\n");
746 return -ENOMEM;830 return -ENOMEM;
747 }831 }
748 832
@@ -804,29 +888,39 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, · 55 unmodified lines
804EXPORT_SYMBOL_GPL(vb2_core_reqbufs);888EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
805 889
806int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,890int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
807 unsigned int *count, unsigned requested_planes,891 unsigned int flags, unsigned int *count,
808 const unsigned requested_sizes[])892 unsigned int requested_planes,
893 const unsigned int requested_sizes[])
809{894{
810 unsigned int num_planes = 0, num_buffers, allocated_buffers;895 unsigned int num_planes = 0, num_buffers, allocated_buffers;
811 unsigned plane_sizes[VB2_MAX_PLANES] = { };896 unsigned plane_sizes[VB2_MAX_PLANES] = { };
897 bool consistent_mem = true;
812 int ret;898 int ret;
813 899
900 if (flags & V4L2_FLAG_MEMORY_NON_CONSISTENT)
901 consistent_mem = false;
902
814 if (q->num_buffers == VB2_MAX_FRAME) {903 if (q->num_buffers == VB2_MAX_FRAME) {
815 dprintk(1, "maximum number of buffers already allocated\n");904 dprintk(q, 1, "maximum number of buffers already allocated\n");
816 return -ENOBUFS;905 return -ENOBUFS;
817 }906 }
818 907
819 if (!q->num_buffers) {908 if (!q->num_buffers) {
820 if (q->waiting_in_dqbuf && *count) {909 if (q->waiting_in_dqbuf && *count) {
821 dprintk(1, "another dup()ped fd is waiting for a buffer\n");910 dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
822 return -EBUSY;911 return -EBUSY;
823 }912 }
824 memset(q->alloc_devs, 0, sizeof(q->alloc_devs));913 memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
825 q->memory = memory;914 q->memory = memory;
915 set_queue_consistency(q, consistent_mem);
826 q->waiting_for_buffers = !q->is_output;916 q->waiting_for_buffers = !q->is_output;
827 } else if (q->memory != memory) {917 } else {
828 dprintk(1, "memory model mismatch\n");918 if (q->memory != memory) {
829 return -EINVAL;919 dprintk(q, 1, "memory model mismatch\n");
920 return -EINVAL;
921 }
922 if (!verify_consistency_attr(q, consistent_mem))
923 return -EINVAL;
830 }924 }
831 925
832 num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers);926 num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers);
@@ -849,7 +943,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, · 16 unmodified lines
849 allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,943 allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,
850 num_planes, plane_sizes);944 num_planes, plane_sizes);
851 if (allocated_buffers == 0) {945 if (allocated_buffers == 0) {
852 dprintk(1, "memory allocation failed\n");946 dprintk(q, 1, "memory allocation failed\n");
853 return -ENOMEM;947 return -ENOMEM;
854 }948 }
855 949
@@ -922,7 +1016,6 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) · 66 unmodified lines
922{1016{
923 struct vb2_queue *q = vb->vb2_queue;1017 struct vb2_queue *q = vb->vb2_queue;
924 unsigned long flags;1018 unsigned long flags;
925 unsigned int plane;
926 1019
927 if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))1020 if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))
928 return;1021 return;
@@ -939,15 +1032,11 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) · 10 unmodified lines
939 */1032 */
940 vb->cnt_buf_done++;1033 vb->cnt_buf_done++;
941#endif1034#endif
942 dprintk(4, "done processing on buffer %d, state: %d\n",1035 dprintk(q, 4, "done processing on buffer %d, state: %s\n",
943 vb->index, state);1036 vb->index, vb2_state_name(state));
944 1037
945 if (state != VB2_BUF_STATE_QUEUED) {1038 if (state != VB2_BUF_STATE_QUEUED)
946 /* sync buffers */1039 __vb2_buf_mem_finish(vb);
947 for (plane = 0; plane < vb->num_planes; ++plane)
948 call_void_memop(vb, finish, vb->planes[plane].mem_priv);
949 vb->synced = 0;
950 }
951 1040
952 spin_lock_irqsave(&q->done_lock, flags);1041 spin_lock_irqsave(&q->done_lock, flags);
953 if (state == VB2_BUF_STATE_QUEUED) {1042 if (state == VB2_BUF_STATE_QUEUED) {
@@ -1029,12 +1118,12 @@ static int __prepare_userptr(struct vb2_buffer *vb) · 75 unmodified lines
1029 && vb->planes[plane].length == planes[plane].length)1118 && vb->planes[plane].length == planes[plane].length)
1030 continue;1119 continue;
1031 1120
1032 dprintk(3, "userspace address for plane %d changed, reacquiring memory\n",1121 dprintk(q, 3, "userspace address for plane %d changed, reacquiring memory\n",
1033 plane);1122 plane);
1034 1123
1035 /* Check if the provided plane buffer is large enough */1124 /* Check if the provided plane buffer is large enough */
1036 if (planes[plane].length < vb->planes[plane].min_length) {1125 if (planes[plane].length < vb->planes[plane].min_length) {
1037 dprintk(1, "provided buffer size %u is less than setup size %u for plane %d\n",1126 dprintk(q, 1, "provided buffer size %u is less than setup size %u for plane %d\n",
1038 planes[plane].length,1127 planes[plane].length,
1039 vb->planes[plane].min_length,1128 vb->planes[plane].min_length,
1040 plane);1129 plane);
@@ -1064,7 +1153,7 @@ static int __prepare_userptr(struct vb2_buffer *vb) · 23 unmodified lines
1064 planes[plane].m.userptr,1153 planes[plane].m.userptr,
1065 planes[plane].length, q->dma_dir);1154 planes[plane].length, q->dma_dir);
1066 if (IS_ERR(mem_priv)) {1155 if (IS_ERR(mem_priv)) {
1067 dprintk(1, "failed acquiring userspace memory for plane %d\n",1156 dprintk(q, 1, "failed acquiring userspace memory for plane %d\n",
1068 plane);1157 plane);
1069 ret = PTR_ERR(mem_priv);1158 ret = PTR_ERR(mem_priv);
1070 goto err;1159 goto err;
@@ -1091,14 +1180,14 @@ static int __prepare_userptr(struct vb2_buffer *vb) · 20 unmodified lines
1091 */1180 */
1092 ret = call_vb_qop(vb, buf_init, vb);1181 ret = call_vb_qop(vb, buf_init, vb);
1093 if (ret) {1182 if (ret) {
1094 dprintk(1, "buffer initialization failed\n");1183 dprintk(q, 1, "buffer initialization failed\n");
1095 goto err;1184 goto err;
1096 }1185 }
1097 }1186 }
1098 1187
1099 ret = call_vb_qop(vb, buf_prepare, vb);1188 ret = call_vb_qop(vb, buf_prepare, vb);
1100 if (ret) {1189 if (ret) {
1101 dprintk(1, "buffer preparation failed\n");1190 dprintk(q, 1, "buffer preparation failed\n");
1102 call_void_vb_qop(vb, buf_cleanup, vb);1191 call_void_vb_qop(vb, buf_cleanup, vb);
1103 goto err;1192 goto err;
1104 }1193 }
@@ -1141,7 +1230,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) · 36 unmodified lines
1141 struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);1230 struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
1142 1231
1143 if (IS_ERR_OR_NULL(dbuf)) {1232 if (IS_ERR_OR_NULL(dbuf)) {
1144 dprintk(1, "invalid dmabuf fd for plane %d\n",1233 dprintk(q, 1, "invalid dmabuf fd for plane %d\n",
1145 plane);1234 plane);
1146 ret = -EINVAL;1235 ret = -EINVAL;
1147 goto err;1236 goto err;
@@ -1152,7 +1241,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) · 4 unmodified lines
1152 planes[plane].length = dbuf->size;1241 planes[plane].length = dbuf->size;
1153 1242
1154 if (planes[plane].length < vb->planes[plane].min_length) {1243 if (planes[plane].length < vb->planes[plane].min_length) {
1155 dprintk(1, "invalid dmabuf length %u for plane %d, minimum length %u\n",1244 dprintk(q, 1, "invalid dmabuf length %u for plane %d, minimum length %u\n",
1156 planes[plane].length, plane,1245 planes[plane].length, plane,
1157 vb->planes[plane].min_length);1246 vb->planes[plane].min_length);
1158 dma_buf_put(dbuf);1247 dma_buf_put(dbuf);
@@ -1167,7 +1256,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) · 8 unmodified lines
1167 continue;1256 continue;
1168 }1257 }
1169 1258
1170 dprintk(3, "buffer for plane %d changed\n", plane);1259 dprintk(q, 3, "buffer for plane %d changed\n", plane);
1171 1260
1172 if (!reacquired) {1261 if (!reacquired) {
1173 reacquired = true;1262 reacquired = true;
@@ -1187,7 +1276,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) · 13 unmodified lines
1187 q->alloc_devs[plane] ? : q->dev,1276 q->alloc_devs[plane] ? : q->dev,
1188 dbuf, planes[plane].length, q->dma_dir);1277 dbuf, planes[plane].length, q->dma_dir);
1189 if (IS_ERR(mem_priv)) {1278 if (IS_ERR(mem_priv)) {
1190 dprintk(1, "failed to attach dmabuf\n");1279 dprintk(q, 1, "failed to attach dmabuf\n");
1191 ret = PTR_ERR(mem_priv);1280 ret = PTR_ERR(mem_priv);
1192 dma_buf_put(dbuf);1281 dma_buf_put(dbuf);
1193 goto err;1282 goto err;
@@ -1208,7 +1297,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) · 14 unmodified lines
1208 1297
1209 ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);1298 ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv);
1210 if (ret) {1299 if (ret) {
1211 dprintk(1, "failed to map dmabuf for plane %d\n",1300 dprintk(q, 1, "failed to map dmabuf for plane %d\n",
1212 plane);1301 plane);
1213 goto err;1302 goto err;
1214 }1303 }
@@ -1233,14 +1322,14 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) · 18 unmodified lines
1233 */1322 */
1234 ret = call_vb_qop(vb, buf_init, vb);1323 ret = call_vb_qop(vb, buf_init, vb);
1235 if (ret) {1324 if (ret) {
1236 dprintk(1, "buffer initialization failed\n");1325 dprintk(q, 1, "buffer initialization failed\n");
1237 goto err;1326 goto err;
1238 }1327 }
1239 }1328 }
1240 1329
1241 ret = call_vb_qop(vb, buf_prepare, vb);1330 ret = call_vb_qop(vb, buf_prepare, vb);
1242 if (ret) {1331 if (ret) {
1243 dprintk(1, "buffer preparation failed\n");1332 dprintk(q, 1, "buffer preparation failed\n");
1244 call_void_vb_qop(vb, buf_cleanup, vb);1333 call_void_vb_qop(vb, buf_cleanup, vb);
1245 goto err;1334 goto err;
1246 }1335 }
@@ -1272,11 +1361,10 @@ static int __buf_prepare(struct vb2_buffer *vb) · 25 unmodified lines
1272{1361{
1273 struct vb2_queue *q = vb->vb2_queue;1362 struct vb2_queue *q = vb->vb2_queue;
1274 enum vb2_buffer_state orig_state = vb->state;1363 enum vb2_buffer_state orig_state = vb->state;
1275 unsigned int plane;
1276 int ret;1364 int ret;
1277 1365
1278 if (q->error) {1366 if (q->error) {
1279 dprintk(1, "fatal error occurred on queue\n");1367 dprintk(q, 1, "fatal error occurred on queue\n");
1280 return -EIO;1368 return -EIO;
1281 }1369 }
1282 1370
@@ -1287,7 +1375,7 @@ static int __buf_prepare(struct vb2_buffer *vb) · 4 unmodified lines
1287 if (q->is_output) {1375 if (q->is_output) {
1288 ret = call_vb_qop(vb, buf_out_validate, vb);1376 ret = call_vb_qop(vb, buf_out_validate, vb);
1289 if (ret) {1377 if (ret) {
1290 dprintk(1, "buffer validation failed\n");1378 dprintk(q, 1, "buffer validation failed\n");
1291 return ret;1379 return ret;
1292 }1380 }
1293 }1381 }
@@ -1311,16 +1399,12 @@ static int __buf_prepare(struct vb2_buffer *vb) · 17 unmodified lines
1311 }1399 }
1312 1400
1313 if (ret) {1401 if (ret) {
1314 dprintk(1, "buffer preparation failed: %d\n", ret);1402 dprintk(q, 1, "buffer preparation failed: %d\n", ret);
1315 vb->state = orig_state;1403 vb->state = orig_state;
1316 return ret;1404 return ret;
1317 }1405 }
1318 1406
1319 /* sync buffers */1407 __vb2_buf_mem_prepare(vb);
1320 for (plane = 0; plane < vb->num_planes; ++plane)
1321 call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
1322
1323 vb->synced = 1;
1324 vb->prepared = 1;1408 vb->prepared = 1;
1325 vb->state = orig_state;1409 vb->state = orig_state;
1326 1410
@@ -1423,12 +1507,12 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) · 96 unmodified lines
1423 1507
1424 vb = q->bufs[index];1508 vb = q->bufs[index];
1425 if (vb->state != VB2_BUF_STATE_DEQUEUED) {1509 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1426 dprintk(1, "invalid buffer state %d\n",1510 dprintk(q, 1, "invalid buffer state %s\n",
1427 vb->state);1511 vb2_state_name(vb->state));
1428 return -EINVAL;1512 return -EINVAL;
1429 }1513 }
1430 if (vb->prepared) {1514 if (vb->prepared) {
1431 dprintk(1, "buffer already prepared\n");1515 dprintk(q, 1, "buffer already prepared\n");
1432 return -EINVAL;1516 return -EINVAL;
1433 }1517 }
1434 1518
@@ -1439,7 +1523,7 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) · 4 unmodified lines
1439 /* Fill buffer information for the userspace */1523 /* Fill buffer information for the userspace */
1440 call_void_bufop(q, fill_user_buffer, vb, pb);1524 call_void_bufop(q, fill_user_buffer, vb, pb);
1441 1525
1442 dprintk(2, "prepare of buffer %d succeeded\n", vb->index);1526 dprintk(q, 2, "prepare of buffer %d succeeded\n", vb->index);
1443 1527
1444 return 0;1528 return 0;
1445}1529}
@@ -1477,7 +1561,7 @@ static int vb2_start_streaming(struct vb2_queue *q) · 31 unmodified lines
1477 1561
1478 q->start_streaming_called = 0;1562 q->start_streaming_called = 0;
1479 1563
1480 dprintk(1, "driver refused to start streaming\n");1564 dprintk(q, 1, "driver refused to start streaming\n");
1481 /*1565 /*
1482 * If you see this warning, then the driver isn't cleaning up properly1566 * If you see this warning, then the driver isn't cleaning up properly
1483 * after a failed start_streaming(). See the start_streaming()1567 * after a failed start_streaming(). See the start_streaming()
@@ -1515,7 +1599,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 31 unmodified lines
1515 int ret;1599 int ret;
1516 1600
1517 if (q->error) {1601 if (q->error) {
1518 dprintk(1, "fatal error occurred on queue\n");1602 dprintk(q, 1, "fatal error occurred on queue\n");
1519 return -EIO;1603 return -EIO;
1520 }1604 }
1521 1605
@@ -1523,14 +1607,14 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 1 unmodified line
1523 1607
1524 if (!req && vb->state != VB2_BUF_STATE_IN_REQUEST &&1608 if (!req && vb->state != VB2_BUF_STATE_IN_REQUEST &&
1525 q->requires_requests) {1609 q->requires_requests) {
1526 dprintk(1, "qbuf requires a request\n");1610 dprintk(q, 1, "qbuf requires a request\n");
1527 return -EBADR;1611 return -EBADR;
1528 }1612 }
1529 1613
1530 if ((req && q->uses_qbuf) ||1614 if ((req && q->uses_qbuf) ||
1531 (!req && vb->state != VB2_BUF_STATE_IN_REQUEST &&1615 (!req && vb->state != VB2_BUF_STATE_IN_REQUEST &&
1532 q->uses_requests)) {1616 q->uses_requests)) {
1533 dprintk(1, "queue in wrong mode (qbuf vs requests)\n");1617 dprintk(q, 1, "queue in wrong mode (qbuf vs requests)\n");
1534 return -EBUSY;1618 return -EBUSY;
1535 }1619 }
1536 1620
@@ -1539,7 +1623,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 2 unmodified lines
1539 1623
1540 q->uses_requests = 1;1624 q->uses_requests = 1;
1541 if (vb->state != VB2_BUF_STATE_DEQUEUED) {1625 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1542 dprintk(1, "buffer %d not in dequeued state\n",1626 dprintk(q, 1, "buffer %d not in dequeued state\n",
1543 vb->index);1627 vb->index);
1544 return -EINVAL;1628 return -EINVAL;
1545 }1629 }
@@ -1547,7 +1631,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 1 unmodified line
1547 if (q->is_output && !vb->prepared) {1631 if (q->is_output && !vb->prepared) {
1548 ret = call_vb_qop(vb, buf_out_validate, vb);1632 ret = call_vb_qop(vb, buf_out_validate, vb);
1549 if (ret) {1633 if (ret) {
1550 dprintk(1, "buffer validation failed\n");1634 dprintk(q, 1, "buffer validation failed\n");
1551 return ret;1635 return ret;
1552 }1636 }
1553 }1637 }
@@ -1583,7 +1667,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 29 unmodified lines
1583 call_void_bufop(q, fill_user_buffer, vb, pb);1667 call_void_bufop(q, fill_user_buffer, vb, pb);
1584 }1668 }
1585 1669
1586 dprintk(2, "qbuf of buffer %d succeeded\n", vb->index);1670 dprintk(q, 2, "qbuf of buffer %d succeeded\n", vb->index);
1587 return 0;1671 return 0;
1588 }1672 }
1589 1673
@@ -1600,10 +1684,11 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 10 unmodified lines
1600 }1684 }
1601 break;1685 break;
1602 case VB2_BUF_STATE_PREPARING:1686 case VB2_BUF_STATE_PREPARING:
1603 dprintk(1, "buffer still being prepared\n");1687 dprintk(q, 1, "buffer still being prepared\n");
1604 return -EINVAL;1688 return -EINVAL;
1605 default:1689 default:
1606 dprintk(1, "invalid buffer state %d\n", vb->state);1690 dprintk(q, 1, "invalid buffer state %s\n",
1691 vb2_state_name(vb->state));
1607 return -EINVAL;1692 return -EINVAL;
1608 }1693 }
1609 1694
@@ -1645,7 +1730,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, · 35 unmodified lines
1645 return ret;1730 return ret;
1646 }1731 }
1647 1732
1648 dprintk(2, "qbuf of buffer %d succeeded\n", vb->index);1733 dprintk(q, 2, "qbuf of buffer %d succeeded\n", vb->index);
1649 return 0;1734 return 0;
1650}1735}
1651EXPORT_SYMBOL_GPL(vb2_core_qbuf);1736EXPORT_SYMBOL_GPL(vb2_core_qbuf);
@@ -1671,22 +1756,22 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) · 19 unmodified lines
1671 int ret;1756 int ret;
1672 1757
1673 if (q->waiting_in_dqbuf) {1758 if (q->waiting_in_dqbuf) {
1674 dprintk(1, "another dup()ped fd is waiting for a buffer\n");1759 dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
1675 return -EBUSY;1760 return -EBUSY;
1676 }1761 }
1677 1762
1678 if (!q->streaming) {1763 if (!q->streaming) {
1679 dprintk(1, "streaming off, will not wait for buffers\n");1764 dprintk(q, 1, "streaming off, will not wait for buffers\n");
1680 return -EINVAL;1765 return -EINVAL;
1681 }1766 }
1682 1767
1683 if (q->error) {1768 if (q->error) {
1684 dprintk(1, "Queue in error state, will not wait for buffers\n");1769 dprintk(q, 1, "Queue in error state, will not wait for buffers\n");
1685 return -EIO;1770 return -EIO;
1686 }1771 }
1687 1772
1688 if (q->last_buffer_dequeued) {1773 if (q->last_buffer_dequeued) {
1689 dprintk(3, "last buffer dequeued already, will not wait for buffers\n");1774 dprintk(q, 3, "last buffer dequeued already, will not wait for buffers\n");
1690 return -EPIPE;1775 return -EPIPE;
1691 }1776 }
1692 1777
@@ -1698,7 +1783,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) · 5 unmodified lines
1698 }1783 }
1699 1784
1700 if (nonblocking) {1785 if (nonblocking) {
1701 dprintk(3, "nonblocking and no buffers to dequeue, will not wait\n");1786 dprintk(q, 3, "nonblocking and no buffers to dequeue, will not wait\n");
1702 return -EAGAIN;1787 return -EAGAIN;
1703 }1788 }
1704 1789
@@ -1713,7 +1798,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) · 8 unmodified lines
1713 /*1798 /*
1714 * All locks have been released, it is safe to sleep now.1799 * All locks have been released, it is safe to sleep now.
1715 */1800 */
1716 dprintk(3, "will sleep waiting for buffers\n");1801 dprintk(q, 3, "will sleep waiting for buffers\n");
1717 ret = wait_event_interruptible(q->done_wq,1802 ret = wait_event_interruptible(q->done_wq,
1718 !list_empty(&q->done_list) || !q->streaming ||1803 !list_empty(&q->done_list) || !q->streaming ||
1719 q->error);1804 q->error);
@@ -1725,7 +1810,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) · 5 unmodified lines
1725 call_void_qop(q, wait_finish, q);1810 call_void_qop(q, wait_finish, q);
1726 q->waiting_in_dqbuf = 0;1811 q->waiting_in_dqbuf = 0;
1727 if (ret) {1812 if (ret) {
1728 dprintk(1, "sleep was interrupted\n");1813 dprintk(q, 1, "sleep was interrupted\n");
1729 return ret;1814 return ret;
1730 }1815 }
1731 }1816 }
@@ -1773,7 +1858,7 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, · 41 unmodified lines
1773int vb2_wait_for_all_buffers(struct vb2_queue *q)1858int vb2_wait_for_all_buffers(struct vb2_queue *q)
1774{1859{
1775 if (!q->streaming) {1860 if (!q->streaming) {
1776 dprintk(1, "streaming off, will not wait for buffers\n");1861 dprintk(q, 1, "streaming off, will not wait for buffers\n");
1777 return -EINVAL;1862 return -EINVAL;
1778 }1863 }
1779 1864
@@ -1811,13 +1896,14 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, · 31 unmodified lines
1811 1896
1812 switch (vb->state) {1897 switch (vb->state) {
1813 case VB2_BUF_STATE_DONE:1898 case VB2_BUF_STATE_DONE:
1814 dprintk(3, "returning done buffer\n");1899 dprintk(q, 3, "returning done buffer\n");
1815 break;1900 break;
1816 case VB2_BUF_STATE_ERROR:1901 case VB2_BUF_STATE_ERROR:
1817 dprintk(3, "returning done buffer with errors\n");1902 dprintk(q, 3, "returning done buffer with errors\n");
1818 break;1903 break;
1819 default:1904 default:
1820 dprintk(1, "invalid buffer state\n");1905 dprintk(q, 1, "invalid buffer state %s\n",
1906 vb2_state_name(vb->state));
1821 return -EINVAL;1907 return -EINVAL;
1822 }1908 }
1823 1909
@@ -1848,8 +1934,8 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, · 24 unmodified lines
1848 media_request_put(vb->request);1934 media_request_put(vb->request);
1849 vb->request = NULL;1935 vb->request = NULL;
1850 1936
1851 dprintk(2, "dqbuf of buffer %d, with state %d\n",1937 dprintk(q, 2, "dqbuf of buffer %d, state: %s\n",
1852 vb->index, vb->state);1938 vb->index, vb2_state_name(vb->state));
1853 1939
1854 return 0;1940 return 0;
1855 1941
@@ -1940,14 +2026,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) · 84 unmodified lines
1940 call_void_vb_qop(vb, buf_request_complete, vb);2026 call_void_vb_qop(vb, buf_request_complete, vb);
1941 }2027 }
1942 2028
1943 if (vb->synced) {2029 __vb2_buf_mem_finish(vb);
1944 unsigned int plane;
1945
1946 for (plane = 0; plane < vb->num_planes; ++plane)
1947 call_void_memop(vb, finish,
1948 vb->planes[plane].mem_priv);
1949 vb->synced = 0;
1950 }
1951 2030
1952 if (vb->prepared) {2031 if (vb->prepared) {
1953 call_void_vb_qop(vb, buf_finish, vb);2032 call_void_vb_qop(vb, buf_finish, vb);
@@ -1971,22 +2050,22 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type) · 17 unmodified lines
1971 int ret;2050 int ret;
1972 2051
1973 if (type != q->type) {2052 if (type != q->type) {
1974 dprintk(1, "invalid stream type\n");2053 dprintk(q, 1, "invalid stream type\n");
1975 return -EINVAL;2054 return -EINVAL;
1976 }2055 }
1977 2056
1978 if (q->streaming) {2057 if (q->streaming) {
1979 dprintk(3, "already streaming\n");2058 dprintk(q, 3, "already streaming\n");
1980 return 0;2059 return 0;
1981 }2060 }
1982 2061
1983 if (!q->num_buffers) {2062 if (!q->num_buffers) {
1984 dprintk(1, "no buffers have been allocated\n");2063 dprintk(q, 1, "no buffers have been allocated\n");
1985 return -EINVAL;2064 return -EINVAL;
1986 }2065 }
1987 2066
1988 if (q->num_buffers < q->min_buffers_needed) {2067 if (q->num_buffers < q->min_buffers_needed) {
1989 dprintk(1, "need at least %u allocated buffers\n",2068 dprintk(q, 1, "need at least %u allocated buffers\n",
1990 q->min_buffers_needed);2069 q->min_buffers_needed);
1991 return -EINVAL;2070 return -EINVAL;
1992 }2071 }
@@ -2006,7 +2085,7 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type) · 13 unmodified lines
2006 2085
2007 q->streaming = 1;2086 q->streaming = 1;
2008 2087
2009 dprintk(3, "successful\n");2088 dprintk(q, 3, "successful\n");
2010 return 0;2089 return 0;
2011}2090}
2012EXPORT_SYMBOL_GPL(vb2_core_streamon);2091EXPORT_SYMBOL_GPL(vb2_core_streamon);
@@ -2022,7 +2101,7 @@ EXPORT_SYMBOL_GPL(vb2_queue_error); · 9 unmodified lines
2022int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)2101int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)
2023{2102{
2024 if (type != q->type) {2103 if (type != q->type) {
2025 dprintk(1, "invalid stream type\n");2104 dprintk(q, 1, "invalid stream type\n");
2026 return -EINVAL;2105 return -EINVAL;
2027 }2106 }
2028 2107
@@ -2039,7 +2118,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type) · 10 unmodified lines
2039 q->waiting_for_buffers = !q->is_output;2118 q->waiting_for_buffers = !q->is_output;
2040 q->last_buffer_dequeued = false;2119 q->last_buffer_dequeued = false;
2041 2120
2042 dprintk(3, "successful\n");2121 dprintk(q, 3, "successful\n");
2043 return 0;2122 return 0;
2044}2123}
2045EXPORT_SYMBOL_GPL(vb2_core_streamoff);2124EXPORT_SYMBOL_GPL(vb2_core_streamoff);
@@ -2082,39 +2161,39 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, · 36 unmodified lines
2082 struct dma_buf *dbuf;2161 struct dma_buf *dbuf;
2083 2162
2084 if (q->memory != VB2_MEMORY_MMAP) {2163 if (q->memory != VB2_MEMORY_MMAP) {
2085 dprintk(1, "queue is not currently set up for mmap\n");2164 dprintk(q, 1, "queue is not currently set up for mmap\n");
2086 return -EINVAL;2165 return -EINVAL;
2087 }2166 }
2088 2167
2089 if (!q->mem_ops->get_dmabuf) {2168 if (!q->mem_ops->get_dmabuf) {
2090 dprintk(1, "queue does not support DMA buffer exporting\n");2169 dprintk(q, 1, "queue does not support DMA buffer exporting\n");
2091 return -EINVAL;2170 return -EINVAL;
2092 }2171 }
2093 2172
2094 if (flags & ~(O_CLOEXEC | O_ACCMODE)) {2173 if (flags & ~(O_CLOEXEC | O_ACCMODE)) {
2095 dprintk(1, "queue does support only O_CLOEXEC and access mode flags\n");2174 dprintk(q, 1, "queue does support only O_CLOEXEC and access mode flags\n");
2096 return -EINVAL;2175 return -EINVAL;
2097 }2176 }
2098 2177
2099 if (type != q->type) {2178 if (type != q->type) {
2100 dprintk(1, "invalid buffer type\n");2179 dprintk(q, 1, "invalid buffer type\n");
2101 return -EINVAL;2180 return -EINVAL;
2102 }2181 }
2103 2182
2104 if (index >= q->num_buffers) {2183 if (index >= q->num_buffers) {
2105 dprintk(1, "buffer index out of range\n");2184 dprintk(q, 1, "buffer index out of range\n");
2106 return -EINVAL;2185 return -EINVAL;
2107 }2186 }
2108 2187
2109 vb = q->bufs[index];2188 vb = q->bufs[index];
2110 2189
2111 if (plane >= vb->num_planes) {2190 if (plane >= vb->num_planes) {
2112 dprintk(1, "buffer plane out of range\n");2191 dprintk(q, 1, "buffer plane out of range\n");
2113 return -EINVAL;2192 return -EINVAL;
2114 }2193 }
2115 2194
2116 if (vb2_fileio_is_active(q)) {2195 if (vb2_fileio_is_active(q)) {
2117 dprintk(1, "expbuf: file io in progress\n");2196 dprintk(q, 1, "expbuf: file io in progress\n");
2118 return -EBUSY;2197 return -EBUSY;
2119 }2198 }
2120 2199
@@ -2123,20 +2202,20 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, · 2 unmodified lines
2123 dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv,2202 dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv,
2124 flags & O_ACCMODE);2203 flags & O_ACCMODE);
2125 if (IS_ERR_OR_NULL(dbuf)) {2204 if (IS_ERR_OR_NULL(dbuf)) {
2126 dprintk(1, "failed to export buffer %d, plane %d\n",2205 dprintk(q, 1, "failed to export buffer %d, plane %d\n",
2127 index, plane);2206 index, plane);
2128 return -EINVAL;2207 return -EINVAL;
2129 }2208 }
2130 2209
2131 ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE);2210 ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE);
2132 if (ret < 0) {2211 if (ret < 0) {
2133 dprintk(3, "buffer %d, plane %d failed to export (%d)\n",2212 dprintk(q, 3, "buffer %d, plane %d failed to export (%d)\n",
2134 index, plane, ret);2213 index, plane, ret);
2135 dma_buf_put(dbuf);2214 dma_buf_put(dbuf);
2136 return ret;2215 return ret;
2137 }2216 }
2138 2217
2139 dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",2218 dprintk(q, 3, "buffer %d, plane %d exported as %d descriptor\n",
2140 index, plane, ret);2219 index, plane, ret);
2141 *fd = ret;2220 *fd = ret;
2142 2221
@@ -2153,7 +2232,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) · 10 unmodified lines
2153 unsigned long length;2232 unsigned long length;
2154 2233
2155 if (q->memory != VB2_MEMORY_MMAP) {2234 if (q->memory != VB2_MEMORY_MMAP) {
2156 dprintk(1, "queue is not currently set up for mmap\n");2235 dprintk(q, 1, "queue is not currently set up for mmap\n");
2157 return -EINVAL;2236 return -EINVAL;
2158 }2237 }
2159 2238
@@ -2161,17 +2240,17 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) · 1 unmodified line
2161 * Check memory area access mode.2240 * Check memory area access mode.
2162 */2241 */
2163 if (!(vma->vm_flags & VM_SHARED)) {2242 if (!(vma->vm_flags & VM_SHARED)) {
2164 dprintk(1, "invalid vma flags, VM_SHARED needed\n");2243 dprintk(q, 1, "invalid vma flags, VM_SHARED needed\n");
2165 return -EINVAL;2244 return -EINVAL;
2166 }2245 }
2167 if (q->is_output) {2246 if (q->is_output) {
2168 if (!(vma->vm_flags & VM_WRITE)) {2247 if (!(vma->vm_flags & VM_WRITE)) {
2169 dprintk(1, "invalid vma flags, VM_WRITE needed\n");2248 dprintk(q, 1, "invalid vma flags, VM_WRITE needed\n");
2170 return -EINVAL;2249 return -EINVAL;
2171 }2250 }
2172 } else {2251 } else {
2173 if (!(vma->vm_flags & VM_READ)) {2252 if (!(vma->vm_flags & VM_READ)) {
2174 dprintk(1, "invalid vma flags, VM_READ needed\n");2253 dprintk(q, 1, "invalid vma flags, VM_READ needed\n");
2175 return -EINVAL;2254 return -EINVAL;
2176 }2255 }
2177 }2256 }
@@ -2179,7 +2258,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) · 1 unmodified line
2179 mutex_lock(&q->mmap_lock);2258 mutex_lock(&q->mmap_lock);
2180 2259
2181 if (vb2_fileio_is_active(q)) {2260 if (vb2_fileio_is_active(q)) {
2182 dprintk(1, "mmap: file io in progress\n");2261 dprintk(q, 1, "mmap: file io in progress\n");
2183 ret = -EBUSY;2262 ret = -EBUSY;
2184 goto unlock;2263 goto unlock;
2185 }2264 }
@@ -2200,7 +2279,7 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) · 14 unmodified lines
2200 */2279 */
2201 length = PAGE_ALIGN(vb->planes[plane].length);2280 length = PAGE_ALIGN(vb->planes[plane].length);
2202 if (length < (vma->vm_end - vma->vm_start)) {2281 if (length < (vma->vm_end - vma->vm_start)) {
2203 dprintk(1,2282 dprintk(q, 1,
2204 "MMAP invalid, as it would overflow buffer length\n");2283 "MMAP invalid, as it would overflow buffer length\n");
2205 ret = -EINVAL;2284 ret = -EINVAL;
2206 goto unlock;2285 goto unlock;
@@ -2220,7 +2299,7 @@ unlock: · 13 unmodified lines
2220 if (ret)2299 if (ret)
2221 return ret;2300 return ret;
2222 2301
2223 dprintk(3, "buffer %d, plane %d successfully mapped\n", buffer, plane);2302 dprintk(q, 3, "buffer %d, plane %d successfully mapped\n", buffer, plane);
2224 return 0;2303 return 0;
2225}2304}
2226EXPORT_SYMBOL_GPL(vb2_mmap);2305EXPORT_SYMBOL_GPL(vb2_mmap);
@@ -2239,7 +2318,7 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, · 12 unmodified lines
2239 int ret;2318 int ret;
2240 2319
2241 if (q->memory != VB2_MEMORY_MMAP) {2320 if (q->memory != VB2_MEMORY_MMAP) {
2242 dprintk(1, "queue is not currently set up for mmap\n");2321 dprintk(q, 1, "queue is not currently set up for mmap\n");
2243 return -EINVAL;2322 return -EINVAL;
2244 }2323 }
2245 2324
@@ -2291,6 +2370,10 @@ int vb2_core_queue_init(struct vb2_queue *q) · 45 unmodified lines
2291 else2370 else
2292 q->dma_dir = q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;2371 q->dma_dir = q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
2293 2372
2373 if (q->name[0] == '\0')
2374 snprintf(q->name, sizeof(q->name), "%s-%p",
2375 q->is_output ? "out" : "cap", q);
2376
2294 return 0;2377 return 0;
2295}2378}
2296EXPORT_SYMBOL_GPL(vb2_core_queue_init);2379EXPORT_SYMBOL_GPL(vb2_core_queue_init);
@@ -2479,7 +2562,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) · 182 unmodified lines
2479 */2562 */
2480 count = 1;2563 count = 1;
2481 2564
2482 dprintk(3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n",2565 dprintk(q, 3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n",
2483 (read) ? "read" : "write", count, q->fileio_read_once,2566 (read) ? "read" : "write", count, q->fileio_read_once,
2484 q->fileio_write_immediately);2567 q->fileio_write_immediately);
2485 2568
@@ -2498,7 +2581,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) · 12 unmodified lines
2498 fileio->memory = VB2_MEMORY_MMAP;2581 fileio->memory = VB2_MEMORY_MMAP;
2499 fileio->type = q->type;2582 fileio->type = q->type;
2500 q->fileio = fileio;2583 q->fileio = fileio;
2501 ret = vb2_core_reqbufs(q, fileio->memory, &fileio->count);2584 ret = vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count);
2502 if (ret)2585 if (ret)
2503 goto err_kfree;2586 goto err_kfree;
2504 2587
@@ -2555,7 +2638,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) · 50 unmodified lines
2555 2638
2556err_reqbufs:2639err_reqbufs:
2557 fileio->count = 0;2640 fileio->count = 0;
2558 vb2_core_reqbufs(q, fileio->memory, &fileio->count);2641 vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count);
2559 2642
2560err_kfree:2643err_kfree:
2561 q->fileio = NULL;2644 q->fileio = NULL;
@@ -2575,9 +2658,9 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q) · 13 unmodified lines
2575 vb2_core_streamoff(q, q->type);2658 vb2_core_streamoff(q, q->type);
2576 q->fileio = NULL;2659 q->fileio = NULL;
2577 fileio->count = 0;2660 fileio->count = 0;
2578 vb2_core_reqbufs(q, fileio->memory, &fileio->count);2661 vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count);
2579 kfree(fileio);2662 kfree(fileio);
2580 dprintk(3, "file io emulator closed\n");2663 dprintk(q, 3, "file io emulator closed\n");
2581 }2664 }
2582 return 0;2665 return 0;
2583}2666}
@@ -2606,7 +2689,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 22 unmodified lines
2606 unsigned index;2689 unsigned index;
2607 int ret;2690 int ret;
2608 2691
2609 dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n",2692 dprintk(q, 3, "mode %s, offset %ld, count %zd, %sblocking\n",
2610 read ? "read" : "write", (long)*ppos, count,2693 read ? "read" : "write", (long)*ppos, count,
2611 nonblock ? "non" : "");2694 nonblock ? "non" : "");
2612 2695
@@ -2614,7 +2697,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 1 unmodified line
2614 return -EINVAL;2697 return -EINVAL;
2615 2698
2616 if (q->waiting_in_dqbuf) {2699 if (q->waiting_in_dqbuf) {
2617 dprintk(3, "another dup()ped fd is %s\n",2700 dprintk(q, 3, "another dup()ped fd is %s\n",
2618 read ? "reading" : "writing");2701 read ? "reading" : "writing");
2619 return -EBUSY;2702 return -EBUSY;
2620 }2703 }
@@ -2624,7 +2707,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 3 unmodified lines
2624 */2707 */
2625 if (!vb2_fileio_is_active(q)) {2708 if (!vb2_fileio_is_active(q)) {
2626 ret = __vb2_init_fileio(q, read);2709 ret = __vb2_init_fileio(q, read);
2627 dprintk(3, "vb2_init_fileio result: %d\n", ret);2710 dprintk(q, 3, "vb2_init_fileio result: %d\n", ret);
2628 if (ret)2711 if (ret)
2629 return ret;2712 return ret;
2630 }2713 }
@@ -2641,7 +2724,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 10 unmodified lines
2641 * Call vb2_dqbuf to get buffer back.2724 * Call vb2_dqbuf to get buffer back.
2642 */2725 */
2643 ret = vb2_core_dqbuf(q, &index, NULL, nonblock);2726 ret = vb2_core_dqbuf(q, &index, NULL, nonblock);
2644 dprintk(5, "vb2_dqbuf result: %d\n", ret);2727 dprintk(q, 5, "vb2_dqbuf result: %d\n", ret);
2645 if (ret)2728 if (ret)
2646 return ret;2729 return ret;
2647 fileio->dq_count += 1;2730 fileio->dq_count += 1;
@@ -2672,20 +2755,20 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 24 unmodified lines
2672 */2755 */
2673 if (buf->pos + count > buf->size) {2756 if (buf->pos + count > buf->size) {
2674 count = buf->size - buf->pos;2757 count = buf->size - buf->pos;
2675 dprintk(5, "reducing read count: %zd\n", count);2758 dprintk(q, 5, "reducing read count: %zd\n", count);
2676 }2759 }
2677 2760
2678 /*2761 /*
2679 * Transfer data to userspace.2762 * Transfer data to userspace.
2680 */2763 */
2681 dprintk(3, "copying %zd bytes - buffer %d, offset %u\n",2764 dprintk(q, 3, "copying %zd bytes - buffer %d, offset %u\n",
2682 count, index, buf->pos);2765 count, index, buf->pos);
2683 if (read)2766 if (read)
2684 ret = copy_to_user(data, buf->vaddr + buf->pos, count);2767 ret = copy_to_user(data, buf->vaddr + buf->pos, count);
2685 else2768 else
2686 ret = copy_from_user(buf->vaddr + buf->pos, data, count);2769 ret = copy_from_user(buf->vaddr + buf->pos, data, count);
2687 if (ret) {2770 if (ret) {
2688 dprintk(3, "error copying data\n");2771 dprintk(q, 3, "error copying data\n");
2689 return -EFAULT;2772 return -EFAULT;
2690 }2773 }
2691 2774
@@ -2705,7 +2788,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 13 unmodified lines
2705 * Check if this is the last buffer to read.2788 * Check if this is the last buffer to read.
2706 */2789 */
2707 if (read && fileio->read_once && fileio->dq_count == 1) {2790 if (read && fileio->read_once && fileio->dq_count == 1) {
2708 dprintk(3, "read limit reached\n");2791 dprintk(q, 3, "read limit reached\n");
2709 return __vb2_cleanup_fileio(q);2792 return __vb2_cleanup_fileio(q);
2710 }2793 }
2711 2794
@@ -2717,7 +2800,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ · 5 unmodified lines
2717 if (copy_timestamp)2800 if (copy_timestamp)
2718 b->timestamp = ktime_get_ns();2801 b->timestamp = ktime_get_ns();
2719 ret = vb2_core_qbuf(q, index, NULL, NULL);2802 ret = vb2_core_qbuf(q, index, NULL, NULL);
2720 dprintk(5, "vb2_dbuf result: %d\n", ret);2803 dprintk(q, 5, "vb2_dbuf result: %d\n", ret);
2721 if (ret)2804 if (ret)
2722 return ret;2805 return ret;
2723 2806
@@ -2804,7 +2887,7 @@ static int vb2_thread(void *data) · 80 unmodified lines
2804 if (!threadio->stop)2887 if (!threadio->stop)
2805 ret = vb2_core_dqbuf(q, &index, NULL, 0);2888 ret = vb2_core_dqbuf(q, &index, NULL, 0);
2806 call_void_qop(q, wait_prepare, q);2889 call_void_qop(q, wait_prepare, q);
2807 dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);2890 dprintk(q, 5, "file io: vb2_dqbuf result: %d\n", ret);
2808 if (!ret)2891 if (!ret)
2809 vb = q->bufs[index];2892 vb = q->bufs[index];
2810 }2893 }
@@ -2858,7 +2941,7 @@ int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, · 47 unmodified lines
2858 threadio->priv = priv;2941 threadio->priv = priv;
2859 2942
2860 ret = __vb2_init_fileio(q, !q->is_output);2943 ret = __vb2_init_fileio(q, !q->is_output);
2861 dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);2944 dprintk(q, 3, "file io: vb2_init_fileio result: %d\n", ret);
2862 if (ret)2945 if (ret)
2863 goto nomem;2946 goto nomem;
2864 q->threadio = threadio;2947 q->threadio = threadio;
drivers/media/common/videobuf2/videobuf2-dma-contig.c+38−6
@@ -42,6 +42,11 @@ struct vb2_dc_buf { · 41 unmodified lines
42 struct dma_buf_attachment *db_attach;42 struct dma_buf_attachment *db_attach;
43};43};
44 44
45static inline bool vb2_dc_buffer_consistent(unsigned long attr)
46{
47 return !(attr & DMA_ATTR_NON_CONSISTENT);
48}
49
45/*********************************************/50/*********************************************/
46/* scatterlist table functions */51/* scatterlist table functions */
47/*********************************************/52/*********************************************/
@@ -95,8 +100,7 @@ static void vb2_dc_prepare(void *buf_priv) · 47 unmodified lines
95 struct vb2_dc_buf *buf = buf_priv;100 struct vb2_dc_buf *buf = buf_priv;
96 struct sg_table *sgt = buf->dma_sgt;101 struct sg_table *sgt = buf->dma_sgt;
97 102
98 /* DMABUF exporter will flush the cache for us */103 if (!sgt)
99 if (!sgt || buf->db_attach)
100 return;104 return;
101 105
102 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,106 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
@@ -108,8 +112,7 @@ static void vb2_dc_finish(void *buf_priv) · 5 unmodified lines
108 struct vb2_dc_buf *buf = buf_priv;112 struct vb2_dc_buf *buf = buf_priv;
109 struct sg_table *sgt = buf->dma_sgt;113 struct sg_table *sgt = buf->dma_sgt;
110 114
111 /* DMABUF exporter will flush the cache for us */115 if (!sgt)
112 if (!sgt || buf->db_attach)
113 return;116 return;
114 117
115 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);118 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
@@ -149,8 +152,7 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, · 33 unmodified lines
149 if (!buf)152 if (!buf)
150 return ERR_PTR(-ENOMEM);153 return ERR_PTR(-ENOMEM);
151 154
152 if (attrs)155 buf->attrs = attrs;
153 buf->attrs = attrs;
154 buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr,156 buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr,
155 GFP_KERNEL | gfp_flags, buf->attrs);157 GFP_KERNEL | gfp_flags, buf->attrs);
156 if (!buf->cookie) {158 if (!buf->cookie) {
@@ -335,6 +337,34 @@ static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf) · 178 unmodified lines
335 vb2_dc_put(dbuf->priv);337 vb2_dc_put(dbuf->priv);
336}338}
337 339
340static int
341vb2_dc_dmabuf_ops_begin_cpu_access(struct dma_buf *dbuf,
342 enum dma_data_direction direction)
343{
344 struct vb2_dc_buf *buf = dbuf->priv;
345 struct sg_table *sgt = buf->dma_sgt;
346
347 if (vb2_dc_buffer_consistent(buf->attrs))
348 return 0;
349
350 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
351 return 0;
352}
353
354static int
355vb2_dc_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf,
356 enum dma_data_direction direction)
357{
358 struct vb2_dc_buf *buf = dbuf->priv;
359 struct sg_table *sgt = buf->dma_sgt;
360
361 if (vb2_dc_buffer_consistent(buf->attrs))
362 return 0;
363
364 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
365 return 0;
366}
367
338static void *vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf)368static void *vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf)
339{369{
340 struct vb2_dc_buf *buf = dbuf->priv;370 struct vb2_dc_buf *buf = dbuf->priv;
@@ -353,6 +383,8 @@ static const struct dma_buf_ops vb2_dc_dmabuf_ops = { · 12 unmodified lines
353 .detach = vb2_dc_dmabuf_ops_detach,383 .detach = vb2_dc_dmabuf_ops_detach,
354 .map_dma_buf = vb2_dc_dmabuf_ops_map,384 .map_dma_buf = vb2_dc_dmabuf_ops_map,
355 .unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,385 .unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
386 .begin_cpu_access = vb2_dc_dmabuf_ops_begin_cpu_access,
387 .end_cpu_access = vb2_dc_dmabuf_ops_end_cpu_access,
356 .vmap = vb2_dc_dmabuf_ops_vmap,388 .vmap = vb2_dc_dmabuf_ops_vmap,
357 .mmap = vb2_dc_dmabuf_ops_mmap,389 .mmap = vb2_dc_dmabuf_ops_mmap,
358 .release = vb2_dc_dmabuf_ops_release,390 .release = vb2_dc_dmabuf_ops_release,
drivers/media/common/videobuf2/videobuf2-dma-sg.c+30−8
@@ -120,6 +120,12 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, · 119 unmodified lines
120 buf->num_pages = size >> PAGE_SHIFT;120 buf->num_pages = size >> PAGE_SHIFT;
121 buf->dma_sgt = &buf->sg_table;121 buf->dma_sgt = &buf->sg_table;
122 122
123 /*
124 * NOTE: dma-sg allocates memory using the page allocator directly, so
125 * there is no memory consistency guarantee, hence dma-sg ignores DMA
126 * attributes passed from the upper layer. That means that
127 * V4L2_FLAG_MEMORY_NON_CONSISTENT has no effect on dma-sg buffers.
128 */
123 buf->pages = kvmalloc_array(buf->num_pages, sizeof(struct page *),129 buf->pages = kvmalloc_array(buf->num_pages, sizeof(struct page *),
124 GFP_KERNEL | __GFP_ZERO);130 GFP_KERNEL | __GFP_ZERO);
125 if (!buf->pages)131 if (!buf->pages)
@@ -198,10 +204,6 @@ static void vb2_dma_sg_prepare(void *buf_priv) · 72 unmodified lines
198 struct vb2_dma_sg_buf *buf = buf_priv;204 struct vb2_dma_sg_buf *buf = buf_priv;
199 struct sg_table *sgt = buf->dma_sgt;205 struct sg_table *sgt = buf->dma_sgt;
200 206
201 /* DMABUF exporter will flush the cache for us */
202 if (buf->db_attach)
203 return;
204
205 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,207 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
206 buf->dma_dir);208 buf->dma_dir);
207}209}
@@ -211,10 +213,6 @@ static void vb2_dma_sg_finish(void *buf_priv) · 3 unmodified lines
211 struct vb2_dma_sg_buf *buf = buf_priv;213 struct vb2_dma_sg_buf *buf = buf_priv;
212 struct sg_table *sgt = buf->dma_sgt;214 struct sg_table *sgt = buf->dma_sgt;
213 215
214 /* DMABUF exporter will flush the cache for us */
215 if (buf->db_attach)
216 return;
217
218 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);216 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
219}217}
220 218
@@ -469,6 +467,28 @@ static void vb2_dma_sg_dmabuf_ops_release(struct dma_buf *dbuf) · 248 unmodified lines
469 vb2_dma_sg_put(dbuf->priv);467 vb2_dma_sg_put(dbuf->priv);
470}468}
471 469
470static int
471vb2_dma_sg_dmabuf_ops_begin_cpu_access(struct dma_buf *dbuf,
472 enum dma_data_direction direction)
473{
474 struct vb2_dma_sg_buf *buf = dbuf->priv;
475 struct sg_table *sgt = buf->dma_sgt;
476
477 dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
478 return 0;
479}
480
481static int
482vb2_dma_sg_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf,
483 enum dma_data_direction direction)
484{
485 struct vb2_dma_sg_buf *buf = dbuf->priv;
486 struct sg_table *sgt = buf->dma_sgt;
487
488 dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
489 return 0;
490}
491
472static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf)492static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf)
473{493{
474 struct vb2_dma_sg_buf *buf = dbuf->priv;494 struct vb2_dma_sg_buf *buf = dbuf->priv;
@@ -487,6 +507,8 @@ static const struct dma_buf_ops vb2_dma_sg_dmabuf_ops = { · 12 unmodified lines
487 .detach = vb2_dma_sg_dmabuf_ops_detach,507 .detach = vb2_dma_sg_dmabuf_ops_detach,
488 .map_dma_buf = vb2_dma_sg_dmabuf_ops_map,508 .map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
489 .unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,509 .unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,
510 .begin_cpu_access = vb2_dma_sg_dmabuf_ops_begin_cpu_access,
511 .end_cpu_access = vb2_dma_sg_dmabuf_ops_end_cpu_access,
490 .vmap = vb2_dma_sg_dmabuf_ops_vmap,512 .vmap = vb2_dma_sg_dmabuf_ops_vmap,
491 .mmap = vb2_dma_sg_dmabuf_ops_mmap,513 .mmap = vb2_dma_sg_dmabuf_ops_mmap,
492 .release = vb2_dma_sg_dmabuf_ops_release,514 .release = vb2_dma_sg_dmabuf_ops_release,
drivers/media/common/videobuf2/videobuf2-v4l2.c+114−33
@@ -35,10 +35,11 @@ · 34 unmodified lines
35static int debug;35static int debug;
36module_param(debug, int, 0644);36module_param(debug, int, 0644);
37 37
38#define dprintk(level, fmt, arg...) \38#define dprintk(q, level, fmt, arg...) \
39 do { \39 do { \
40 if (debug >= level) \40 if (debug >= level) \
41 pr_info("vb2-v4l2: %s: " fmt, __func__, ## arg); \41 pr_info("vb2-v4l2: [%p] %s: " fmt, \
42 (q)->name, __func__, ## arg); \
42 } while (0)43 } while (0)
43 44
44/* Flags that are set by us */45/* Flags that are set by us */
@@ -66,12 +67,14 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer · 21 unmodified lines
66 67
67 /* Is memory for copying plane information present? */68 /* Is memory for copying plane information present? */
68 if (b->m.planes == NULL) {69 if (b->m.planes == NULL) {
69 dprintk(1, "multi-planar buffer passed but planes array not provided\n");70 dprintk(vb->vb2_queue, 1,
71 "multi-planar buffer passed but planes array not provided\n");
70 return -EINVAL;72 return -EINVAL;
71 }73 }
72 74
73 if (b->length < vb->num_planes || b->length > VB2_MAX_PLANES) {75 if (b->length < vb->num_planes || b->length > VB2_MAX_PLANES) {
74 dprintk(1, "incorrect planes array length, expected %d, got %d\n",76 dprintk(vb->vb2_queue, 1,
77 "incorrect planes array length, expected %d, got %d\n",
75 vb->num_planes, b->length);78 vb->num_planes, b->length);
76 return -EINVAL;79 return -EINVAL;
77 }80 }
@@ -94,7 +97,7 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) · 16 unmodified lines
94 unsigned int bytesused;97 unsigned int bytesused;
95 unsigned int plane;98 unsigned int plane;
96 99
97 if (!V4L2_TYPE_IS_OUTPUT(b->type))100 if (V4L2_TYPE_IS_CAPTURE(b->type))
98 return 0;101 return 0;
99 102
100 if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {103 if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
@@ -114,7 +117,8 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) · 13 unmodified lines
114 return -EINVAL;117 return -EINVAL;
115 }118 }
116 } else {119 } else {
117 length = (b->memory == VB2_MEMORY_USERPTR)120 length = (b->memory == VB2_MEMORY_USERPTR ||
121 b->memory == VB2_MEMORY_DMABUF)
118 ? b->length : vb->planes[0].length;122 ? b->length : vb->planes[0].length;
119 123
120 if (b->bytesused > length)124 if (b->bytesused > length)
@@ -179,7 +183,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b · 58 unmodified lines
179 183
180 ret = __verify_length(vb, b);184 ret = __verify_length(vb, b);
181 if (ret < 0) {185 if (ret < 0) {
182 dprintk(1, "plane parameters verification failed: %d\n", ret);186 dprintk(q, 1, "plane parameters verification failed: %d\n", ret);
183 return ret;187 return ret;
184 }188 }
185 if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) {189 if (b->field == V4L2_FIELD_ALTERNATE && q->is_output) {
@@ -192,7 +196,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b · 6 unmodified lines
192 * that just says that it is either a top or a bottom field,196 * that just says that it is either a top or a bottom field,
193 * but not which of the two it is.197 * but not which of the two it is.
194 */198 */
195 dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n");199 dprintk(q, 1, "the field is incorrectly set to ALTERNATE for an output buffer\n");
196 return -EINVAL;200 return -EINVAL;
197 }201 }
198 vbuf->sequence = 0;202 vbuf->sequence = 0;
@@ -307,7 +311,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b · 108 unmodified lines
307 311
308 /* Zero flags that we handle */312 /* Zero flags that we handle */
309 vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;313 vbuf->flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
310 if (!vb->vb2_queue->copy_timestamp || !V4L2_TYPE_IS_OUTPUT(b->type)) {314 if (!vb->vb2_queue->copy_timestamp || V4L2_TYPE_IS_CAPTURE(b->type)) {
311 /*315 /*
312 * Non-COPY timestamps and non-OUTPUT queues will get316 * Non-COPY timestamps and non-OUTPUT queues will get
313 * their timestamp and timestamp source flags from the317 * their timestamp and timestamp source flags from the
@@ -337,6 +341,53 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b · 23 unmodified lines
337 return 0;341 return 0;
338}342}
339 343
344static void set_buffer_cache_hints(struct vb2_queue *q,
345 struct vb2_buffer *vb,
346 struct v4l2_buffer *b)
347{
348 /*
349 * DMA exporter should take care of cache syncs, so we can avoid
350 * explicit ->prepare()/->finish() syncs. For other ->memory types
351 * we always need ->prepare() or/and ->finish() cache sync.
352 */
353 if (q->memory == VB2_MEMORY_DMABUF) {
354 vb->need_cache_sync_on_finish = 0;
355 vb->need_cache_sync_on_prepare = 0;
356 return;
357 }
358
359 /*
360 * Cache sync/invalidation flags are set by default in order to
361 * preserve existing behaviour for old apps/drivers.
362 */
363 vb->need_cache_sync_on_prepare = 1;
364 vb->need_cache_sync_on_finish = 1;
365
366 if (!vb2_queue_allows_cache_hints(q)) {
367 /*
368 * Clear buffer cache flags if queue does not support user
369 * space hints. That's to indicate to userspace that these
370 * flags won't work.
371 */
372 b->flags &= ~V4L2_BUF_FLAG_NO_CACHE_INVALIDATE;
373 b->flags &= ~V4L2_BUF_FLAG_NO_CACHE_CLEAN;
374 return;
375 }
376
377 /*
378 * ->finish() cache sync can be avoided when queue direction is
379 * TO_DEVICE.
380 */
381 if (q->dma_dir == DMA_TO_DEVICE)
382 vb->need_cache_sync_on_finish = 0;
383
384 if (b->flags & V4L2_BUF_FLAG_NO_CACHE_INVALIDATE)
385 vb->need_cache_sync_on_finish = 0;
386
387 if (b->flags & V4L2_BUF_FLAG_NO_CACHE_CLEAN)
388 vb->need_cache_sync_on_prepare = 0;
389}
390
340static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *mdev,391static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
341 struct v4l2_buffer *b, bool is_prepare,392 struct v4l2_buffer *b, bool is_prepare,
342 struct media_request **p_req)393 struct media_request **p_req)
@@ -348,23 +399,23 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md · 5 unmodified lines
348 int ret;399 int ret;
349 400
350 if (b->type != q->type) {401 if (b->type != q->type) {
351 dprintk(1, "%s: invalid buffer type\n", opname);402 dprintk(q, 1, "%s: invalid buffer type\n", opname);
352 return -EINVAL;403 return -EINVAL;
353 }404 }
354 405
355 if (b->index >= q->num_buffers) {406 if (b->index >= q->num_buffers) {
356 dprintk(1, "%s: buffer index out of range\n", opname);407 dprintk(q, 1, "%s: buffer index out of range\n", opname);
357 return -EINVAL;408 return -EINVAL;
358 }409 }
359 410
360 if (q->bufs[b->index] == NULL) {411 if (q->bufs[b->index] == NULL) {
361 /* Should never happen */412 /* Should never happen */
362 dprintk(1, "%s: buffer is NULL\n", opname);413 dprintk(q, 1, "%s: buffer is NULL\n", opname);
363 return -EINVAL;414 return -EINVAL;
364 }415 }
365 416
366 if (b->memory != q->memory) {417 if (b->memory != q->memory) {
367 dprintk(1, "%s: invalid memory type\n", opname);418 dprintk(q, 1, "%s: invalid memory type\n", opname);
368 return -EINVAL;419 return -EINVAL;
369 }420 }
370 421
@@ -376,11 +427,12 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md · 5 unmodified lines
376 427
377 if (!is_prepare && (b->flags & V4L2_BUF_FLAG_REQUEST_FD) &&428 if (!is_prepare && (b->flags & V4L2_BUF_FLAG_REQUEST_FD) &&
378 vb->state != VB2_BUF_STATE_DEQUEUED) {429 vb->state != VB2_BUF_STATE_DEQUEUED) {
379 dprintk(1, "%s: buffer is not in dequeued state\n", opname);430 dprintk(q, 1, "%s: buffer is not in dequeued state\n", opname);
380 return -EINVAL;431 return -EINVAL;
381 }432 }
382 433
383 if (!vb->prepared) {434 if (!vb->prepared) {
435 set_buffer_cache_hints(q, vb, b);
384 /* Copy relevant information provided by the userspace */436 /* Copy relevant information provided by the userspace */
385 memset(vbuf->planes, 0,437 memset(vbuf->planes, 0,
386 sizeof(vbuf->planes[0]) * vb->num_planes);438 sizeof(vbuf->planes[0]) * vb->num_planes);
@@ -394,19 +446,19 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md · 7 unmodified lines
394 446
395 if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) {447 if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) {
396 if (q->requires_requests) {448 if (q->requires_requests) {
397 dprintk(1, "%s: queue requires requests\n", opname);449 dprintk(q, 1, "%s: queue requires requests\n", opname);
398 return -EBADR;450 return -EBADR;
399 }451 }
400 if (q->uses_requests) {452 if (q->uses_requests) {
401 dprintk(1, "%s: queue uses requests\n", opname);453 dprintk(q, 1, "%s: queue uses requests\n", opname);
402 return -EBUSY;454 return -EBUSY;
403 }455 }
404 return 0;456 return 0;
405 } else if (!q->supports_requests) {457 } else if (!q->supports_requests) {
406 dprintk(1, "%s: queue does not support requests\n", opname);458 dprintk(q, 1, "%s: queue does not support requests\n", opname);
407 return -EBADR;459 return -EBADR;
408 } else if (q->uses_qbuf) {460 } else if (q->uses_qbuf) {
409 dprintk(1, "%s: queue does not use requests\n", opname);461 dprintk(q, 1, "%s: queue does not use requests\n", opname);
410 return -EBUSY;462 return -EBUSY;
411 }463 }
412 464
@@ -436,13 +488,13 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md · 23 unmodified lines
436 return -EINVAL;488 return -EINVAL;
437 489
438 if (b->request_fd < 0) {490 if (b->request_fd < 0) {
439 dprintk(1, "%s: request_fd < 0\n", opname);491 dprintk(q, 1, "%s: request_fd < 0\n", opname);
440 return -EINVAL;492 return -EINVAL;
441 }493 }
442 494
443 req = media_request_get_by_fd(mdev, b->request_fd);495 req = media_request_get_by_fd(mdev, b->request_fd);
444 if (IS_ERR(req)) {496 if (IS_ERR(req)) {
445 dprintk(1, "%s: invalid request_fd\n", opname);497 dprintk(q, 1, "%s: invalid request_fd\n", opname);
446 return PTR_ERR(req);498 return PTR_ERR(req);
447 }499 }
448 500
@@ -452,7 +504,7 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md · 3 unmodified lines
452 */504 */
453 if (req->state != MEDIA_REQUEST_STATE_IDLE &&505 if (req->state != MEDIA_REQUEST_STATE_IDLE &&
454 req->state != MEDIA_REQUEST_STATE_UPDATING) {506 req->state != MEDIA_REQUEST_STATE_UPDATING) {
455 dprintk(1, "%s: request is not idle\n", opname);507 dprintk(q, 1, "%s: request is not idle\n", opname);
456 media_request_put(req);508 media_request_put(req);
457 return -EBUSY;509 return -EBUSY;
458 }510 }
@@ -635,12 +687,12 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b) · 176 unmodified lines
635 int ret;687 int ret;
636 688
637 if (b->type != q->type) {689 if (b->type != q->type) {
638 dprintk(1, "wrong buffer type\n");690 dprintk(q, 1, "wrong buffer type\n");
639 return -EINVAL;691 return -EINVAL;
640 }692 }
641 693
642 if (b->index >= q->num_buffers) {694 if (b->index >= q->num_buffers) {
643 dprintk(1, "buffer index out of range\n");695 dprintk(q, 1, "buffer index out of range\n");
644 return -EINVAL;696 return -EINVAL;
645 }697 }
646 vb = q->bufs[b->index];698 vb = q->bufs[b->index];
@@ -662,18 +714,30 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps) · 15 unmodified lines
662 *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF;714 *caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF;
663 if (q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)715 if (q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)
664 *caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF;716 *caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
717 if (q->allow_cache_hints && q->io_modes & VB2_MMAP)
718 *caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS;
665#ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API719#ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API
666 if (q->supports_requests)720 if (q->supports_requests)
667 *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;721 *caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
668#endif722#endif
669}723}
670 724
725static void clear_consistency_attr(struct vb2_queue *q,
726 int memory,
727 unsigned int *flags)
728{
729 if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP)
730 *flags &= ~V4L2_FLAG_MEMORY_NON_CONSISTENT;
731}
732
671int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)733int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
672{734{
673 int ret = vb2_verify_memory_type(q, req->memory, req->type);735 int ret = vb2_verify_memory_type(q, req->memory, req->type);
674 736
675 fill_buf_caps(q, &req->capabilities);737 fill_buf_caps(q, &req->capabilities);
676 return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count);738 clear_consistency_attr(q, req->memory, &req->flags);
739 return ret ? ret : vb2_core_reqbufs(q, req->memory,
740 req->flags, &req->count);
677}741}
678EXPORT_SYMBOL_GPL(vb2_reqbufs);742EXPORT_SYMBOL_GPL(vb2_reqbufs);
679 743
@@ -683,7 +747,7 @@ int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev, · 3 unmodified lines
683 int ret;747 int ret;
684 748
685 if (vb2_fileio_is_active(q)) {749 if (vb2_fileio_is_active(q)) {
686 dprintk(1, "file io in progress\n");750 dprintk(q, 1, "file io in progress\n");
687 return -EBUSY;751 return -EBUSY;
688 }752 }
689 753
@@ -705,6 +769,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) · 15 unmodified lines
705 unsigned i;769 unsigned i;
706 770
707 fill_buf_caps(q, &create->capabilities);771 fill_buf_caps(q, &create->capabilities);
772 clear_consistency_attr(q, create->memory, &create->flags);
708 create->index = q->num_buffers;773 create->index = q->num_buffers;
709 if (create->count == 0)774 if (create->count == 0)
710 return ret != -EBUSY ? ret : 0;775 return ret != -EBUSY ? ret : 0;
@@ -748,7 +813,10 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) · 37 unmodified lines
748 if (requested_sizes[i] == 0)813 if (requested_sizes[i] == 0)
749 return -EINVAL;814 return -EINVAL;
750 return ret ? ret : vb2_core_create_bufs(q, create->memory,815 return ret ? ret : vb2_core_create_bufs(q, create->memory,
751 &create->count, requested_planes, requested_sizes);816 create->flags,
817 &create->count,
818 requested_planes,
819 requested_sizes);
752}820}
753EXPORT_SYMBOL_GPL(vb2_create_bufs);821EXPORT_SYMBOL_GPL(vb2_create_bufs);
754 822
@@ -759,7 +827,7 @@ int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev, · 4 unmodified lines
759 int ret;827 int ret;
760 828
761 if (vb2_fileio_is_active(q)) {829 if (vb2_fileio_is_active(q)) {
762 dprintk(1, "file io in progress\n");830 dprintk(q, 1, "file io in progress\n");
763 return -EBUSY;831 return -EBUSY;
764 }832 }
765 833
@@ -778,12 +846,12 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) · 12 unmodified lines
778 int ret;846 int ret;
779 847
780 if (vb2_fileio_is_active(q)) {848 if (vb2_fileio_is_active(q)) {
781 dprintk(1, "file io in progress\n");849 dprintk(q, 1, "file io in progress\n");
782 return -EBUSY;850 return -EBUSY;
783 }851 }
784 852
785 if (b->type != q->type) {853 if (b->type != q->type) {
786 dprintk(1, "invalid buffer type\n");854 dprintk(q, 1, "invalid buffer type\n");
787 return -EINVAL;855 return -EINVAL;
788 }856 }
789 857
@@ -807,7 +875,7 @@ EXPORT_SYMBOL_GPL(vb2_dqbuf); · 17 unmodified lines
807int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)875int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
808{876{
809 if (vb2_fileio_is_active(q)) {877 if (vb2_fileio_is_active(q)) {
810 dprintk(1, "file io in progress\n");878 dprintk(q, 1, "file io in progress\n");
811 return -EBUSY;879 return -EBUSY;
812 }880 }
813 return vb2_core_streamon(q, type);881 return vb2_core_streamon(q, type);
@@ -817,7 +885,7 @@ EXPORT_SYMBOL_GPL(vb2_streamon); · 3 unmodified lines
817int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)885int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
818{886{
819 if (vb2_fileio_is_active(q)) {887 if (vb2_fileio_is_active(q)) {
820 dprintk(1, "file io in progress\n");888 dprintk(q, 1, "file io in progress\n");
821 return -EBUSY;889 return -EBUSY;
822 }890 }
823 return vb2_core_streamoff(q, type);891 return vb2_core_streamoff(q, type);
@@ -831,7 +899,7 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) · 7 unmodified lines
831}899}
832EXPORT_SYMBOL_GPL(vb2_expbuf);900EXPORT_SYMBOL_GPL(vb2_expbuf);
833 901
834int vb2_queue_init(struct vb2_queue *q)902int vb2_queue_init_name(struct vb2_queue *q, const char *name)
835{903{
836 /*904 /*
837 * Sanity check905 * Sanity check
@@ -867,8 +935,19 @@ int vb2_queue_init(struct vb2_queue *q) · 29 unmodified lines
867 */935 */
868 q->quirk_poll_must_check_waiting_for_buffers = true;936 q->quirk_poll_must_check_waiting_for_buffers = true;
869 937
938 if (name)
939 strscpy(q->name, name, sizeof(q->name));
940 else
941 q->name[0] = '\0';
942
870 return vb2_core_queue_init(q);943 return vb2_core_queue_init(q);
871}944}
945EXPORT_SYMBOL_GPL(vb2_queue_init_name);
946
947int vb2_queue_init(struct vb2_queue *q)
948{
949 return vb2_queue_init_name(q, NULL);
950}
872EXPORT_SYMBOL_GPL(vb2_queue_init);951EXPORT_SYMBOL_GPL(vb2_queue_init);
873 952
874void vb2_queue_release(struct vb2_queue *q)953void vb2_queue_release(struct vb2_queue *q)
@@ -919,11 +998,12 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv, · 44 unmodified lines
919 int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type);998 int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type);
920 999
921 fill_buf_caps(vdev->queue, &p->capabilities);1000 fill_buf_caps(vdev->queue, &p->capabilities);
1001 clear_consistency_attr(vdev->queue, p->memory, &p->flags);
922 if (res)1002 if (res)
923 return res;1003 return res;
924 if (vb2_queue_is_busy(vdev, file))1004 if (vb2_queue_is_busy(vdev, file))
925 return -EBUSY;1005 return -EBUSY;
926 res = vb2_core_reqbufs(vdev->queue, p->memory, &p->count);1006 res = vb2_core_reqbufs(vdev->queue, p->memory, p->flags, &p->count);
927 /* If count == 0, then the owner has released all buffers and he1007 /* If count == 0, then the owner has released all buffers and he
928 is no longer owner of the queue. Otherwise we have a new owner. */1008 is no longer owner of the queue. Otherwise we have a new owner. */
929 if (res == 0)1009 if (res == 0)
@@ -941,6 +1021,7 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv, · 11 unmodified lines
941 1021
942 p->index = vdev->queue->num_buffers;1022 p->index = vdev->queue->num_buffers;
943 fill_buf_caps(vdev->queue, &p->capabilities);1023 fill_buf_caps(vdev->queue, &p->capabilities);
1024 clear_consistency_attr(vdev->queue, p->memory, &p->flags);
944 /*1025 /*
945 * If count == 0, then just check if memory and type are valid.1026 * If count == 0, then just check if memory and type are valid.
946 * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0.1027 * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0.
drivers/media/dvb-core/dvb_vb2.c+1−1
@@ -342,7 +342,7 @@ int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req) · 341 unmodified lines
342 342
343 ctx->buf_siz = req->size;343 ctx->buf_siz = req->size;
344 ctx->buf_cnt = req->count;344 ctx->buf_cnt = req->count;
345 ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, &req->count);345 ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, 0, &req->count);
346 if (ret) {346 if (ret) {
347 ctx->state = DVB_VB2_STATE_NONE;347 ctx->state = DVB_VB2_STATE_NONE;
348 dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name,348 dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name,
drivers/media/dvb-frontends/drxk_hard.c+0−11
@@ -155,17 +155,6 @@ if (debug >= level) \ · 154 unmodified lines
155 printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \155 printk(KERN_DEBUG KBUILD_MODNAME ": %s " fmt, __func__, ##arg); \
156} while (0)156} while (0)
157 157
158
159static inline u32 MulDiv32(u32 a, u32 b, u32 c)
160{
161 u64 tmp64;
162
163 tmp64 = (u64) a * (u64) b;
164 do_div(tmp64, c);
165
166 return (u32) tmp64;
167}
168
169static inline u32 Frac28a(u32 a, u32 c)158static inline u32 Frac28a(u32 a, u32 c)
170{159{
171 int i = 0;160 int i = 0;
drivers/media/dvb-frontends/rtl2832_sdr.c+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>5 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
6 *6 *
7 * GNU Radio plugin "gr-kernel" for device usage will be on:7 * GNU Radio plugin "gr-kernel" for device usage will be on:
8 * http://git.linuxtv.org/anttip/gr-kernel.git8 * https://git.linuxtv.org/anttip/gr-kernel.git
9 */9 */
10 10
11#include "rtl2832_sdr.h"11#include "rtl2832_sdr.h"
drivers/media/firewire/firedtv-fw.c+2−0
@@ -272,6 +272,8 @@ static int node_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) · 271 unmodified lines
272 272
273 name_len = fw_csr_string(unit->directory, CSR_MODEL,273 name_len = fw_csr_string(unit->directory, CSR_MODEL,
274 name, sizeof(name));274 name, sizeof(name));
275 if (name_len < 0)
276 return name_len;
275 for (i = ARRAY_SIZE(model_names); --i; )277 for (i = ARRAY_SIZE(model_names); --i; )
276 if (strlen(model_names[i]) <= name_len &&278 if (strlen(model_names[i]) <= name_len &&
277 strncmp(name, model_names[i], name_len) == 0)279 strncmp(name, model_names[i], name_len) == 0)
drivers/media/i2c/Kconfig+39−0
@@ -464,6 +464,19 @@ config VIDEO_VPX3220 · 463 unmodified lines
464 To compile this driver as a module, choose M here: the464 To compile this driver as a module, choose M here: the
465 module will be called vpx3220.465 module will be called vpx3220.
466 466
467config VIDEO_MAX9286
468 tristate "Maxim MAX9286 GMSL deserializer support"
469 depends on I2C && I2C_MUX
470 depends on OF
471 select V4L2_FWNODE
472 select VIDEO_V4L2_SUBDEV_API
473 select MEDIA_CONTROLLER
474 help
475 This driver supports the Maxim MAX9286 GMSL deserializer.
476
477 To compile this driver as a module, choose M here: the
478 module will be called max9286.
479
467comment "Video and audio decoders"480comment "Video and audio decoders"
468 481
469config VIDEO_SAA717X482config VIDEO_SAA717X
@@ -860,6 +873,7 @@ config VIDEO_OV2685 · 390 unmodified lines
860config VIDEO_OV2740873config VIDEO_OV2740
861 tristate "OmniVision OV2740 sensor support"874 tristate "OmniVision OV2740 sensor support"
862 depends on VIDEO_V4L2 && I2C875 depends on VIDEO_V4L2 && I2C
876 depends on ACPI || COMPILE_TEST
863 select MEDIA_CONTROLLER877 select MEDIA_CONTROLLER
864 select VIDEO_V4L2_SUBDEV_API878 select VIDEO_V4L2_SUBDEV_API
865 select V4L2_FWNODE879 select V4L2_FWNODE
@@ -1157,6 +1171,19 @@ config VIDEO_NOON010PC30 · 291 unmodified lines
1157 1171
1158source "drivers/media/i2c/m5mols/Kconfig"1172source "drivers/media/i2c/m5mols/Kconfig"
1159 1173
1174config VIDEO_RDACM20
1175 tristate "IMI RDACM20 camera support"
1176 depends on I2C
1177 select V4L2_FWNODE
1178 select VIDEO_V4L2_SUBDEV_API
1179 select MEDIA_CONTROLLER
1180 help
1181 This driver supports the IMI RDACM20 GMSL camera, used in
1182 ADAS systems.
1183
1184 This camera should be used in conjunction with a GMSL
1185 deserialiser such as the MAX9286.
1186
1160config VIDEO_RJ54N11187config VIDEO_RJ54N1
1161 tristate "Sharp RJ54N1CB0C sensor support"1188 tristate "Sharp RJ54N1CB0C sensor support"
1162 depends on I2C && VIDEO_V4L21189 depends on I2C && VIDEO_V4L2
@@ -1253,6 +1280,18 @@ config VIDEO_DW9714 · 90 unmodified lines
1253 capability. This is designed for linear control of1280 capability. This is designed for linear control of
1254 voice coil motors, controlled via I2C serial interface.1281 voice coil motors, controlled via I2C serial interface.
1255 1282
1283config VIDEO_DW9768
1284 tristate "DW9768 lens voice coil support"
1285 depends on I2C && VIDEO_V4L2
1286 select MEDIA_CONTROLLER
1287 select VIDEO_V4L2_SUBDEV_API
1288 select V4L2_FWNODE
1289 help
1290 This is a driver for the DW9768 camera lens voice coil.
1291 DW9768 is a 10 bit DAC with 100mA output current sink
1292 capability. This is designed for linear control of
1293 voice coil motors, controlled via I2C serial interface.
1294
1256config VIDEO_DW9807_VCM1295config VIDEO_DW9807_VCM
1257 tristate "DW9807 lens voice coil support"1296 tristate "DW9807 lens voice coil support"
1258 depends on I2C && VIDEO_V4L21297 depends on I2C && VIDEO_V4L2
drivers/media/i2c/Makefile+4−0
@@ -24,6 +24,7 @@ obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o · 23 unmodified lines
24obj-$(CONFIG_VIDEO_AD5820) += ad5820.o24obj-$(CONFIG_VIDEO_AD5820) += ad5820.o
25obj-$(CONFIG_VIDEO_AK7375) += ak7375.o25obj-$(CONFIG_VIDEO_AK7375) += ak7375.o
26obj-$(CONFIG_VIDEO_DW9714) += dw9714.o26obj-$(CONFIG_VIDEO_DW9714) += dw9714.o
27obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
27obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o28obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
28obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o29obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
29obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o30obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
@@ -118,6 +119,9 @@ obj-$(CONFIG_VIDEO_IMX274) += imx274.o · 88 unmodified lines
118obj-$(CONFIG_VIDEO_IMX290) += imx290.o119obj-$(CONFIG_VIDEO_IMX290) += imx290.o
119obj-$(CONFIG_VIDEO_IMX319) += imx319.o120obj-$(CONFIG_VIDEO_IMX319) += imx319.o
120obj-$(CONFIG_VIDEO_IMX355) += imx355.o121obj-$(CONFIG_VIDEO_IMX355) += imx355.o
122obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
123rdacm20-camera_module-objs := rdacm20.o max9271.o
124obj-$(CONFIG_VIDEO_RDACM20) += rdacm20-camera_module.o
121obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o125obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
122 126
123obj-$(CONFIG_SDR_MAX2175) += max2175.o127obj-$(CONFIG_SDR_MAX2175) += max2175.o
drivers/media/i2c/dw9768.c+554−0
@@ -0,0 +1,554 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2020 MediaTek Inc.
3
4#include <linux/delay.h>
5#include <linux/i2c.h>
6#include <linux/module.h>
7#include <linux/pm_runtime.h>
8#include <linux/regulator/consumer.h>
9#include <media/v4l2-async.h>
10#include <media/v4l2-ctrls.h>
11#include <media/v4l2-device.h>
12#include <media/v4l2-fwnode.h>
13#include <media/v4l2-subdev.h>
14
15#define DW9768_NAME "dw9768"
16#define DW9768_MAX_FOCUS_POS (1024 - 1)
17/*
18 * This sets the minimum granularity for the focus positions.
19 * A value of 1 gives maximum accuracy for a desired focus position
20 */
21#define DW9768_FOCUS_STEPS 1
22
23/*
24 * Ring control and Power control register
25 * Bit[1] RING_EN
26 * 0: Direct mode
27 * 1: AAC mode (ringing control mode)
28 * Bit[0] PD
29 * 0: Normal operation mode
30 * 1: Power down mode
31 * DW9768 requires waiting time of Topr after PD reset takes place.
32 */
33#define DW9768_RING_PD_CONTROL_REG 0x02
34#define DW9768_PD_MODE_OFF 0x00
35#define DW9768_PD_MODE_EN BIT(0)
36#define DW9768_AAC_MODE_EN BIT(1)
37
38/*
39 * DW9768 separates two registers to control the VCM position.
40 * One for MSB value, another is LSB value.
41 * DAC_MSB: D[9:8] (ADD: 0x03)
42 * DAC_LSB: D[7:0] (ADD: 0x04)
43 * D[9:0] DAC data input: positive output current = D[9:0] / 1023 * 100[mA]
44 */
45#define DW9768_MSB_ADDR 0x03
46#define DW9768_LSB_ADDR 0x04
47#define DW9768_STATUS_ADDR 0x05
48
49/*
50 * AAC mode control & prescale register
51 * Bit[7:5] Namely AC[2:0], decide the VCM mode and operation time.
52 * 001 AAC2 0.48 x Tvib
53 * 010 AAC3 0.70 x Tvib
54 * 011 AAC4 0.75 x Tvib
55 * 101 AAC8 1.13 x Tvib
56 * Bit[2:0] Namely PRESC[2:0], set the internal clock dividing rate as follow.
57 * 000 2
58 * 001 1
59 * 010 1/2
60 * 011 1/4
61 * 100 8
62 * 101 4
63 */
64#define DW9768_AAC_PRESC_REG 0x06
65#define DW9768_AAC_MODE_SEL_MASK GENMASK(7, 5)
66#define DW9768_CLOCK_PRE_SCALE_SEL_MASK GENMASK(2, 0)
67
68/*
69 * VCM period of vibration register
70 * Bit[5:0] Defined as VCM rising periodic time (Tvib) together with PRESC[2:0]
71 * Tvib = (6.3ms + AACT[5:0] * 0.1ms) * Dividing Rate
72 * Dividing Rate is the internal clock dividing rate that is defined at
73 * PRESCALE register (ADD: 0x06)
74 */
75#define DW9768_AAC_TIME_REG 0x07
76
77/*
78 * DW9768 requires waiting time (delay time) of t_OPR after power-up,
79 * or in the case of PD reset taking place.
80 */
81#define DW9768_T_OPR_US 1000
82#define DW9768_TVIB_MS_BASE10 (64 - 1)
83#define DW9768_AAC_MODE_DEFAULT 2
84#define DW9768_AAC_TIME_DEFAULT 0x20
85#define DW9768_CLOCK_PRE_SCALE_DEFAULT 1
86
87/*
88 * This acts as the minimum granularity of lens movement.
89 * Keep this value power of 2, so the control steps can be
90 * uniformly adjusted for gradual lens movement, with desired
91 * number of control steps.
92 */
93#define DW9768_MOVE_STEPS 16
94
95static const char * const dw9768_supply_names[] = {
96 "vin", /* Digital I/O power */
97 "vdd", /* Digital core power */
98};
99
100/* dw9768 device structure */
101struct dw9768 {
102 struct regulator_bulk_data supplies[ARRAY_SIZE(dw9768_supply_names)];
103 struct v4l2_ctrl_handler ctrls;
104 struct v4l2_ctrl *focus;
105 struct v4l2_subdev sd;
106
107 u32 aac_mode;
108 u32 aac_timing;
109 u32 clock_presc;
110 u32 move_delay_us;
111};
112
113static inline struct dw9768 *sd_to_dw9768(struct v4l2_subdev *subdev)
114{
115 return container_of(subdev, struct dw9768, sd);
116}
117
118struct regval_list {
119 u8 reg_num;
120 u8 value;
121};
122
123struct dw9768_aac_mode_ot_multi {
124 u32 aac_mode_enum;
125 u32 ot_multi_base100;
126};
127
128struct dw9768_clk_presc_dividing_rate {
129 u32 clk_presc_enum;
130 u32 dividing_rate_base100;
131};
132
133static const struct dw9768_aac_mode_ot_multi aac_mode_ot_multi[] = {
134 {1, 48},
135 {2, 70},
136 {3, 75},
137 {5, 113},
138};
139
140static const struct dw9768_clk_presc_dividing_rate presc_dividing_rate[] = {
141 {0, 200},
142 {1, 100},
143 {2, 50},
144 {3, 25},
145 {4, 800},
146 {5, 400},
147};
148
149static u32 dw9768_find_ot_multi(u32 aac_mode_param)
150{
151 u32 cur_ot_multi_base100 = 70;
152 unsigned int i;
153
154 for (i = 0; i < ARRAY_SIZE(aac_mode_ot_multi); i++) {
155 if (aac_mode_ot_multi[i].aac_mode_enum == aac_mode_param) {
156 cur_ot_multi_base100 =
157 aac_mode_ot_multi[i].ot_multi_base100;
158 }
159 }
160
161 return cur_ot_multi_base100;
162}
163
164static u32 dw9768_find_dividing_rate(u32 presc_param)
165{
166 u32 cur_clk_dividing_rate_base100 = 100;
167 unsigned int i;
168
169 for (i = 0; i < ARRAY_SIZE(presc_dividing_rate); i++) {
170 if (presc_dividing_rate[i].clk_presc_enum == presc_param) {
171 cur_clk_dividing_rate_base100 =
172 presc_dividing_rate[i].dividing_rate_base100;
173 }
174 }
175
176 return cur_clk_dividing_rate_base100;
177}
178
179/*
180 * DW9768_AAC_PRESC_REG & DW9768_AAC_TIME_REG determine VCM operation time.
181 * For current VCM mode: AAC3, Operation Time would be 0.70 x Tvib.
182 * Tvib = (6.3ms + AACT[5:0] * 0.1MS) * Dividing Rate.
183 * Below is calculation of the operation delay for each step.
184 */
185static inline u32 dw9768_cal_move_delay(u32 aac_mode_param, u32 presc_param,
186 u32 aac_timing_param)
187{
188 u32 Tvib_us;
189 u32 ot_multi_base100;
190 u32 clk_dividing_rate_base100;
191
192 ot_multi_base100 = dw9768_find_ot_multi(aac_mode_param);
193
194 clk_dividing_rate_base100 = dw9768_find_dividing_rate(presc_param);
195
196 Tvib_us = (DW9768_TVIB_MS_BASE10 + aac_timing_param) *
197 clk_dividing_rate_base100;
198
199 return Tvib_us * ot_multi_base100 / 100;
200}
201
202static int dw9768_mod_reg(struct dw9768 *dw9768, u8 reg, u8 mask, u8 val)
203{
204 struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd);
205 int ret;
206
207 ret = i2c_smbus_read_byte_data(client, reg);
208 if (ret < 0)
209 return ret;
210
211 val = ((unsigned char)ret & ~mask) | (val & mask);
212
213 return i2c_smbus_write_byte_data(client, reg, val);
214}
215
216static int dw9768_set_dac(struct dw9768 *dw9768, u16 val)
217{
218 struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd);
219
220 /* Write VCM position to registers */
221 return i2c_smbus_write_word_swapped(client, DW9768_MSB_ADDR, val);
222}
223
224static int dw9768_init(struct dw9768 *dw9768)
225{
226 struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd);
227 int ret, val;
228
229 /* Reset DW9768_RING_PD_CONTROL_REG to default status 0x00 */
230 ret = i2c_smbus_write_byte_data(client, DW9768_RING_PD_CONTROL_REG,
231 DW9768_PD_MODE_OFF);
232 if (ret < 0)
233 return ret;
234
235 /*
236 * DW9769 requires waiting delay time of t_OPR
237 * after PD reset takes place.
238 */
239 usleep_range(DW9768_T_OPR_US, DW9768_T_OPR_US + 100);
240
241 /* Set DW9768_RING_PD_CONTROL_REG to DW9768_AAC_MODE_EN(0x01) */
242 ret = i2c_smbus_write_byte_data(client, DW9768_RING_PD_CONTROL_REG,
243 DW9768_AAC_MODE_EN);
244 if (ret < 0)
245 return ret;
246
247 /* Set AAC mode */
248 ret = dw9768_mod_reg(dw9768, DW9768_AAC_PRESC_REG,
249 DW9768_AAC_MODE_SEL_MASK,
250 dw9768->aac_mode << 5);
251 if (ret < 0)
252 return ret;
253
254 /* Set clock presc */
255 if (dw9768->clock_presc != DW9768_CLOCK_PRE_SCALE_DEFAULT) {
256 ret = dw9768_mod_reg(dw9768, DW9768_AAC_PRESC_REG,
257 DW9768_CLOCK_PRE_SCALE_SEL_MASK,
258 dw9768->clock_presc);
259 if (ret < 0)
260 return ret;
261 }
262
263 /* Set AAC Timing */
264 if (dw9768->aac_timing != DW9768_AAC_TIME_DEFAULT) {
265 ret = i2c_smbus_write_byte_data(client, DW9768_AAC_TIME_REG,
266 dw9768->aac_timing);
267 if (ret < 0)
268 return ret;
269 }
270
271 for (val = dw9768->focus->val % DW9768_MOVE_STEPS;
272 val <= dw9768->focus->val;
273 val += DW9768_MOVE_STEPS) {
274 ret = dw9768_set_dac(dw9768, val);
275 if (ret) {
276 dev_err(&client->dev, "I2C failure: %d", ret);
277 return ret;
278 }
279 usleep_range(dw9768->move_delay_us,
280 dw9768->move_delay_us + 1000);
281 }
282
283 return 0;
284}
285
286static int dw9768_release(struct dw9768 *dw9768)
287{
288 struct i2c_client *client = v4l2_get_subdevdata(&dw9768->sd);
289 int ret, val;
290
291 val = round_down(dw9768->focus->val, DW9768_MOVE_STEPS);
292 for ( ; val >= 0; val -= DW9768_MOVE_STEPS) {
293 ret = dw9768_set_dac(dw9768, val);
294 if (ret) {
295 dev_err(&client->dev, "I2C write fail: %d", ret);
296 return ret;
297 }
298 usleep_range(dw9768->move_delay_us,
299 dw9768->move_delay_us + 1000);
300 }
301
302 ret = i2c_smbus_write_byte_data(client, DW9768_RING_PD_CONTROL_REG,
303 DW9768_PD_MODE_EN);
304 if (ret < 0)
305 return ret;
306
307 /*
308 * DW9769 requires waiting delay time of t_OPR
309 * after PD reset takes place.
310 */
311 usleep_range(DW9768_T_OPR_US, DW9768_T_OPR_US + 100);
312
313 return 0;
314}
315
316static int dw9768_runtime_suspend(struct device *dev)
317{
318 struct i2c_client *client = to_i2c_client(dev);
319 struct v4l2_subdev *sd = i2c_get_clientdata(client);
320 struct dw9768 *dw9768 = sd_to_dw9768(sd);
321
322 dw9768_release(dw9768);
323 regulator_bulk_disable(ARRAY_SIZE(dw9768_supply_names),
324 dw9768->supplies);
325
326 return 0;
327}
328
329static int dw9768_runtime_resume(struct device *dev)
330{
331 struct i2c_client *client = to_i2c_client(dev);
332 struct v4l2_subdev *sd = i2c_get_clientdata(client);
333 struct dw9768 *dw9768 = sd_to_dw9768(sd);
334 int ret;
335
336 ret = regulator_bulk_enable(ARRAY_SIZE(dw9768_supply_names),
337 dw9768->supplies);
338 if (ret < 0) {
339 dev_err(dev, "failed to enable regulators\n");
340 return ret;
341 }
342
343 /*
344 * The datasheet refers to t_OPR that needs to be waited before sending
345 * I2C commands after power-up.
346 */
347 usleep_range(DW9768_T_OPR_US, DW9768_T_OPR_US + 100);
348
349 ret = dw9768_init(dw9768);
350 if (ret < 0)
351 goto disable_regulator;
352
353 return 0;
354
355disable_regulator:
356 regulator_bulk_disable(ARRAY_SIZE(dw9768_supply_names),
357 dw9768->supplies);
358
359 return ret;
360}
361
362static int dw9768_set_ctrl(struct v4l2_ctrl *ctrl)
363{
364 struct dw9768 *dw9768 = container_of(ctrl->handler,
365 struct dw9768, ctrls);
366
367 if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
368 return dw9768_set_dac(dw9768, ctrl->val);
369
370 return 0;
371}
372
373static const struct v4l2_ctrl_ops dw9768_ctrl_ops = {
374 .s_ctrl = dw9768_set_ctrl,
375};
376
377static int dw9768_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
378{
379 int ret;
380
381 ret = pm_runtime_get_sync(sd->dev);
382 if (ret < 0) {
383 pm_runtime_put_noidle(sd->dev);
384 return ret;
385 }
386
387 return 0;
388}
389
390static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
391{
392 pm_runtime_put(sd->dev);
393
394 return 0;
395}
396
397static const struct v4l2_subdev_internal_ops dw9768_int_ops = {
398 .open = dw9768_open,
399 .close = dw9768_close,
400};
401
402static const struct v4l2_subdev_ops dw9768_ops = { };
403
404static int dw9768_init_controls(struct dw9768 *dw9768)
405{
406 struct v4l2_ctrl_handler *hdl = &dw9768->ctrls;
407 const struct v4l2_ctrl_ops *ops = &dw9768_ctrl_ops;
408
409 v4l2_ctrl_handler_init(hdl, 1);
410
411 dw9768->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE, 0,
412 DW9768_MAX_FOCUS_POS,
413 DW9768_FOCUS_STEPS, 0);
414
415 if (hdl->error)
416 return hdl->error;
417
418 dw9768->sd.ctrl_handler = hdl;
419
420 return 0;
421}
422
423static int dw9768_probe(struct i2c_client *client)
424{
425 struct device *dev = &client->dev;
426 struct dw9768 *dw9768;
427 unsigned int i;
428 int ret;
429
430 dw9768 = devm_kzalloc(dev, sizeof(*dw9768), GFP_KERNEL);
431 if (!dw9768)
432 return -ENOMEM;
433
434 /* Initialize subdev */
435 v4l2_i2c_subdev_init(&dw9768->sd, client, &dw9768_ops);
436
437 dw9768->aac_mode = DW9768_AAC_MODE_DEFAULT;
438 dw9768->aac_timing = DW9768_AAC_TIME_DEFAULT;
439 dw9768->clock_presc = DW9768_CLOCK_PRE_SCALE_DEFAULT;
440
441 /* Optional indication of AAC mode select */
442 fwnode_property_read_u32(dev_fwnode(dev), "dongwoon,aac-mode",
443 &dw9768->aac_mode);
444
445 /* Optional indication of clock pre-scale select */
446 fwnode_property_read_u32(dev_fwnode(dev), "dongwoon,clock-presc",
447 &dw9768->clock_presc);
448
449 /* Optional indication of AAC Timing */
450 fwnode_property_read_u32(dev_fwnode(dev), "dongwoon,aac-timing",
451 &dw9768->aac_timing);
452
453 dw9768->move_delay_us = dw9768_cal_move_delay(dw9768->aac_mode,
454 dw9768->clock_presc,
455 dw9768->aac_timing);
456
457 for (i = 0; i < ARRAY_SIZE(dw9768_supply_names); i++)
458 dw9768->supplies[i].supply = dw9768_supply_names[i];
459
460 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dw9768_supply_names),
461 dw9768->supplies);
462 if (ret) {
463 dev_err(dev, "failed to get regulators\n");
464 return ret;
465 }
466
467 /* Initialize controls */
468 ret = dw9768_init_controls(dw9768);
469 if (ret)
470 goto err_free_handler;
471
472 /* Initialize subdev */
473 dw9768->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
474 dw9768->sd.internal_ops = &dw9768_int_ops;
475
476 ret = media_entity_pads_init(&dw9768->sd.entity, 0, NULL);
477 if (ret < 0)
478 goto err_free_handler;
479
480 dw9768->sd.entity.function = MEDIA_ENT_F_LENS;
481
482 pm_runtime_enable(dev);
483 if (!pm_runtime_enabled(dev)) {
484 ret = dw9768_runtime_resume(dev);
485 if (ret < 0) {
486 dev_err(dev, "failed to power on: %d\n", ret);
487 goto err_clean_entity;
488 }
489 }
490
491 ret = v4l2_async_register_subdev(&dw9768->sd);
492 if (ret < 0) {
493 dev_err(dev, "failed to register V4L2 subdev: %d", ret);
494 goto err_power_off;
495 }
496
497 return 0;
498
499err_power_off:
500 if (pm_runtime_enabled(dev))
501 pm_runtime_disable(dev);
502 else
503 dw9768_runtime_suspend(dev);
504err_clean_entity:
505 media_entity_cleanup(&dw9768->sd.entity);
506err_free_handler:
507 v4l2_ctrl_handler_free(&dw9768->ctrls);
508
509 return ret;
510}
511
512static int dw9768_remove(struct i2c_client *client)
513{
514 struct v4l2_subdev *sd = i2c_get_clientdata(client);
515 struct dw9768 *dw9768 = sd_to_dw9768(sd);
516
517 v4l2_async_unregister_subdev(&dw9768->sd);
518 v4l2_ctrl_handler_free(&dw9768->ctrls);
519 media_entity_cleanup(&dw9768->sd.entity);
520 pm_runtime_disable(&client->dev);
521 if (!pm_runtime_status_suspended(&client->dev))
522 dw9768_runtime_suspend(&client->dev);
523 pm_runtime_set_suspended(&client->dev);
524
525 return 0;
526}
527
528static const struct of_device_id dw9768_of_table[] = {
529 { .compatible = "dongwoon,dw9768" },
530 { .compatible = "giantec,gt9769" },
531 {}
532};
533MODULE_DEVICE_TABLE(of, dw9768_of_table);
534
535static const struct dev_pm_ops dw9768_pm_ops = {
536 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
537 pm_runtime_force_resume)
538 SET_RUNTIME_PM_OPS(dw9768_runtime_suspend, dw9768_runtime_resume, NULL)
539};
540
541static struct i2c_driver dw9768_i2c_driver = {
542 .driver = {
543 .name = DW9768_NAME,
544 .pm = &dw9768_pm_ops,
545 .of_match_table = dw9768_of_table,
546 },
547 .probe_new = dw9768_probe,
548 .remove = dw9768_remove,
549};
550module_i2c_driver(dw9768_i2c_driver);
551
552MODULE_AUTHOR("Dongchun Zhu <dongchun.zhu@mediatek.com>");
553MODULE_DESCRIPTION("DW9768 VCM driver");
554MODULE_LICENSE("GPL v2");
drivers/media/i2c/imx290.c+343−61
@@ -25,9 +25,19 @@ · 24 unmodified lines
25#define IMX290_STANDBY 0x300025#define IMX290_STANDBY 0x3000
26#define IMX290_REGHOLD 0x300126#define IMX290_REGHOLD 0x3001
27#define IMX290_XMSTA 0x300227#define IMX290_XMSTA 0x3002
28#define IMX290_FR_FDG_SEL 0x3009
29#define IMX290_BLKLEVEL_LOW 0x300a
30#define IMX290_BLKLEVEL_HIGH 0x300b
28#define IMX290_GAIN 0x301431#define IMX290_GAIN 0x3014
32#define IMX290_HMAX_LOW 0x301c
33#define IMX290_HMAX_HIGH 0x301d
34#define IMX290_PGCTRL 0x308c
35#define IMX290_PHY_LANE_NUM 0x3407
36#define IMX290_CSI_LANE_MODE 0x3443
29 37
30#define IMX290_DEFAULT_LINK_FREQ 44550000038#define IMX290_PGCTRL_REGEN BIT(0)
39#define IMX290_PGCTRL_THRU BIT(1)
40#define IMX290_PGCTRL_MODE(n) ((n) << 4)
31 41
32static const char * const imx290_supply_name[] = {42static const char * const imx290_supply_name[] = {
33 "vdda",43 "vdda",
@@ -45,8 +55,8 @@ struct imx290_regval { · 11 unmodified lines
45struct imx290_mode {55struct imx290_mode {
46 u32 width;56 u32 width;
47 u32 height;57 u32 height;
48 u32 pixel_rate;58 u32 hmax;
49 u32 link_freq_index;59 u8 link_freq_index;
50 60
51 const struct imx290_regval *data;61 const struct imx290_regval *data;
52 u32 data_size;62 u32 data_size;
@@ -56,9 +66,10 @@ struct imx290 { · 3 unmodified lines
56 struct device *dev;66 struct device *dev;
57 struct clk *xclk;67 struct clk *xclk;
58 struct regmap *regmap;68 struct regmap *regmap;
69 u8 nlanes;
70 u8 bpp;
59 71
60 struct v4l2_subdev sd;72 struct v4l2_subdev sd;
61 struct v4l2_fwnode_endpoint ep;
62 struct media_pad pad;73 struct media_pad pad;
63 struct v4l2_mbus_framefmt current_format;74 struct v4l2_mbus_framefmt current_format;
64 const struct imx290_mode *current_mode;75 const struct imx290_mode *current_mode;
@@ -75,10 +86,12 @@ struct imx290 { · 10 unmodified lines
75 86
76struct imx290_pixfmt {87struct imx290_pixfmt {
77 u32 code;88 u32 code;
89 u8 bpp;
78};90};
79 91
80static const struct imx290_pixfmt imx290_formats[] = {92static const struct imx290_pixfmt imx290_formats[] = {
81 { MEDIA_BUS_FMT_SRGGB10_1X10 },93 { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
94 { MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
82};95};
83 96
84static const struct regmap_config imx290_regmap_config = {97static const struct regmap_config imx290_regmap_config = {
@@ -87,16 +100,24 @@ static const struct regmap_config imx290_regmap_config = { · 2 unmodified lines
87 .cache_type = REGCACHE_RBTREE,100 .cache_type = REGCACHE_RBTREE,
88};101};
89 102
103static const char * const imx290_test_pattern_menu[] = {
104 "Disabled",
105 "Sequence Pattern 1",
106 "Horizontal Color-bar Chart",
107 "Vertical Color-bar Chart",
108 "Sequence Pattern 2",
109 "Gradation Pattern 1",
110 "Gradation Pattern 2",
111 "000/555h Toggle Pattern",
112};
113
90static const struct imx290_regval imx290_global_init_settings[] = {114static const struct imx290_regval imx290_global_init_settings[] = {
91 { 0x3007, 0x00 },115 { 0x3007, 0x00 },
92 { 0x3009, 0x00 },
93 { 0x3018, 0x65 },116 { 0x3018, 0x65 },
94 { 0x3019, 0x04 },117 { 0x3019, 0x04 },
95 { 0x301a, 0x00 },118 { 0x301a, 0x00 },
96 { 0x3443, 0x03 },
97 { 0x3444, 0x20 },119 { 0x3444, 0x20 },
98 { 0x3445, 0x25 },120 { 0x3445, 0x25 },
99 { 0x3407, 0x03 },
100 { 0x303a, 0x0c },121 { 0x303a, 0x0c },
101 { 0x3040, 0x00 },122 { 0x3040, 0x00 },
102 { 0x3041, 0x00 },123 { 0x3041, 0x00 },
@@ -169,7 +190,6 @@ static const struct imx290_regval imx290_1080p_settings[] = { · 66 unmodified lines
169 { 0x3164, 0x1a },190 { 0x3164, 0x1a },
170 { 0x3480, 0x49 },191 { 0x3480, 0x49 },
171 /* data rate settings */192 /* data rate settings */
172 { 0x3009, 0x01 },
173 { 0x3405, 0x10 },193 { 0x3405, 0x10 },
174 { 0x3446, 0x57 },194 { 0x3446, 0x57 },
175 { 0x3447, 0x00 },195 { 0x3447, 0x00 },
@@ -187,8 +207,6 @@ static const struct imx290_regval imx290_1080p_settings[] = { · 11 unmodified lines
187 { 0x3453, 0x00 },207 { 0x3453, 0x00 },
188 { 0x3454, 0x17 },208 { 0x3454, 0x17 },
189 { 0x3455, 0x00 },209 { 0x3455, 0x00 },
190 { 0x301c, 0x98 },
191 { 0x301d, 0x08 },
192};210};
193 211
194static const struct imx290_regval imx290_720p_settings[] = {212static const struct imx290_regval imx290_720p_settings[] = {
@@ -210,7 +228,6 @@ static const struct imx290_regval imx290_720p_settings[] = { · 15 unmodified lines
210 { 0x3164, 0x1a },228 { 0x3164, 0x1a },
211 { 0x3480, 0x49 },229 { 0x3480, 0x49 },
212 /* data rate settings */230 /* data rate settings */
213 { 0x3009, 0x01 },
214 { 0x3405, 0x10 },231 { 0x3405, 0x10 },
215 { 0x3446, 0x4f },232 { 0x3446, 0x4f },
216 { 0x3447, 0x00 },233 { 0x3447, 0x00 },
@@ -228,8 +245,6 @@ static const struct imx290_regval imx290_720p_settings[] = { · 11 unmodified lines
228 { 0x3453, 0x00 },245 { 0x3453, 0x00 },
229 { 0x3454, 0x17 },246 { 0x3454, 0x17 },
230 { 0x3455, 0x00 },247 { 0x3455, 0x00 },
231 { 0x301c, 0xe4 },
232 { 0x301d, 0x0c },
233};248};
234 249
235static const struct imx290_regval imx290_10bit_settings[] = {250static const struct imx290_regval imx290_10bit_settings[] = {
@@ -244,31 +259,105 @@ static const struct imx290_regval imx290_10bit_settings[] = { · 8 unmodified lines
244 { 0x300b, 0x00},259 { 0x300b, 0x00},
245};260};
246 261
262static const struct imx290_regval imx290_12bit_settings[] = {
263 { 0x3005, 0x01 },
264 { 0x3046, 0x01 },
265 { 0x3129, 0x00 },
266 { 0x317c, 0x00 },
267 { 0x31ec, 0x0e },
268 { 0x3441, 0x0c },
269 { 0x3442, 0x0c },
270 { 0x300a, 0xf0 },
271 { 0x300b, 0x00 },
272};
273
247/* supported link frequencies */274/* supported link frequencies */
248static const s64 imx290_link_freq[] = {275#define FREQ_INDEX_1080P 0
249 IMX290_DEFAULT_LINK_FREQ,276#define FREQ_INDEX_720P 1
277static const s64 imx290_link_freq_2lanes[] = {
278 [FREQ_INDEX_1080P] = 445500000,
279 [FREQ_INDEX_720P] = 297000000,
250};280};
281static const s64 imx290_link_freq_4lanes[] = {
282 [FREQ_INDEX_1080P] = 222750000,
283 [FREQ_INDEX_720P] = 148500000,
284};
285
286/*
287 * In this function and in the similar ones below We rely on imx290_probe()
288 * to ensure that nlanes is either 2 or 4.
289 */
290static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290)
291{
292 if (imx290->nlanes == 2)
293 return imx290_link_freq_2lanes;
294 else
295 return imx290_link_freq_4lanes;
296}
297
298static inline int imx290_link_freqs_num(const struct imx290 *imx290)
299{
300 if (imx290->nlanes == 2)
301 return ARRAY_SIZE(imx290_link_freq_2lanes);
302 else
303 return ARRAY_SIZE(imx290_link_freq_4lanes);
304}
251 305
252/* Mode configs */306/* Mode configs */
253static const struct imx290_mode imx290_modes[] = {307static const struct imx290_mode imx290_modes_2lanes[] = {
308 {
309 .width = 1920,
310 .height = 1080,
311 .hmax = 0x1130,
312 .link_freq_index = FREQ_INDEX_1080P,
313 .data = imx290_1080p_settings,
314 .data_size = ARRAY_SIZE(imx290_1080p_settings),
315 },
316 {
317 .width = 1280,
318 .height = 720,
319 .hmax = 0x19c8,
320 .link_freq_index = FREQ_INDEX_720P,
321 .data = imx290_720p_settings,
322 .data_size = ARRAY_SIZE(imx290_720p_settings),
323 },
324};
325
326static const struct imx290_mode imx290_modes_4lanes[] = {
254 {327 {
255 .width = 1920,328 .width = 1920,
256 .height = 1080,329 .height = 1080,
330 .hmax = 0x0898,
331 .link_freq_index = FREQ_INDEX_1080P,
257 .data = imx290_1080p_settings,332 .data = imx290_1080p_settings,
258 .data_size = ARRAY_SIZE(imx290_1080p_settings),333 .data_size = ARRAY_SIZE(imx290_1080p_settings),
259 .pixel_rate = 178200000,
260 .link_freq_index = 0,
261 },334 },
262 {335 {
263 .width = 1280,336 .width = 1280,
264 .height = 720,337 .height = 720,
338 .hmax = 0x0ce4,
339 .link_freq_index = FREQ_INDEX_720P,
265 .data = imx290_720p_settings,340 .data = imx290_720p_settings,
266 .data_size = ARRAY_SIZE(imx290_720p_settings),341 .data_size = ARRAY_SIZE(imx290_720p_settings),
267 .pixel_rate = 178200000,
268 .link_freq_index = 0,
269 },342 },
270};343};
271 344
345static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
346{
347 if (imx290->nlanes == 2)
348 return imx290_modes_2lanes;
349 else
350 return imx290_modes_4lanes;
351}
352
353static inline int imx290_modes_num(const struct imx290 *imx290)
354{
355 if (imx290->nlanes == 2)
356 return ARRAY_SIZE(imx290_modes_2lanes);
357 else
358 return ARRAY_SIZE(imx290_modes_4lanes);
359}
360
272static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)361static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
273{362{
274 return container_of(_sd, struct imx290, sd);363 return container_of(_sd, struct imx290, sd);
@@ -314,11 +403,11 @@ static int imx290_set_register_array(struct imx290 *imx290, · 39 unmodified lines
314 ret = imx290_write_reg(imx290, settings->reg, settings->val);403 ret = imx290_write_reg(imx290, settings->reg, settings->val);
315 if (ret < 0)404 if (ret < 0)
316 return ret;405 return ret;
317
318 /* Settle time is 10ms for all registers */
319 msleep(10);
320 }406 }
321 407
408 /* Provide 10ms settle time */
409 usleep_range(10000, 11000);
410
322 return 0;411 return 0;
323}412}
324 413
@@ -391,6 +480,27 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) · 66 unmodified lines
391 case V4L2_CID_GAIN:480 case V4L2_CID_GAIN:
392 ret = imx290_set_gain(imx290, ctrl->val);481 ret = imx290_set_gain(imx290, ctrl->val);
393 break;482 break;
483 case V4L2_CID_TEST_PATTERN:
484 if (ctrl->val) {
485 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00);
486 imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00);
487 usleep_range(10000, 11000);
488 imx290_write_reg(imx290, IMX290_PGCTRL,
489 (u8)(IMX290_PGCTRL_REGEN |
490 IMX290_PGCTRL_THRU |
491 IMX290_PGCTRL_MODE(ctrl->val)));
492 } else {
493 imx290_write_reg(imx290, IMX290_PGCTRL, 0x00);
494 usleep_range(10000, 11000);
495 if (imx290->bpp == 10)
496 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW,
497 0x3c);
498 else /* 12 bits per pixel */
499 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW,
500 0xf0);
501 imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00);
502 }
503 break;
394 default:504 default:
395 ret = -EINVAL;505 ret = -EINVAL;
396 break;506 break;
@@ -417,6 +527,28 @@ static int imx290_enum_mbus_code(struct v4l2_subdev *sd, · 20 unmodified lines
417 return 0;527 return 0;
418}528}
419 529
530static int imx290_enum_frame_size(struct v4l2_subdev *sd,
531 struct v4l2_subdev_pad_config *cfg,
532 struct v4l2_subdev_frame_size_enum *fse)
533{
534 const struct imx290 *imx290 = to_imx290(sd);
535 const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290);
536
537 if ((fse->code != imx290_formats[0].code) &&
538 (fse->code != imx290_formats[1].code))
539 return -EINVAL;
540
541 if (fse->index >= imx290_modes_num(imx290))
542 return -EINVAL;
543
544 fse->min_width = imx290_modes[fse->index].width;
545 fse->max_width = imx290_modes[fse->index].width;
546 fse->min_height = imx290_modes[fse->index].height;
547 fse->max_height = imx290_modes[fse->index].height;
548
549 return 0;
550}
551
420static int imx290_get_fmt(struct v4l2_subdev *sd,552static int imx290_get_fmt(struct v4l2_subdev *sd,
421 struct v4l2_subdev_pad_config *cfg,553 struct v4l2_subdev_pad_config *cfg,
422 struct v4l2_subdev_format *fmt)554 struct v4l2_subdev_format *fmt)
@@ -439,6 +571,30 @@ static int imx290_get_fmt(struct v4l2_subdev *sd, · 16 unmodified lines
439 return 0;571 return 0;
440}572}
441 573
574static inline u8 imx290_get_link_freq_index(struct imx290 *imx290)
575{
576 return imx290->current_mode->link_freq_index;
577}
578
579static s64 imx290_get_link_freq(struct imx290 *imx290)
580{
581 u8 index = imx290_get_link_freq_index(imx290);
582
583 return *(imx290_link_freqs_ptr(imx290) + index);
584}
585
586static u64 imx290_calc_pixel_rate(struct imx290 *imx290)
587{
588 s64 link_freq = imx290_get_link_freq(imx290);
589 u8 nlanes = imx290->nlanes;
590 u64 pixel_rate;
591
592 /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
593 pixel_rate = link_freq * 2 * nlanes;
594 do_div(pixel_rate, imx290->bpp);
595 return pixel_rate;
596}
597
442static int imx290_set_fmt(struct v4l2_subdev *sd,598static int imx290_set_fmt(struct v4l2_subdev *sd,
443 struct v4l2_subdev_pad_config *cfg,599 struct v4l2_subdev_pad_config *cfg,
444 struct v4l2_subdev_format *fmt)600 struct v4l2_subdev_format *fmt)
@@ -450,9 +606,8 @@ static int imx290_set_fmt(struct v4l2_subdev *sd, · 5 unmodified lines
450 606
451 mutex_lock(&imx290->lock);607 mutex_lock(&imx290->lock);
452 608
453 mode = v4l2_find_nearest_size(imx290_modes,609 mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290),
454 ARRAY_SIZE(imx290_modes),610 imx290_modes_num(imx290), width, height,
455 width, height,
456 fmt->format.width, fmt->format.height);611 fmt->format.width, fmt->format.height);
457 612
458 fmt->format.width = mode->width;613 fmt->format.width = mode->width;
@@ -472,10 +627,15 @@ static int imx290_set_fmt(struct v4l2_subdev *sd, · 13 unmodified lines
472 format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);627 format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
473 } else {628 } else {
474 format = &imx290->current_format;629 format = &imx290->current_format;
475 __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
476 __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, mode->pixel_rate);
477
478 imx290->current_mode = mode;630 imx290->current_mode = mode;
631 imx290->bpp = imx290_formats[i].bpp;
632
633 if (imx290->link_freq)
634 __v4l2_ctrl_s_ctrl(imx290->link_freq,
635 imx290_get_link_freq_index(imx290));
636 if (imx290->pixel_rate)
637 __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate,
638 imx290_calc_pixel_rate(imx290));
479 }639 }
480 640
481 *format = fmt->format;641 *format = fmt->format;
@@ -499,12 +659,11 @@ static int imx290_entity_init_cfg(struct v4l2_subdev *subdev, · 17 unmodified lines
499 return 0;659 return 0;
500}660}
501 661
502static int imx290_write_current_format(struct imx290 *imx290,662static int imx290_write_current_format(struct imx290 *imx290)
503 struct v4l2_mbus_framefmt *format)
504{663{
505 int ret;664 int ret;
506 665
507 switch (format->code) {666 switch (imx290->current_format.code) {
508 case MEDIA_BUS_FMT_SRGGB10_1X10:667 case MEDIA_BUS_FMT_SRGGB10_1X10:
509 ret = imx290_set_register_array(imx290, imx290_10bit_settings,668 ret = imx290_set_register_array(imx290, imx290_10bit_settings,
510 ARRAY_SIZE(669 ARRAY_SIZE(
@@ -514,6 +673,15 @@ static int imx290_write_current_format(struct imx290 *imx290, · 3 unmodified lines
514 return ret;673 return ret;
515 }674 }
516 break;675 break;
676 case MEDIA_BUS_FMT_SRGGB12_1X12:
677 ret = imx290_set_register_array(imx290, imx290_12bit_settings,
678 ARRAY_SIZE(
679 imx290_12bit_settings));
680 if (ret < 0) {
681 dev_err(imx290->dev, "Could not set format registers\n");
682 return ret;
683 }
684 break;
517 default:685 default:
518 dev_err(imx290->dev, "Unknown pixel format\n");686 dev_err(imx290->dev, "Unknown pixel format\n");
519 return -EINVAL;687 return -EINVAL;
@@ -522,6 +690,25 @@ static int imx290_write_current_format(struct imx290 *imx290, · 2 unmodified lines
522 return 0;690 return 0;
523}691}
524 692
693static int imx290_set_hmax(struct imx290 *imx290, u32 val)
694{
695 int ret;
696
697 ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff));
698 if (ret) {
699 dev_err(imx290->dev, "Error setting HMAX register\n");
700 return ret;
701 }
702
703 ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff));
704 if (ret) {
705 dev_err(imx290->dev, "Error setting HMAX register\n");
706 return ret;
707 }
708
709 return 0;
710}
711
525/* Start streaming */712/* Start streaming */
526static int imx290_start_streaming(struct imx290 *imx290)713static int imx290_start_streaming(struct imx290 *imx290)
527{714{
@@ -536,8 +723,8 @@ static int imx290_start_streaming(struct imx290 *imx290) · 8 unmodified lines
536 return ret;723 return ret;
537 }724 }
538 725
539 /* Set current frame format */726 /* Apply the register values related to current frame format */
540 ret = imx290_write_current_format(imx290, &imx290->current_format);727 ret = imx290_write_current_format(imx290);
541 if (ret < 0) {728 if (ret < 0) {
542 dev_err(imx290->dev, "Could not set frame format\n");729 dev_err(imx290->dev, "Could not set frame format\n");
543 return ret;730 return ret;
@@ -550,6 +737,9 @@ static int imx290_start_streaming(struct imx290 *imx290) · 6 unmodified lines
550 dev_err(imx290->dev, "Could not set current mode\n");737 dev_err(imx290->dev, "Could not set current mode\n");
551 return ret;738 return ret;
552 }739 }
740 ret = imx290_set_hmax(imx290, imx290->current_mode->hmax);
741 if (ret < 0)
742 return ret;
553 743
554 /* Apply customized values from user */744 /* Apply customized values from user */
555 ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);745 ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
@@ -607,6 +797,49 @@ static int imx290_get_regulators(struct device *dev, struct imx290 *imx290) · 51 unmodified lines
607 imx290->supplies);797 imx290->supplies);
608}798}
609 799
800static int imx290_set_data_lanes(struct imx290 *imx290)
801{
802 int ret = 0, laneval, frsel;
803
804 switch (imx290->nlanes) {
805 case 2:
806 laneval = 0x01;
807 frsel = 0x02;
808 break;
809 case 4:
810 laneval = 0x03;
811 frsel = 0x01;
812 break;
813 default:
814 /*
815 * We should never hit this since the data lane count is
816 * validated in probe itself
817 */
818 dev_err(imx290->dev, "Lane configuration not supported\n");
819 ret = -EINVAL;
820 goto exit;
821 }
822
823 ret = imx290_write_reg(imx290, IMX290_PHY_LANE_NUM, laneval);
824 if (ret) {
825 dev_err(imx290->dev, "Error setting Physical Lane number register\n");
826 goto exit;
827 }
828
829 ret = imx290_write_reg(imx290, IMX290_CSI_LANE_MODE, laneval);
830 if (ret) {
831 dev_err(imx290->dev, "Error setting CSI Lane mode register\n");
832 goto exit;
833 }
834
835 ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, frsel);
836 if (ret)
837 dev_err(imx290->dev, "Error setting FR/FDG SEL register\n");
838
839exit:
840 return ret;
841}
842
610static int imx290_power_on(struct device *dev)843static int imx290_power_on(struct device *dev)
611{844{
612 struct i2c_client *client = to_i2c_client(dev);845 struct i2c_client *client = to_i2c_client(dev);
@@ -628,9 +861,12 @@ static int imx290_power_on(struct device *dev) · 15 unmodified lines
628 }861 }
629 862
630 usleep_range(1, 2);863 usleep_range(1, 2);
631 gpiod_set_value_cansleep(imx290->rst_gpio, 1);864 gpiod_set_value_cansleep(imx290->rst_gpio, 0);
632 usleep_range(30000, 31000);865 usleep_range(30000, 31000);
633 866
867 /* Set data lane count */
868 imx290_set_data_lanes(imx290);
869
634 return 0;870 return 0;
635}871}
636 872
@@ -641,14 +877,14 @@ static int imx290_power_off(struct device *dev) · 4 unmodified lines
641 struct imx290 *imx290 = to_imx290(sd);877 struct imx290 *imx290 = to_imx290(sd);
642 878
643 clk_disable_unprepare(imx290->xclk);879 clk_disable_unprepare(imx290->xclk);
644 gpiod_set_value_cansleep(imx290->rst_gpio, 0);880 gpiod_set_value_cansleep(imx290->rst_gpio, 1);
645 regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies);881 regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies);
646 882
647 return 0;883 return 0;
648}884}
649 885
650static const struct dev_pm_ops imx290_pm_ops = {886static const struct dev_pm_ops imx290_pm_ops = {
651 SET_RUNTIME_PM_OPS(imx290_power_on, imx290_power_off, NULL)887 SET_RUNTIME_PM_OPS(imx290_power_off, imx290_power_on, NULL)
652};888};
653 889
654static const struct v4l2_subdev_video_ops imx290_video_ops = {890static const struct v4l2_subdev_video_ops imx290_video_ops = {
@@ -658,6 +894,7 @@ static const struct v4l2_subdev_video_ops imx290_video_ops = { · 3 unmodified lines
658static const struct v4l2_subdev_pad_ops imx290_pad_ops = {894static const struct v4l2_subdev_pad_ops imx290_pad_ops = {
659 .init_cfg = imx290_entity_init_cfg,895 .init_cfg = imx290_entity_init_cfg,
660 .enum_mbus_code = imx290_enum_mbus_code,896 .enum_mbus_code = imx290_enum_mbus_code,
897 .enum_frame_size = imx290_enum_frame_size,
661 .get_fmt = imx290_get_fmt,898 .get_fmt = imx290_get_fmt,
662 .set_fmt = imx290_set_fmt,899 .set_fmt = imx290_set_fmt,
663};900};
@@ -671,12 +908,39 @@ static const struct media_entity_operations imx290_subdev_entity_ops = { · 7 unmodified lines
671 .link_validate = v4l2_subdev_link_validate,908 .link_validate = v4l2_subdev_link_validate,
672};909};
673 910
911/*
912 * Returns 0 if all link frequencies used by the driver for the given number
913 * of MIPI data lanes are mentioned in the device tree, or the value of the
914 * first missing frequency otherwise.
915 */
916static s64 imx290_check_link_freqs(const struct imx290 *imx290,
917 const struct v4l2_fwnode_endpoint *ep)
918{
919 int i, j;
920 const s64 *freqs = imx290_link_freqs_ptr(imx290);
921 int freqs_count = imx290_link_freqs_num(imx290);
922
923 for (i = 0; i < freqs_count; i++) {
924 for (j = 0; j < ep->nr_of_link_frequencies; j++)
925 if (freqs[i] == ep->link_frequencies[j])
926 break;
927 if (j == ep->nr_of_link_frequencies)
928 return freqs[i];
929 }
930 return 0;
931}
932
674static int imx290_probe(struct i2c_client *client)933static int imx290_probe(struct i2c_client *client)
675{934{
676 struct device *dev = &client->dev;935 struct device *dev = &client->dev;
677 struct fwnode_handle *endpoint;936 struct fwnode_handle *endpoint;
937 /* Only CSI2 is supported for now: */
938 struct v4l2_fwnode_endpoint ep = {
939 .bus_type = V4L2_MBUS_CSI2_DPHY
940 };
678 struct imx290 *imx290;941 struct imx290 *imx290;
679 u32 xclk_freq;942 u32 xclk_freq;
943 s64 fq;
680 int ret;944 int ret;
681 945
682 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);946 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
@@ -696,35 +960,40 @@ static int imx290_probe(struct i2c_client *client) · 13 unmodified lines
696 return -EINVAL;960 return -EINVAL;
697 }961 }
698 962
699 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &imx290->ep);963 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
700 fwnode_handle_put(endpoint);964 fwnode_handle_put(endpoint);
701 if (ret) {965 if (ret == -ENXIO) {
966 dev_err(dev, "Unsupported bus type, should be CSI2\n");
967 goto free_err;
968 } else if (ret) {
702 dev_err(dev, "Parsing endpoint node failed\n");969 dev_err(dev, "Parsing endpoint node failed\n");
703 goto free_err;970 goto free_err;
704 }971 }
705 972
706 if (!imx290->ep.nr_of_link_frequencies) {973 /* Get number of data lanes */
707 dev_err(dev, "link-frequency property not found in DT\n");974 imx290->nlanes = ep.bus.mipi_csi2.num_data_lanes;
975 if (imx290->nlanes != 2 && imx290->nlanes != 4) {
976 dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes);
708 ret = -EINVAL;977 ret = -EINVAL;
709 goto free_err;978 goto free_err;
710 }979 }
711 980
712 if (imx290->ep.link_frequencies[0] != IMX290_DEFAULT_LINK_FREQ) {981 dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes);
713 dev_err(dev, "Unsupported link frequency\n");982
983 if (!ep.nr_of_link_frequencies) {
984 dev_err(dev, "link-frequency property not found in DT\n");
714 ret = -EINVAL;985 ret = -EINVAL;
715 goto free_err;986 goto free_err;
716 }987 }
717 988
718 /* Only CSI2 is supported for now */989 /* Check that link frequences for all the modes are in device tree */
719 if (imx290->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {990 fq = imx290_check_link_freqs(imx290, &ep);
720 dev_err(dev, "Unsupported bus type, should be CSI2\n");991 if (fq) {
992 dev_err(dev, "Link frequency of %lld is not supported\n", fq);
721 ret = -EINVAL;993 ret = -EINVAL;
722 goto free_err;994 goto free_err;
723 }995 }
724 996
725 /* Set default mode to max resolution */
726 imx290->current_mode = &imx290_modes[0];
727
728 /* get system clock (xclk) */997 /* get system clock (xclk) */
729 imx290->xclk = devm_clk_get(dev, "xclk");998 imx290->xclk = devm_clk_get(dev, "xclk");
730 if (IS_ERR(imx290->xclk)) {999 if (IS_ERR(imx290->xclk)) {
@@ -760,7 +1029,8 @@ static int imx290_probe(struct i2c_client *client) · 29 unmodified lines
760 goto free_err;1029 goto free_err;
761 }1030 }
762 1031
763 imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);1032 imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset",
1033 GPIOD_OUT_HIGH);
764 if (IS_ERR(imx290->rst_gpio)) {1034 if (IS_ERR(imx290->rst_gpio)) {
765 dev_err(dev, "Cannot get reset gpio\n");1035 dev_err(dev, "Cannot get reset gpio\n");
766 ret = PTR_ERR(imx290->rst_gpio);1036 ret = PTR_ERR(imx290->rst_gpio);
@@ -769,23 +1039,35 @@ static int imx290_probe(struct i2c_client *client) · 2 unmodified lines
769 1039
770 mutex_init(&imx290->lock);1040 mutex_init(&imx290->lock);
771 1041
772 v4l2_ctrl_handler_init(&imx290->ctrls, 3);1042 /*
1043 * Initialize the frame format. In particular, imx290->current_mode
1044 * and imx290->bpp are set to defaults: imx290_calc_pixel_rate() call
1045 * below relies on these fields.
1046 */
1047 imx290_entity_init_cfg(&imx290->sd, NULL);
1048
1049 v4l2_ctrl_handler_init(&imx290->ctrls, 4);
773 1050
774 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,1051 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
775 V4L2_CID_GAIN, 0, 72, 1, 0);1052 V4L2_CID_GAIN, 0, 72, 1, 0);
1053
776 imx290->link_freq =1054 imx290->link_freq =
777 v4l2_ctrl_new_int_menu(&imx290->ctrls,1055 v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
778 &imx290_ctrl_ops,
779 V4L2_CID_LINK_FREQ,1056 V4L2_CID_LINK_FREQ,
780 ARRAY_SIZE(imx290_link_freq) - 1,1057 imx290_link_freqs_num(imx290) - 1, 0,
781 0, imx290_link_freq);1058 imx290_link_freqs_ptr(imx290));
782 if (imx290->link_freq)1059 if (imx290->link_freq)
783 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;1060 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
784 1061
785 imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,1062 imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
786 V4L2_CID_PIXEL_RATE, 1,1063 V4L2_CID_PIXEL_RATE,
787 INT_MAX, 1,1064 1, INT_MAX, 1,
788 imx290_modes[0].pixel_rate);1065 imx290_calc_pixel_rate(imx290));
1066
1067 v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops,
1068 V4L2_CID_TEST_PATTERN,
1069 ARRAY_SIZE(imx290_test_pattern_menu) - 1,
1070 0, 0, imx290_test_pattern_menu);
789 1071
790 imx290->sd.ctrl_handler = &imx290->ctrls;1072 imx290->sd.ctrl_handler = &imx290->ctrls;
791 1073
@@ -826,7 +1108,7 @@ static int imx290_probe(struct i2c_client *client) · 34 unmodified lines
826 pm_runtime_enable(dev);1108 pm_runtime_enable(dev);
827 pm_runtime_idle(dev);1109 pm_runtime_idle(dev);
828 1110
829 v4l2_fwnode_endpoint_free(&imx290->ep);1111 v4l2_fwnode_endpoint_free(&ep);
830 1112
831 return 0;1113 return 0;
832 1114
@@ -836,7 +1118,7 @@ free_ctrl: · 3 unmodified lines
836 v4l2_ctrl_handler_free(&imx290->ctrls);1118 v4l2_ctrl_handler_free(&imx290->ctrls);
837 mutex_destroy(&imx290->lock);1119 mutex_destroy(&imx290->lock);
838free_err:1120free_err:
839 v4l2_fwnode_endpoint_free(&imx290->ep);1121 v4l2_fwnode_endpoint_free(&ep);
840 1122
841 return ret;1123 return ret;
842}1124}
drivers/media/i2c/max9271.c+341−0
@@ -0,0 +1,341 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017-2020 Jacopo Mondi
4 * Copyright (C) 2017-2020 Kieran Bingham
5 * Copyright (C) 2017-2020 Laurent Pinchart
6 * Copyright (C) 2017-2020 Niklas Söderlund
7 * Copyright (C) 2016 Renesas Electronics Corporation
8 * Copyright (C) 2015 Cogent Embedded, Inc.
9 *
10 * This file exports functions to control the Maxim MAX9271 GMSL serializer
11 * chip. This is not a self-contained driver, as MAX9271 is usually embedded in
12 * camera modules with at least one image sensor and optional additional
13 * components, such as uController units or ISPs/DSPs.
14 *
15 * Drivers for the camera modules (i.e. rdacm20/21) are expected to use
16 * functions exported from this library driver to maximize code re-use.
17 */
18
19#include <linux/delay.h>
20#include <linux/i2c.h>
21
22#include "max9271.h"
23
24static int max9271_read(struct max9271_device *dev, u8 reg)
25{
26 int ret;
27
28 dev_dbg(&dev->client->dev, "%s(0x%02x)\n", __func__, reg);
29
30 ret = i2c_smbus_read_byte_data(dev->client, reg);
31 if (ret < 0)
32 dev_dbg(&dev->client->dev,
33 "%s: register 0x%02x read failed (%d)\n",
34 __func__, reg, ret);
35
36 return ret;
37}
38
39static int max9271_write(struct max9271_device *dev, u8 reg, u8 val)
40{
41 int ret;
42
43 dev_dbg(&dev->client->dev, "%s(0x%02x, 0x%02x)\n", __func__, reg, val);
44
45 ret = i2c_smbus_write_byte_data(dev->client, reg, val);
46 if (ret < 0)
47 dev_err(&dev->client->dev,
48 "%s: register 0x%02x write failed (%d)\n",
49 __func__, reg, ret);
50
51 return ret;
52}
53
54/*
55 * max9271_pclk_detect() - Detect valid pixel clock from image sensor
56 *
57 * Wait up to 10ms for a valid pixel clock.
58 *
59 * Returns 0 for success, < 0 for pixel clock not properly detected
60 */
61static int max9271_pclk_detect(struct max9271_device *dev)
62{
63 unsigned int i;
64 int ret;
65
66 for (i = 0; i < 100; i++) {
67 ret = max9271_read(dev, 0x15);
68 if (ret < 0)
69 return ret;
70
71 if (ret & MAX9271_PCLKDET)
72 return 0;
73
74 usleep_range(50, 100);
75 }
76
77 dev_err(&dev->client->dev, "Unable to detect valid pixel clock\n");
78
79 return -EIO;
80}
81
82int max9271_set_serial_link(struct max9271_device *dev, bool enable)
83{
84 int ret;
85 u8 val = MAX9271_REVCCEN | MAX9271_FWDCCEN;
86
87 if (enable) {
88 ret = max9271_pclk_detect(dev);
89 if (ret)
90 return ret;
91
92 val |= MAX9271_SEREN;
93 } else {
94 val |= MAX9271_CLINKEN;
95 }
96
97 /*
98 * The serializer temporarily disables the reverse control channel for
99 * 350µs after starting/stopping the forward serial link, but the
100 * deserializer synchronization time isn't clearly documented.
101 *
102 * According to the serializer datasheet we should wait 3ms, while
103 * according to the deserializer datasheet we should wait 5ms.
104 *
105 * Short delays here appear to show bit-errors in the writes following.
106 * Therefore a conservative delay seems best here.
107 */
108 max9271_write(dev, 0x04, val);
109 usleep_range(5000, 8000);
110
111 return 0;
112}
113EXPORT_SYMBOL_GPL(max9271_set_serial_link);
114
115int max9271_configure_i2c(struct max9271_device *dev, u8 i2c_config)
116{
117 int ret;
118
119 ret = max9271_write(dev, 0x0d, i2c_config);
120 if (ret)
121 return ret;
122
123 /* The delay required after an I2C bus configuration change is not
124 * characterized in the serializer manual. Sleep up to 5msec to
125 * stay safe.
126 */
127 usleep_range(3500, 5000);
128
129 return 0;
130}
131EXPORT_SYMBOL_GPL(max9271_configure_i2c);
132
133int max9271_set_high_threshold(struct max9271_device *dev, bool enable)
134{
135 int ret;
136
137 ret = max9271_read(dev, 0x08);
138 if (ret < 0)
139 return ret;
140
141 /*
142 * Enable or disable reverse channel high threshold to increase
143 * immunity to power supply noise.
144 */
145 max9271_write(dev, 0x08, enable ? ret | BIT(0) : ret & ~BIT(0));
146 usleep_range(2000, 2500);
147
148 return 0;
149}
150EXPORT_SYMBOL_GPL(max9271_set_high_threshold);
151
152int max9271_configure_gmsl_link(struct max9271_device *dev)
153{
154 /*
155 * Configure the GMSL link:
156 *
157 * - Double input mode, high data rate, 24-bit mode
158 * - Latch input data on PCLKIN rising edge
159 * - Enable HS/VS encoding
160 * - 1-bit parity error detection
161 *
162 * TODO: Make the GMSL link configuration parametric.
163 */
164 max9271_write(dev, 0x07, MAX9271_DBL | MAX9271_HVEN |
165 MAX9271_EDC_1BIT_PARITY);
166 usleep_range(5000, 8000);
167
168 /*
169 * Adjust spread spectrum to +4% and auto-detect pixel clock
170 * and serial link rate.
171 */
172 max9271_write(dev, 0x02, MAX9271_SPREAD_SPECT_4 | MAX9271_R02_RES |
173 MAX9271_PCLK_AUTODETECT | MAX9271_SERIAL_AUTODETECT);
174 usleep_range(5000, 8000);
175
176 return 0;
177}
178EXPORT_SYMBOL_GPL(max9271_configure_gmsl_link);
179
180int max9271_set_gpios(struct max9271_device *dev, u8 gpio_mask)
181{
182 int ret;
183
184 ret = max9271_read(dev, 0x0f);
185 if (ret < 0)
186 return 0;
187
188 ret |= gpio_mask;
189 ret = max9271_write(dev, 0x0f, ret);
190 if (ret < 0) {
191 dev_err(&dev->client->dev, "Failed to set gpio (%d)\n", ret);
192 return ret;
193 }
194
195 usleep_range(3500, 5000);
196
197 return 0;
198}
199EXPORT_SYMBOL_GPL(max9271_set_gpios);
200
201int max9271_clear_gpios(struct max9271_device *dev, u8 gpio_mask)
202{
203 int ret;
204
205 ret = max9271_read(dev, 0x0f);
206 if (ret < 0)
207 return 0;
208
209 ret &= ~gpio_mask;
210 ret = max9271_write(dev, 0x0f, ret);
211 if (ret < 0) {
212 dev_err(&dev->client->dev, "Failed to clear gpio (%d)\n", ret);
213 return ret;
214 }
215
216 usleep_range(3500, 5000);
217
218 return 0;
219}
220EXPORT_SYMBOL_GPL(max9271_clear_gpios);
221
222int max9271_enable_gpios(struct max9271_device *dev, u8 gpio_mask)
223{
224 int ret;
225
226 ret = max9271_read(dev, 0x0f);
227 if (ret < 0)
228 return 0;
229
230 /* BIT(0) reserved: GPO is always enabled. */
231 ret |= gpio_mask | BIT(0);
232 ret = max9271_write(dev, 0x0e, ret);
233 if (ret < 0) {
234 dev_err(&dev->client->dev, "Failed to enable gpio (%d)\n", ret);
235 return ret;
236 }
237
238 usleep_range(3500, 5000);
239
240 return 0;
241}
242EXPORT_SYMBOL_GPL(max9271_enable_gpios);
243
244int max9271_disable_gpios(struct max9271_device *dev, u8 gpio_mask)
245{
246 int ret;
247
248 ret = max9271_read(dev, 0x0f);
249 if (ret < 0)
250 return 0;
251
252 /* BIT(0) reserved: GPO cannot be disabled */
253 ret &= (~gpio_mask | BIT(0));
254 ret = max9271_write(dev, 0x0e, ret);
255 if (ret < 0) {
256 dev_err(&dev->client->dev, "Failed to disable gpio (%d)\n", ret);
257 return ret;
258 }
259
260 usleep_range(3500, 5000);
261
262 return 0;
263}
264EXPORT_SYMBOL_GPL(max9271_disable_gpios);
265
266int max9271_verify_id(struct max9271_device *dev)
267{
268 int ret;
269
270 ret = max9271_read(dev, 0x1e);
271 if (ret < 0) {
272 dev_err(&dev->client->dev, "MAX9271 ID read failed (%d)\n",
273 ret);
274 return ret;
275 }
276
277 if (ret != MAX9271_ID) {
278 dev_err(&dev->client->dev, "MAX9271 ID mismatch (0x%02x)\n",
279 ret);
280 return -ENXIO;
281 }
282
283 return 0;
284}
285EXPORT_SYMBOL_GPL(max9271_verify_id);
286
287int max9271_set_address(struct max9271_device *dev, u8 addr)
288{
289 int ret;
290
291 ret = max9271_write(dev, 0x00, addr << 1);
292 if (ret < 0) {
293 dev_err(&dev->client->dev,
294 "MAX9271 I2C address change failed (%d)\n", ret);
295 return ret;
296 }
297 usleep_range(3500, 5000);
298
299 return 0;
300}
301EXPORT_SYMBOL_GPL(max9271_set_address);
302
303int max9271_set_deserializer_address(struct max9271_device *dev, u8 addr)
304{
305 int ret;
306
307 ret = max9271_write(dev, 0x01, addr << 1);
308 if (ret < 0) {
309 dev_err(&dev->client->dev,
310 "MAX9271 deserializer address set failed (%d)\n", ret);
311 return ret;
312 }
313 usleep_range(3500, 5000);
314
315 return 0;
316}
317EXPORT_SYMBOL_GPL(max9271_set_deserializer_address);
318
319int max9271_set_translation(struct max9271_device *dev, u8 source, u8 dest)
320{
321 int ret;
322
323 ret = max9271_write(dev, 0x09, source << 1);
324 if (ret < 0) {
325 dev_err(&dev->client->dev,
326 "MAX9271 I2C translation setup failed (%d)\n", ret);
327 return ret;
328 }
329 usleep_range(3500, 5000);
330
331 ret = max9271_write(dev, 0x0a, dest << 1);
332 if (ret < 0) {
333 dev_err(&dev->client->dev,
334 "MAX9271 I2C translation setup failed (%d)\n", ret);
335 return ret;
336 }
337 usleep_range(3500, 5000);
338
339 return 0;
340}
341EXPORT_SYMBOL_GPL(max9271_set_translation);
drivers/media/i2c/max9271.h+224−0
@@ -0,0 +1,224 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2017-2020 Jacopo Mondi
4 * Copyright (C) 2017-2020 Kieran Bingham
5 * Copyright (C) 2017-2020 Laurent Pinchart
6 * Copyright (C) 2017-2020 Niklas Söderlund
7 * Copyright (C) 2016 Renesas Electronics Corporation
8 * Copyright (C) 2015 Cogent Embedded, Inc.
9 */
10
11#include <linux/i2c.h>
12
13#define MAX9271_DEFAULT_ADDR 0x40
14
15/* Register 0x02 */
16#define MAX9271_SPREAD_SPECT_0 (0 << 5)
17#define MAX9271_SPREAD_SPECT_05 (1 << 5)
18#define MAX9271_SPREAD_SPECT_15 (2 << 5)
19#define MAX9271_SPREAD_SPECT_1 (5 << 5)
20#define MAX9271_SPREAD_SPECT_2 (3 << 5)
21#define MAX9271_SPREAD_SPECT_3 (6 << 5)
22#define MAX9271_SPREAD_SPECT_4 (7 << 5)
23#define MAX9271_R02_RES BIT(4)
24#define MAX9271_PCLK_AUTODETECT (3 << 2)
25#define MAX9271_SERIAL_AUTODETECT (0x03)
26/* Register 0x04 */
27#define MAX9271_SEREN BIT(7)
28#define MAX9271_CLINKEN BIT(6)
29#define MAX9271_PRBSEN BIT(5)
30#define MAX9271_SLEEP BIT(4)
31#define MAX9271_INTTYPE_I2C (0 << 2)
32#define MAX9271_INTTYPE_UART (1 << 2)
33#define MAX9271_INTTYPE_NONE (2 << 2)
34#define MAX9271_REVCCEN BIT(1)
35#define MAX9271_FWDCCEN BIT(0)
36/* Register 0x07 */
37#define MAX9271_DBL BIT(7)
38#define MAX9271_DRS BIT(6)
39#define MAX9271_BWS BIT(5)
40#define MAX9271_ES BIT(4)
41#define MAX9271_HVEN BIT(2)
42#define MAX9271_EDC_1BIT_PARITY (0 << 0)
43#define MAX9271_EDC_6BIT_CRC (1 << 0)
44#define MAX9271_EDC_6BIT_HAMMING (2 << 0)
45/* Register 0x08 */
46#define MAX9271_INVVS BIT(7)
47#define MAX9271_INVHS BIT(6)
48#define MAX9271_REV_LOGAIN BIT(3)
49#define MAX9271_REV_HIVTH BIT(0)
50/* Register 0x09 */
51#define MAX9271_ID 0x09
52/* Register 0x0d */
53#define MAX9271_I2CLOCACK BIT(7)
54#define MAX9271_I2CSLVSH_1046NS_469NS (3 << 5)
55#define MAX9271_I2CSLVSH_938NS_352NS (2 << 5)
56#define MAX9271_I2CSLVSH_469NS_234NS (1 << 5)
57#define MAX9271_I2CSLVSH_352NS_117NS (0 << 5)
58#define MAX9271_I2CMSTBT_837KBPS (7 << 2)
59#define MAX9271_I2CMSTBT_533KBPS (6 << 2)
60#define MAX9271_I2CMSTBT_339KBPS (5 << 2)
61#define MAX9271_I2CMSTBT_173KBPS (4 << 2)
62#define MAX9271_I2CMSTBT_105KBPS (3 << 2)
63#define MAX9271_I2CMSTBT_84KBPS (2 << 2)
64#define MAX9271_I2CMSTBT_28KBPS (1 << 2)
65#define MAX9271_I2CMSTBT_8KBPS (0 << 2)
66#define MAX9271_I2CSLVTO_NONE (3 << 0)
67#define MAX9271_I2CSLVTO_1024US (2 << 0)
68#define MAX9271_I2CSLVTO_256US (1 << 0)
69#define MAX9271_I2CSLVTO_64US (0 << 0)
70/* Register 0x0f */
71#define MAX9271_GPIO5OUT BIT(5)
72#define MAX9271_GPIO4OUT BIT(4)
73#define MAX9271_GPIO3OUT BIT(3)
74#define MAX9271_GPIO2OUT BIT(2)
75#define MAX9271_GPIO1OUT BIT(1)
76#define MAX9271_GPO BIT(0)
77/* Register 0x15 */
78#define MAX9271_PCLKDET BIT(0)
79
80/**
81 * struct max9271_device - max9271 device
82 * @client: The i2c client for the max9271 instance
83 */
84struct max9271_device {
85 struct i2c_client *client;
86};
87
88/**
89 * max9271_set_serial_link() - Enable/disable serial link
90 * @dev: The max9271 device
91 * @enable: Serial link enable/disable flag
92 *
93 * Return 0 on success or a negative error code on failure
94 */
95int max9271_set_serial_link(struct max9271_device *dev, bool enable);
96
97/**
98 * max9271_configure_i2c() - Configure I2C bus parameters
99 * @dev: The max9271 device
100 * @i2c_config: The I2C bus configuration bit mask
101 *
102 * Configure MAX9271 I2C interface. The bus configuration provided in the
103 * @i2c_config parameter shall be assembled using bit values defined by the
104 * MAX9271_I2C* macros.
105 *
106 * Return 0 on success or a negative error code on failure
107 */
108int max9271_configure_i2c(struct max9271_device *dev, u8 i2c_config);
109
110/**
111 * max9271_set_high_threshold() - Enable or disable reverse channel high
112 * threshold
113 * @dev: The max9271 device
114 * @enable: High threshold enable/disable flag
115 *
116 * Return 0 on success or a negative error code on failure
117 */
118int max9271_set_high_threshold(struct max9271_device *dev, bool enable);
119
120/**
121 * max9271_configure_gmsl_link() - Configure the GMSL link
122 * @dev: The max9271 device
123 *
124 * FIXME: the GMSL link configuration is currently hardcoded and performed
125 * by programming registers 0x04, 0x07 and 0x02.
126 *
127 * Return 0 on success or a negative error code on failure
128 */
129int max9271_configure_gmsl_link(struct max9271_device *dev);
130
131/**
132 * max9271_set_gpios() - Set gpio lines to physical high value
133 * @dev: The max9271 device
134 * @gpio_mask: The mask of gpio lines to set to high value
135 *
136 * The @gpio_mask parameter shall be assembled using the MAX9271_GP[IO|O]*
137 * bit values.
138 *
139 * Return 0 on success or a negative error code on failure
140 */
141int max9271_set_gpios(struct max9271_device *dev, u8 gpio_mask);
142
143/**
144 * max9271_clear_gpios() - Set gpio lines to physical low value
145 * @dev: The max9271 device
146 * @gpio_mask: The mask of gpio lines to set to low value
147 *
148 * The @gpio_mask parameter shall be assembled using the MAX9271_GP[IO|O]*
149 * bit values.
150 *
151 * Return 0 on success or a negative error code on failure
152 */
153int max9271_clear_gpios(struct max9271_device *dev, u8 gpio_mask);
154
155/**
156 * max9271_enable_gpios() - Enable gpio lines
157 * @dev: The max9271 device
158 * @gpio_mask: The mask of gpio lines to enable
159 *
160 * The @gpio_mask parameter shall be assembled using the MAX9271_GPIO*
161 * bit values. GPO line is always enabled by default.
162 *
163 * Return 0 on success or a negative error code on failure
164 */
165int max9271_enable_gpios(struct max9271_device *dev, u8 gpio_mask);
166
167/**
168 * max9271_disable_gpios() - Disable gpio lines
169 * @dev: The max9271 device
170 * @gpio_mask: The mask of gpio lines to disable
171 *
172 * The @gpio_mask parameter shall be assembled using the MAX9271_GPIO*
173 * bit values. GPO line is always enabled by default and cannot be disabled.
174 *
175 * Return 0 on success or a negative error code on failure
176 */
177int max9271_disable_gpios(struct max9271_device *dev, u8 gpio_mask);
178
179/**
180 * max9271_verify_id() - Read and verify MAX9271 id
181 * @dev: The max9271 device
182 *
183 * Return 0 on success or a negative error code on failure
184 */
185int max9271_verify_id(struct max9271_device *dev);
186
187/**
188 * max9271_set_address() - Program a new I2C address
189 * @dev: The max9271 device
190 * @addr: The new I2C address in 7-bit format
191 *
192 * This function only takes care of programming the new I2C address @addr to
193 * in the MAX9271 chip registers, it is responsiblity of the caller to set
194 * the i2c address client to the @addr value to be able to communicate with
195 * the MAX9271 chip using the I2C framework APIs after this function returns.
196 *
197 * Return 0 on success or a negative error code on failure
198 */
199int max9271_set_address(struct max9271_device *dev, u8 addr);
200
201/**
202 * max9271_set_deserializer_address() - Program the remote deserializer address
203 * @dev: The max9271 device
204 * @addr: The deserializer I2C address in 7-bit format
205 *
206 * Return 0 on success or a negative error code on failure
207 */
208int max9271_set_deserializer_address(struct max9271_device *dev, u8 addr);
209
210/**
211 * max9271_set_translation() - Program I2C address translation
212 * @dev: The max9271 device
213 * @source: The I2C source address
214 * @dest: The I2C destination address
215 *
216 * Program address translation from @source to @dest. This is required to
217 * communicate with local devices that do not support address reprogramming.
218 *
219 * TODO: The device supports translation of two address, this function currently
220 * supports a single one.
221 *
222 * Return 0 on success or a negative error code on failure
223 */
224int max9271_set_translation(struct max9271_device *dev, u8 source, u8 dest);
drivers/media/i2c/max9286.c+1320−0
@@ -0,0 +1,1320 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Maxim MAX9286 GMSL Deserializer Driver
4 *
5 * Copyright (C) 2017-2019 Jacopo Mondi
6 * Copyright (C) 2017-2019 Kieran Bingham
7 * Copyright (C) 2017-2019 Laurent Pinchart
8 * Copyright (C) 2017-2019 Niklas Söderlund
9 * Copyright (C) 2016 Renesas Electronics Corporation
10 * Copyright (C) 2015 Cogent Embedded, Inc.
11 */
12
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/fwnode.h>
16#include <linux/gpio/consumer.h>
17#include <linux/gpio/driver.h>
18#include <linux/i2c.h>
19#include <linux/i2c-mux.h>
20#include <linux/module.h>
21#include <linux/mutex.h>
22#include <linux/of_graph.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25
26#include <media/v4l2-async.h>
27#include <media/v4l2-ctrls.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-fwnode.h>
30#include <media/v4l2-subdev.h>
31
32/* Register 0x00 */
33#define MAX9286_MSTLINKSEL_AUTO (7 << 5)
34#define MAX9286_MSTLINKSEL(n) ((n) << 5)
35#define MAX9286_EN_VS_GEN BIT(4)
36#define MAX9286_LINKEN(n) (1 << (n))
37/* Register 0x01 */
38#define MAX9286_FSYNCMODE_ECU (3 << 6)
39#define MAX9286_FSYNCMODE_EXT (2 << 6)
40#define MAX9286_FSYNCMODE_INT_OUT (1 << 6)
41#define MAX9286_FSYNCMODE_INT_HIZ (0 << 6)
42#define MAX9286_GPIEN BIT(5)
43#define MAX9286_ENLMO_RSTFSYNC BIT(2)
44#define MAX9286_FSYNCMETH_AUTO (2 << 0)
45#define MAX9286_FSYNCMETH_SEMI_AUTO (1 << 0)
46#define MAX9286_FSYNCMETH_MANUAL (0 << 0)
47#define MAX9286_REG_FSYNC_PERIOD_L 0x06
48#define MAX9286_REG_FSYNC_PERIOD_M 0x07
49#define MAX9286_REG_FSYNC_PERIOD_H 0x08
50/* Register 0x0a */
51#define MAX9286_FWDCCEN(n) (1 << ((n) + 4))
52#define MAX9286_REVCCEN(n) (1 << (n))
53/* Register 0x0c */
54#define MAX9286_HVEN BIT(7)
55#define MAX9286_EDC_6BIT_HAMMING (2 << 5)
56#define MAX9286_EDC_6BIT_CRC (1 << 5)
57#define MAX9286_EDC_1BIT_PARITY (0 << 5)
58#define MAX9286_DESEL BIT(4)
59#define MAX9286_INVVS BIT(3)
60#define MAX9286_INVHS BIT(2)
61#define MAX9286_HVSRC_D0 (2 << 0)
62#define MAX9286_HVSRC_D14 (1 << 0)
63#define MAX9286_HVSRC_D18 (0 << 0)
64/* Register 0x0f */
65#define MAX9286_0X0F_RESERVED BIT(3)
66/* Register 0x12 */
67#define MAX9286_CSILANECNT(n) (((n) - 1) << 6)
68#define MAX9286_CSIDBL BIT(5)
69#define MAX9286_DBL BIT(4)
70#define MAX9286_DATATYPE_USER_8BIT (11 << 0)
71#define MAX9286_DATATYPE_USER_YUV_12BIT (10 << 0)
72#define MAX9286_DATATYPE_USER_24BIT (9 << 0)
73#define MAX9286_DATATYPE_RAW14 (8 << 0)
74#define MAX9286_DATATYPE_RAW11 (7 << 0)
75#define MAX9286_DATATYPE_RAW10 (6 << 0)
76#define MAX9286_DATATYPE_RAW8 (5 << 0)
77#define MAX9286_DATATYPE_YUV422_10BIT (4 << 0)
78#define MAX9286_DATATYPE_YUV422_8BIT (3 << 0)
79#define MAX9286_DATATYPE_RGB555 (2 << 0)
80#define MAX9286_DATATYPE_RGB565 (1 << 0)
81#define MAX9286_DATATYPE_RGB888 (0 << 0)
82/* Register 0x15 */
83#define MAX9286_VC(n) ((n) << 5)
84#define MAX9286_VCTYPE BIT(4)
85#define MAX9286_CSIOUTEN BIT(3)
86#define MAX9286_0X15_RESV (3 << 0)
87/* Register 0x1b */
88#define MAX9286_SWITCHIN(n) (1 << ((n) + 4))
89#define MAX9286_ENEQ(n) (1 << (n))
90/* Register 0x27 */
91#define MAX9286_LOCKED BIT(7)
92/* Register 0x31 */
93#define MAX9286_FSYNC_LOCKED BIT(6)
94/* Register 0x34 */
95#define MAX9286_I2CLOCACK BIT(7)
96#define MAX9286_I2CSLVSH_1046NS_469NS (3 << 5)
97#define MAX9286_I2CSLVSH_938NS_352NS (2 << 5)
98#define MAX9286_I2CSLVSH_469NS_234NS (1 << 5)
99#define MAX9286_I2CSLVSH_352NS_117NS (0 << 5)
100#define MAX9286_I2CMSTBT_837KBPS (7 << 2)
101#define MAX9286_I2CMSTBT_533KBPS (6 << 2)
102#define MAX9286_I2CMSTBT_339KBPS (5 << 2)
103#define MAX9286_I2CMSTBT_173KBPS (4 << 2)
104#define MAX9286_I2CMSTBT_105KBPS (3 << 2)
105#define MAX9286_I2CMSTBT_84KBPS (2 << 2)
106#define MAX9286_I2CMSTBT_28KBPS (1 << 2)
107#define MAX9286_I2CMSTBT_8KBPS (0 << 2)
108#define MAX9286_I2CSLVTO_NONE (3 << 0)
109#define MAX9286_I2CSLVTO_1024US (2 << 0)
110#define MAX9286_I2CSLVTO_256US (1 << 0)
111#define MAX9286_I2CSLVTO_64US (0 << 0)
112/* Register 0x3b */
113#define MAX9286_REV_TRF(n) ((n) << 4)
114#define MAX9286_REV_AMP(n) ((((n) - 30) / 10) << 1) /* in mV */
115#define MAX9286_REV_AMP_X BIT(0)
116/* Register 0x3f */
117#define MAX9286_EN_REV_CFG BIT(6)
118#define MAX9286_REV_FLEN(n) ((n) - 20)
119/* Register 0x49 */
120#define MAX9286_VIDEO_DETECT_MASK 0x0f
121/* Register 0x69 */
122#define MAX9286_LFLTBMONMASKED BIT(7)
123#define MAX9286_LOCKMONMASKED BIT(6)
124#define MAX9286_AUTOCOMBACKEN BIT(5)
125#define MAX9286_AUTOMASKEN BIT(4)
126#define MAX9286_MASKLINK(n) ((n) << 0)
127
128/*
129 * The sink and source pads are created to match the OF graph port numbers so
130 * that their indexes can be used interchangeably.
131 */
132#define MAX9286_NUM_GMSL 4
133#define MAX9286_N_SINKS 4
134#define MAX9286_N_PADS 5
135#define MAX9286_SRC_PAD 4
136
137struct max9286_source {
138 struct v4l2_async_subdev asd;
139 struct v4l2_subdev *sd;
140 struct fwnode_handle *fwnode;
141};
142
143#define asd_to_max9286_source(_asd) \
144 container_of(_asd, struct max9286_source, asd)
145
146struct max9286_priv {
147 struct i2c_client *client;
148 struct gpio_desc *gpiod_pwdn;
149 struct v4l2_subdev sd;
150 struct media_pad pads[MAX9286_N_PADS];
151 struct regulator *regulator;
152
153 struct gpio_chip gpio;
154 u8 gpio_state;
155
156 struct i2c_mux_core *mux;
157 unsigned int mux_channel;
158 bool mux_open;
159
160 struct v4l2_ctrl_handler ctrls;
161 struct v4l2_ctrl *pixelrate;
162
163 struct v4l2_mbus_framefmt fmt[MAX9286_N_SINKS];
164
165 /* Protects controls and fmt structures */
166 struct mutex mutex;
167
168 unsigned int nsources;
169 unsigned int source_mask;
170 unsigned int route_mask;
171 unsigned int bound_sources;
172 unsigned int csi2_data_lanes;
173 struct max9286_source sources[MAX9286_NUM_GMSL];
174 struct v4l2_async_notifier notifier;
175};
176
177static struct max9286_source *next_source(struct max9286_priv *priv,
178 struct max9286_source *source)
179{
180 if (!source)
181 source = &priv->sources[0];
182 else
183 source++;
184
185 for (; source < &priv->sources[MAX9286_NUM_GMSL]; source++) {
186 if (source->fwnode)
187 return source;
188 }
189
190 return NULL;
191}
192
193#define for_each_source(priv, source) \
194 for ((source) = NULL; ((source) = next_source((priv), (source))); )
195
196#define to_index(priv, source) ((source) - &(priv)->sources[0])
197
198static inline struct max9286_priv *sd_to_max9286(struct v4l2_subdev *sd)
199{
200 return container_of(sd, struct max9286_priv, sd);
201}
202
203/* -----------------------------------------------------------------------------
204 * I2C IO
205 */
206
207static int max9286_read(struct max9286_priv *priv, u8 reg)
208{
209 int ret;
210
211 ret = i2c_smbus_read_byte_data(priv->client, reg);
212 if (ret < 0)
213 dev_err(&priv->client->dev,
214 "%s: register 0x%02x read failed (%d)\n",
215 __func__, reg, ret);
216
217 return ret;
218}
219
220static int max9286_write(struct max9286_priv *priv, u8 reg, u8 val)
221{
222 int ret;
223
224 ret = i2c_smbus_write_byte_data(priv->client, reg, val);
225 if (ret < 0)
226 dev_err(&priv->client->dev,
227 "%s: register 0x%02x write failed (%d)\n",
228 __func__, reg, ret);
229
230 return ret;
231}
232
233/* -----------------------------------------------------------------------------
234 * I2C Multiplexer
235 */
236
237static void max9286_i2c_mux_configure(struct max9286_priv *priv, u8 conf)
238{
239 max9286_write(priv, 0x0a, conf);
240
241 /*
242 * We must sleep after any change to the forward or reverse channel
243 * configuration.
244 */
245 usleep_range(3000, 5000);
246}
247
248static void max9286_i2c_mux_open(struct max9286_priv *priv)
249{
250 /* Open all channels on the MAX9286 */
251 max9286_i2c_mux_configure(priv, 0xff);
252
253 priv->mux_open = true;
254}
255
256static void max9286_i2c_mux_close(struct max9286_priv *priv)
257{
258 /*
259 * Ensure that both the forward and reverse channel are disabled on the
260 * mux, and that the channel ID is invalidated to ensure we reconfigure
261 * on the next max9286_i2c_mux_select() call.
262 */
263 max9286_i2c_mux_configure(priv, 0x00);
264
265 priv->mux_open = false;
266 priv->mux_channel = -1;
267}
268
269static int max9286_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan)
270{
271 struct max9286_priv *priv = i2c_mux_priv(muxc);
272
273 /* Channel select is disabled when configured in the opened state. */
274 if (priv->mux_open)
275 return 0;
276
277 if (priv->mux_channel == chan)
278 return 0;
279
280 priv->mux_channel = chan;
281
282 max9286_i2c_mux_configure(priv,
283 MAX9286_FWDCCEN(chan) |
284 MAX9286_REVCCEN(chan));
285
286 return 0;
287}
288
289static int max9286_i2c_mux_init(struct max9286_priv *priv)
290{
291 struct max9286_source *source;
292 int ret;
293
294 if (!i2c_check_functionality(priv->client->adapter,
295 I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
296 return -ENODEV;
297
298 priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
299 priv->nsources, 0, I2C_MUX_LOCKED,
300 max9286_i2c_mux_select, NULL);
301 if (!priv->mux)
302 return -ENOMEM;
303
304 priv->mux->priv = priv;
305
306 for_each_source(priv, source) {
307 unsigned int index = to_index(priv, source);
308
309 ret = i2c_mux_add_adapter(priv->mux, 0, index, 0);
310 if (ret < 0)
311 goto error;
312 }
313
314 return 0;
315
316error:
317 i2c_mux_del_adapters(priv->mux);
318 return ret;
319}
320
321static void max9286_configure_i2c(struct max9286_priv *priv, bool localack)
322{
323 u8 config = MAX9286_I2CSLVSH_469NS_234NS | MAX9286_I2CSLVTO_1024US |
324 MAX9286_I2CMSTBT_105KBPS;
325
326 if (localack)
327 config |= MAX9286_I2CLOCACK;
328
329 max9286_write(priv, 0x34, config);
330 usleep_range(3000, 5000);
331}
332
333/*
334 * max9286_check_video_links() - Make sure video links are detected and locked
335 *
336 * Performs safety checks on video link status. Make sure they are detected
337 * and all enabled links are locked.
338 *
339 * Returns 0 for success, -EIO for errors.
340 */
341static int max9286_check_video_links(struct max9286_priv *priv)
342{
343 unsigned int i;
344 int ret;
345
346 /*
347 * Make sure valid video links are detected.
348 * The delay is not characterized in de-serializer manual, wait up
349 * to 5 ms.
350 */
351 for (i = 0; i < 10; i++) {
352 ret = max9286_read(priv, 0x49);
353 if (ret < 0)
354 return -EIO;
355
356 if ((ret & MAX9286_VIDEO_DETECT_MASK) == priv->source_mask)
357 break;
358
359 usleep_range(350, 500);
360 }
361
362 if (i == 10) {
363 dev_err(&priv->client->dev,
364 "Unable to detect video links: 0x%02x\n", ret);
365 return -EIO;
366 }
367
368 /* Make sure all enabled links are locked (4ms max). */
369 for (i = 0; i < 10; i++) {
370 ret = max9286_read(priv, 0x27);
371 if (ret < 0)
372 return -EIO;
373
374 if (ret & MAX9286_LOCKED)
375 break;
376
377 usleep_range(350, 450);
378 }
379
380 if (i == 10) {
381 dev_err(&priv->client->dev, "Not all enabled links locked\n");
382 return -EIO;
383 }
384
385 return 0;
386}
387
388/*
389 * max9286_check_config_link() - Detect and wait for configuration links
390 *
391 * Determine if the configuration channel is up and settled for a link.
392 *
393 * Returns 0 for success, -EIO for errors.
394 */
395static int max9286_check_config_link(struct max9286_priv *priv,
396 unsigned int source_mask)
397{
398 unsigned int conflink_mask = (source_mask & 0x0f) << 4;
399 unsigned int i;
400 int ret;
401
402 /*
403 * Make sure requested configuration links are detected.
404 * The delay is not characterized in the chip manual: wait up
405 * to 5 milliseconds.
406 */
407 for (i = 0; i < 10; i++) {
408 ret = max9286_read(priv, 0x49) & 0xf0;
409 if (ret < 0)
410 return -EIO;
411
412 if (ret == conflink_mask)
413 break;
414
415 usleep_range(350, 500);
416 }
417
418 if (ret != conflink_mask) {
419 dev_err(&priv->client->dev,
420 "Unable to detect configuration links: 0x%02x expected 0x%02x\n",
421 ret, conflink_mask);
422 return -EIO;
423 }
424
425 dev_info(&priv->client->dev,
426 "Successfully detected configuration links after %u loops: 0x%02x\n",
427 i, conflink_mask);
428
429 return 0;
430}
431
432/* -----------------------------------------------------------------------------
433 * V4L2 Subdev
434 */
435
436static int max9286_set_pixelrate(struct max9286_priv *priv)
437{
438 struct max9286_source *source = NULL;
439 u64 pixelrate = 0;
440
441 for_each_source(priv, source) {
442 struct v4l2_ctrl *ctrl;
443 u64 source_rate = 0;
444
445 /* Pixel rate is mandatory to be reported by sources. */
446 ctrl = v4l2_ctrl_find(source->sd->ctrl_handler,
447 V4L2_CID_PIXEL_RATE);
448 if (!ctrl) {
449 pixelrate = 0;
450 break;
451 }
452
453 /* All source must report the same pixel rate. */
454 source_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
455 if (!pixelrate) {
456 pixelrate = source_rate;
457 } else if (pixelrate != source_rate) {
458 dev_err(&priv->client->dev,
459 "Unable to calculate pixel rate\n");
460 return -EINVAL;
461 }
462 }
463
464 if (!pixelrate) {
465 dev_err(&priv->client->dev,
466 "No pixel rate control available in sources\n");
467 return -EINVAL;
468 }
469
470 /*
471 * The CSI-2 transmitter pixel rate is the single source rate multiplied
472 * by the number of available sources.
473 */
474 return v4l2_ctrl_s_ctrl_int64(priv->pixelrate,
475 pixelrate * priv->nsources);
476}
477
478static int max9286_notify_bound(struct v4l2_async_notifier *notifier,
479 struct v4l2_subdev *subdev,
480 struct v4l2_async_subdev *asd)
481{
482 struct max9286_priv *priv = sd_to_max9286(notifier->sd);
483 struct max9286_source *source = asd_to_max9286_source(asd);
484 unsigned int index = to_index(priv, source);
485 unsigned int src_pad;
486 int ret;
487
488 ret = media_entity_get_fwnode_pad(&subdev->entity,
489 source->fwnode,
490 MEDIA_PAD_FL_SOURCE);
491 if (ret < 0) {
492 dev_err(&priv->client->dev,
493 "Failed to find pad for %s\n", subdev->name);
494 return ret;
495 }
496
497 priv->bound_sources |= BIT(index);
498 source->sd = subdev;
499 src_pad = ret;
500
501 ret = media_create_pad_link(&source->sd->entity, src_pad,
502 &priv->sd.entity, index,
503 MEDIA_LNK_FL_ENABLED |
504 MEDIA_LNK_FL_IMMUTABLE);
505 if (ret) {
506 dev_err(&priv->client->dev,
507 "Unable to link %s:%u -> %s:%u\n",
508 source->sd->name, src_pad, priv->sd.name, index);
509 return ret;
510 }
511
512 dev_dbg(&priv->client->dev, "Bound %s pad: %u on index %u\n",
513 subdev->name, src_pad, index);
514
515 /*
516 * We can only register v4l2_async_notifiers, which do not provide a
517 * means to register a complete callback. bound_sources allows us to
518 * identify when all remote serializers have completed their probe.
519 */
520 if (priv->bound_sources != priv->source_mask)
521 return 0;
522
523 /*
524 * All enabled sources have probed and enabled their reverse control
525 * channels:
526 *
527 * - Verify all configuration links are properly detected
528 * - Disable auto-ack as communication on the control channel are now
529 * stable.
530 */
531 max9286_check_config_link(priv, priv->source_mask);
532
533 /*
534 * Re-configure I2C with local acknowledge disabled after cameras have
535 * probed.
536 */
537 max9286_configure_i2c(priv, false);
538
539 return max9286_set_pixelrate(priv);
540}
541
542static void max9286_notify_unbind(struct v4l2_async_notifier *notifier,
543 struct v4l2_subdev *subdev,
544 struct v4l2_async_subdev *asd)
545{
546 struct max9286_priv *priv = sd_to_max9286(notifier->sd);
547 struct max9286_source *source = asd_to_max9286_source(asd);
548 unsigned int index = to_index(priv, source);
549
550 source->sd = NULL;
551 priv->bound_sources &= ~BIT(index);
552}
553
554static const struct v4l2_async_notifier_operations max9286_notify_ops = {
555 .bound = max9286_notify_bound,
556 .unbind = max9286_notify_unbind,
557};
558
559static int max9286_v4l2_notifier_register(struct max9286_priv *priv)
560{
561 struct device *dev = &priv->client->dev;
562 struct max9286_source *source = NULL;
563 int ret;
564
565 if (!priv->nsources)
566 return 0;
567
568 v4l2_async_notifier_init(&priv->notifier);
569
570 for_each_source(priv, source) {
571 unsigned int i = to_index(priv, source);
572
573 source->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
574 source->asd.match.fwnode = source->fwnode;
575
576 ret = v4l2_async_notifier_add_subdev(&priv->notifier,
577 &source->asd);
578 if (ret) {
579 dev_err(dev, "Failed to add subdev for source %d", i);
580 v4l2_async_notifier_cleanup(&priv->notifier);
581 return ret;
582 }
583
584 /*
585 * Balance the reference counting handled through
586 * v4l2_async_notifier_cleanup()
587 */
588 fwnode_handle_get(source->fwnode);
589 }
590
591 priv->notifier.ops = &max9286_notify_ops;
592
593 ret = v4l2_async_subdev_notifier_register(&priv->sd, &priv->notifier);
594 if (ret) {
595 dev_err(dev, "Failed to register subdev_notifier");
596 v4l2_async_notifier_cleanup(&priv->notifier);
597 return ret;
598 }
599
600 return 0;
601}
602
603static void max9286_v4l2_notifier_unregister(struct max9286_priv *priv)
604{
605 if (!priv->nsources)
606 return;
607
608 v4l2_async_notifier_unregister(&priv->notifier);
609 v4l2_async_notifier_cleanup(&priv->notifier);
610}
611
612static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
613{
614 struct max9286_priv *priv = sd_to_max9286(sd);
615 struct max9286_source *source;
616 unsigned int i;
617 bool sync = false;
618 int ret;
619
620 if (enable) {
621 /*
622 * The frame sync between cameras is transmitted across the
623 * reverse channel as GPIO. We must open all channels while
624 * streaming to allow this synchronisation signal to be shared.
625 */
626 max9286_i2c_mux_open(priv);
627
628 /* Start all cameras. */
629 for_each_source(priv, source) {
630 ret = v4l2_subdev_call(source->sd, video, s_stream, 1);
631 if (ret)
632 return ret;
633 }
634
635 ret = max9286_check_video_links(priv);
636 if (ret)
637 return ret;
638
639 /*
640 * Wait until frame synchronization is locked.
641 *
642 * Manual says frame sync locking should take ~6 VTS.
643 * From practical experience at least 8 are required. Give
644 * 12 complete frames time (~400ms at 30 fps) to achieve frame
645 * locking before returning error.
646 */
647 for (i = 0; i < 40; i++) {
648 if (max9286_read(priv, 0x31) & MAX9286_FSYNC_LOCKED) {
649 sync = true;
650 break;
651 }
652 usleep_range(9000, 11000);
653 }
654
655 if (!sync) {
656 dev_err(&priv->client->dev,
657 "Failed to get frame synchronization\n");
658 return -EXDEV; /* Invalid cross-device link */
659 }
660
661 /*
662 * Enable CSI output, VC set according to link number.
663 * Bit 7 must be set (chip manual says it's 0 and reserved).
664 */
665 max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
666 MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
667 } else {
668 max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
669
670 /* Stop all cameras. */
671 for_each_source(priv, source)
672 v4l2_subdev_call(source->sd, video, s_stream, 0);
673
674 max9286_i2c_mux_close(priv);
675 }
676
677 return 0;
678}
679
680static int max9286_enum_mbus_code(struct v4l2_subdev *sd,
681 struct v4l2_subdev_pad_config *cfg,
682 struct v4l2_subdev_mbus_code_enum *code)
683{
684 if (code->pad || code->index > 0)
685 return -EINVAL;
686
687 code->code = MEDIA_BUS_FMT_UYVY8_1X16;
688
689 return 0;
690}
691
692static struct v4l2_mbus_framefmt *
693max9286_get_pad_format(struct max9286_priv *priv,
694 struct v4l2_subdev_pad_config *cfg,
695 unsigned int pad, u32 which)
696{
697 switch (which) {
698 case V4L2_SUBDEV_FORMAT_TRY:
699 return v4l2_subdev_get_try_format(&priv->sd, cfg, pad);
700 case V4L2_SUBDEV_FORMAT_ACTIVE:
701 return &priv->fmt[pad];
702 default:
703 return NULL;
704 }
705}
706
707static int max9286_set_fmt(struct v4l2_subdev *sd,
708 struct v4l2_subdev_pad_config *cfg,
709 struct v4l2_subdev_format *format)
710{
711 struct max9286_priv *priv = sd_to_max9286(sd);
712 struct v4l2_mbus_framefmt *cfg_fmt;
713
714 if (format->pad == MAX9286_SRC_PAD)
715 return -EINVAL;
716
717 /* Refuse non YUV422 formats as we hardcode DT to 8 bit YUV422 */
718 switch (format->format.code) {
719 case MEDIA_BUS_FMT_UYVY8_1X16:
720 case MEDIA_BUS_FMT_VYUY8_1X16:
721 case MEDIA_BUS_FMT_YUYV8_1X16:
722 case MEDIA_BUS_FMT_YVYU8_1X16:
723 break;
724 default:
725 format->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
726 break;
727 }
728
729 cfg_fmt = max9286_get_pad_format(priv, cfg, format->pad, format->which);
730 if (!cfg_fmt)
731 return -EINVAL;
732
733 mutex_lock(&priv->mutex);
734 *cfg_fmt = format->format;
735 mutex_unlock(&priv->mutex);
736
737 return 0;
738}
739
740static int max9286_get_fmt(struct v4l2_subdev *sd,
741 struct v4l2_subdev_pad_config *cfg,
742 struct v4l2_subdev_format *format)
743{
744 struct max9286_priv *priv = sd_to_max9286(sd);
745 struct v4l2_mbus_framefmt *cfg_fmt;
746 unsigned int pad = format->pad;
747
748 /*
749 * Multiplexed Stream Support: Support link validation by returning the
750 * format of the first bound link. All links must have the same format,
751 * as we do not support mixing and matching of cameras connected to the
752 * max9286.
753 */
754 if (pad == MAX9286_SRC_PAD)
755 pad = __ffs(priv->bound_sources);
756
757 cfg_fmt = max9286_get_pad_format(priv, cfg, pad, format->which);
758 if (!cfg_fmt)
759 return -EINVAL;
760
761 mutex_lock(&priv->mutex);
762 format->format = *cfg_fmt;
763 mutex_unlock(&priv->mutex);
764
765 return 0;
766}
767
768static const struct v4l2_subdev_video_ops max9286_video_ops = {
769 .s_stream = max9286_s_stream,
770};
771
772static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
773 .enum_mbus_code = max9286_enum_mbus_code,
774 .get_fmt = max9286_get_fmt,
775 .set_fmt = max9286_set_fmt,
776};
777
778static const struct v4l2_subdev_ops max9286_subdev_ops = {
779 .video = &max9286_video_ops,
780 .pad = &max9286_pad_ops,
781};
782
783static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
784{
785 fmt->width = 1280;
786 fmt->height = 800;
787 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
788 fmt->colorspace = V4L2_COLORSPACE_SRGB;
789 fmt->field = V4L2_FIELD_NONE;
790 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
791 fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
792 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
793}
794
795static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
796{
797 struct v4l2_mbus_framefmt *format;
798 unsigned int i;
799
800 for (i = 0; i < MAX9286_N_SINKS; i++) {
801 format = v4l2_subdev_get_try_format(subdev, fh->pad, i);
802 max9286_init_format(format);
803 }
804
805 return 0;
806}
807
808static const struct v4l2_subdev_internal_ops max9286_subdev_internal_ops = {
809 .open = max9286_open,
810};
811
812static int max9286_s_ctrl(struct v4l2_ctrl *ctrl)
813{
814 switch (ctrl->id) {
815 case V4L2_CID_PIXEL_RATE:
816 return 0;
817 default:
818 return -EINVAL;
819 }
820}
821
822static const struct v4l2_ctrl_ops max9286_ctrl_ops = {
823 .s_ctrl = max9286_s_ctrl,
824};
825
826static int max9286_v4l2_register(struct max9286_priv *priv)
827{
828 struct device *dev = &priv->client->dev;
829 struct fwnode_handle *ep;
830 int ret;
831 int i;
832
833 /* Register v4l2 async notifiers for connected Camera subdevices */
834 ret = max9286_v4l2_notifier_register(priv);
835 if (ret) {
836 dev_err(dev, "Unable to register V4L2 async notifiers\n");
837 return ret;
838 }
839
840 /* Configure V4L2 for the MAX9286 itself */
841
842 for (i = 0; i < MAX9286_N_SINKS; i++)
843 max9286_init_format(&priv->fmt[i]);
844
845 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops);
846 priv->sd.internal_ops = &max9286_subdev_internal_ops;
847 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
848
849 v4l2_ctrl_handler_init(&priv->ctrls, 1);
850 priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
851 &max9286_ctrl_ops,
852 V4L2_CID_PIXEL_RATE,
853 1, INT_MAX, 1, 50000000);
854
855 priv->sd.ctrl_handler = &priv->ctrls;
856 ret = priv->ctrls.error;
857 if (ret)
858 goto err_async;
859
860 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
861
862 priv->pads[MAX9286_SRC_PAD].flags = MEDIA_PAD_FL_SOURCE;
863 for (i = 0; i < MAX9286_SRC_PAD; i++)
864 priv->pads[i].flags = MEDIA_PAD_FL_SINK;
865 ret = media_entity_pads_init(&priv->sd.entity, MAX9286_N_PADS,
866 priv->pads);
867 if (ret)
868 goto err_async;
869
870 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), MAX9286_SRC_PAD,
871 0, 0);
872 if (!ep) {
873 dev_err(dev, "Unable to retrieve endpoint on \"port@4\"\n");
874 ret = -ENOENT;
875 goto err_async;
876 }
877 priv->sd.fwnode = ep;
878
879 ret = v4l2_async_register_subdev(&priv->sd);
880 if (ret < 0) {
881 dev_err(dev, "Unable to register subdevice\n");
882 goto err_put_node;
883 }
884
885 return 0;
886
887err_put_node:
888 fwnode_handle_put(ep);
889err_async:
890 max9286_v4l2_notifier_unregister(priv);
891
892 return ret;
893}
894
895static void max9286_v4l2_unregister(struct max9286_priv *priv)
896{
897 fwnode_handle_put(priv->sd.fwnode);
898 v4l2_async_unregister_subdev(&priv->sd);
899 max9286_v4l2_notifier_unregister(priv);
900}
901
902/* -----------------------------------------------------------------------------
903 * Probe/Remove
904 */
905
906static int max9286_setup(struct max9286_priv *priv)
907{
908 /*
909 * Link ordering values for all enabled links combinations. Orders must
910 * be assigned sequentially from 0 to the number of enabled links
911 * without leaving any hole for disabled links. We thus assign orders to
912 * enabled links first, and use the remaining order values for disabled
913 * links are all links must have a different order value;
914 */
915 static const u8 link_order[] = {
916 (3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* xxxx */
917 (3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* xxx0 */
918 (3 << 6) | (2 << 4) | (0 << 2) | (1 << 0), /* xx0x */
919 (3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* xx10 */
920 (3 << 6) | (0 << 4) | (2 << 2) | (1 << 0), /* x0xx */
921 (3 << 6) | (1 << 4) | (2 << 2) | (0 << 0), /* x1x0 */
922 (3 << 6) | (1 << 4) | (0 << 2) | (2 << 0), /* x10x */
923 (3 << 6) | (1 << 4) | (1 << 2) | (0 << 0), /* x210 */
924 (0 << 6) | (3 << 4) | (2 << 2) | (1 << 0), /* 0xxx */
925 (1 << 6) | (3 << 4) | (2 << 2) | (0 << 0), /* 1xx0 */
926 (1 << 6) | (3 << 4) | (0 << 2) | (2 << 0), /* 1x0x */
927 (2 << 6) | (3 << 4) | (1 << 2) | (0 << 0), /* 2x10 */
928 (1 << 6) | (0 << 4) | (3 << 2) | (2 << 0), /* 10xx */
929 (2 << 6) | (1 << 4) | (3 << 2) | (0 << 0), /* 21x0 */
930 (2 << 6) | (1 << 4) | (0 << 2) | (3 << 0), /* 210x */
931 (3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* 3210 */
932 };
933
934 /*
935 * Set the I2C bus speed.
936 *
937 * Enable I2C Local Acknowledge during the probe sequences of the camera
938 * only. This should be disabled after the mux is initialised.
939 */
940 max9286_configure_i2c(priv, true);
941
942 /*
943 * Reverse channel setup.
944 *
945 * - Enable custom reverse channel configuration (through register 0x3f)
946 * and set the first pulse length to 35 clock cycles.
947 * - Increase the reverse channel amplitude to 170mV to accommodate the
948 * high threshold enabled by the serializer driver.
949 */
950 max9286_write(priv, 0x3f, MAX9286_EN_REV_CFG | MAX9286_REV_FLEN(35));
951 max9286_write(priv, 0x3b, MAX9286_REV_TRF(1) | MAX9286_REV_AMP(70) |
952 MAX9286_REV_AMP_X);
953 usleep_range(2000, 2500);
954
955 /*
956 * Enable GMSL links, mask unused ones and autodetect link
957 * used as CSI clock source.
958 */
959 max9286_write(priv, 0x00, MAX9286_MSTLINKSEL_AUTO | priv->route_mask);
960 max9286_write(priv, 0x0b, link_order[priv->route_mask]);
961 max9286_write(priv, 0x69, (0xf & ~priv->route_mask));
962
963 /*
964 * Video format setup:
965 * Disable CSI output, VC is set according to Link number.
966 */
967 max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
968
969 /* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */
970 max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
971 MAX9286_CSILANECNT(priv->csi2_data_lanes) |
972 MAX9286_DATATYPE_YUV422_8BIT);
973
974 /* Automatic: FRAMESYNC taken from the slowest Link. */
975 max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
976 MAX9286_FSYNCMETH_AUTO);
977
978 /* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
979 max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
980 MAX9286_HVSRC_D14);
981
982 /*
983 * The overlap window seems to provide additional validation by tracking
984 * the delay between vsync and frame sync, generating an error if the
985 * delay is bigger than the programmed window, though it's not yet clear
986 * what value should be set.
987 *
988 * As it's an optional value and can be disabled, we do so by setting
989 * a 0 overlap value.
990 */
991 max9286_write(priv, 0x63, 0);
992 max9286_write(priv, 0x64, 0);
993
994 /*
995 * Wait for 2ms to allow the link to resynchronize after the
996 * configuration change.
997 */
998 usleep_range(2000, 5000);
999
1000 return 0;
1001}
1002
1003static void max9286_gpio_set(struct gpio_chip *chip,
1004 unsigned int offset, int value)
1005{
1006 struct max9286_priv *priv = gpiochip_get_data(chip);
1007
1008 if (value)
1009 priv->gpio_state |= BIT(offset);
1010 else
1011 priv->gpio_state &= ~BIT(offset);
1012
1013 max9286_write(priv, 0x0f, MAX9286_0X0F_RESERVED | priv->gpio_state);
1014}
1015
1016static int max9286_gpio_get(struct gpio_chip *chip, unsigned int offset)
1017{
1018 struct max9286_priv *priv = gpiochip_get_data(chip);
1019
1020 return priv->gpio_state & BIT(offset);
1021}
1022
1023static int max9286_register_gpio(struct max9286_priv *priv)
1024{
1025 struct device *dev = &priv->client->dev;
1026 struct gpio_chip *gpio = &priv->gpio;
1027 int ret;
1028
1029 /* Configure the GPIO */
1030 gpio->label = dev_name(dev);
1031 gpio->parent = dev;
1032 gpio->owner = THIS_MODULE;
1033 gpio->of_node = dev->of_node;
1034 gpio->ngpio = 2;
1035 gpio->base = -1;
1036 gpio->set = max9286_gpio_set;
1037 gpio->get = max9286_gpio_get;
1038 gpio->can_sleep = true;
1039
1040 /* GPIO values default to high */
1041 priv->gpio_state = BIT(0) | BIT(1);
1042
1043 ret = devm_gpiochip_add_data(dev, gpio, priv);
1044 if (ret)
1045 dev_err(dev, "Unable to create gpio_chip\n");
1046
1047 return ret;
1048}
1049
1050static int max9286_init(struct device *dev)
1051{
1052 struct max9286_priv *priv;
1053 struct i2c_client *client;
1054 int ret;
1055
1056 client = to_i2c_client(dev);
1057 priv = i2c_get_clientdata(client);
1058
1059 /* Enable the bus power. */
1060 ret = regulator_enable(priv->regulator);
1061 if (ret < 0) {
1062 dev_err(&client->dev, "Unable to turn PoC on\n");
1063 return ret;
1064 }
1065
1066 ret = max9286_setup(priv);
1067 if (ret) {
1068 dev_err(dev, "Unable to setup max9286\n");
1069 goto err_regulator;
1070 }
1071
1072 /*
1073 * Register all V4L2 interactions for the MAX9286 and notifiers for
1074 * any subdevices connected.
1075 */
1076 ret = max9286_v4l2_register(priv);
1077 if (ret) {
1078 dev_err(dev, "Failed to register with V4L2\n");
1079 goto err_regulator;
1080 }
1081
1082 ret = max9286_i2c_mux_init(priv);
1083 if (ret) {
1084 dev_err(dev, "Unable to initialize I2C multiplexer\n");
1085 goto err_v4l2_register;
1086 }
1087
1088 /* Leave the mux channels disabled until they are selected. */
1089 max9286_i2c_mux_close(priv);
1090
1091 return 0;
1092
1093err_v4l2_register:
1094 max9286_v4l2_unregister(priv);
1095err_regulator:
1096 regulator_disable(priv->regulator);
1097
1098 return ret;
1099}
1100
1101static void max9286_cleanup_dt(struct max9286_priv *priv)
1102{
1103 struct max9286_source *source;
1104
1105 for_each_source(priv, source) {
1106 fwnode_handle_put(source->fwnode);
1107 source->fwnode = NULL;
1108 }
1109}
1110
1111static int max9286_parse_dt(struct max9286_priv *priv)
1112{
1113 struct device *dev = &priv->client->dev;
1114 struct device_node *i2c_mux;
1115 struct device_node *node = NULL;
1116 unsigned int i2c_mux_mask = 0;
1117
1118 /* Balance the of_node_put() performed by of_find_node_by_name(). */
1119 of_node_get(dev->of_node);
1120 i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux");
1121 if (!i2c_mux) {
1122 dev_err(dev, "Failed to find i2c-mux node\n");
1123 return -EINVAL;
1124 }
1125
1126 /* Identify which i2c-mux channels are enabled */
1127 for_each_child_of_node(i2c_mux, node) {
1128 u32 id = 0;
1129
1130 of_property_read_u32(node, "reg", &id);
1131 if (id >= MAX9286_NUM_GMSL)
1132 continue;
1133
1134 if (!of_device_is_available(node)) {
1135 dev_dbg(dev, "Skipping disabled I2C bus port %u\n", id);
1136 continue;
1137 }
1138
1139 i2c_mux_mask |= BIT(id);
1140 }
1141 of_node_put(node);
1142 of_node_put(i2c_mux);
1143
1144 /* Parse the endpoints */
1145 for_each_endpoint_of_node(dev->of_node, node) {
1146 struct max9286_source *source;
1147 struct of_endpoint ep;
1148
1149 of_graph_parse_endpoint(node, &ep);
1150 dev_dbg(dev, "Endpoint %pOF on port %d",
1151 ep.local_node, ep.port);
1152
1153 if (ep.port > MAX9286_NUM_GMSL) {
1154 dev_err(dev, "Invalid endpoint %s on port %d",
1155 of_node_full_name(ep.local_node), ep.port);
1156 continue;
1157 }
1158
1159 /* For the source endpoint just parse the bus configuration. */
1160 if (ep.port == MAX9286_SRC_PAD) {
1161 struct v4l2_fwnode_endpoint vep = {
1162 .bus_type = V4L2_MBUS_CSI2_DPHY
1163 };
1164 int ret;
1165
1166 ret = v4l2_fwnode_endpoint_parse(
1167 of_fwnode_handle(node), &vep);
1168 if (ret) {
1169 of_node_put(node);
1170 return ret;
1171 }
1172
1173 priv->csi2_data_lanes =
1174 vep.bus.mipi_csi2.num_data_lanes;
1175
1176 continue;
1177 }
1178
1179 /* Skip if the corresponding GMSL link is unavailable. */
1180 if (!(i2c_mux_mask & BIT(ep.port)))
1181 continue;
1182
1183 if (priv->sources[ep.port].fwnode) {
1184 dev_err(dev,
1185 "Multiple port endpoints are not supported: %d",
1186 ep.port);
1187
1188 continue;
1189 }
1190
1191 source = &priv->sources[ep.port];
1192 source->fwnode = fwnode_graph_get_remote_endpoint(
1193 of_fwnode_handle(node));
1194 if (!source->fwnode) {
1195 dev_err(dev,
1196 "Endpoint %pOF has no remote endpoint connection\n",
1197 ep.local_node);
1198
1199 continue;
1200 }
1201
1202 priv->source_mask |= BIT(ep.port);
1203 priv->nsources++;
1204 }
1205 of_node_put(node);
1206
1207 priv->route_mask = priv->source_mask;
1208
1209 return 0;
1210}
1211
1212static int max9286_probe(struct i2c_client *client)
1213{
1214 struct max9286_priv *priv;
1215 int ret;
1216
1217 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
1218 if (!priv)
1219 return -ENOMEM;
1220
1221 mutex_init(&priv->mutex);
1222
1223 priv->client = client;
1224 i2c_set_clientdata(client, priv);
1225
1226 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
1227 GPIOD_OUT_HIGH);
1228 if (IS_ERR(priv->gpiod_pwdn))
1229 return PTR_ERR(priv->gpiod_pwdn);
1230
1231 gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn");
1232 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
1233
1234 /* Wait at least 4ms before the I2C lines latch to the address */
1235 if (priv->gpiod_pwdn)
1236 usleep_range(4000, 5000);
1237
1238 /*
1239 * The MAX9286 starts by default with all ports enabled, we disable all
1240 * ports early to ensure that all channels are disabled if we error out
1241 * and keep the bus consistent.
1242 */
1243 max9286_i2c_mux_close(priv);
1244
1245 /*
1246 * The MAX9286 initialises with auto-acknowledge enabled by default.
1247 * This can be invasive to other transactions on the same bus, so
1248 * disable it early. It will be enabled only as and when needed.
1249 */
1250 max9286_configure_i2c(priv, false);
1251
1252 ret = max9286_register_gpio(priv);
1253 if (ret)
1254 goto err_powerdown;
1255
1256 priv->regulator = devm_regulator_get(&client->dev, "poc");
1257 if (IS_ERR(priv->regulator)) {
1258 if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
1259 dev_err(&client->dev,
1260 "Unable to get PoC regulator (%ld)\n",
1261 PTR_ERR(priv->regulator));
1262 ret = PTR_ERR(priv->regulator);
1263 goto err_powerdown;
1264 }
1265
1266 ret = max9286_parse_dt(priv);
1267 if (ret)
1268 goto err_powerdown;
1269
1270 ret = max9286_init(&client->dev);
1271 if (ret < 0)
1272 goto err_cleanup_dt;
1273
1274 return 0;
1275
1276err_cleanup_dt:
1277 max9286_cleanup_dt(priv);
1278err_powerdown:
1279 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
1280
1281 return ret;
1282}
1283
1284static int max9286_remove(struct i2c_client *client)
1285{
1286 struct max9286_priv *priv = i2c_get_clientdata(client);
1287
1288 i2c_mux_del_adapters(priv->mux);
1289
1290 max9286_v4l2_unregister(priv);
1291
1292 regulator_disable(priv->regulator);
1293
1294 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
1295
1296 max9286_cleanup_dt(priv);
1297
1298 return 0;
1299}
1300
1301static const struct of_device_id max9286_dt_ids[] = {
1302 { .compatible = "maxim,max9286" },
1303 {},
1304};
1305MODULE_DEVICE_TABLE(of, max9286_dt_ids);
1306
1307static struct i2c_driver max9286_i2c_driver = {
1308 .driver = {
1309 .name = "max9286",
1310 .of_match_table = of_match_ptr(max9286_dt_ids),
1311 },
1312 .probe_new = max9286_probe,
1313 .remove = max9286_remove,
1314};
1315
1316module_i2c_driver(max9286_i2c_driver);
1317
1318MODULE_DESCRIPTION("Maxim MAX9286 GMSL Deserializer Driver");
1319MODULE_AUTHOR("Jacopo Mondi, Kieran Bingham, Laurent Pinchart, Niklas Söderlund, Vladimir Barinov");
1320MODULE_LICENSE("GPL");
drivers/media/i2c/ov2740.c+146−3
@@ -7,6 +7,8 @@ · 6 unmodified lines
7#include <linux/i2c.h>7#include <linux/i2c.h>
8#include <linux/module.h>8#include <linux/module.h>
9#include <linux/pm_runtime.h>9#include <linux/pm_runtime.h>
10#include <linux/nvmem-provider.h>
11#include <linux/regmap.h>
10#include <media/v4l2-ctrls.h>12#include <media/v4l2-ctrls.h>
11#include <media/v4l2-device.h>13#include <media/v4l2-device.h>
12#include <media/v4l2-fwnode.h>14#include <media/v4l2-fwnode.h>
@@ -59,6 +61,21 @@ · 46 unmodified lines
59#define OV2740_TEST_PATTERN_ENABLE BIT(7)61#define OV2740_TEST_PATTERN_ENABLE BIT(7)
60#define OV2740_TEST_PATTERN_BAR_SHIFT 262#define OV2740_TEST_PATTERN_BAR_SHIFT 2
61 63
64/* ISP CTRL00 */
65#define OV2740_REG_ISP_CTRL00 0x5000
66/* ISP CTRL01 */
67#define OV2740_REG_ISP_CTRL01 0x5001
68/* Customer Addresses: 0x7010 - 0x710F */
69#define CUSTOMER_USE_OTP_SIZE 0x100
70/* OTP registers from sensor */
71#define OV2740_REG_OTP_CUSTOMER 0x7010
72
73struct nvm_data {
74 char *nvm_buffer;
75 struct nvmem_device *nvmem;
76 struct regmap *regmap;
77};
78
62enum {79enum {
63 OV2740_LINK_FREQ_360MHZ_INDEX,80 OV2740_LINK_FREQ_360MHZ_INDEX,
64};81};
@@ -915,6 +932,130 @@ static int ov2740_remove(struct i2c_client *client) · 850 unmodified lines
915 return 0;932 return 0;
916}933}
917 934
935static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm)
936{
937 struct ov2740 *ov2740 = to_ov2740(i2c_get_clientdata(client));
938 u32 isp_ctrl00 = 0;
939 u32 isp_ctrl01 = 0;
940 int ret;
941
942 ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, &isp_ctrl00);
943 if (ret) {
944 dev_err(&client->dev, "failed to read ISP CTRL00\n");
945 goto exit;
946 }
947 ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, &isp_ctrl01);
948 if (ret) {
949 dev_err(&client->dev, "failed to read ISP CTRL01\n");
950 goto exit;
951 }
952
953 /* Clear bit 5 of ISP CTRL00 */
954 ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1,
955 isp_ctrl00 & ~BIT(5));
956 if (ret) {
957 dev_err(&client->dev, "failed to write ISP CTRL00\n");
958 goto exit;
959 }
960
961 /* Clear bit 7 of ISP CTRL01 */
962 ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1,
963 isp_ctrl01 & ~BIT(7));
964 if (ret) {
965 dev_err(&client->dev, "failed to write ISP CTRL01\n");
966 goto exit;
967 }
968
969 ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
970 OV2740_MODE_STREAMING);
971 if (ret) {
972 dev_err(&client->dev, "failed to start streaming\n");
973 goto exit;
974 }
975
976 /*
977 * Users are not allowed to access OTP-related registers and memory
978 * during the 20 ms period after streaming starts (0x100 = 0x01).
979 */
980 msleep(20);
981
982 ret = regmap_bulk_read(nvm->regmap, OV2740_REG_OTP_CUSTOMER,
983 nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE);
984 if (ret) {
985 dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret);
986 goto exit;
987 }
988
989 ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
990 OV2740_MODE_STANDBY);
991 ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01);
992 ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00);
993
994exit:
995 return ret;
996}
997
998static int ov2740_nvmem_read(void *priv, unsigned int off, void *val,
999 size_t count)
1000{
1001 struct nvm_data *nvm = priv;
1002
1003 memcpy(val, nvm->nvm_buffer + off, count);
1004
1005 return 0;
1006}
1007
1008static int ov2740_register_nvmem(struct i2c_client *client)
1009{
1010 struct nvm_data *nvm;
1011 struct regmap_config regmap_config = { };
1012 struct nvmem_config nvmem_config = { };
1013 struct regmap *regmap;
1014 struct device *dev = &client->dev;
1015 int ret = 0;
1016
1017 nvm = devm_kzalloc(dev, sizeof(*nvm), GFP_KERNEL);
1018 if (!nvm)
1019 return -ENOMEM;
1020
1021 regmap_config.val_bits = 8;
1022 regmap_config.reg_bits = 16;
1023 regmap_config.disable_locking = true;
1024 regmap = devm_regmap_init_i2c(client, &regmap_config);
1025 if (IS_ERR(regmap))
1026 return PTR_ERR(regmap);
1027
1028 nvm->regmap = regmap;
1029
1030 nvmem_config.name = dev_name(dev);
1031 nvmem_config.dev = dev;
1032 nvmem_config.read_only = true;
1033 nvmem_config.root_only = true;
1034 nvmem_config.owner = THIS_MODULE;
1035 nvmem_config.compat = true;
1036 nvmem_config.base_dev = dev;
1037 nvmem_config.reg_read = ov2740_nvmem_read;
1038 nvmem_config.reg_write = NULL;
1039 nvmem_config.priv = nvm;
1040 nvmem_config.stride = 1;
1041 nvmem_config.word_size = 1;
1042 nvmem_config.size = CUSTOMER_USE_OTP_SIZE;
1043
1044 nvm->nvmem = devm_nvmem_register(dev, &nvmem_config);
1045 if (IS_ERR(nvm->nvmem))
1046 return PTR_ERR(nvm->nvmem);
1047
1048 nvm->nvm_buffer = devm_kzalloc(dev, CUSTOMER_USE_OTP_SIZE, GFP_KERNEL);
1049 if (!nvm->nvm_buffer)
1050 return -ENOMEM;
1051
1052 ret = ov2740_load_otp_data(client, nvm);
1053 if (ret)
1054 dev_err(dev, "failed to load OTP data, ret %d\n", ret);
1055
1056 return ret;
1057}
1058
918static int ov2740_probe(struct i2c_client *client)1059static int ov2740_probe(struct i2c_client *client)
919{1060{
920 struct ov2740 *ov2740;1061 struct ov2740 *ov2740;
@@ -964,6 +1105,10 @@ static int ov2740_probe(struct i2c_client *client) · 43 unmodified lines
964 goto probe_error_media_entity_cleanup;1105 goto probe_error_media_entity_cleanup;
965 }1106 }
966 1107
1108 ret = ov2740_register_nvmem(client);
1109 if (ret)
1110 dev_err(&client->dev, "register nvmem failed, ret %d\n", ret);
1111
967 /*1112 /*
968 * Device is already turned on by i2c-core with ACPI domain PM.1113 * Device is already turned on by i2c-core with ACPI domain PM.
969 * Enable runtime PM and turn off the device.1114 * Enable runtime PM and turn off the device.
@@ -988,20 +1133,18 @@ static const struct dev_pm_ops ov2740_pm_ops = { · 18 unmodified lines
988 SET_SYSTEM_SLEEP_PM_OPS(ov2740_suspend, ov2740_resume)1133 SET_SYSTEM_SLEEP_PM_OPS(ov2740_suspend, ov2740_resume)
989};1134};
990 1135
991#ifdef CONFIG_ACPI
992static const struct acpi_device_id ov2740_acpi_ids[] = {1136static const struct acpi_device_id ov2740_acpi_ids[] = {
993 {"INT3474"},1137 {"INT3474"},
994 {}1138 {}
995};1139};
996 1140
997MODULE_DEVICE_TABLE(acpi, ov2740_acpi_ids);1141MODULE_DEVICE_TABLE(acpi, ov2740_acpi_ids);
998#endif
999 1142
1000static struct i2c_driver ov2740_i2c_driver = {1143static struct i2c_driver ov2740_i2c_driver = {
1001 .driver = {1144 .driver = {
1002 .name = "ov2740",1145 .name = "ov2740",
1003 .pm = &ov2740_pm_ops,1146 .pm = &ov2740_pm_ops,
1004 .acpi_match_table = ACPI_PTR(ov2740_acpi_ids),1147 .acpi_match_table = ov2740_acpi_ids,
1005 },1148 },
1006 .probe_new = ov2740_probe,1149 .probe_new = ov2740_probe,
1007 .remove = ov2740_remove,1150 .remove = ov2740_remove,
drivers/media/i2c/ov9640.c+1−1
@@ -772,6 +772,6 @@ static struct i2c_driver ov9640_i2c_driver = { · 771 unmodified lines
772 772
773module_i2c_driver(ov9640_i2c_driver);773module_i2c_driver(ov9640_i2c_driver);
774 774
775MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");775MODULE_DESCRIPTION("OmniVision OV96xx CMOS Image Sensor driver");
776MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");776MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
777MODULE_LICENSE("GPL v2");777MODULE_LICENSE("GPL v2");
drivers/media/i2c/rdacm20.c+667−0
@@ -0,0 +1,667 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * IMI RDACM20 GMSL Camera Driver
4 *
5 * Copyright (C) 2017-2020 Jacopo Mondi
6 * Copyright (C) 2017-2020 Kieran Bingham
7 * Copyright (C) 2017-2019 Laurent Pinchart
8 * Copyright (C) 2017-2019 Niklas Söderlund
9 * Copyright (C) 2016 Renesas Electronics Corporation
10 * Copyright (C) 2015 Cogent Embedded, Inc.
11 */
12
13/*
14 * The camera is made of an Omnivision OV10635 sensor connected to a Maxim
15 * MAX9271 GMSL serializer.
16 */
17
18#include <linux/delay.h>
19#include <linux/fwnode.h>
20#include <linux/init.h>
21#include <linux/i2c.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/videodev2.h>
25
26#include <media/v4l2-async.h>
27#include <media/v4l2-ctrls.h>
28#include <media/v4l2-subdev.h>
29
30#include "max9271.h"
31
32#define OV10635_I2C_ADDRESS 0x30
33
34#define OV10635_SOFTWARE_RESET 0x0103
35#define OV10635_PID 0x300a
36#define OV10635_VER 0x300b
37#define OV10635_SC_CMMN_SCCB_ID 0x300c
38#define OV10635_SC_CMMN_SCCB_ID_SELECT BIT(0)
39#define OV10635_VERSION 0xa635
40
41#define OV10635_WIDTH 1280
42#define OV10635_HEIGHT 800
43
44/* VTS = PCLK / FPS / HTS / 2 (= 88MHz / 1572 / 30 / 2) */
45#define OV10635_HTS 1572
46/* FPS = 29,9998 */
47#define OV10635_VTS 933
48
49/*
50 * As the drivers supports a single MEDIA_BUS_FMT_UYVY8_2X8 format we
51 * can harcode the pixel rate.
52 *
53 * PCLK is fed through the system clock, programmed @88MHz.
54 * MEDIA_BUS_FMT_UYVY8_2X8 format = 2 samples per pixel.
55 *
56 * Pixelrate = PCLK / 2
57 * FPS = (OV10635_VTS * OV10635_HTS) / PixelRate
58 * = 29,9998
59 */
60#define OV10635_PIXEL_RATE (44000000)
61
62static const struct ov10635_reg {
63 u16 reg;
64 u8 val;
65} ov10635_regs_wizard[] = {
66 { 0x301b, 0xff }, { 0x301c, 0xff }, { 0x301a, 0xff }, { 0x3011, 0x42 },
67 { 0x6900, 0x0c }, { 0x6901, 0x19 }, { 0x3503, 0x10 }, { 0x3025, 0x03 },
68 { 0x3003, 0x16 }, { 0x3004, 0x30 }, { 0x3005, 0x40 }, { 0x3006, 0x91 },
69 { 0x3600, 0x74 }, { 0x3601, 0x2b }, { 0x3612, 0x00 }, { 0x3611, 0x67 },
70 { 0x3633, 0xca }, { 0x3602, 0xaf }, { 0x3603, 0x04 }, { 0x3630, 0x28 },
71 { 0x3631, 0x16 }, { 0x3714, 0x10 }, { 0x371d, 0x01 }, { 0x4300, 0x3a },
72 { 0x3007, 0x01 }, { 0x3024, 0x03 }, { 0x3020, 0x0a }, { 0x3702, 0x0d },
73 { 0x3703, 0x20 }, { 0x3704, 0x15 }, { 0x3709, 0xa8 }, { 0x370c, 0xc7 },
74 { 0x370d, 0x80 }, { 0x3712, 0x00 }, { 0x3713, 0x20 }, { 0x3715, 0x04 },
75 { 0x381d, 0x40 }, { 0x381c, 0x00 }, { 0x3822, 0x50 }, { 0x3824, 0x10 },
76 { 0x3815, 0x8c }, { 0x3804, 0x05 }, { 0x3805, 0x1f }, { 0x3800, 0x00 },
77 { 0x3801, 0x00 }, { 0x3806, 0x03 }, { 0x3807, 0x28 }, { 0x3802, 0x00 },
78 { 0x3803, 0x07 }, { 0x3808, 0x05 }, { 0x3809, 0x00 }, { 0x380a, 0x03 },
79 { 0x380b, 0x20 }, { 0x380c, OV10635_HTS >> 8 },
80 { 0x380d, OV10635_HTS & 0xff }, { 0x380e, OV10635_VTS >> 8 },
81 { 0x380f, OV10635_VTS & 0xff }, { 0x3813, 0x02 }, { 0x3811, 0x08 },
82 { 0x381f, 0x0c }, { 0x3819, 0x04 }, { 0x3804, 0x01 }, { 0x3805, 0x00 },
83 { 0x3828, 0x03 }, { 0x3829, 0x10 }, { 0x382a, 0x10 }, { 0x3621, 0x63 },
84 { 0x5005, 0x08 }, { 0x56d5, 0x00 }, { 0x56d6, 0x80 }, { 0x56d7, 0x00 },
85 { 0x56d8, 0x00 }, { 0x56d9, 0x00 }, { 0x56da, 0x80 }, { 0x56db, 0x00 },
86 { 0x56dc, 0x00 }, { 0x56e8, 0x00 }, { 0x56e9, 0x7f }, { 0x56ea, 0x00 },
87 { 0x56eb, 0x7f }, { 0x5100, 0x00 }, { 0x5101, 0x80 }, { 0x5102, 0x00 },
88 { 0x5103, 0x80 }, { 0x5104, 0x00 }, { 0x5105, 0x80 }, { 0x5106, 0x00 },
89 { 0x5107, 0x80 }, { 0x5108, 0x00 }, { 0x5109, 0x00 }, { 0x510a, 0x00 },
90 { 0x510b, 0x00 }, { 0x510c, 0x00 }, { 0x510d, 0x00 }, { 0x510e, 0x00 },
91 { 0x510f, 0x00 }, { 0x5110, 0x00 }, { 0x5111, 0x80 }, { 0x5112, 0x00 },
92 { 0x5113, 0x80 }, { 0x5114, 0x00 }, { 0x5115, 0x80 }, { 0x5116, 0x00 },
93 { 0x5117, 0x80 }, { 0x5118, 0x00 }, { 0x5119, 0x00 }, { 0x511a, 0x00 },
94 { 0x511b, 0x00 }, { 0x511c, 0x00 }, { 0x511d, 0x00 }, { 0x511e, 0x00 },
95 { 0x511f, 0x00 }, { 0x56d0, 0x00 }, { 0x5006, 0x04 }, { 0x5608, 0x05 },
96 { 0x52d7, 0x06 }, { 0x528d, 0x08 }, { 0x5293, 0x12 }, { 0x52d3, 0x12 },
97 { 0x5288, 0x06 }, { 0x5289, 0x20 }, { 0x52c8, 0x06 }, { 0x52c9, 0x20 },
98 { 0x52cd, 0x04 }, { 0x5381, 0x00 }, { 0x5382, 0xff }, { 0x5589, 0x76 },
99 { 0x558a, 0x47 }, { 0x558b, 0xef }, { 0x558c, 0xc9 }, { 0x558d, 0x49 },
100 { 0x558e, 0x30 }, { 0x558f, 0x67 }, { 0x5590, 0x3f }, { 0x5591, 0xf0 },
101 { 0x5592, 0x10 }, { 0x55a2, 0x6d }, { 0x55a3, 0x55 }, { 0x55a4, 0xc3 },
102 { 0x55a5, 0xb5 }, { 0x55a6, 0x43 }, { 0x55a7, 0x38 }, { 0x55a8, 0x5f },
103 { 0x55a9, 0x4b }, { 0x55aa, 0xf0 }, { 0x55ab, 0x10 }, { 0x5581, 0x52 },
104 { 0x5300, 0x01 }, { 0x5301, 0x00 }, { 0x5302, 0x00 }, { 0x5303, 0x0e },
105 { 0x5304, 0x00 }, { 0x5305, 0x0e }, { 0x5306, 0x00 }, { 0x5307, 0x36 },
106 { 0x5308, 0x00 }, { 0x5309, 0xd9 }, { 0x530a, 0x00 }, { 0x530b, 0x0f },
107 { 0x530c, 0x00 }, { 0x530d, 0x2c }, { 0x530e, 0x00 }, { 0x530f, 0x59 },
108 { 0x5310, 0x00 }, { 0x5311, 0x7b }, { 0x5312, 0x00 }, { 0x5313, 0x22 },
109 { 0x5314, 0x00 }, { 0x5315, 0xd5 }, { 0x5316, 0x00 }, { 0x5317, 0x13 },
110 { 0x5318, 0x00 }, { 0x5319, 0x18 }, { 0x531a, 0x00 }, { 0x531b, 0x26 },
111 { 0x531c, 0x00 }, { 0x531d, 0xdc }, { 0x531e, 0x00 }, { 0x531f, 0x02 },
112 { 0x5320, 0x00 }, { 0x5321, 0x24 }, { 0x5322, 0x00 }, { 0x5323, 0x56 },
113 { 0x5324, 0x00 }, { 0x5325, 0x85 }, { 0x5326, 0x00 }, { 0x5327, 0x20 },
114 { 0x5609, 0x01 }, { 0x560a, 0x40 }, { 0x560b, 0x01 }, { 0x560c, 0x40 },
115 { 0x560d, 0x00 }, { 0x560e, 0xfa }, { 0x560f, 0x00 }, { 0x5610, 0xfa },
116 { 0x5611, 0x02 }, { 0x5612, 0x80 }, { 0x5613, 0x02 }, { 0x5614, 0x80 },
117 { 0x5615, 0x01 }, { 0x5616, 0x2c }, { 0x5617, 0x01 }, { 0x5618, 0x2c },
118 { 0x563b, 0x01 }, { 0x563c, 0x01 }, { 0x563d, 0x01 }, { 0x563e, 0x01 },
119 { 0x563f, 0x03 }, { 0x5640, 0x03 }, { 0x5641, 0x03 }, { 0x5642, 0x05 },
120 { 0x5643, 0x09 }, { 0x5644, 0x05 }, { 0x5645, 0x05 }, { 0x5646, 0x05 },
121 { 0x5647, 0x05 }, { 0x5651, 0x00 }, { 0x5652, 0x80 }, { 0x521a, 0x01 },
122 { 0x521b, 0x03 }, { 0x521c, 0x06 }, { 0x521d, 0x0a }, { 0x521e, 0x0e },
123 { 0x521f, 0x12 }, { 0x5220, 0x16 }, { 0x5223, 0x02 }, { 0x5225, 0x04 },
124 { 0x5227, 0x08 }, { 0x5229, 0x0c }, { 0x522b, 0x12 }, { 0x522d, 0x18 },
125 { 0x522f, 0x1e }, { 0x5241, 0x04 }, { 0x5242, 0x01 }, { 0x5243, 0x03 },
126 { 0x5244, 0x06 }, { 0x5245, 0x0a }, { 0x5246, 0x0e }, { 0x5247, 0x12 },
127 { 0x5248, 0x16 }, { 0x524a, 0x03 }, { 0x524c, 0x04 }, { 0x524e, 0x08 },
128 { 0x5250, 0x0c }, { 0x5252, 0x12 }, { 0x5254, 0x18 }, { 0x5256, 0x1e },
129 /* fifo_line_length = 2*hts */
130 { 0x4606, (2 * OV10635_HTS) >> 8 }, { 0x4607, (2 * OV10635_HTS) & 0xff },
131 /* fifo_hsync_start = 2*(hts - xres) */
132 { 0x460a, (2 * (OV10635_HTS - OV10635_WIDTH)) >> 8 },
133 { 0x460b, (2 * (OV10635_HTS - OV10635_WIDTH)) & 0xff },
134 { 0x460c, 0x00 }, { 0x4620, 0x0e },
135 /* BT601: 0x08 is also acceptable as HS/VS mode */
136 { 0x4700, 0x04 }, { 0x4701, 0x00 }, { 0x4702, 0x01 }, { 0x4004, 0x04 },
137 { 0x4005, 0x18 }, { 0x4001, 0x06 }, { 0x4050, 0x22 }, { 0x4051, 0x24 },
138 { 0x4052, 0x02 }, { 0x4057, 0x9c }, { 0x405a, 0x00 }, { 0x4202, 0x02 },
139 { 0x3023, 0x10 }, { 0x0100, 0x01 }, { 0x0100, 0x01 }, { 0x6f10, 0x07 },
140 { 0x6f11, 0x82 }, { 0x6f12, 0x04 }, { 0x6f13, 0x00 }, { 0xd000, 0x19 },
141 { 0xd001, 0xa0 }, { 0xd002, 0x00 }, { 0xd003, 0x01 }, { 0xd004, 0xa9 },
142 { 0xd005, 0xad }, { 0xd006, 0x10 }, { 0xd007, 0x40 }, { 0xd008, 0x44 },
143 { 0xd009, 0x00 }, { 0xd00a, 0x68 }, { 0xd00b, 0x00 }, { 0xd00c, 0x15 },
144 { 0xd00d, 0x00 }, { 0xd00e, 0x00 }, { 0xd00f, 0x00 }, { 0xd040, 0x9c },
145 { 0xd041, 0x21 }, { 0xd042, 0xff }, { 0xd043, 0xf8 }, { 0xd044, 0xd4 },
146 { 0xd045, 0x01 }, { 0xd046, 0x48 }, { 0xd047, 0x00 }, { 0xd048, 0xd4 },
147 { 0xd049, 0x01 }, { 0xd04a, 0x50 }, { 0xd04b, 0x04 }, { 0xd04c, 0x18 },
148 { 0xd04d, 0x60 }, { 0xd04e, 0x00 }, { 0xd04f, 0x01 }, { 0xd050, 0xa8 },
149 { 0xd051, 0x63 }, { 0xd052, 0x02 }, { 0xd053, 0xa4 }, { 0xd054, 0x85 },
150 { 0xd055, 0x43 }, { 0xd056, 0x00 }, { 0xd057, 0x00 }, { 0xd058, 0x18 },
151 { 0xd059, 0x60 }, { 0xd05a, 0x00 }, { 0xd05b, 0x01 }, { 0xd05c, 0xa8 },
152 { 0xd05d, 0x63 }, { 0xd05e, 0x03 }, { 0xd05f, 0xf0 }, { 0xd060, 0x98 },
153 { 0xd061, 0xa3 }, { 0xd062, 0x00 }, { 0xd063, 0x00 }, { 0xd064, 0x8c },
154 { 0xd065, 0x6a }, { 0xd066, 0x00 }, { 0xd067, 0x6e }, { 0xd068, 0xe5 },
155 { 0xd069, 0x85 }, { 0xd06a, 0x18 }, { 0xd06b, 0x00 }, { 0xd06c, 0x10 },
156 { 0xd06d, 0x00 }, { 0xd06e, 0x00 }, { 0xd06f, 0x10 }, { 0xd070, 0x9c },
157 { 0xd071, 0x80 }, { 0xd072, 0x00 }, { 0xd073, 0x03 }, { 0xd074, 0x18 },
158 { 0xd075, 0x60 }, { 0xd076, 0x00 }, { 0xd077, 0x01 }, { 0xd078, 0xa8 },
159 { 0xd079, 0x63 }, { 0xd07a, 0x07 }, { 0xd07b, 0x80 }, { 0xd07c, 0x07 },
160 { 0xd07d, 0xff }, { 0xd07e, 0xf9 }, { 0xd07f, 0x03 }, { 0xd080, 0x8c },
161 { 0xd081, 0x63 }, { 0xd082, 0x00 }, { 0xd083, 0x00 }, { 0xd084, 0xa5 },
162 { 0xd085, 0x6b }, { 0xd086, 0x00 }, { 0xd087, 0xff }, { 0xd088, 0x18 },
163 { 0xd089, 0x80 }, { 0xd08a, 0x00 }, { 0xd08b, 0x01 }, { 0xd08c, 0xa8 },
164 { 0xd08d, 0x84 }, { 0xd08e, 0x01 }, { 0xd08f, 0x04 }, { 0xd090, 0xe1 },
165 { 0xd091, 0x6b }, { 0xd092, 0x58 }, { 0xd093, 0x00 }, { 0xd094, 0x94 },
166 { 0xd095, 0x6a }, { 0xd096, 0x00 }, { 0xd097, 0x70 }, { 0xd098, 0xe1 },
167 { 0xd099, 0x6b }, { 0xd09a, 0x20 }, { 0xd09b, 0x00 }, { 0xd09c, 0x95 },
168 { 0xd09d, 0x6b }, { 0xd09e, 0x00 }, { 0xd09f, 0x00 }, { 0xd0a0, 0xe4 },
169 { 0xd0a1, 0x8b }, { 0xd0a2, 0x18 }, { 0xd0a3, 0x00 }, { 0xd0a4, 0x0c },
170 { 0xd0a5, 0x00 }, { 0xd0a6, 0x00 }, { 0xd0a7, 0x23 }, { 0xd0a8, 0x15 },
171 { 0xd0a9, 0x00 }, { 0xd0aa, 0x00 }, { 0xd0ab, 0x00 }, { 0xd0ac, 0x18 },
172 { 0xd0ad, 0x60 }, { 0xd0ae, 0x80 }, { 0xd0af, 0x06 }, { 0xd0b0, 0xa8 },
173 { 0xd0b1, 0x83 }, { 0xd0b2, 0x40 }, { 0xd0b3, 0x08 }, { 0xd0b4, 0xa8 },
174 { 0xd0b5, 0xe3 }, { 0xd0b6, 0x38 }, { 0xd0b7, 0x2a }, { 0xd0b8, 0xa8 },
175 { 0xd0b9, 0xc3 }, { 0xd0ba, 0x40 }, { 0xd0bb, 0x09 }, { 0xd0bc, 0xa8 },
176 { 0xd0bd, 0xa3 }, { 0xd0be, 0x38 }, { 0xd0bf, 0x29 }, { 0xd0c0, 0x8c },
177 { 0xd0c1, 0x65 }, { 0xd0c2, 0x00 }, { 0xd0c3, 0x00 }, { 0xd0c4, 0xd8 },
178 { 0xd0c5, 0x04 }, { 0xd0c6, 0x18 }, { 0xd0c7, 0x00 }, { 0xd0c8, 0x8c },
179 { 0xd0c9, 0x67 }, { 0xd0ca, 0x00 }, { 0xd0cb, 0x00 }, { 0xd0cc, 0xd8 },
180 { 0xd0cd, 0x06 }, { 0xd0ce, 0x18 }, { 0xd0cf, 0x00 }, { 0xd0d0, 0x18 },
181 { 0xd0d1, 0x60 }, { 0xd0d2, 0x80 }, { 0xd0d3, 0x06 }, { 0xd0d4, 0xa8 },
182 { 0xd0d5, 0xe3 }, { 0xd0d6, 0x67 }, { 0xd0d7, 0x02 }, { 0xd0d8, 0xa9 },
183 { 0xd0d9, 0x03 }, { 0xd0da, 0x67 }, { 0xd0db, 0x03 }, { 0xd0dc, 0xa8 },
184 { 0xd0dd, 0xc3 }, { 0xd0de, 0x3d }, { 0xd0df, 0x05 }, { 0xd0e0, 0x8c },
185 { 0xd0e1, 0x66 }, { 0xd0e2, 0x00 }, { 0xd0e3, 0x00 }, { 0xd0e4, 0xb8 },
186 { 0xd0e5, 0x63 }, { 0xd0e6, 0x00 }, { 0xd0e7, 0x18 }, { 0xd0e8, 0xb8 },
187 { 0xd0e9, 0x63 }, { 0xd0ea, 0x00 }, { 0xd0eb, 0x98 }, { 0xd0ec, 0xbc },
188 { 0xd0ed, 0x03 }, { 0xd0ee, 0x00 }, { 0xd0ef, 0x00 }, { 0xd0f0, 0x10 },
189 { 0xd0f1, 0x00 }, { 0xd0f2, 0x00 }, { 0xd0f3, 0x16 }, { 0xd0f4, 0xb8 },
190 { 0xd0f5, 0x83 }, { 0xd0f6, 0x00 }, { 0xd0f7, 0x19 }, { 0xd0f8, 0x8c },
191 { 0xd0f9, 0x67 }, { 0xd0fa, 0x00 }, { 0xd0fb, 0x00 }, { 0xd0fc, 0xb8 },
192 { 0xd0fd, 0xa4 }, { 0xd0fe, 0x00 }, { 0xd0ff, 0x98 }, { 0xd100, 0xb8 },
193 { 0xd101, 0x83 }, { 0xd102, 0x00 }, { 0xd103, 0x08 }, { 0xd104, 0x8c },
194 { 0xd105, 0x68 }, { 0xd106, 0x00 }, { 0xd107, 0x00 }, { 0xd108, 0xe0 },
195 { 0xd109, 0x63 }, { 0xd10a, 0x20 }, { 0xd10b, 0x04 }, { 0xd10c, 0xe0 },
196 { 0xd10d, 0x65 }, { 0xd10e, 0x18 }, { 0xd10f, 0x00 }, { 0xd110, 0xa4 },
197 { 0xd111, 0x83 }, { 0xd112, 0xff }, { 0xd113, 0xff }, { 0xd114, 0xb8 },
198 { 0xd115, 0x64 }, { 0xd116, 0x00 }, { 0xd117, 0x48 }, { 0xd118, 0xd8 },
199 { 0xd119, 0x07 }, { 0xd11a, 0x18 }, { 0xd11b, 0x00 }, { 0xd11c, 0xd8 },
200 { 0xd11d, 0x08 }, { 0xd11e, 0x20 }, { 0xd11f, 0x00 }, { 0xd120, 0x9c },
201 { 0xd121, 0x60 }, { 0xd122, 0x00 }, { 0xd123, 0x00 }, { 0xd124, 0xd8 },
202 { 0xd125, 0x06 }, { 0xd126, 0x18 }, { 0xd127, 0x00 }, { 0xd128, 0x00 },
203 { 0xd129, 0x00 }, { 0xd12a, 0x00 }, { 0xd12b, 0x08 }, { 0xd12c, 0x15 },
204 { 0xd12d, 0x00 }, { 0xd12e, 0x00 }, { 0xd12f, 0x00 }, { 0xd130, 0x8c },
205 { 0xd131, 0x6a }, { 0xd132, 0x00 }, { 0xd133, 0x76 }, { 0xd134, 0xbc },
206 { 0xd135, 0x23 }, { 0xd136, 0x00 }, { 0xd137, 0x00 }, { 0xd138, 0x13 },
207 { 0xd139, 0xff }, { 0xd13a, 0xff }, { 0xd13b, 0xe6 }, { 0xd13c, 0x18 },
208 { 0xd13d, 0x60 }, { 0xd13e, 0x80 }, { 0xd13f, 0x06 }, { 0xd140, 0x03 },
209 { 0xd141, 0xff }, { 0xd142, 0xff }, { 0xd143, 0xdd }, { 0xd144, 0xa8 },
210 { 0xd145, 0x83 }, { 0xd146, 0x40 }, { 0xd147, 0x08 }, { 0xd148, 0x85 },
211 { 0xd149, 0x21 }, { 0xd14a, 0x00 }, { 0xd14b, 0x00 }, { 0xd14c, 0x85 },
212 { 0xd14d, 0x41 }, { 0xd14e, 0x00 }, { 0xd14f, 0x04 }, { 0xd150, 0x44 },
213 { 0xd151, 0x00 }, { 0xd152, 0x48 }, { 0xd153, 0x00 }, { 0xd154, 0x9c },
214 { 0xd155, 0x21 }, { 0xd156, 0x00 }, { 0xd157, 0x08 }, { 0x6f0e, 0x03 },
215 { 0x6f0f, 0x00 }, { 0x460e, 0x08 }, { 0x460f, 0x01 }, { 0x4610, 0x00 },
216 { 0x4611, 0x01 }, { 0x4612, 0x00 }, { 0x4613, 0x01 },
217 /* 8 bits */
218 { 0x4605, 0x08 },
219 /* Swap data bits order [9:0] -> [0:9] */
220 { 0x4709, 0x10 }, { 0x4608, 0x00 }, { 0x4609, 0x08 }, { 0x6804, 0x00 },
221 { 0x6805, 0x06 }, { 0x6806, 0x00 }, { 0x5120, 0x00 }, { 0x3510, 0x00 },
222 { 0x3504, 0x00 }, { 0x6800, 0x00 }, { 0x6f0d, 0x01 },
223 /* PCLK falling edge */
224 { 0x4708, 0x01 }, { 0x5000, 0xff }, { 0x5001, 0xbf }, { 0x5002, 0x7e },
225 { 0x503d, 0x00 }, { 0xc450, 0x01 }, { 0xc452, 0x04 }, { 0xc453, 0x00 },
226 { 0xc454, 0x00 }, { 0xc455, 0x01 }, { 0xc456, 0x01 }, { 0xc457, 0x00 },
227 { 0xc458, 0x00 }, { 0xc459, 0x00 }, { 0xc45b, 0x00 }, { 0xc45c, 0x01 },
228 { 0xc45d, 0x00 }, { 0xc45e, 0x00 }, { 0xc45f, 0x00 }, { 0xc460, 0x00 },
229 { 0xc461, 0x01 }, { 0xc462, 0x01 }, { 0xc464, 0x03 }, { 0xc465, 0x00 },
230 { 0xc466, 0x8a }, { 0xc467, 0x00 }, { 0xc468, 0x86 }, { 0xc469, 0x00 },
231 { 0xc46a, 0x40 }, { 0xc46b, 0x50 }, { 0xc46c, 0x30 }, { 0xc46d, 0x28 },
232 { 0xc46e, 0x60 }, { 0xc46f, 0x40 }, { 0xc47c, 0x01 }, { 0xc47d, 0x38 },
233 { 0xc47e, 0x00 }, { 0xc47f, 0x00 }, { 0xc480, 0x00 }, { 0xc481, 0xff },
234 { 0xc482, 0x00 }, { 0xc483, 0x40 }, { 0xc484, 0x00 }, { 0xc485, 0x18 },
235 { 0xc486, 0x00 }, { 0xc487, 0x18 },
236 { 0xc488, (OV10635_VTS - 8) * 16 >> 8},
237 { 0xc489, (OV10635_VTS - 8) * 16 & 0xff},
238 { 0xc48a, (OV10635_VTS - 8) * 16 >> 8},
239 { 0xc48b, (OV10635_VTS - 8) * 16 & 0xff}, { 0xc48c, 0x00 },
240 { 0xc48d, 0x04 }, { 0xc48e, 0x00 }, { 0xc48f, 0x04 }, { 0xc490, 0x03 },
241 { 0xc492, 0x20 }, { 0xc493, 0x08 }, { 0xc498, 0x02 }, { 0xc499, 0x00 },
242 { 0xc49a, 0x02 }, { 0xc49b, 0x00 }, { 0xc49c, 0x02 }, { 0xc49d, 0x00 },
243 { 0xc49e, 0x02 }, { 0xc49f, 0x60 }, { 0xc4a0, 0x03 }, { 0xc4a1, 0x00 },
244 { 0xc4a2, 0x04 }, { 0xc4a3, 0x00 }, { 0xc4a4, 0x00 }, { 0xc4a5, 0x10 },
245 { 0xc4a6, 0x00 }, { 0xc4a7, 0x40 }, { 0xc4a8, 0x00 }, { 0xc4a9, 0x80 },
246 { 0xc4aa, 0x0d }, { 0xc4ab, 0x00 }, { 0xc4ac, 0x0f }, { 0xc4ad, 0xc0 },
247 { 0xc4b4, 0x01 }, { 0xc4b5, 0x01 }, { 0xc4b6, 0x00 }, { 0xc4b7, 0x01 },
248 { 0xc4b8, 0x00 }, { 0xc4b9, 0x01 }, { 0xc4ba, 0x01 }, { 0xc4bb, 0x00 },
249 { 0xc4bc, 0x01 }, { 0xc4bd, 0x60 }, { 0xc4be, 0x02 }, { 0xc4bf, 0x33 },
250 { 0xc4c8, 0x03 }, { 0xc4c9, 0xd0 }, { 0xc4ca, 0x0e }, { 0xc4cb, 0x00 },
251 { 0xc4cc, 0x0e }, { 0xc4cd, 0x51 }, { 0xc4ce, 0x0e }, { 0xc4cf, 0x51 },
252 { 0xc4d0, 0x04 }, { 0xc4d1, 0x80 }, { 0xc4e0, 0x04 }, { 0xc4e1, 0x02 },
253 { 0xc4e2, 0x01 }, { 0xc4e4, 0x10 }, { 0xc4e5, 0x20 }, { 0xc4e6, 0x30 },
254 { 0xc4e7, 0x40 }, { 0xc4e8, 0x50 }, { 0xc4e9, 0x60 }, { 0xc4ea, 0x70 },
255 { 0xc4eb, 0x80 }, { 0xc4ec, 0x90 }, { 0xc4ed, 0xa0 }, { 0xc4ee, 0xb0 },
256 { 0xc4ef, 0xc0 }, { 0xc4f0, 0xd0 }, { 0xc4f1, 0xe0 }, { 0xc4f2, 0xf0 },
257 { 0xc4f3, 0x80 }, { 0xc4f4, 0x00 }, { 0xc4f5, 0x20 }, { 0xc4f6, 0x02 },
258 { 0xc4f7, 0x00 }, { 0xc4f8, 0x00 }, { 0xc4f9, 0x00 }, { 0xc4fa, 0x00 },
259 { 0xc4fb, 0x01 }, { 0xc4fc, 0x01 }, { 0xc4fd, 0x00 }, { 0xc4fe, 0x04 },
260 { 0xc4ff, 0x02 }, { 0xc500, 0x48 }, { 0xc501, 0x74 }, { 0xc502, 0x58 },
261 { 0xc503, 0x80 }, { 0xc504, 0x05 }, { 0xc505, 0x80 }, { 0xc506, 0x03 },
262 { 0xc507, 0x80 }, { 0xc508, 0x01 }, { 0xc509, 0xc0 }, { 0xc50a, 0x01 },
263 { 0xc50b, 0xa0 }, { 0xc50c, 0x01 }, { 0xc50d, 0x2c }, { 0xc50e, 0x01 },
264 { 0xc50f, 0x0a }, { 0xc510, 0x00 }, { 0xc511, 0x00 }, { 0xc512, 0xe5 },
265 { 0xc513, 0x14 }, { 0xc514, 0x04 }, { 0xc515, 0x00 }, { 0xc518, OV10635_VTS >> 8},
266 { 0xc519, OV10635_VTS & 0xff}, { 0xc51a, OV10635_HTS >> 8},
267 { 0xc51b, OV10635_HTS & 0xff}, { 0xc2e0, 0x00 }, { 0xc2e1, 0x51 },
268 { 0xc2e2, 0x00 }, { 0xc2e3, 0xd6 }, { 0xc2e4, 0x01 }, { 0xc2e5, 0x5e },
269 { 0xc2e9, 0x01 }, { 0xc2ea, 0x7a }, { 0xc2eb, 0x90 }, { 0xc2ed, 0x00 },
270 { 0xc2ee, 0x7a }, { 0xc2ef, 0x64 }, { 0xc308, 0x00 }, { 0xc309, 0x00 },
271 { 0xc30a, 0x00 }, { 0xc30c, 0x00 }, { 0xc30d, 0x01 }, { 0xc30e, 0x00 },
272 { 0xc30f, 0x00 }, { 0xc310, 0x01 }, { 0xc311, 0x60 }, { 0xc312, 0xff },
273 { 0xc313, 0x08 }, { 0xc314, 0x01 }, { 0xc315, 0x00 }, { 0xc316, 0xff },
274 { 0xc317, 0x0b }, { 0xc318, 0x00 }, { 0xc319, 0x0c }, { 0xc31a, 0x00 },
275 { 0xc31b, 0xe0 }, { 0xc31c, 0x00 }, { 0xc31d, 0x14 }, { 0xc31e, 0x00 },
276 { 0xc31f, 0xc5 }, { 0xc320, 0xff }, { 0xc321, 0x4b }, { 0xc322, 0xff },
277 { 0xc323, 0xf0 }, { 0xc324, 0xff }, { 0xc325, 0xe8 }, { 0xc326, 0x00 },
278 { 0xc327, 0x46 }, { 0xc328, 0xff }, { 0xc329, 0xd2 }, { 0xc32a, 0xff },
279 { 0xc32b, 0xe4 }, { 0xc32c, 0xff }, { 0xc32d, 0xbb }, { 0xc32e, 0x00 },
280 { 0xc32f, 0x61 }, { 0xc330, 0xff }, { 0xc331, 0xf9 }, { 0xc332, 0x00 },
281 { 0xc333, 0xd9 }, { 0xc334, 0x00 }, { 0xc335, 0x2e }, { 0xc336, 0x00 },
282 { 0xc337, 0xb1 }, { 0xc338, 0xff }, { 0xc339, 0x64 }, { 0xc33a, 0xff },
283 { 0xc33b, 0xeb }, { 0xc33c, 0xff }, { 0xc33d, 0xe8 }, { 0xc33e, 0x00 },
284 { 0xc33f, 0x48 }, { 0xc340, 0xff }, { 0xc341, 0xd0 }, { 0xc342, 0xff },
285 { 0xc343, 0xed }, { 0xc344, 0xff }, { 0xc345, 0xad }, { 0xc346, 0x00 },
286 { 0xc347, 0x66 }, { 0xc348, 0x01 }, { 0xc349, 0x00 }, { 0x6700, 0x04 },
287 { 0x6701, 0x7b }, { 0x6702, 0xfd }, { 0x6703, 0xf9 }, { 0x6704, 0x3d },
288 { 0x6705, 0x71 }, { 0x6706, 0x78 }, { 0x6708, 0x05 }, { 0x6f06, 0x6f },
289 { 0x6f07, 0x00 }, { 0x6f0a, 0x6f }, { 0x6f0b, 0x00 }, { 0x6f00, 0x03 },
290 { 0xc34c, 0x01 }, { 0xc34d, 0x00 }, { 0xc34e, 0x46 }, { 0xc34f, 0x55 },
291 { 0xc350, 0x00 }, { 0xc351, 0x40 }, { 0xc352, 0x00 }, { 0xc353, 0xff },
292 { 0xc354, 0x04 }, { 0xc355, 0x08 }, { 0xc356, 0x01 }, { 0xc357, 0xef },
293 { 0xc358, 0x30 }, { 0xc359, 0x01 }, { 0xc35a, 0x64 }, { 0xc35b, 0x46 },
294 { 0xc35c, 0x00 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
295 { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
296 { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
297 { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
298 { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
299 { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 },
300 { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0x3042, 0xf0 }, { 0xc261, 0x01 },
301 { 0x301b, 0xf0 }, { 0x301c, 0xf0 }, { 0x301a, 0xf0 }, { 0x6f00, 0xc3 },
302 { 0xc46a, 0x30 }, { 0xc46d, 0x20 }, { 0xc464, 0x84 }, { 0xc465, 0x00 },
303 { 0x6f00, 0x03 }, { 0x6f00, 0x43 }, { 0x381c, 0x00 }, { 0x381d, 0x40 },
304 { 0xc454, 0x01 }, { 0x6f00, 0xc3 }, { 0xc454, 0x00 }, { 0xc4b1, 0x02 },
305 { 0xc4b2, 0x01 }, { 0xc4b3, 0x03 }, { 0x6f00, 0x03 }, { 0x6f00, 0x43 },
306 /* enable FSIN (FRAMESYNC input) functionality */
307 { 0x3832, (0x0d + 2 * 0x20 + 0x15 + 38) >> 8 },
308 { 0x3833, (0x0d + 2 * 0x20 + 0x15 + 38) & 0xff },
309 { 0x3834, OV10635_VTS >> 8 }, { 0x3835, OV10635_VTS & 0xff },
310 { 0x302e, 0x01 },
311};
312
313struct rdacm20_device {
314 struct device *dev;
315 struct max9271_device *serializer;
316 struct i2c_client *sensor;
317 struct v4l2_subdev sd;
318 struct media_pad pad;
319 struct v4l2_ctrl_handler ctrls;
320 u32 addrs[2];
321};
322
323static inline struct rdacm20_device *sd_to_rdacm20(struct v4l2_subdev *sd)
324{
325 return container_of(sd, struct rdacm20_device, sd);
326}
327
328static inline struct rdacm20_device *i2c_to_rdacm20(struct i2c_client *client)
329{
330 return sd_to_rdacm20(i2c_get_clientdata(client));
331}
332
333static int ov10635_read16(struct rdacm20_device *dev, u16 reg)
334{
335 u8 buf[2] = { reg >> 8, reg & 0xff };
336 int ret;
337
338 ret = i2c_master_send(dev->sensor, buf, 2);
339 if (ret != 2) {
340 dev_dbg(dev->dev, "%s: register 0x%04x write failed (%d)\n",
341 __func__, reg, ret);
342 return ret;
343 }
344
345 ret = i2c_master_recv(dev->sensor, buf, 2);
346 if (ret < 0) {
347 dev_dbg(dev->dev, "%s: register 0x%04x read failed (%d)\n",
348 __func__, reg, ret);
349 return ret;
350 }
351
352 return (buf[0] << 8) | buf[1];
353}
354
355static int __ov10635_write(struct rdacm20_device *dev, u16 reg, u8 val)
356{
357 u8 buf[3] = { reg >> 8, reg & 0xff, val };
358 int ret;
359
360 dev_dbg(dev->dev, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
361
362 ret = i2c_master_send(dev->sensor, buf, 3);
363 return ret < 0 ? ret : 0;
364}
365
366static int ov10635_write(struct rdacm20_device *dev, u16 reg, u8 val)
367{
368 int ret;
369
370 ret = __ov10635_write(dev, reg, val);
371 if (ret < 0)
372 dev_err(dev->dev, "%s: register 0x%04x write failed (%d)\n",
373 __func__, reg, ret);
374
375 return ret;
376}
377
378static int ov10635_set_regs(struct rdacm20_device *dev,
379 const struct ov10635_reg *regs,
380 unsigned int nr_regs)
381{
382 unsigned int i;
383 int ret;
384
385 for (i = 0; i < nr_regs; i++) {
386 ret = __ov10635_write(dev, regs[i].reg, regs[i].val);
387 if (ret) {
388 dev_err(dev->dev,
389 "%s: register %u (0x%04x) write failed (%d)\n",
390 __func__, i, regs[i].reg, ret);
391 return ret;
392 }
393 }
394
395 return 0;
396}
397
398static int rdacm20_s_stream(struct v4l2_subdev *sd, int enable)
399{
400 struct rdacm20_device *dev = sd_to_rdacm20(sd);
401
402 return max9271_set_serial_link(dev->serializer, enable);
403}
404
405static int rdacm20_enum_mbus_code(struct v4l2_subdev *sd,
406 struct v4l2_subdev_pad_config *cfg,
407 struct v4l2_subdev_mbus_code_enum *code)
408{
409 if (code->pad || code->index > 0)
410 return -EINVAL;
411
412 code->code = MEDIA_BUS_FMT_UYVY8_2X8;
413
414 return 0;
415}
416
417static int rdacm20_get_fmt(struct v4l2_subdev *sd,
418 struct v4l2_subdev_pad_config *cfg,
419 struct v4l2_subdev_format *format)
420{
421 struct v4l2_mbus_framefmt *mf = &format->format;
422
423 if (format->pad)
424 return -EINVAL;
425
426 mf->width = OV10635_WIDTH;
427 mf->height = OV10635_HEIGHT;
428 mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
429 mf->colorspace = V4L2_COLORSPACE_RAW;
430 mf->field = V4L2_FIELD_NONE;
431 mf->ycbcr_enc = V4L2_YCBCR_ENC_601;
432 mf->quantization = V4L2_QUANTIZATION_FULL_RANGE;
433 mf->xfer_func = V4L2_XFER_FUNC_NONE;
434
435 return 0;
436}
437
438static struct v4l2_subdev_video_ops rdacm20_video_ops = {
439 .s_stream = rdacm20_s_stream,
440};
441
442static const struct v4l2_subdev_pad_ops rdacm20_subdev_pad_ops = {
443 .enum_mbus_code = rdacm20_enum_mbus_code,
444 .get_fmt = rdacm20_get_fmt,
445 .set_fmt = rdacm20_get_fmt,
446};
447
448static struct v4l2_subdev_ops rdacm20_subdev_ops = {
449 .video = &rdacm20_video_ops,
450 .pad = &rdacm20_subdev_pad_ops,
451};
452
453static int rdacm20_initialize(struct rdacm20_device *dev)
454{
455 unsigned int retry = 3;
456 int ret;
457
458 /* Verify communication with the MAX9271: ping to wakeup. */
459 dev->serializer->client->addr = MAX9271_DEFAULT_ADDR;
460 i2c_smbus_read_byte(dev->serializer->client);
461
462 /* Serial link disabled during config as it needs a valid pixel clock. */
463 ret = max9271_set_serial_link(dev->serializer, false);
464 if (ret)
465 return ret;
466
467 /*
468 * Ensure that we have a good link configuration before attempting to
469 * identify the device.
470 */
471 max9271_configure_i2c(dev->serializer, MAX9271_I2CSLVSH_469NS_234NS |
472 MAX9271_I2CSLVTO_1024US |
473 MAX9271_I2CMSTBT_105KBPS);
474
475 max9271_configure_gmsl_link(dev->serializer);
476
477 ret = max9271_verify_id(dev->serializer);
478 if (ret < 0)
479 return ret;
480
481 ret = max9271_set_address(dev->serializer, dev->addrs[0]);
482 if (ret < 0)
483 return ret;
484 dev->serializer->client->addr = dev->addrs[0];
485
486 /*
487 * Reset the sensor by cycling the OV10635 reset signal connected to the
488 * MAX9271 GPIO1 and verify communication with the OV10635.
489 */
490 max9271_clear_gpios(dev->serializer, MAX9271_GPIO1OUT);
491 usleep_range(10000, 15000);
492 max9271_set_gpios(dev->serializer, MAX9271_GPIO1OUT);
493 usleep_range(10000, 15000);
494
495again:
496 ret = ov10635_read16(dev, OV10635_PID);
497 if (ret < 0) {
498 if (retry--)
499 goto again;
500
501 dev_err(dev->dev, "OV10635 ID read failed (%d)\n",
502 ret);
503 return -ENXIO;
504 }
505
506 if (ret != OV10635_VERSION) {
507 if (retry--)
508 goto again;
509
510 dev_err(dev->dev, "OV10635 ID mismatch (0x%04x)\n",
511 ret);
512 return -ENXIO;
513 }
514
515 /* Change the sensor I2C address. */
516 ret = ov10635_write(dev, OV10635_SC_CMMN_SCCB_ID,
517 (dev->addrs[1] << 1) |
518 OV10635_SC_CMMN_SCCB_ID_SELECT);
519 if (ret < 0) {
520 dev_err(dev->dev,
521 "OV10635 I2C address change failed (%d)\n", ret);
522 return ret;
523 }
524 dev->sensor->addr = dev->addrs[1];
525 usleep_range(3500, 5000);
526
527 /* Program the 0V10635 initial configuration. */
528 ret = ov10635_set_regs(dev, ov10635_regs_wizard,
529 ARRAY_SIZE(ov10635_regs_wizard));
530 if (ret)
531 return ret;
532
533 dev_info(dev->dev, "Identified MAX9271 + OV10635 device\n");
534
535 return 0;
536}
537
538static int rdacm20_probe(struct i2c_client *client)
539{
540 struct rdacm20_device *dev;
541 struct fwnode_handle *ep;
542 int ret;
543
544 dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
545 if (!dev)
546 return -ENOMEM;
547 dev->dev = &client->dev;
548
549 dev->serializer = devm_kzalloc(&client->dev, sizeof(*dev->serializer),
550 GFP_KERNEL);
551 if (!dev->serializer)
552 return -ENOMEM;
553
554 dev->serializer->client = client;
555
556 ret = of_property_read_u32_array(client->dev.of_node, "reg",
557 dev->addrs, 2);
558 if (ret < 0) {
559 dev_err(dev->dev, "Invalid DT reg property: %d\n", ret);
560 return -EINVAL;
561 }
562
563 /* Create the dummy I2C client for the sensor. */
564 dev->sensor = i2c_new_dummy_device(client->adapter,
565 OV10635_I2C_ADDRESS);
566 if (IS_ERR(dev->sensor)) {
567 ret = PTR_ERR(dev->sensor);
568 goto error;
569 }
570
571 /* Initialize the hardware. */
572 ret = rdacm20_initialize(dev);
573 if (ret < 0)
574 goto error;
575
576 /* Initialize and register the subdevice. */
577 v4l2_i2c_subdev_init(&dev->sd, client, &rdacm20_subdev_ops);
578 dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
579
580 v4l2_ctrl_handler_init(&dev->ctrls, 1);
581 v4l2_ctrl_new_std(&dev->ctrls, NULL, V4L2_CID_PIXEL_RATE,
582 OV10635_PIXEL_RATE, OV10635_PIXEL_RATE, 1,
583 OV10635_PIXEL_RATE);
584 dev->sd.ctrl_handler = &dev->ctrls;
585
586 ret = dev->ctrls.error;
587 if (ret)
588 goto error_free_ctrls;
589
590 dev->pad.flags = MEDIA_PAD_FL_SOURCE;
591 dev->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
592 ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
593 if (ret < 0)
594 goto error_free_ctrls;
595
596 ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
597 if (!ep) {
598 dev_err(&client->dev,
599 "Unable to get endpoint in node %pOF\n",
600 client->dev.of_node);
601 ret = -ENOENT;
602 goto error_free_ctrls;
603 }
604 dev->sd.fwnode = ep;
605
606 ret = v4l2_async_register_subdev(&dev->sd);
607 if (ret)
608 goto error_put_node;
609
610 return 0;
611
612error_put_node:
613 fwnode_handle_put(ep);
614error_free_ctrls:
615 v4l2_ctrl_handler_free(&dev->ctrls);
616error:
617 media_entity_cleanup(&dev->sd.entity);
618 if (dev->sensor)
619 i2c_unregister_device(dev->sensor);
620
621 dev_err(&client->dev, "probe failed\n");
622
623 return ret;
624}
625
626static int rdacm20_remove(struct i2c_client *client)
627{
628 struct rdacm20_device *dev = i2c_to_rdacm20(client);
629
630 fwnode_handle_put(dev->sd.fwnode);
631 v4l2_async_unregister_subdev(&dev->sd);
632 v4l2_ctrl_handler_free(&dev->ctrls);
633 media_entity_cleanup(&dev->sd.entity);
634 i2c_unregister_device(dev->sensor);
635
636 return 0;
637}
638
639static void rdacm20_shutdown(struct i2c_client *client)
640{
641 struct rdacm20_device *dev = i2c_to_rdacm20(client);
642
643 /* make sure stream off during shutdown (reset/reboot) */
644 rdacm20_s_stream(&dev->sd, 0);
645}
646
647static const struct of_device_id rdacm20_of_ids[] = {
648 { .compatible = "imi,rdacm20", },
649 { }
650};
651MODULE_DEVICE_TABLE(of, rdacm20_of_ids);
652
653static struct i2c_driver rdacm20_i2c_driver = {
654 .driver = {
655 .name = "rdacm20",
656 .of_match_table = rdacm20_of_ids,
657 },
658 .probe_new = rdacm20_probe,
659 .remove = rdacm20_remove,
660 .shutdown = rdacm20_shutdown,
661};
662
663module_i2c_driver(rdacm20_i2c_driver);
664
665MODULE_DESCRIPTION("GMSL Camera driver for RDACM20");
666MODULE_AUTHOR("Vladimir Barinov");
667MODULE_LICENSE("GPL");
drivers/media/i2c/s5k6a3.c+1−1
@@ -197,7 +197,7 @@ static int __s5k6a3_power_on(struct s5k6a3 *sensor) · 196 unmodified lines
197 197
198 ret = pm_runtime_get(sensor->dev);198 ret = pm_runtime_get(sensor->dev);
199 if (ret < 0)199 if (ret < 0)
200 return ret;200 goto error_rpm_put;
201 201
202 ret = regulator_enable(sensor->supplies[i].consumer);202 ret = regulator_enable(sensor->supplies[i].consumer);
203 if (ret < 0)203 if (ret < 0)
drivers/media/i2c/smiapp/smiapp-core.c+2−3
@@ -508,9 +508,7 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl) · 507 unmodified lines
508 break;508 break;
509 }509 }
510 510
511 pm_runtime_get_noresume(&client->dev);511 pm_status = pm_runtime_get_if_active(&client->dev, true);
512 pm_status = pm_runtime_get_if_in_use(&client->dev);
513 pm_runtime_put_noidle(&client->dev);
514 if (!pm_status)512 if (!pm_status)
515 return 0;513 return 0;
516 514
@@ -3103,6 +3101,7 @@ static int smiapp_probe(struct i2c_client *client) · 2586 unmodified lines
3103 return 0;3101 return 0;
3104 3102
3105out_disable_runtime_pm:3103out_disable_runtime_pm:
3104 pm_runtime_put_noidle(&client->dev);
3106 pm_runtime_disable(&client->dev);3105 pm_runtime_disable(&client->dev);
3107 3106
3108out_media_entity_cleanup:3107out_media_entity_cleanup:
drivers/media/i2c/tvp5150.c+6−2
@@ -1664,8 +1664,10 @@ static int tvp5150_registered(struct v4l2_subdev *sd) · 1663 unmodified lines
1664 return 0;1664 return 0;
1665 1665
1666err:1666err:
1667 for (i = 0; i < decoder->connectors_num; i++)1667 for (i = 0; i < decoder->connectors_num; i++) {
1668 media_device_unregister_entity(&decoder->connectors[i].ent);1668 media_device_unregister_entity(&decoder->connectors[i].ent);
1669 media_entity_cleanup(&decoder->connectors[i].ent);
1670 }
1669 return ret;1671 return ret;
1670#endif1672#endif
1671 1673
@@ -2248,8 +2250,10 @@ static int tvp5150_remove(struct i2c_client *c) · 576 unmodified lines
2248 2250
2249 for (i = 0; i < decoder->connectors_num; i++)2251 for (i = 0; i < decoder->connectors_num; i++)
2250 v4l2_fwnode_connector_free(&decoder->connectors[i].base);2252 v4l2_fwnode_connector_free(&decoder->connectors[i].base);
2251 for (i = 0; i < decoder->connectors_num; i++)2253 for (i = 0; i < decoder->connectors_num; i++) {
2252 media_device_unregister_entity(&decoder->connectors[i].ent);2254 media_device_unregister_entity(&decoder->connectors[i].ent);
2255 media_entity_cleanup(&decoder->connectors[i].ent);
2256 }
2253 v4l2_async_unregister_subdev(sd);2257 v4l2_async_unregister_subdev(sd);
2254 v4l2_ctrl_handler_free(&decoder->hdl);2258 v4l2_ctrl_handler_free(&decoder->hdl);
2255 pm_runtime_disable(&c->dev);2259 pm_runtime_disable(&c->dev);
drivers/media/mc/mc-request.c+17−14
@@ -296,9 +296,18 @@ int media_request_alloc(struct media_device *mdev, int *alloc_fd) · 295 unmodified lines
296 if (WARN_ON(!mdev->ops->req_alloc ^ !mdev->ops->req_free))296 if (WARN_ON(!mdev->ops->req_alloc ^ !mdev->ops->req_free))
297 return -ENOMEM;297 return -ENOMEM;
298 298
299 if (mdev->ops->req_alloc)
300 req = mdev->ops->req_alloc(mdev);
301 else
302 req = kzalloc(sizeof(*req), GFP_KERNEL);
303 if (!req)
304 return -ENOMEM;
305
299 fd = get_unused_fd_flags(O_CLOEXEC);306 fd = get_unused_fd_flags(O_CLOEXEC);
300 if (fd < 0)307 if (fd < 0) {
301 return fd;308 ret = fd;
309 goto err_free_req;
310 }
302 311
303 filp = anon_inode_getfile("request", &request_fops, NULL, O_CLOEXEC);312 filp = anon_inode_getfile("request", &request_fops, NULL, O_CLOEXEC);
304 if (IS_ERR(filp)) {313 if (IS_ERR(filp)) {
@@ -306,15 +315,6 @@ int media_request_alloc(struct media_device *mdev, int *alloc_fd) · 1 unmodified line
306 goto err_put_fd;315 goto err_put_fd;
307 }316 }
308 317
309 if (mdev->ops->req_alloc)
310 req = mdev->ops->req_alloc(mdev);
311 else
312 req = kzalloc(sizeof(*req), GFP_KERNEL);
313 if (!req) {
314 ret = -ENOMEM;
315 goto err_fput;
316 }
317
318 filp->private_data = req;318 filp->private_data = req;
319 req->mdev = mdev;319 req->mdev = mdev;
320 req->state = MEDIA_REQUEST_STATE_IDLE;320 req->state = MEDIA_REQUEST_STATE_IDLE;
@@ -336,12 +336,15 @@ int media_request_alloc(struct media_device *mdev, int *alloc_fd) · 15 unmodified lines
336 336
337 return 0;337 return 0;
338 338
339err_fput:
340 fput(filp);
341
342err_put_fd:339err_put_fd:
343 put_unused_fd(fd);340 put_unused_fd(fd);
344 341
342err_free_req:
343 if (mdev->ops->req_free)
344 mdev->ops->req_free(req);
345 else
346 kfree(req);
347
345 return ret;348 return ret;
346}349}
347 350
drivers/media/pci/cx18/cx18-cards.c+1−1
@@ -35,7 +35,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_nxp = { · 34 unmodified lines
35 .tv = { 0x61, 0x60, I2C_CLIENT_END },35 .tv = { 0x61, 0x60, I2C_CLIENT_END },
36};36};
37 37
38/* Please add new PCI IDs to: http://pci-ids.ucw.cz/38/* Please add new PCI IDs to: https://pci-ids.ucw.cz/
39 This keeps the PCI ID database up to date. Note that the entries39 This keeps the PCI ID database up to date. Note that the entries
40 must be added under vendor 0x4444 (Conexant) as subsystem IDs.40 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
41 New vendor IDs should still be added to the vendor ID list. */41 New vendor IDs should still be added to the vendor ID list. */
drivers/media/pci/cx23885/cx23885-core.c+0−3
@@ -2235,9 +2235,6 @@ static struct pci_driver cx23885_pci_driver = { · 2234 unmodified lines
2235 .id_table = cx23885_pci_tbl,2235 .id_table = cx23885_pci_tbl,
2236 .probe = cx23885_initdev,2236 .probe = cx23885_initdev,
2237 .remove = cx23885_finidev,2237 .remove = cx23885_finidev,
2238 /* TODO */
2239 .suspend = NULL,
2240 .resume = NULL,
2241};2238};
2242 2239
2243static int __init cx23885_init(void)2240static int __init cx23885_init(void)
drivers/media/pci/cx23885/cx23888-ir.c+0−20
@@ -175,19 +175,6 @@ static inline u16 count_to_clock_divider(unsigned int d) · 174 unmodified lines
175 return (u16) d;175 return (u16) d;
176}176}
177 177
178static inline u16 ns_to_clock_divider(unsigned int ns)
179{
180 return count_to_clock_divider(
181 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000));
182}
183
184static inline unsigned int clock_divider_to_ns(unsigned int divider)
185{
186 /* Period of the Rx or Tx clock in ns */
187 return DIV_ROUND_CLOSEST((divider + 1) * 1000,
188 CX23888_IR_REFCLK_FREQ / 1000000);
189}
190
191static inline u16 carrier_freq_to_clock_divider(unsigned int freq)178static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
192{179{
193 return count_to_clock_divider(180 return count_to_clock_divider(
@@ -199,13 +186,6 @@ static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider) · 5 unmodified lines
199 return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);186 return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16);
200}187}
201 188
202static inline u16 freq_to_clock_divider(unsigned int freq,
203 unsigned int rollovers)
204{
205 return count_to_clock_divider(
206 DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers));
207}
208
209static inline unsigned int clock_divider_to_freq(unsigned int divider,189static inline unsigned int clock_divider_to_freq(unsigned int divider,
210 unsigned int rollovers)190 unsigned int rollovers)
211{191{
drivers/media/pci/cx25821/cx25821-core.c+0−3
@@ -1374,9 +1374,6 @@ static struct pci_driver cx25821_pci_driver = { · 1373 unmodified lines
1374 .id_table = cx25821_pci_tbl,1374 .id_table = cx25821_pci_tbl,
1375 .probe = cx25821_initdev,1375 .probe = cx25821_initdev,
1376 .remove = cx25821_finidev,1376 .remove = cx25821_finidev,
1377 /* TODO */
1378 .suspend = NULL,
1379 .resume = NULL,
1380};1377};
1381 1378
1382static int __init cx25821_init(void)1379static int __init cx25821_init(void)
drivers/media/pci/cx88/cx88-video.c+16−44
@@ -385,8 +385,7 @@ static int start_video_dma(struct cx8800_dev *dev, · 384 unmodified lines
385 return 0;385 return 0;
386}386}
387 387
388#ifdef CONFIG_PM388static int __maybe_unused stop_video_dma(struct cx8800_dev *dev)
389static int stop_video_dma(struct cx8800_dev *dev)
390{389{
391 struct cx88_core *core = dev->core;390 struct cx88_core *core = dev->core;
392 391
@@ -402,8 +401,8 @@ static int stop_video_dma(struct cx8800_dev *dev) · 9 unmodified lines
402 return 0;401 return 0;
403}402}
404 403
405static int restart_video_queue(struct cx8800_dev *dev,404static int __maybe_unused restart_video_queue(struct cx8800_dev *dev,
406 struct cx88_dmaqueue *q)405 struct cx88_dmaqueue *q)
407{406{
408 struct cx88_buffer *buf;407 struct cx88_buffer *buf;
409 408
@@ -415,7 +414,6 @@ static int restart_video_queue(struct cx8800_dev *dev, · 5 unmodified lines
415 }414 }
416 return 0;415 return 0;
417}416}
418#endif
419 417
420/* ------------------------------------------------------------------ */418/* ------------------------------------------------------------------ */
421 419
@@ -1551,10 +1549,9 @@ static void cx8800_finidev(struct pci_dev *pci_dev) · 1129 unmodified lines
1551 kfree(dev);1549 kfree(dev);
1552}1550}
1553 1551
1554#ifdef CONFIG_PM1552static int __maybe_unused cx8800_suspend(struct device *dev_d)
1555static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
1556{1553{
1557 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);1554 struct cx8800_dev *dev = dev_get_drvdata(dev_d);
1558 struct cx88_core *core = dev->core;1555 struct cx88_core *core = dev->core;
1559 unsigned long flags;1556 unsigned long flags;
1560 1557
@@ -1575,40 +1572,17 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) · 14 unmodified lines
1575 /* FIXME -- shutdown device */1572 /* FIXME -- shutdown device */
1576 cx88_shutdown(core);1573 cx88_shutdown(core);
1577 1574
1578 pci_save_state(pci_dev);1575 dev->state.disabled = 1;
1579 if (pci_set_power_state(pci_dev,
1580 pci_choose_state(pci_dev, state)) != 0) {
1581 pci_disable_device(pci_dev);
1582 dev->state.disabled = 1;
1583 }
1584 return 0;1576 return 0;
1585}1577}
1586 1578
1587static int cx8800_resume(struct pci_dev *pci_dev)1579static int __maybe_unused cx8800_resume(struct device *dev_d)
1588{1580{
1589 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);1581 struct cx8800_dev *dev = dev_get_drvdata(dev_d);
1590 struct cx88_core *core = dev->core;1582 struct cx88_core *core = dev->core;
1591 unsigned long flags;1583 unsigned long flags;
1592 int err;
1593 1584
1594 if (dev->state.disabled) {1585 dev->state.disabled = 0;
1595 err = pci_enable_device(pci_dev);
1596 if (err) {
1597 pr_err("can't enable device\n");
1598 return err;
1599 }
1600
1601 dev->state.disabled = 0;
1602 }
1603 err = pci_set_power_state(pci_dev, PCI_D0);
1604 if (err) {
1605 pr_err("can't set power state\n");
1606 pci_disable_device(pci_dev);
1607 dev->state.disabled = 1;
1608
1609 return err;
1610 }
1611 pci_restore_state(pci_dev);
1612 1586
1613 /* FIXME: re-initialize hardware */1587 /* FIXME: re-initialize hardware */
1614 cx88_reset(core);1588 cx88_reset(core);
@@ -1631,7 +1605,6 @@ static int cx8800_resume(struct pci_dev *pci_dev) · 16 unmodified lines
1631 1605
1632 return 0;1606 return 0;
1633}1607}
1634#endif
1635 1608
1636/* ----------------------------------------------------------- */1609/* ----------------------------------------------------------- */
1637 1610
@@ -1647,15 +1620,14 @@ static const struct pci_device_id cx8800_pci_tbl[] = { · 9 unmodified lines
1647};1620};
1648MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);1621MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
1649 1622
1623static SIMPLE_DEV_PM_OPS(cx8800_pm_ops, cx8800_suspend, cx8800_resume);
1624
1650static struct pci_driver cx8800_pci_driver = {1625static struct pci_driver cx8800_pci_driver = {
1651 .name = "cx8800",1626 .name = "cx8800",
1652 .id_table = cx8800_pci_tbl,1627 .id_table = cx8800_pci_tbl,
1653 .probe = cx8800_initdev,1628 .probe = cx8800_initdev,
1654 .remove = cx8800_finidev,1629 .remove = cx8800_finidev,
1655#ifdef CONFIG_PM1630 .driver.pm = &cx8800_pm_ops,
1656 .suspend = cx8800_suspend,
1657 .resume = cx8800_resume,
1658#endif
1659};1631};
1660 1632
1661module_pci_driver(cx8800_pci_driver);1633module_pci_driver(cx8800_pci_driver);
drivers/media/pci/dt3155/dt3155.c+1−1
@@ -426,7 +426,7 @@ static int dt3155_init_board(struct dt3155_priv *pd) · 425 unmodified lines
426 iowrite32(FIFO_EN | SRST, pd->regs + CSR1);426 iowrite32(FIFO_EN | SRST, pd->regs + CSR1);
427 iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT);427 iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT);
428 iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT);428 iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT);
429 iowrite32(0x00000020, pd->regs + FIFO_TRIGER);429 iowrite32(0x00000020, pd->regs + FIFO_TRIGGER);
430 iowrite32(0x00000103, pd->regs + XFER_MODE);430 iowrite32(0x00000103, pd->regs + XFER_MODE);
431 iowrite32(0, pd->regs + RETRY_WAIT_CNT);431 iowrite32(0, pd->regs + RETRY_WAIT_CNT);
432 iowrite32(0, pd->regs + INT_CSR);432 iowrite32(0, pd->regs + INT_CSR);
drivers/media/pci/dt3155/dt3155.h+1−1
@@ -31,7 +31,7 @@ · 30 unmodified lines
31#define ODD_DMA_STRIDE 0x2431#define ODD_DMA_STRIDE 0x24
32#define EVEN_PIXEL_FMT 0x3032#define EVEN_PIXEL_FMT 0x30
33#define ODD_PIXEL_FMT 0x3433#define ODD_PIXEL_FMT 0x34
34#define FIFO_TRIGER 0x3834#define FIFO_TRIGGER 0x38
35#define XFER_MODE 0x3C35#define XFER_MODE 0x3C
36#define CSR1 0x4036#define CSR1 0x40
37#define RETRY_WAIT_CNT 0x4437#define RETRY_WAIT_CNT 0x44
drivers/media/pci/ivtv/ivtv-cards.c+1−1
@@ -53,7 +53,7 @@ static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = { · 52 unmodified lines
53 53
54/********************** card configuration *******************************/54/********************** card configuration *******************************/
55 55
56/* Please add new PCI IDs to: http://pci-ids.ucw.cz/56/* Please add new PCI IDs to: https://pci-ids.ucw.cz/
57 This keeps the PCI ID database up to date. Note that the entries57 This keeps the PCI ID database up to date. Note that the entries
58 must be added under vendor 0x4444 (Conexant) as subsystem IDs.58 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
59 New vendor IDs should still be added to the vendor ID list. */59 New vendor IDs should still be added to the vendor ID list. */
drivers/media/pci/meye/meye.c+5−10
@@ -1528,19 +1528,16 @@ static const struct v4l2_ctrl_ops meye_ctrl_ops = { · 1527 unmodified lines
1528 .s_ctrl = meye_s_ctrl,1528 .s_ctrl = meye_s_ctrl,
1529};1529};
1530 1530
1531#ifdef CONFIG_PM1531static int __maybe_unused meye_suspend(struct device *dev)
1532static int meye_suspend(struct pci_dev *pdev, pm_message_t state)
1533{1532{
1534 pci_save_state(pdev);
1535 meye.pm_mchip_mode = meye.mchip_mode;1533 meye.pm_mchip_mode = meye.mchip_mode;
1536 mchip_hic_stop();1534 mchip_hic_stop();
1537 mchip_set(MCHIP_MM_INTA, 0x0);1535 mchip_set(MCHIP_MM_INTA, 0x0);
1538 return 0;1536 return 0;
1539}1537}
1540 1538
1541static int meye_resume(struct pci_dev *pdev)1539static int __maybe_unused meye_resume(struct device *dev)
1542{1540{
1543 pci_restore_state(pdev);
1544 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);1541 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1545 1542
1546 mchip_delay(MCHIP_HIC_CMD, 0);1543 mchip_delay(MCHIP_HIC_CMD, 0);
@@ -1562,7 +1559,6 @@ static int meye_resume(struct pci_dev *pdev) · 15 unmodified lines
1562 }1559 }
1563 return 0;1560 return 0;
1564}1561}
1565#endif
1566 1562
1567static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)1563static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
1568{1564{
@@ -1788,15 +1784,14 @@ static const struct pci_device_id meye_pci_tbl[] = { · 219 unmodified lines
1788 1784
1789MODULE_DEVICE_TABLE(pci, meye_pci_tbl);1785MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
1790 1786
1787static SIMPLE_DEV_PM_OPS(meye_pm_ops, meye_suspend, meye_resume);
1788
1791static struct pci_driver meye_driver = {1789static struct pci_driver meye_driver = {
1792 .name = "meye",1790 .name = "meye",
1793 .id_table = meye_pci_tbl,1791 .id_table = meye_pci_tbl,
1794 .probe = meye_probe,1792 .probe = meye_probe,
1795 .remove = meye_remove,1793 .remove = meye_remove,
1796#ifdef CONFIG_PM1794 .driver.pm = &meye_pm_ops,
1797 .suspend = meye_suspend,
1798 .resume = meye_resume,
1799#endif
1800};1795};
1801 1796
1802static int __init meye_init(void)1797static int __init meye_init(void)
drivers/media/pci/meye/meye.h+0−2
@@ -305,9 +305,7 @@ struct meye { · 304 unmodified lines
305 u16 colour;305 u16 colour;
306 struct meye_params params; /* additional parameters */306 struct meye_params params; /* additional parameters */
307 unsigned long in_use; /* set to 1 if the device is in use */307 unsigned long in_use; /* set to 1 if the device is in use */
308#ifdef CONFIG_PM
309 u8 pm_mchip_mode; /* old mchip mode */308 u8 pm_mchip_mode; /* old mchip mode */
310#endif
311};309};
312 310
313#endif311#endif
drivers/media/pci/saa7164/saa7164-core.c+0−3
@@ -1539,9 +1539,6 @@ static struct pci_driver saa7164_pci_driver = { · 1538 unmodified lines
1539 .id_table = saa7164_pci_tbl,1539 .id_table = saa7164_pci_tbl,
1540 .probe = saa7164_initdev,1540 .probe = saa7164_initdev,
1541 .remove = saa7164_finidev,1541 .remove = saa7164_finidev,
1542 /* TODO */
1543 .suspend = NULL,
1544 .resume = NULL,
1545};1542};
1546 1543
1547static int __init saa7164_init(void)1544static int __init saa7164_init(void)
drivers/media/pci/solo6x10/solo6x10-core.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-disp.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-eeprom.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-enc.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-g723.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-gpio.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-i2c.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-jpeg.h+1−1
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-offsets.h+1−1
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-p2m.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-regs.h+1−1
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-tw28.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-tw28.h+1−1
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10-v4l2.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/solo6x10/solo6x10.h+1−1
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*2/*
3 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
4 *4 *
5 * Original author:5 * Original author:
6 * Ben Collins <bcollins@ubuntu.com>6 * Ben Collins <bcollins@ubuntu.com>
drivers/media/pci/sta2x11/sta2x11_vip.c+15−48
@@ -1167,21 +1167,18 @@ static void sta2x11_vip_remove_one(struct pci_dev *pdev) · 1166 unmodified lines
1167 */1167 */
1168}1168}
1169 1169
1170#ifdef CONFIG_PM
1171
1172/**1170/**
1173 * sta2x11_vip_suspend - set device into power save mode1171 * sta2x11_vip_suspend - set device into power save mode
1174 * @pdev: PCI device1172 * @dev_d: PCI device
1175 * @state: new state of device
1176 *1173 *
1177 * all relevant registers are saved and an attempt to set a new state is made.1174 * all relevant registers are saved and an attempt to set a new state is made.
1178 *1175 *
1179 * return value: 0 always indicate success,1176 * return value: 0 always indicate success,
1180 * even if device could not be disabled. (workaround for hardware problem)1177 * even if device could not be disabled. (workaround for hardware problem)
1181 */1178 */
1182static int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state)1179static int __maybe_unused sta2x11_vip_suspend(struct device *dev_d)
1183{1180{
1184 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);1181 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev_d);
1185 struct sta2x11_vip *vip =1182 struct sta2x11_vip *vip =
1186 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);1183 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1187 unsigned long flags;1184 unsigned long flags;
@@ -1198,15 +1195,8 @@ static int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state) · 10 unmodified lines
1198 vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] =1195 vip->register_save_area[SAVE_COUNT + IRQ_COUNT + i] =
1199 reg_read(vip, registers_to_save[i]);1196 reg_read(vip, registers_to_save[i]);
1200 spin_unlock_irqrestore(&vip->slock, flags);1197 spin_unlock_irqrestore(&vip->slock, flags);
1201 /* save pci state */1198
1202 pci_save_state(pdev);1199 vip->disabled = 1;
1203 if (pci_set_power_state(pdev, pci_choose_state(pdev, state))) {
1204 /*
1205 * do not call pci_disable_device on sta2x11 because it
1206 * break all other Bus masters on this EP
1207 */
1208 vip->disabled = 1;
1209 }
1210 1200
1211 pr_info("VIP: suspend\n");1201 pr_info("VIP: suspend\n");
1212 return 0;1202 return 0;
@@ -1214,45 +1204,23 @@ static int sta2x11_vip_suspend(struct pci_dev *pdev, pm_message_t state) · 1 unmodified line
1214 1204
1215/**1205/**
1216 * sta2x11_vip_resume - resume device operation1206 * sta2x11_vip_resume - resume device operation
1217 * @pdev : PCI device1207 * @dev_d : PCI device
1218 *
1219 * re-enable device, set PCI state to powered and restore registers.
1220 * resume normal device operation afterwards.
1221 *1208 *
1222 * return value: 0, no error.1209 * return value: 0, no error.
1223 *1210 *
1224 * other, could not set device to power on state.1211 * other, could not set device to power on state.
1225 */1212 */
1226static int sta2x11_vip_resume(struct pci_dev *pdev)1213static int __maybe_unused sta2x11_vip_resume(struct device *dev_d)
1227{1214{
1228 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);1215 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev_d);
1229 struct sta2x11_vip *vip =1216 struct sta2x11_vip *vip =
1230 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);1217 container_of(v4l2_dev, struct sta2x11_vip, v4l2_dev);
1231 unsigned long flags;1218 unsigned long flags;
1232 int ret, i;1219 int i;
1233 1220
1234 pr_info("VIP: resume\n");1221 pr_info("VIP: resume\n");
1235 /* restore pci state */
1236 if (vip->disabled) {
1237 ret = pci_enable_device(pdev);
1238 if (ret) {
1239 pr_warn("VIP: Can't enable device.\n");
1240 return ret;
1241 }
1242 vip->disabled = 0;
1243 }
1244 ret = pci_set_power_state(pdev, PCI_D0);
1245 if (ret) {
1246 /*
1247 * do not call pci_disable_device on sta2x11 because it
1248 * break all other Bus masters on this EP
1249 */
1250 pr_warn("VIP: Can't enable device.\n");
1251 vip->disabled = 1;
1252 return ret;
1253 }
1254 1222
1255 pci_restore_state(pdev);1223 vip->disabled = 0;
1256 1224
1257 spin_lock_irqsave(&vip->slock, flags);1225 spin_lock_irqsave(&vip->slock, flags);
1258 for (i = 1; i < SAVE_COUNT; i++)1226 for (i = 1; i < SAVE_COUNT; i++)
@@ -1266,22 +1234,21 @@ static int sta2x11_vip_resume(struct pci_dev *pdev) · 7 unmodified lines
1266 return 0;1234 return 0;
1267}1235}
1268 1236
1269#endif
1270
1271static const struct pci_device_id sta2x11_vip_pci_tbl[] = {1237static const struct pci_device_id sta2x11_vip_pci_tbl[] = {
1272 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},1238 {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIP)},
1273 {0,}1239 {0,}
1274};1240};
1275 1241
1242static SIMPLE_DEV_PM_OPS(sta2x11_vip_pm_ops,
1243 sta2x11_vip_suspend,
1244 sta2x11_vip_resume);
1245
1276static struct pci_driver sta2x11_vip_driver = {1246static struct pci_driver sta2x11_vip_driver = {
1277 .name = KBUILD_MODNAME,1247 .name = KBUILD_MODNAME,
1278 .probe = sta2x11_vip_init_one,1248 .probe = sta2x11_vip_init_one,
1279 .remove = sta2x11_vip_remove_one,1249 .remove = sta2x11_vip_remove_one,
1280 .id_table = sta2x11_vip_pci_tbl,1250 .id_table = sta2x11_vip_pci_tbl,
1281#ifdef CONFIG_PM1251 .driver.pm = &sta2x11_vip_pm_ops,
1282 .suspend = sta2x11_vip_suspend,
1283 .resume = sta2x11_vip_resume,
1284#endif
1285};1252};
1286 1253
1287static int __init sta2x11_vip_init_module(void)1254static int __init sta2x11_vip_init_module(void)
drivers/media/pci/ttpci/av7110.c+3−2
@@ -406,14 +406,15 @@ static void debiirq(unsigned long cookie) · 405 unmodified lines
406 case DATA_CI_GET:406 case DATA_CI_GET:
407 {407 {
408 u8 *data = av7110->debi_virt;408 u8 *data = av7110->debi_virt;
409 u8 data_0 = data[0];
409 410
410 if ((data[0] < 2) && data[2] == 0xff) {411 if (data_0 < 2 && data[2] == 0xff) {
411 int flags = 0;412 int flags = 0;
412 if (data[5] > 0)413 if (data[5] > 0)
413 flags |= CA_CI_MODULE_PRESENT;414 flags |= CA_CI_MODULE_PRESENT;
414 if (data[5] > 5)415 if (data[5] > 5)
415 flags |= CA_CI_MODULE_READY;416 flags |= CA_CI_MODULE_READY;
416 av7110->ci_slot[data[0]].flags = flags;417 av7110->ci_slot[data_0].flags = flags;
417 } else418 } else
418 ci_get_data(&av7110->ci_rbuffer,419 ci_get_data(&av7110->ci_rbuffer,
419 av7110->debi_virt,420 av7110->debi_virt,
drivers/media/pci/ttpci/budget-core.c+8−3
@@ -369,20 +369,25 @@ static int budget_register(struct budget *budget) · 368 unmodified lines
369 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);369 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
370 370
371 if (ret < 0)371 if (ret < 0)
372 return ret;372 goto err_release_dmx;
373 373
374 budget->mem_frontend.source = DMX_MEMORY_FE;374 budget->mem_frontend.source = DMX_MEMORY_FE;
375 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);375 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);
376 if (ret < 0)376 if (ret < 0)
377 return ret;377 goto err_release_dmx;
378 378
379 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend);379 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend);
380 if (ret < 0)380 if (ret < 0)
381 return ret;381 goto err_release_dmx;
382 382
383 dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);383 dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
384 384
385 return 0;385 return 0;
386
387err_release_dmx:
388 dvb_dmxdev_release(&budget->dmxdev);
389 dvb_dmx_release(&budget->demux);
390 return ret;
386}391}
387 392
388static void budget_unregister(struct budget *budget)393static void budget_unregister(struct budget *budget)
drivers/media/pci/tw5864/tw5864-core.c+1−1
@@ -65,7 +65,7 @@ module_param_array(video_nr, int, NULL, 0444); · 64 unmodified lines
65MODULE_PARM_DESC(video_nr, "video devices numbers array");65MODULE_PARM_DESC(video_nr, "video devices numbers array");
66 66
67/*67/*
68 * Please add any new PCI IDs to: http://pci-ids.ucw.cz. This keeps68 * Please add any new PCI IDs to: https://pci-ids.ucw.cz. This keeps
69 * the PCI ID database up to date. Note that the entries must be69 * the PCI ID database up to date. Note that the entries must be
70 * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.70 * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.
71 */71 */
drivers/media/pci/tw68/tw68-core.c+12−20
@@ -57,7 +57,7 @@ static atomic_t tw68_instance = ATOMIC_INIT(0); · 56 unmodified lines
57/* ------------------------------------------------------------------ */57/* ------------------------------------------------------------------ */
58 58
59/*59/*
60 * Please add any new PCI IDs to: http://pci-ids.ucw.cz. This keeps60 * Please add any new PCI IDs to: https://pci-ids.ucw.cz. This keeps
61 * the PCI ID database up to date. Note that the entries must be61 * the PCI ID database up to date. Note that the entries must be
62 * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.62 * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.
63 */63 */
@@ -359,10 +359,9 @@ static void tw68_finidev(struct pci_dev *pci_dev) · 295 unmodified lines
359 v4l2_device_unregister(&dev->v4l2_dev);359 v4l2_device_unregister(&dev->v4l2_dev);
360}360}
361 361
362#ifdef CONFIG_PM362static int __maybe_unused tw68_suspend(struct device *dev_d)
363
364static int tw68_suspend(struct pci_dev *pci_dev , pm_message_t state)
365{363{
364 struct pci_dev *pci_dev = to_pci_dev(dev_d);
366 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);365 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
367 struct tw68_dev *dev = container_of(v4l2_dev,366 struct tw68_dev *dev = container_of(v4l2_dev,
368 struct tw68_dev, v4l2_dev);367 struct tw68_dev, v4l2_dev);
@@ -373,24 +372,19 @@ static int tw68_suspend(struct pci_dev *pci_dev , pm_message_t state) · 4 unmodified lines
373 372
374 synchronize_irq(pci_dev->irq);373 synchronize_irq(pci_dev->irq);
375 374
376 pci_save_state(pci_dev);
377 pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
378 vb2_discard_done(&dev->vidq);375 vb2_discard_done(&dev->vidq);
379 376
380 return 0;377 return 0;
381}378}
382 379
383static int tw68_resume(struct pci_dev *pci_dev)380static int __maybe_unused tw68_resume(struct device *dev_d)
384{381{
385 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);382 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev_d);
386 struct tw68_dev *dev = container_of(v4l2_dev,383 struct tw68_dev *dev = container_of(v4l2_dev,
387 struct tw68_dev, v4l2_dev);384 struct tw68_dev, v4l2_dev);
388 struct tw68_buf *buf;385 struct tw68_buf *buf;
389 unsigned long flags;386 unsigned long flags;
390 387
391 pci_set_power_state(pci_dev, PCI_D0);
392 pci_restore_state(pci_dev);
393
394 /* Do things that are done in tw68_initdev ,388 /* Do things that are done in tw68_initdev ,
395 except of initializing memory structures.*/389 except of initializing memory structures.*/
396 390
@@ -408,19 +402,17 @@ static int tw68_resume(struct pci_dev *pci_dev) · 11 unmodified lines
408 402
409 return 0;403 return 0;
410}404}
411#endif
412 405
413/* ----------------------------------------------------------- */406/* ----------------------------------------------------------- */
414 407
408static SIMPLE_DEV_PM_OPS(tw68_pm_ops, tw68_suspend, tw68_resume);
409
415static struct pci_driver tw68_pci_driver = {410static struct pci_driver tw68_pci_driver = {
416 .name = "tw68",411 .name = "tw68",
417 .id_table = tw68_pci_tbl,412 .id_table = tw68_pci_tbl,
418 .probe = tw68_initdev,413 .probe = tw68_initdev,
419 .remove = tw68_finidev,414 .remove = tw68_finidev,
420#ifdef CONFIG_PM415 .driver.pm = &tw68_pm_ops,
421 .suspend = tw68_suspend,
422 .resume = tw68_resume
423#endif
424};416};
425 417
426module_pci_driver(tw68_pci_driver);418module_pci_driver(tw68_pci_driver);
drivers/media/platform/am437x/am437x-vpfe.c+3−16
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include <media/v4l2-ctrls.h>26#include <media/v4l2-ctrls.h>
27#include <media/v4l2-event.h>27#include <media/v4l2-event.h>
28#include <media/v4l2-fwnode.h>28#include <media/v4l2-fwnode.h>
29#include <media/v4l2-rect.h>
29 30
30#include "am437x-vpfe.h"31#include "am437x-vpfe.h"
31 32
@@ -1987,20 +1988,6 @@ vpfe_g_selection(struct file *file, void *fh, struct v4l2_selection *s) · 1955 unmodified lines
1987 return 0;1988 return 0;
1988}1989}
1989 1990
1990static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1991{
1992 if (a->left < b->left || a->top < b->top)
1993 return 0;
1994
1995 if (a->left + a->width > b->left + b->width)
1996 return 0;
1997
1998 if (a->top + a->height > b->top + b->height)
1999 return 0;
2000
2001 return 1;
2002}
2003
2004static int1991static int
2005vpfe_s_selection(struct file *file, void *fh, struct v4l2_selection *s)1992vpfe_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
2006{1993{
@@ -2025,10 +2012,10 @@ vpfe_s_selection(struct file *file, void *fh, struct v4l2_selection *s) · 18 unmodified lines
2025 r.left = clamp_t(unsigned int, r.left, 0, cr.width - r.width);2012 r.left = clamp_t(unsigned int, r.left, 0, cr.width - r.width);
2026 r.top = clamp_t(unsigned int, r.top, 0, cr.height - r.height);2013 r.top = clamp_t(unsigned int, r.top, 0, cr.height - r.height);
2027 2014
2028 if (s->flags & V4L2_SEL_FLAG_LE && !enclosed_rectangle(&r, &s->r))2015 if (s->flags & V4L2_SEL_FLAG_LE && !v4l2_rect_enclosed(&r, &s->r))
2029 return -ERANGE;2016 return -ERANGE;
2030 2017
2031 if (s->flags & V4L2_SEL_FLAG_GE && !enclosed_rectangle(&s->r, &r))2018 if (s->flags & V4L2_SEL_FLAG_GE && !v4l2_rect_enclosed(&s->r, &r))
2032 return -ERANGE;2019 return -ERANGE;
2033 2020
2034 s->r = vpfe->crop = r;2021 s->r = vpfe->crop = r;
drivers/media/platform/atmel/atmel-isc-base.c+24−36
@@ -225,9 +225,6 @@ const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = { · 224 unmodified lines
225 (((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \225 (((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \
226 (((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))226 (((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))
227 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)228static inline void isc_update_v4l2_ctrls(struct isc_device *isc)
232{229{
233 struct isc_ctrls *ctrls = &isc->ctrls;230 struct isc_ctrls *ctrls = &isc->ctrls;
@@ -238,14 +235,10 @@ static inline void isc_update_v4l2_ctrls(struct isc_device *isc) · 4 unmodified lines
238 v4l2_ctrl_s_ctrl(isc->gr_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GR]);235 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]);236 v4l2_ctrl_s_ctrl(isc->gb_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GB]);
240 237
241 v4l2_ctrl_s_ctrl(isc->r_off_ctrl,238 v4l2_ctrl_s_ctrl(isc->r_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_R]);
242 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_R]));239 v4l2_ctrl_s_ctrl(isc->b_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_B]);
243 v4l2_ctrl_s_ctrl(isc->b_off_ctrl,240 v4l2_ctrl_s_ctrl(isc->gr_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GR]);
244 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_B]));241 v4l2_ctrl_s_ctrl(isc->gb_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GB]);
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}242}
250 243
251static inline void isc_update_awb_ctrls(struct isc_device *isc)244static inline void isc_update_awb_ctrls(struct isc_device *isc)
@@ -255,11 +248,11 @@ static inline void isc_update_awb_ctrls(struct isc_device *isc) · 3 unmodified lines
255 /* In here we set our actual hw pipeline config */248 /* In here we set our actual hw pipeline config */
256 249
257 regmap_write(isc->regmap, ISC_WB_O_RGR,250 regmap_write(isc->regmap, ISC_WB_O_RGR,
258 (ISC_WB_O_ZERO_VAL - (ctrls->offset[ISC_HIS_CFG_MODE_R])) |251 ((ctrls->offset[ISC_HIS_CFG_MODE_R])) |
259 ((ISC_WB_O_ZERO_VAL - ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));252 ((ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));
260 regmap_write(isc->regmap, ISC_WB_O_BGB,253 regmap_write(isc->regmap, ISC_WB_O_BGB,
261 (ISC_WB_O_ZERO_VAL - (ctrls->offset[ISC_HIS_CFG_MODE_B])) |254 ((ctrls->offset[ISC_HIS_CFG_MODE_B])) |
262 ((ISC_WB_O_ZERO_VAL - ctrls->offset[ISC_HIS_CFG_MODE_GB]) << 16));255 ((ctrls->offset[ISC_HIS_CFG_MODE_GB]) << 16));
263 regmap_write(isc->regmap, ISC_WB_G_RGR,256 regmap_write(isc->regmap, ISC_WB_G_RGR,
264 ctrls->gain[ISC_HIS_CFG_MODE_R] |257 ctrls->gain[ISC_HIS_CFG_MODE_R] |
265 (ctrls->gain[ISC_HIS_CFG_MODE_GR] << 16));258 (ctrls->gain[ISC_HIS_CFG_MODE_GR] << 16));
@@ -275,12 +268,8 @@ static inline void isc_reset_awb_ctrls(struct isc_device *isc) · 9 unmodified lines
275 for (c = ISC_HIS_CFG_MODE_GR; c <= ISC_HIS_CFG_MODE_B; c++) {268 for (c = ISC_HIS_CFG_MODE_GR; c <= ISC_HIS_CFG_MODE_B; c++) {
276 /* gains have a fixed point at 9 decimals */269 /* gains have a fixed point at 9 decimals */
277 isc->ctrls.gain[c] = 1 << 9;270 isc->ctrls.gain[c] = 1 << 9;
278 /* offsets are in 2's complements, the value271 /* offsets are in 2's complements */
279 * will be substracted from ISC_WB_O_ZERO_VAL to obtain272 isc->ctrls.offset[c] = 0;
280 * 2's complement of a value between 0 and
281 * ISC_WB_O_ZERO_VAL >> 1
282 */
283 isc->ctrls.offset[c] = ISC_WB_O_ZERO_VAL;
284 }273 }
285}274}
286 275
@@ -1774,9 +1763,12 @@ static void isc_wb_update(struct isc_ctrls *ctrls) · 1487 unmodified lines
1774 */1763 */
1775 ctrls->offset[c] = (offset[c] - 1) << 3;1764 ctrls->offset[c] = (offset[c] - 1) << 3;
1776 1765
1777 /* the offset is then taken and converted to 2's complements */1766 /*
1778 if (!ctrls->offset[c])1767 * the offset is then taken and converted to 2's complements,
1779 ctrls->offset[c] = ISC_WB_O_ZERO_VAL;1768 * and must be negative, as we subtract this value from the
1769 * color components
1770 */
1771 ctrls->offset[c] = -ctrls->offset[c];
1780 1772
1781 /*1773 /*
1782 * the stretch gain is the total number of histogram bins1774 * the stretch gain is the total number of histogram bins
@@ -1938,17 +1930,13 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl) · 155 unmodified lines
1938 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val;1930 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val;
1939 1931
1940 if (ctrl->cluster[ISC_CTRL_R_OFF]->is_new)1932 if (ctrl->cluster[ISC_CTRL_R_OFF]->is_new)
1941 ctrls->offset[ISC_HIS_CFG_MODE_R] =1933 ctrls->offset[ISC_HIS_CFG_MODE_R] = isc->r_off_ctrl->val;
1942 ISC_CTRL_V4L2_TO_ISC(isc->r_off_ctrl->val);
1943 if (ctrl->cluster[ISC_CTRL_B_OFF]->is_new)1934 if (ctrl->cluster[ISC_CTRL_B_OFF]->is_new)
1944 ctrls->offset[ISC_HIS_CFG_MODE_B] =1935 ctrls->offset[ISC_HIS_CFG_MODE_B] = isc->b_off_ctrl->val;
1945 ISC_CTRL_V4L2_TO_ISC(isc->b_off_ctrl->val);
1946 if (ctrl->cluster[ISC_CTRL_GR_OFF]->is_new)1936 if (ctrl->cluster[ISC_CTRL_GR_OFF]->is_new)
1947 ctrls->offset[ISC_HIS_CFG_MODE_GR] =1937 ctrls->offset[ISC_HIS_CFG_MODE_GR] = isc->gr_off_ctrl->val;
1948 ISC_CTRL_V4L2_TO_ISC(isc->gr_off_ctrl->val);
1949 if (ctrl->cluster[ISC_CTRL_GB_OFF]->is_new)1938 if (ctrl->cluster[ISC_CTRL_GB_OFF]->is_new)
1950 ctrls->offset[ISC_HIS_CFG_MODE_GB] =1939 ctrls->offset[ISC_HIS_CFG_MODE_GB] = isc->gb_off_ctrl->val;
1951 ISC_CTRL_V4L2_TO_ISC(isc->gb_off_ctrl->val);
1952 1940
1953 isc_update_awb_ctrls(isc);1941 isc_update_awb_ctrls(isc);
1954 1942
@@ -2010,13 +1998,13 @@ static int isc_g_volatile_awb_ctrl(struct v4l2_ctrl *ctrl) · 55 unmodified lines
2010 ctrls->gain[ISC_HIS_CFG_MODE_GB];1998 ctrls->gain[ISC_HIS_CFG_MODE_GB];
2011 1999
2012 ctrl->cluster[ISC_CTRL_R_OFF]->val =2000 ctrl->cluster[ISC_CTRL_R_OFF]->val =
2013 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_R]);2001 ctrls->offset[ISC_HIS_CFG_MODE_R];
2014 ctrl->cluster[ISC_CTRL_B_OFF]->val =2002 ctrl->cluster[ISC_CTRL_B_OFF]->val =
2015 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_B]);2003 ctrls->offset[ISC_HIS_CFG_MODE_B];
2016 ctrl->cluster[ISC_CTRL_GR_OFF]->val =2004 ctrl->cluster[ISC_CTRL_GR_OFF]->val =
2017 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_GR]);2005 ctrls->offset[ISC_HIS_CFG_MODE_GR];
2018 ctrl->cluster[ISC_CTRL_GB_OFF]->val =2006 ctrl->cluster[ISC_CTRL_GB_OFF]->val =
2019 ISC_CTRL_ISC_TO_V4L2(ctrls->offset[ISC_HIS_CFG_MODE_GB]);2007 ctrls->offset[ISC_HIS_CFG_MODE_GB];
2020 break;2008 break;
2021 }2009 }
2022 return 0;2010 return 0;
drivers/media/platform/atmel/atmel-isc-regs.h+0−2
@@ -108,8 +108,6 @@ · 107 unmodified lines
108/* ISC White Balance Gain for B, GB Register */108/* ISC White Balance Gain for B, GB Register */
109#define ISC_WB_G_BGB 0x0000006c109#define ISC_WB_G_BGB 0x0000006c
110 110
111#define ISC_WB_O_ZERO_VAL (1 << 13)
112
113/* ISC Color Filter Array Control Register */111/* ISC Color Filter Array Control Register */
114#define ISC_CFA_CTRL 0x00000070112#define ISC_CFA_CTRL 0x00000070
115 113
drivers/media/platform/atmel/atmel-isc.h+1−1
@@ -133,7 +133,7 @@ struct isc_ctrls { · 132 unmodified lines
133 133
134 /* one for each component : GR, R, GB, B */134 /* one for each component : GR, R, GB, B */
135 u32 gain[HIST_BAYER];135 u32 gain[HIST_BAYER];
136 u32 offset[HIST_BAYER];136 s32 offset[HIST_BAYER];
137 137
138 u32 hist_entry[HIST_ENTRIES];138 u32 hist_entry[HIST_ENTRIES];
139 u32 hist_count[HIST_BAYER];139 u32 hist_count[HIST_BAYER];
drivers/media/platform/atmel/atmel-sama5d2-isc.c+2−0
@@ -321,11 +321,13 @@ static const struct dev_pm_ops atmel_isc_dev_pm_ops = { · 320 unmodified lines
321 SET_RUNTIME_PM_OPS(isc_runtime_suspend, isc_runtime_resume, NULL)321 SET_RUNTIME_PM_OPS(isc_runtime_suspend, isc_runtime_resume, NULL)
322};322};
323 323
324#if IS_ENABLED(CONFIG_OF)
324static const struct of_device_id atmel_isc_of_match[] = {325static const struct of_device_id atmel_isc_of_match[] = {
325 { .compatible = "atmel,sama5d2-isc" },326 { .compatible = "atmel,sama5d2-isc" },
326 { }327 { }
327};328};
328MODULE_DEVICE_TABLE(of, atmel_isc_of_match);329MODULE_DEVICE_TABLE(of, atmel_isc_of_match);
330#endif
329 331
330static struct platform_driver atmel_isc_driver = {332static struct platform_driver atmel_isc_driver = {
331 .probe = atmel_isc_probe,333 .probe = atmel_isc_probe,
drivers/media/platform/coda/coda-common.c+2−3
@@ -2653,7 +2653,7 @@ static int coda_open(struct file *file) · 2652 unmodified lines
2653 2653
2654 ret = clk_prepare_enable(dev->clk_per);2654 ret = clk_prepare_enable(dev->clk_per);
2655 if (ret)2655 if (ret)
2656 goto err_clk_per;2656 goto err_pm_get;
2657 2657
2658 ret = clk_prepare_enable(dev->clk_ahb);2658 ret = clk_prepare_enable(dev->clk_ahb);
2659 if (ret)2659 if (ret)
@@ -2692,9 +2692,8 @@ err_ctx_init: · 32 unmodified lines
2692 clk_disable_unprepare(dev->clk_ahb);2692 clk_disable_unprepare(dev->clk_ahb);
2693err_clk_ahb:2693err_clk_ahb:
2694 clk_disable_unprepare(dev->clk_per);2694 clk_disable_unprepare(dev->clk_per);
2695err_clk_per:
2696 pm_runtime_put_sync(dev->dev);
2697err_pm_get:2695err_pm_get:
2696 pm_runtime_put_sync(dev->dev);
2698 v4l2_fh_del(&ctx->fh);2697 v4l2_fh_del(&ctx->fh);
2699 v4l2_fh_exit(&ctx->fh);2698 v4l2_fh_exit(&ctx->fh);
2700err_coda_name_init:2699err_coda_name_init:
drivers/media/platform/coda/coda-jpeg.c+4−1
@@ -327,8 +327,11 @@ int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb) · 326 unmodified lines
327 "only 8-bit quantization tables supported\n");327 "only 8-bit quantization tables supported\n");
328 continue;328 continue;
329 }329 }
330 if (!ctx->params.jpeg_qmat_tab[i])330 if (!ctx->params.jpeg_qmat_tab[i]) {
331 ctx->params.jpeg_qmat_tab[i] = kmalloc(64, GFP_KERNEL);331 ctx->params.jpeg_qmat_tab[i] = kmalloc(64, GFP_KERNEL);
332 if (!ctx->params.jpeg_qmat_tab[i])
333 return -ENOMEM;
334 }
332 memcpy(ctx->params.jpeg_qmat_tab[i],335 memcpy(ctx->params.jpeg_qmat_tab[i],
333 quantization_tables[i].start, 64);336 quantization_tables[i].start, 64);
334 }337 }
drivers/media/platform/davinci/vpbe_display.c+1−1
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-only1// SPDX-License-Identifier: GPL-2.0-only
2/*2/*
3 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/3 * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
4 */4 */
5#include <linux/kernel.h>5#include <linux/kernel.h>
6#include <linux/init.h>6#include <linux/init.h>
drivers/media/platform/davinci/vpif.c+2−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5 * The hardware supports SDTV, HDTV formats, raw data capture.5 * The hardware supports SDTV, HDTV formats, raw data capture.
6 * Currently, the driver supports NTSC and PAL standards.6 * Currently, the driver supports NTSC and PAL standards.
7 *7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/8 * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
9 *9 *
10 * This program is free software; you can redistribute it and/or10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as11 * modify it under the terms of the GNU General Public License as
@@ -458,6 +458,7 @@ static int vpif_probe(struct platform_device *pdev) · 446 unmodified lines
458 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);458 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
459 if (!res_irq) {459 if (!res_irq) {
460 dev_warn(&pdev->dev, "Missing IRQ resource.\n");460 dev_warn(&pdev->dev, "Missing IRQ resource.\n");
461 pm_runtime_put(&pdev->dev);
461 return -EINVAL;462 return -EINVAL;
462 }463 }
463 464
drivers/media/platform/davinci/vpif.h+1−1
@@ -1,7 +1,7 @@
1/*1/*
2 * VPIF header file2 * VPIF header file
3 *3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/4 * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
5 *5 *
6 * This program is free software; you can redistribute it and/or6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as7 * modify it under the terms of the GNU General Public License as
drivers/media/platform/davinci/vpif_capture.c+0−2
@@ -1482,8 +1482,6 @@ probe_out: · 1481 unmodified lines
1482 /* Unregister video device */1482 /* Unregister video device */
1483 video_unregister_device(&ch->video_dev);1483 video_unregister_device(&ch->video_dev);
1484 }1484 }
1485 kfree(vpif_obj.sd);
1486 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1487 1485
1488 return err;1486 return err;
1489}1487}
drivers/media/platform/davinci/vpif_display.c+1−1
@@ -2,7 +2,7 @@ · 1 unmodified line
2 * vpif-display - VPIF display driver2 * vpif-display - VPIF display driver
3 * Display driver for TI DaVinci VPIF3 * Display driver for TI DaVinci VPIF
4 *4 *
5 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/5 * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
6 * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>6 * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
7 *7 *
8 * This program is free software; you can redistribute it and/or8 * This program is free software; you can redistribute it and/or
drivers/media/platform/davinci/vpif_display.h+1−1
@@ -1,7 +1,7 @@
1/*1/*
2 * VPIF display header file2 * VPIF display header file
3 *3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/4 * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/
5 *5 *
6 * This program is free software; you can redistribute it and/or6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as7 * modify it under the terms of the GNU General Public License as
drivers/media/platform/davinci/vpss.c+16−4
@@ -505,19 +505,31 @@ static void vpss_exit(void) · 504 unmodified lines
505 505
506static int __init vpss_init(void)506static int __init vpss_init(void)
507{507{
508 int ret;
509
508 if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control"))510 if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control"))
509 return -EBUSY;511 return -EBUSY;
510 512
511 oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);513 oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
512 if (unlikely(!oper_cfg.vpss_regs_base2)) {514 if (unlikely(!oper_cfg.vpss_regs_base2)) {
513 release_mem_region(VPSS_CLK_CTRL, 4);515 ret = -ENOMEM;
514 return -ENOMEM;516 goto err_ioremap;
515 }517 }
516 518
517 writel(VPSS_CLK_CTRL_VENCCLKEN |519 writel(VPSS_CLK_CTRL_VENCCLKEN |
518 VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);520 VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
521
522 ret = platform_driver_register(&vpss_driver);
523 if (ret)
524 goto err_pd_register;
525
526 return 0;
519 527
520 return platform_driver_register(&vpss_driver);528err_pd_register:
529 iounmap(oper_cfg.vpss_regs_base2);
530err_ioremap:
531 release_mem_region(VPSS_CLK_CTRL, 4);
532 return ret;
521}533}
522subsys_initcall(vpss_init);534subsys_initcall(vpss_init);
523module_exit(vpss_exit);535module_exit(vpss_exit);
drivers/media/platform/exynos-gsc/gsc-core.c+1−1
@@ -577,7 +577,7 @@ int gsc_try_selection(struct gsc_ctx *ctx, struct v4l2_selection *s) · 576 unmodified lines
577 v4l_bound_align_image(&tmp_w, min_w, max_w, mod_x,577 v4l_bound_align_image(&tmp_w, min_w, max_w, mod_x,
578 &tmp_h, min_h, max_h, mod_y, 0);578 &tmp_h, min_h, max_h, mod_y, 0);
579 579
580 if (!V4L2_TYPE_IS_OUTPUT(s->type) &&580 if (V4L2_TYPE_IS_CAPTURE(s->type) &&
581 (ctx->gsc_ctrls.rotate->val == 90 ||581 (ctx->gsc_ctrls.rotate->val == 90 ||
582 ctx->gsc_ctrls.rotate->val == 270))582 ctx->gsc_ctrls.rotate->val == 270))
583 gsc_check_crop_change(tmp_h, tmp_w,583 gsc_check_crop_change(tmp_h, tmp_w,
drivers/media/platform/exynos-gsc/gsc-m2m.c+1−1
@@ -255,7 +255,7 @@ static int gsc_m2m_buf_prepare(struct vb2_buffer *vb) · 254 unmodified lines
255 if (IS_ERR(frame))255 if (IS_ERR(frame))
256 return PTR_ERR(frame);256 return PTR_ERR(frame);
257 257
258 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {258 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
259 for (i = 0; i < frame->fmt->num_planes; i++)259 for (i = 0; i < frame->fmt->num_planes; i++)
260 vb2_set_plane_payload(vb, i, frame->payload[i]);260 vb2_set_plane_payload(vb, i, frame->payload[i]);
261 }261 }
drivers/media/platform/exynos4-is/fimc-capture.c+6−16
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include <media/v4l2-device.h>21#include <media/v4l2-device.h>
22#include <media/v4l2-ioctl.h>22#include <media/v4l2-ioctl.h>
23#include <media/v4l2-mem2mem.h>23#include <media/v4l2-mem2mem.h>
24#include <media/v4l2-rect.h>
24#include <media/videobuf2-v4l2.h>25#include <media/videobuf2-v4l2.h>
25#include <media/videobuf2-dma-contig.h>26#include <media/videobuf2-dma-contig.h>
26 27
@@ -478,8 +479,10 @@ static int fimc_capture_open(struct file *file) · 451 unmodified lines
478 479
479 set_bit(ST_CAPT_BUSY, &fimc->state);480 set_bit(ST_CAPT_BUSY, &fimc->state);
480 ret = pm_runtime_get_sync(&fimc->pdev->dev);481 ret = pm_runtime_get_sync(&fimc->pdev->dev);
481 if (ret < 0)482 if (ret < 0) {
483 pm_runtime_put_sync(&fimc->pdev->dev);
482 goto unlock;484 goto unlock;
485 }
483 486
484 ret = v4l2_fh_open(file);487 ret = v4l2_fh_open(file);
485 if (ret) {488 if (ret) {
@@ -1299,19 +1302,6 @@ static int fimc_cap_g_selection(struct file *file, void *fh, · 813 unmodified lines
1299 return -EINVAL;1302 return -EINVAL;
1300}1303}
1301 1304
1302/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1303static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1304{
1305 if (a->left < b->left || a->top < b->top)
1306 return 0;
1307 if (a->left + a->width > b->left + b->width)
1308 return 0;
1309 if (a->top + a->height > b->top + b->height)
1310 return 0;
1311
1312 return 1;
1313}
1314
1315static int fimc_cap_s_selection(struct file *file, void *fh,1305static int fimc_cap_s_selection(struct file *file, void *fh,
1316 struct v4l2_selection *s)1306 struct v4l2_selection *s)
1317{1307{
@@ -1334,11 +1324,11 @@ static int fimc_cap_s_selection(struct file *file, void *fh, · 16 unmodified lines
1334 fimc_capture_try_selection(ctx, &rect, s->target);1324 fimc_capture_try_selection(ctx, &rect, s->target);
1335 1325
1336 if (s->flags & V4L2_SEL_FLAG_LE &&1326 if (s->flags & V4L2_SEL_FLAG_LE &&
1337 !enclosed_rectangle(&rect, &s->r))1327 !v4l2_rect_enclosed(&rect, &s->r))
1338 return -ERANGE;1328 return -ERANGE;
1339 1329
1340 if (s->flags & V4L2_SEL_FLAG_GE &&1330 if (s->flags & V4L2_SEL_FLAG_GE &&
1341 !enclosed_rectangle(&s->r, &rect))1331 !v4l2_rect_enclosed(&s->r, &rect))
1342 return -ERANGE;1332 return -ERANGE;
1343 1333
1344 s->r = rect;1334 s->r = rect;
drivers/media/platform/exynos4-is/fimc-is.c+1−0
@@ -871,6 +871,7 @@ err_dfs: · 870 unmodified lines
871err_sd:871err_sd:
872 fimc_is_unregister_subdevs(is);872 fimc_is_unregister_subdevs(is);
873err_pm:873err_pm:
874 pm_runtime_put_noidle(dev);
874 if (!pm_runtime_enabled(dev))875 if (!pm_runtime_enabled(dev))
875 fimc_is_runtime_suspend(dev);876 fimc_is_runtime_suspend(dev);
876err_irq:877err_irq:
drivers/media/platform/exynos4-is/fimc-isp-video.c+1−0
@@ -293,6 +293,7 @@ static int isp_video_open(struct file *file) · 292 unmodified lines
293 if (!ret)293 if (!ret)
294 goto unlock;294 goto unlock;
295rel_fh:295rel_fh:
296 pm_runtime_put_noidle(&isp->pdev->dev);
296 v4l2_fh_release(file);297 v4l2_fh_release(file);
297unlock:298unlock:
298 mutex_unlock(&isp->video_lock);299 mutex_unlock(&isp->video_lock);
drivers/media/platform/exynos4-is/fimc-lite.c+3−15
@@ -25,6 +25,7 @@ · 24 unmodified lines
25#include <media/v4l2-device.h>25#include <media/v4l2-device.h>
26#include <media/v4l2-ioctl.h>26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-mem2mem.h>27#include <media/v4l2-mem2mem.h>
28#include <media/v4l2-rect.h>
28#include <media/videobuf2-v4l2.h>29#include <media/videobuf2-v4l2.h>
29#include <media/videobuf2-dma-contig.h>30#include <media/videobuf2-dma-contig.h>
30#include <media/drv-intf/exynos-fimc.h>31#include <media/drv-intf/exynos-fimc.h>
@@ -868,19 +869,6 @@ static int fimc_lite_reqbufs(struct file *file, void *priv, · 837 unmodified lines
868 return ret;869 return ret;
869}870}
870 871
871/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
872static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
873{
874 if (a->left < b->left || a->top < b->top)
875 return 0;
876 if (a->left + a->width > b->left + b->width)
877 return 0;
878 if (a->top + a->height > b->top + b->height)
879 return 0;
880
881 return 1;
882}
883
884static int fimc_lite_g_selection(struct file *file, void *fh,872static int fimc_lite_g_selection(struct file *file, void *fh,
885 struct v4l2_selection *sel)873 struct v4l2_selection *sel)
886{874{
@@ -922,11 +910,11 @@ static int fimc_lite_s_selection(struct file *file, void *fh, · 35 unmodified lines
922 fimc_lite_try_compose(fimc, &rect);910 fimc_lite_try_compose(fimc, &rect);
923 911
924 if ((sel->flags & V4L2_SEL_FLAG_LE) &&912 if ((sel->flags & V4L2_SEL_FLAG_LE) &&
925 !enclosed_rectangle(&rect, &sel->r))913 !v4l2_rect_enclosed(&rect, &sel->r))
926 return -ERANGE;914 return -ERANGE;
927 915
928 if ((sel->flags & V4L2_SEL_FLAG_GE) &&916 if ((sel->flags & V4L2_SEL_FLAG_GE) &&
929 !enclosed_rectangle(&sel->r, &rect))917 !v4l2_rect_enclosed(&sel->r, &rect))
930 return -ERANGE;918 return -ERANGE;
931 919
932 sel->r = rect;920 sel->r = rect;
drivers/media/platform/exynos4-is/media-dev.c+4−1
@@ -1270,6 +1270,9 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd) · 1269 unmodified lines
1270 1270
1271 pctl->state_idle = pinctrl_lookup_state(pctl->pinctrl,1271 pctl->state_idle = pinctrl_lookup_state(pctl->pinctrl,
1272 PINCTRL_STATE_IDLE);1272 PINCTRL_STATE_IDLE);
1273 if (IS_ERR(pctl->state_idle))
1274 return PTR_ERR(pctl->state_idle);
1275
1273 return 0;1276 return 0;
1274}1277}
1275 1278
@@ -1439,7 +1442,7 @@ static int fimc_md_probe(struct platform_device *pdev) · 163 unmodified lines
1439 INIT_LIST_HEAD(&fmd->pipelines);1442 INIT_LIST_HEAD(&fmd->pipelines);
1440 fmd->pdev = pdev;1443 fmd->pdev = pdev;
1441 1444
1442 strscpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",1445 strscpy(fmd->media_dev.model, "Samsung S5P FIMC",
1443 sizeof(fmd->media_dev.model));1446 sizeof(fmd->media_dev.model));
1444 fmd->media_dev.ops = &fimc_md_ops;1447 fmd->media_dev.ops = &fimc_md_ops;
1445 fmd->media_dev.dev = dev;1448 fmd->media_dev.dev = dev;
drivers/media/platform/marvell-ccic/cafe-driver.c+7−24
@@ -604,44 +604,28 @@ static void cafe_pci_remove(struct pci_dev *pdev) · 603 unmodified lines
604}604}
605 605
606 606
607#ifdef CONFIG_PM
608/*607/*
609 * Basic power management.608 * Basic power management.
610 */609 */
611static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)610static int __maybe_unused cafe_pci_suspend(struct device *dev)
612{611{
613 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);612 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
614 struct cafe_camera *cam = to_cam(v4l2_dev);613 struct cafe_camera *cam = to_cam(v4l2_dev);
615 int ret;
616 614
617 ret = pci_save_state(pdev);
618 if (ret)
619 return ret;
620 mccic_suspend(&cam->mcam);615 mccic_suspend(&cam->mcam);
621 pci_disable_device(pdev);
622 return 0;616 return 0;
623}617}
624 618
625 619
626static int cafe_pci_resume(struct pci_dev *pdev)620static int __maybe_unused cafe_pci_resume(struct device *dev)
627{621{
628 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);622 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
629 struct cafe_camera *cam = to_cam(v4l2_dev);623 struct cafe_camera *cam = to_cam(v4l2_dev);
630 int ret = 0;
631 624
632 pci_restore_state(pdev);
633 ret = pci_enable_device(pdev);
634
635 if (ret) {
636 cam_warn(cam, "Unable to re-enable device on resume!\n");
637 return ret;
638 }
639 cafe_ctlr_init(&cam->mcam);625 cafe_ctlr_init(&cam->mcam);
640 return mccic_resume(&cam->mcam);626 return mccic_resume(&cam->mcam);
641}627}
642 628
643#endif /* CONFIG_PM */
644
645static const struct pci_device_id cafe_ids[] = {629static const struct pci_device_id cafe_ids[] = {
646 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL,630 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL,
647 PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) },631 PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) },
@@ -650,15 +634,14 @@ static const struct pci_device_id cafe_ids[] = { · 2 unmodified lines
650 634
651MODULE_DEVICE_TABLE(pci, cafe_ids);635MODULE_DEVICE_TABLE(pci, cafe_ids);
652 636
637static SIMPLE_DEV_PM_OPS(cafe_pci_pm_ops, cafe_pci_suspend, cafe_pci_resume);
638
653static struct pci_driver cafe_pci_driver = {639static struct pci_driver cafe_pci_driver = {
654 .name = "cafe1000-ccic",640 .name = "cafe1000-ccic",
655 .id_table = cafe_ids,641 .id_table = cafe_ids,
656 .probe = cafe_pci_probe,642 .probe = cafe_pci_probe,
657 .remove = cafe_pci_remove,643 .remove = cafe_pci_remove,
658#ifdef CONFIG_PM644 .driver.pm = &cafe_pci_pm_ops,
659 .suspend = cafe_pci_suspend,
660 .resume = cafe_pci_resume,
661#endif
662};645};
663 646
664 647
drivers/media/platform/marvell-ccic/mcam-core.c+2−3
@@ -1940,6 +1940,7 @@ int mccic_register(struct mcam_camera *cam) · 1939 unmodified lines
1940out:1940out:
1941 v4l2_async_notifier_unregister(&cam->notifier);1941 v4l2_async_notifier_unregister(&cam->notifier);
1942 v4l2_device_unregister(&cam->v4l2_dev);1942 v4l2_device_unregister(&cam->v4l2_dev);
1943 v4l2_async_notifier_cleanup(&cam->notifier);
1943 return ret;1944 return ret;
1944}1945}
1945EXPORT_SYMBOL_GPL(mccic_register);1946EXPORT_SYMBOL_GPL(mccic_register);
@@ -1961,14 +1962,13 @@ void mccic_shutdown(struct mcam_camera *cam) · 15 unmodified lines
1961 v4l2_ctrl_handler_free(&cam->ctrl_handler);1962 v4l2_ctrl_handler_free(&cam->ctrl_handler);
1962 v4l2_async_notifier_unregister(&cam->notifier);1963 v4l2_async_notifier_unregister(&cam->notifier);
1963 v4l2_device_unregister(&cam->v4l2_dev);1964 v4l2_device_unregister(&cam->v4l2_dev);
1965 v4l2_async_notifier_cleanup(&cam->notifier);
1964}1966}
1965EXPORT_SYMBOL_GPL(mccic_shutdown);1967EXPORT_SYMBOL_GPL(mccic_shutdown);
1966 1968
1967/*1969/*
1968 * Power management1970 * Power management
1969 */1971 */
1970#ifdef CONFIG_PM
1971
1972void mccic_suspend(struct mcam_camera *cam)1972void mccic_suspend(struct mcam_camera *cam)
1973{1973{
1974 mutex_lock(&cam->s_mutex);1974 mutex_lock(&cam->s_mutex);
@@ -2015,7 +2015,6 @@ int mccic_resume(struct mcam_camera *cam) · 40 unmodified lines
2015 return ret;2015 return ret;
2016}2016}
2017EXPORT_SYMBOL_GPL(mccic_resume);2017EXPORT_SYMBOL_GPL(mccic_resume);
2018#endif /* CONFIG_PM */
2019 2018
2020MODULE_LICENSE("GPL v2");2019MODULE_LICENSE("GPL v2");
2021MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");2020MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
drivers/media/platform/marvell-ccic/mcam-core.h+0−2
@@ -236,10 +236,8 @@ static inline void mcam_reg_set_bit(struct mcam_camera *cam, · 235 unmodified lines
236int mccic_register(struct mcam_camera *cam);236int mccic_register(struct mcam_camera *cam);
237int mccic_irq(struct mcam_camera *cam, unsigned int irqs);237int mccic_irq(struct mcam_camera *cam, unsigned int irqs);
238void mccic_shutdown(struct mcam_camera *cam);238void mccic_shutdown(struct mcam_camera *cam);
239#ifdef CONFIG_PM
240void mccic_suspend(struct mcam_camera *cam);239void mccic_suspend(struct mcam_camera *cam);
241int mccic_resume(struct mcam_camera *cam);240int mccic_resume(struct mcam_camera *cam);
242#endif
243 241
244/*242/*
245 * Register definitions for the m88alp01 camera interface. Offsets in bytes243 * Register definitions for the m88alp01 camera interface. Offsets in bytes
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c+1−1
@@ -731,7 +731,7 @@ static void mtk_jpeg_stop_streaming(struct vb2_queue *q) · 730 unmodified lines
731 * subsampling. Update capture queue when the stream is off.731 * subsampling. Update capture queue when the stream is off.
732 */732 */
733 if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&733 if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
734 !V4L2_TYPE_IS_OUTPUT(q->type)) {734 V4L2_TYPE_IS_CAPTURE(q->type)) {
735 struct mtk_jpeg_src_buf *src_buf;735 struct mtk_jpeg_src_buf *src_buf;
736 736
737 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);737 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c+19−57
@@ -14,46 +14,6 @@ · 13 unmodified lines
14#include "mtk_mdp_comp.h"14#include "mtk_mdp_comp.h"
15 15
16 16
17static const char * const mtk_mdp_comp_stem[MTK_MDP_COMP_TYPE_MAX] = {
18 "mdp-rdma",
19 "mdp-rsz",
20 "mdp-wdma",
21 "mdp-wrot",
22};
23
24struct mtk_mdp_comp_match {
25 enum mtk_mdp_comp_type type;
26 int alias_id;
27};
28
29static const struct mtk_mdp_comp_match mtk_mdp_matches[MTK_MDP_COMP_ID_MAX] = {
30 { MTK_MDP_RDMA, 0 },
31 { MTK_MDP_RDMA, 1 },
32 { MTK_MDP_RSZ, 0 },
33 { MTK_MDP_RSZ, 1 },
34 { MTK_MDP_RSZ, 2 },
35 { MTK_MDP_WDMA, 0 },
36 { MTK_MDP_WROT, 0 },
37 { MTK_MDP_WROT, 1 },
38};
39
40int mtk_mdp_comp_get_id(struct device *dev, struct device_node *node,
41 enum mtk_mdp_comp_type comp_type)
42{
43 int id = of_alias_get_id(node, mtk_mdp_comp_stem[comp_type]);
44 int i;
45
46 for (i = 0; i < ARRAY_SIZE(mtk_mdp_matches); i++) {
47 if (comp_type == mtk_mdp_matches[i].type &&
48 id == mtk_mdp_matches[i].alias_id)
49 return i;
50 }
51
52 dev_err(dev, "Failed to get id. type: %d, id: %d\n", comp_type, id);
53
54 return -EINVAL;
55}
56
57void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)17void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
58{18{
59 int i, err;19 int i, err;
@@ -62,8 +22,8 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp) · 2 unmodified lines
62 err = mtk_smi_larb_get(comp->larb_dev);22 err = mtk_smi_larb_get(comp->larb_dev);
63 if (err)23 if (err)
64 dev_err(dev,24 dev_err(dev,
65 "failed to get larb, err %d. type:%d id:%d\n",25 "failed to get larb, err %d. type:%d\n",
66 err, comp->type, comp->id);26 err, comp->type);
67 }27 }
68 28
69 for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {29 for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -72,8 +32,8 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp) · 2 unmodified lines
72 err = clk_prepare_enable(comp->clk[i]);32 err = clk_prepare_enable(comp->clk[i]);
73 if (err)33 if (err)
74 dev_err(dev,34 dev_err(dev,
75 "failed to enable clock, err %d. type:%d id:%d i:%d\n",35 "failed to enable clock, err %d. type:%d i:%d\n",
76 err, comp->type, comp->id, i);36 err, comp->type, i);
77 }37 }
78}38}
79 39
@@ -92,29 +52,24 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp) · 12 unmodified lines
92}52}
93 53
94int mtk_mdp_comp_init(struct device *dev, struct device_node *node,54int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
95 struct mtk_mdp_comp *comp, enum mtk_mdp_comp_id comp_id)55 struct mtk_mdp_comp *comp,
56 enum mtk_mdp_comp_type comp_type)
96{57{
97 struct device_node *larb_node;58 struct device_node *larb_node;
98 struct platform_device *larb_pdev;59 struct platform_device *larb_pdev;
60 int ret;
99 int i;61 int i;
100 62
101 if (comp_id < 0 || comp_id >= MTK_MDP_COMP_ID_MAX) {
102 dev_err(dev, "Invalid comp_id %d\n", comp_id);
103 return -EINVAL;
104 }
105
106 comp->dev_node = of_node_get(node);63 comp->dev_node = of_node_get(node);
107 comp->id = comp_id;64 comp->type = comp_type;
108 comp->type = mtk_mdp_matches[comp_id].type;
109 comp->regs = of_iomap(node, 0);
110 65
111 for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {66 for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
112 comp->clk[i] = of_clk_get(node, i);67 comp->clk[i] = of_clk_get(node, i);
113 if (IS_ERR(comp->clk[i])) {68 if (IS_ERR(comp->clk[i])) {
114 if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)69 if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
115 dev_err(dev, "Failed to get clock\n");70 dev_err(dev, "Failed to get clock\n");
116 71 ret = PTR_ERR(comp->clk[i]);
117 return PTR_ERR(comp->clk[i]);72 goto put_dev;
118 }73 }
119 74
120 /* Only RDMA needs two clocks */75 /* Only RDMA needs two clocks */
@@ -133,20 +88,27 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node, · 12 unmodified lines
133 if (!larb_node) {88 if (!larb_node) {
134 dev_err(dev,89 dev_err(dev,
135 "Missing mediadek,larb phandle in %pOF node\n", node);90 "Missing mediadek,larb phandle in %pOF node\n", node);
136 return -EINVAL;91 ret = -EINVAL;
92 goto put_dev;
137 }93 }
138 94
139 larb_pdev = of_find_device_by_node(larb_node);95 larb_pdev = of_find_device_by_node(larb_node);
140 if (!larb_pdev) {96 if (!larb_pdev) {
141 dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);97 dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
142 of_node_put(larb_node);98 of_node_put(larb_node);
143 return -EPROBE_DEFER;99 ret = -EPROBE_DEFER;
100 goto put_dev;
144 }101 }
145 of_node_put(larb_node);102 of_node_put(larb_node);
146 103
147 comp->larb_dev = &larb_pdev->dev;104 comp->larb_dev = &larb_pdev->dev;
148 105
149 return 0;106 return 0;
107
108put_dev:
109 of_node_put(comp->dev_node);
110
111 return ret;
150}112}
151 113
152void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)114void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
drivers/media/platform/mtk-mdp/mtk_mdp_comp.h+4−19
@@ -22,41 +22,26 @@ enum mtk_mdp_comp_type { · 21 unmodified lines
22 MTK_MDP_COMP_TYPE_MAX,22 MTK_MDP_COMP_TYPE_MAX,
23};23};
24 24
25enum mtk_mdp_comp_id {
26 MTK_MDP_COMP_RDMA0,
27 MTK_MDP_COMP_RDMA1,
28 MTK_MDP_COMP_RSZ0,
29 MTK_MDP_COMP_RSZ1,
30 MTK_MDP_COMP_RSZ2,
31 MTK_MDP_COMP_WDMA,
32 MTK_MDP_COMP_WROT0,
33 MTK_MDP_COMP_WROT1,
34 MTK_MDP_COMP_ID_MAX,
35};
36
37/**25/**
38 * struct mtk_mdp_comp - the MDP's function component data26 * struct mtk_mdp_comp - the MDP's function component data
27 * @node: list node to track sibing MDP components
39 * @dev_node: component device node28 * @dev_node: component device node
40 * @clk: clocks required for component29 * @clk: clocks required for component
41 * @regs: Mapped address of component registers.
42 * @larb_dev: SMI device required for component30 * @larb_dev: SMI device required for component
43 * @type: component type31 * @type: component type
44 * @id: component ID
45 */32 */
46struct mtk_mdp_comp {33struct mtk_mdp_comp {
34 struct list_head node;
47 struct device_node *dev_node;35 struct device_node *dev_node;
48 struct clk *clk[2];36 struct clk *clk[2];
49 void __iomem *regs;
50 struct device *larb_dev;37 struct device *larb_dev;
51 enum mtk_mdp_comp_type type;38 enum mtk_mdp_comp_type type;
52 enum mtk_mdp_comp_id id;
53};39};
54 40
55int mtk_mdp_comp_init(struct device *dev, struct device_node *node,41int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
56 struct mtk_mdp_comp *comp, enum mtk_mdp_comp_id comp_id);42 struct mtk_mdp_comp *comp,
43 enum mtk_mdp_comp_type comp_type);
57void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);44void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
58int mtk_mdp_comp_get_id(struct device *dev, struct device_node *node,
59 enum mtk_mdp_comp_type comp_type);
60void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);45void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
61void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);46void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
62 47
drivers/media/platform/mtk-mdp/mtk_mdp_core.c+44−25
@@ -55,19 +55,19 @@ MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids); · 54 unmodified lines
55static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)55static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
56{56{
57 struct device *dev = &mdp->pdev->dev;57 struct device *dev = &mdp->pdev->dev;
58 int i;58 struct mtk_mdp_comp *comp_node;
59 59
60 for (i = 0; i < ARRAY_SIZE(mdp->comp); i++)60 list_for_each_entry(comp_node, &mdp->comp_list, node)
61 mtk_mdp_comp_clock_on(dev, mdp->comp[i]);61 mtk_mdp_comp_clock_on(dev, comp_node);
62}62}
63 63
64static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)64static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
65{65{
66 struct device *dev = &mdp->pdev->dev;66 struct device *dev = &mdp->pdev->dev;
67 int i;67 struct mtk_mdp_comp *comp_node;
68 68
69 for (i = 0; i < ARRAY_SIZE(mdp->comp); i++)69 list_for_each_entry(comp_node, &mdp->comp_list, node)
70 mtk_mdp_comp_clock_off(dev, mdp->comp[i]);70 mtk_mdp_comp_clock_off(dev, comp_node);
71}71}
72 72
73static void mtk_mdp_wdt_worker(struct work_struct *work)73static void mtk_mdp_wdt_worker(struct work_struct *work)
@@ -91,12 +91,25 @@ static void mtk_mdp_reset_handler(void *priv) · 17 unmodified lines
91 queue_work(mdp->wdt_wq, &mdp->wdt_work);91 queue_work(mdp->wdt_wq, &mdp->wdt_work);
92}92}
93 93
94void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
95 struct mtk_mdp_comp *comp)
96{
97 list_add(&mdp->comp_list, &comp->node);
98}
99
100void mtk_mdp_unregister_component(struct mtk_mdp_dev *mdp,
101 struct mtk_mdp_comp *comp)
102{
103 list_del(&comp->node);
104}
105
94static int mtk_mdp_probe(struct platform_device *pdev)106static int mtk_mdp_probe(struct platform_device *pdev)
95{107{
96 struct mtk_mdp_dev *mdp;108 struct mtk_mdp_dev *mdp;
97 struct device *dev = &pdev->dev;109 struct device *dev = &pdev->dev;
98 struct device_node *node, *parent;110 struct device_node *node, *parent;
99 int i, ret = 0;111 struct mtk_mdp_comp *comp, *comp_temp;
112 int ret = 0;
100 113
101 mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);114 mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
102 if (!mdp)115 if (!mdp)
@@ -104,6 +117,7 @@ static int mtk_mdp_probe(struct platform_device *pdev) · 1 unmodified line
104 117
105 mdp->id = pdev->id;118 mdp->id = pdev->id;
106 mdp->pdev = pdev;119 mdp->pdev = pdev;
120 INIT_LIST_HEAD(&mdp->comp_list);
107 INIT_LIST_HEAD(&mdp->ctx_list);121 INIT_LIST_HEAD(&mdp->ctx_list);
108 122
109 mutex_init(&mdp->lock);123 mutex_init(&mdp->lock);
@@ -123,8 +137,6 @@ static int mtk_mdp_probe(struct platform_device *pdev) · 13 unmodified lines
123 for_each_child_of_node(parent, node) {137 for_each_child_of_node(parent, node) {
124 const struct of_device_id *of_id;138 const struct of_device_id *of_id;
125 enum mtk_mdp_comp_type comp_type;139 enum mtk_mdp_comp_type comp_type;
126 int comp_id;
127 struct mtk_mdp_comp *comp;
128 140
129 of_id = of_match_node(mtk_mdp_comp_dt_ids, node);141 of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
130 if (!of_id)142 if (!of_id)
@@ -137,12 +149,6 @@ static int mtk_mdp_probe(struct platform_device *pdev) · 6 unmodified lines
137 }149 }
138 150
139 comp_type = (enum mtk_mdp_comp_type)of_id->data;151 comp_type = (enum mtk_mdp_comp_type)of_id->data;
140 comp_id = mtk_mdp_comp_get_id(dev, node, comp_type);
141 if (comp_id < 0) {
142 dev_warn(dev, "Skipping unknown component %pOF\n",
143 node);
144 continue;
145 }
146 152
147 comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);153 comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
148 if (!comp) {154 if (!comp) {
@@ -150,13 +156,14 @@ static int mtk_mdp_probe(struct platform_device *pdev) · 1 unmodified line
150 of_node_put(node);156 of_node_put(node);
151 goto err_comp;157 goto err_comp;
152 }158 }
153 mdp->comp[comp_id] = comp;
154 159
155 ret = mtk_mdp_comp_init(dev, node, comp, comp_id);160 ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
156 if (ret) {161 if (ret) {
157 of_node_put(node);162 of_node_put(node);
158 goto err_comp;163 goto err_comp;
159 }164 }
165
166 mtk_mdp_register_component(mdp, comp);
160 }167 }
161 168
162 mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);169 mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
@@ -188,12 +195,20 @@ static int mtk_mdp_probe(struct platform_device *pdev) · 25 unmodified lines
188 }195 }
189 196
190 mdp->vpu_dev = vpu_get_plat_device(pdev);197 mdp->vpu_dev = vpu_get_plat_device(pdev);
191 vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,198 ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
192 VPU_RST_MDP);199 VPU_RST_MDP);
200 if (ret) {
201 dev_err(&pdev->dev, "Failed to register reset handler\n");
202 goto err_m2m_register;
203 }
193 204
194 platform_set_drvdata(pdev, mdp);205 platform_set_drvdata(pdev, mdp);
195 206
196 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));207 ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
208 if (ret) {
209 dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
210 goto err_m2m_register;
211 }
197 212
198 pm_runtime_enable(dev);213 pm_runtime_enable(dev);
199 dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);214 dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
@@ -212,8 +227,10 @@ err_alloc_wdt_wq: · 12 unmodified lines
212err_alloc_job_wq:227err_alloc_job_wq:
213 228
214err_comp:229err_comp:
215 for (i = 0; i < ARRAY_SIZE(mdp->comp); i++)230 list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
216 mtk_mdp_comp_deinit(dev, mdp->comp[i]);231 mtk_mdp_unregister_component(mdp, comp);
232 mtk_mdp_comp_deinit(dev, comp);
233 }
217 234
218 dev_dbg(dev, "err %d\n", ret);235 dev_dbg(dev, "err %d\n", ret);
219 return ret;236 return ret;
@@ -222,7 +239,7 @@ err_comp: · 2 unmodified lines
222static int mtk_mdp_remove(struct platform_device *pdev)239static int mtk_mdp_remove(struct platform_device *pdev)
223{240{
224 struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);241 struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
225 int i;242 struct mtk_mdp_comp *comp, *comp_temp;
226 243
227 pm_runtime_disable(&pdev->dev);244 pm_runtime_disable(&pdev->dev);
228 vb2_dma_contig_clear_max_seg_size(&pdev->dev);245 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
@@ -235,8 +252,10 @@ static int mtk_mdp_remove(struct platform_device *pdev) · 6 unmodified lines
235 flush_workqueue(mdp->job_wq);252 flush_workqueue(mdp->job_wq);
236 destroy_workqueue(mdp->job_wq);253 destroy_workqueue(mdp->job_wq);
237 254
238 for (i = 0; i < ARRAY_SIZE(mdp->comp); i++)255 list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
239 mtk_mdp_comp_deinit(&pdev->dev, mdp->comp[i]);256 mtk_mdp_unregister_component(mdp, comp);
257 mtk_mdp_comp_deinit(&pdev->dev, comp);
258 }
240 259
241 dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);260 dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
242 return 0;261 return 0;
drivers/media/platform/mtk-mdp/mtk_mdp_core.h+8−4
@@ -28,8 +28,6 @@ · 27 unmodified lines
28#define MTK_MDP_FMT_FLAG_CAPTURE BIT(1)28#define MTK_MDP_FMT_FLAG_CAPTURE BIT(1)
29 29
30#define MTK_MDP_VPU_INIT BIT(0)30#define MTK_MDP_VPU_INIT BIT(0)
31#define MTK_MDP_SRC_FMT BIT(1)
32#define MTK_MDP_DST_FMT BIT(2)
33#define MTK_MDP_CTX_ERROR BIT(5)31#define MTK_MDP_CTX_ERROR BIT(5)
34 32
35/**33/**
@@ -138,7 +136,7 @@ struct mtk_mdp_variant { · 102 unmodified lines
138 * @pdev: pointer to the image processor platform device136 * @pdev: pointer to the image processor platform device
139 * @variant: the IP variant information137 * @variant: the IP variant information
140 * @id: image processor device index (0..MTK_MDP_MAX_DEVS)138 * @id: image processor device index (0..MTK_MDP_MAX_DEVS)
141 * @comp: MDP function components139 * @comp_list: list of MDP function components
142 * @m2m_dev: v4l2 memory-to-memory device data140 * @m2m_dev: v4l2 memory-to-memory device data
143 * @ctx_list: list of struct mtk_mdp_ctx141 * @ctx_list: list of struct mtk_mdp_ctx
144 * @vdev: video device for image processor driver142 * @vdev: video device for image processor driver
@@ -156,7 +154,7 @@ struct mtk_mdp_dev { · 11 unmodified lines
156 struct platform_device *pdev;154 struct platform_device *pdev;
157 struct mtk_mdp_variant *variant;155 struct mtk_mdp_variant *variant;
158 u16 id;156 u16 id;
159 struct mtk_mdp_comp *comp[MTK_MDP_COMP_ID_MAX];157 struct list_head comp_list;
160 struct v4l2_m2m_dev *m2m_dev;158 struct v4l2_m2m_dev *m2m_dev;
161 struct list_head ctx_list;159 struct list_head ctx_list;
162 struct video_device *vdev;160 struct video_device *vdev;
@@ -223,6 +221,12 @@ struct mtk_mdp_ctx { · 60 unmodified lines
223 221
224extern int mtk_mdp_dbg_level;222extern int mtk_mdp_dbg_level;
225 223
224void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
225 struct mtk_mdp_comp *comp);
226
227void mtk_mdp_unregister_component(struct mtk_mdp_dev *mdp,
228 struct mtk_mdp_comp *comp);
229
226#if defined(DEBUG)230#if defined(DEBUG)
227 231
228#define mtk_mdp_dbg(level, fmt, args...) \232#define mtk_mdp_dbg(level, fmt, args...) \
drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c+37−60
@@ -193,7 +193,7 @@ static const struct mtk_mdp_fmt *mtk_mdp_try_fmt_mplane(struct mtk_mdp_ctx *ctx, · 192 unmodified lines
193 193
194 pix_mp->field = V4L2_FIELD_NONE;194 pix_mp->field = V4L2_FIELD_NONE;
195 pix_mp->pixelformat = fmt->pixelformat;195 pix_mp->pixelformat = fmt->pixelformat;
196 if (!V4L2_TYPE_IS_OUTPUT(f->type)) {196 if (V4L2_TYPE_IS_CAPTURE(f->type)) {
197 pix_mp->colorspace = ctx->colorspace;197 pix_mp->colorspace = ctx->colorspace;
198 pix_mp->xfer_func = ctx->xfer_func;198 pix_mp->xfer_func = ctx->xfer_func;
199 pix_mp->ycbcr_enc = ctx->ycbcr_enc;199 pix_mp->ycbcr_enc = ctx->ycbcr_enc;
@@ -327,9 +327,8 @@ static int mtk_mdp_try_crop(struct mtk_mdp_ctx *ctx, u32 type, · 127 unmodified lines
327 mtk_mdp_bound_align_image(&new_w, min_w, max_w, align_w,327 mtk_mdp_bound_align_image(&new_w, min_w, max_w, align_w,
328 &new_h, min_h, max_h, align_h);328 &new_h, min_h, max_h, align_h);
329 329
330 if (!V4L2_TYPE_IS_OUTPUT(type) &&330 if (V4L2_TYPE_IS_CAPTURE(type) &&
331 (ctx->ctrls.rotate->val == 90 ||331 (ctx->ctrls.rotate->val == 90 || ctx->ctrls.rotate->val == 270))
332 ctx->ctrls.rotate->val == 270))
333 mtk_mdp_check_crop_change(new_h, new_w,332 mtk_mdp_check_crop_change(new_h, new_w,
334 &r->width, &r->height);333 &r->width, &r->height);
335 else334 else
@@ -369,13 +368,6 @@ void mtk_mdp_ctx_state_lock_set(struct mtk_mdp_ctx *ctx, u32 state) · 33 unmodified lines
369 mutex_unlock(&ctx->slock);368 mutex_unlock(&ctx->slock);
370}369}
371 370
372static void mtk_mdp_ctx_state_lock_clear(struct mtk_mdp_ctx *ctx, u32 state)
373{
374 mutex_lock(&ctx->slock);
375 ctx->state &= ~state;
376 mutex_unlock(&ctx->slock);
377}
378
379static bool mtk_mdp_ctx_state_is_set(struct mtk_mdp_ctx *ctx, u32 mask)371static bool mtk_mdp_ctx_state_is_set(struct mtk_mdp_ctx *ctx, u32 mask)
380{372{
381 bool ret;373 bool ret;
@@ -726,11 +718,6 @@ static int mtk_mdp_m2m_s_fmt_mplane(struct file *file, void *fh, · 344 unmodified lines
726 ctx->quant = pix_mp->quantization;718 ctx->quant = pix_mp->quantization;
727 }719 }
728 720
729 if (V4L2_TYPE_IS_OUTPUT(f->type))
730 mtk_mdp_ctx_state_lock_set(ctx, MTK_MDP_SRC_FMT);
731 else
732 mtk_mdp_ctx_state_lock_set(ctx, MTK_MDP_DST_FMT);
733
734 mtk_mdp_dbg(2, "[%d] type:%d, frame:%dx%d", ctx->id, f->type,721 mtk_mdp_dbg(2, "[%d] type:%d, frame:%dx%d", ctx->id, f->type,
735 frame->width, frame->height);722 frame->width, frame->height);
736 723
@@ -742,13 +729,6 @@ static int mtk_mdp_m2m_reqbufs(struct file *file, void *fh, · 5 unmodified lines
742{729{
743 struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);730 struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
744 731
745 if (reqbufs->count == 0) {
746 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
747 mtk_mdp_ctx_state_lock_clear(ctx, MTK_MDP_SRC_FMT);
748 else
749 mtk_mdp_ctx_state_lock_clear(ctx, MTK_MDP_DST_FMT);
750 }
751
752 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);732 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
753}733}
754 734
@@ -758,14 +738,6 @@ static int mtk_mdp_m2m_streamon(struct file *file, void *fh, · 3 unmodified lines
758 struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);738 struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
759 int ret;739 int ret;
760 740
761 /* The source and target color format need to be set */
762 if (V4L2_TYPE_IS_OUTPUT(type)) {
763 if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_SRC_FMT))
764 return -EINVAL;
765 } else if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_DST_FMT)) {
766 return -EINVAL;
767 }
768
769 if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_VPU_INIT)) {741 if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_VPU_INIT)) {
770 ret = mtk_mdp_vpu_init(&ctx->vpu);742 ret = mtk_mdp_vpu_init(&ctx->vpu);
771 if (ret < 0) {743 if (ret < 0) {
@@ -899,24 +871,21 @@ static int mtk_mdp_m2m_s_selection(struct file *file, void *fh, · 127 unmodified lines
899 frame = &ctx->d_frame;871 frame = &ctx->d_frame;
900 872
901 /* Check to see if scaling ratio is within supported range */873 /* Check to see if scaling ratio is within supported range */
902 if (mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_DST_FMT | MTK_MDP_SRC_FMT)) {874 if (V4L2_TYPE_IS_OUTPUT(s->type))
903 if (V4L2_TYPE_IS_OUTPUT(s->type)) {875 ret = mtk_mdp_check_scaler_ratio(variant, new_r.width,
904 ret = mtk_mdp_check_scaler_ratio(variant, new_r.width,876 new_r.height, ctx->d_frame.crop.width,
905 new_r.height, ctx->d_frame.crop.width,877 ctx->d_frame.crop.height,
906 ctx->d_frame.crop.height,878 ctx->ctrls.rotate->val);
907 ctx->ctrls.rotate->val);879 else
908 } else {880 ret = mtk_mdp_check_scaler_ratio(variant,
909 ret = mtk_mdp_check_scaler_ratio(variant,881 ctx->s_frame.crop.width,
910 ctx->s_frame.crop.width,882 ctx->s_frame.crop.height, new_r.width,
911 ctx->s_frame.crop.height, new_r.width,883 new_r.height, ctx->ctrls.rotate->val);
912 new_r.height, ctx->ctrls.rotate->val);
913 }
914 884
915 if (ret) {885 if (ret) {
916 dev_info(&ctx->mdp_dev->pdev->dev,886 dev_info(&ctx->mdp_dev->pdev->dev,
917 "Out of scaler range");887 "Out of scaler range");
918 return -EINVAL;888 return -EINVAL;
919 }
920 }889 }
921 890
922 s->r = new_r;891 s->r = new_r;
@@ -989,7 +958,6 @@ static int mtk_mdp_s_ctrl(struct v4l2_ctrl *ctrl) · 66 unmodified lines
989 struct mtk_mdp_ctx *ctx = ctrl_to_ctx(ctrl);958 struct mtk_mdp_ctx *ctx = ctrl_to_ctx(ctrl);
990 struct mtk_mdp_dev *mdp = ctx->mdp_dev;959 struct mtk_mdp_dev *mdp = ctx->mdp_dev;
991 struct mtk_mdp_variant *variant = mdp->variant;960 struct mtk_mdp_variant *variant = mdp->variant;
992 u32 state = MTK_MDP_DST_FMT | MTK_MDP_SRC_FMT;
993 int ret = 0;961 int ret = 0;
994 962
995 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)963 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
@@ -1003,17 +971,15 @@ static int mtk_mdp_s_ctrl(struct v4l2_ctrl *ctrl) · 7 unmodified lines
1003 ctx->vflip = ctrl->val;971 ctx->vflip = ctrl->val;
1004 break;972 break;
1005 case V4L2_CID_ROTATE:973 case V4L2_CID_ROTATE:
1006 if (mtk_mdp_ctx_state_is_set(ctx, state)) {974 ret = mtk_mdp_check_scaler_ratio(variant,
1007 ret = mtk_mdp_check_scaler_ratio(variant,975 ctx->s_frame.crop.width,
1008 ctx->s_frame.crop.width,976 ctx->s_frame.crop.height,
1009 ctx->s_frame.crop.height,977 ctx->d_frame.crop.width,
1010 ctx->d_frame.crop.width,978 ctx->d_frame.crop.height,
1011 ctx->d_frame.crop.height,979 ctx->ctrls.rotate->val);
1012 ctx->ctrls.rotate->val);980
1013 981 if (ret)
1014 if (ret)982 return -EINVAL;
1015 return -EINVAL;
1016 }
1017 983
1018 ctx->rotation = ctrl->val;984 ctx->rotation = ctrl->val;
1019 break;985 break;
@@ -1090,6 +1056,7 @@ static int mtk_mdp_m2m_open(struct file *file) · 70 unmodified lines
1090 struct video_device *vfd = video_devdata(file);1056 struct video_device *vfd = video_devdata(file);
1091 struct mtk_mdp_ctx *ctx = NULL;1057 struct mtk_mdp_ctx *ctx = NULL;
1092 int ret;1058 int ret;
1059 struct v4l2_format default_format;
1093 1060
1094 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);1061 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1095 if (!ctx)1062 if (!ctx)
@@ -1144,6 +1111,16 @@ static int mtk_mdp_m2m_open(struct file *file) · 48 unmodified lines
1144 list_add(&ctx->list, &mdp->ctx_list);1111 list_add(&ctx->list, &mdp->ctx_list);
1145 mutex_unlock(&mdp->lock);1112 mutex_unlock(&mdp->lock);
1146 1113
1114 /* Default format */
1115 memset(&default_format, 0, sizeof(default_format));
1116 default_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1117 default_format.fmt.pix_mp.width = 32;
1118 default_format.fmt.pix_mp.height = 32;
1119 default_format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420M;
1120 mtk_mdp_m2m_s_fmt_mplane(file, &ctx->fh, &default_format);
1121 default_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1122 mtk_mdp_m2m_s_fmt_mplane(file, &ctx->fh, &default_format);
1123
1147 mtk_mdp_dbg(0, "%s [%d]", dev_name(&mdp->pdev->dev), ctx->id);1124 mtk_mdp_dbg(0, "%s [%d]", dev_name(&mdp->pdev->dev), ctx->id);
1148 1125
1149 return 0;1126 return 0;
drivers/media/platform/omap3isp/isppreview.c+3−1
@@ -2287,7 +2287,7 @@ static int preview_init_entities(struct isp_prev_device *prev) · 2286 unmodified lines
2287 me->ops = &preview_media_ops;2287 me->ops = &preview_media_ops;
2288 ret = media_entity_pads_init(me, PREV_PADS_NUM, pads);2288 ret = media_entity_pads_init(me, PREV_PADS_NUM, pads);
2289 if (ret < 0)2289 if (ret < 0)
2290 return ret;2290 goto error_handler_free;
2291 2291
2292 preview_init_formats(sd, NULL);2292 preview_init_formats(sd, NULL);
2293 2293
@@ -2320,6 +2320,8 @@ error_video_out: · 26 unmodified lines
2320 omap3isp_video_cleanup(&prev->video_in);2320 omap3isp_video_cleanup(&prev->video_in);
2321error_video_in:2321error_video_in:
2322 media_entity_cleanup(&prev->subdev.entity);2322 media_entity_cleanup(&prev->subdev.entity);
2323error_handler_free:
2324 v4l2_ctrl_handler_free(&prev->ctrls);
2323 return ret;2325 return ret;
2324}2326}
2325 2327
drivers/media/platform/pxa_camera.c+9−12
@@ -2504,17 +2504,14 @@ static int pxa_camera_probe(struct platform_device *pdev) · 2503 unmodified lines
2504 if (err)2504 if (err)
2505 goto exit_notifier_cleanup;2505 goto exit_notifier_cleanup;
2506 2506
2507 if (pcdev->mclk) {2507 v4l2_clk_name_i2c(clk_name, sizeof(clk_name),
2508 v4l2_clk_name_i2c(clk_name, sizeof(clk_name),2508 pcdev->asd.match.i2c.adapter_id,
2509 pcdev->asd.match.i2c.adapter_id,2509 pcdev->asd.match.i2c.address);
2510 pcdev->asd.match.i2c.address);2510
2511 2511 pcdev->mclk_clk = v4l2_clk_register(&pxa_camera_mclk_ops, clk_name, NULL);
2512 pcdev->mclk_clk = v4l2_clk_register(&pxa_camera_mclk_ops,2512 if (IS_ERR(pcdev->mclk_clk)) {
2513 clk_name, NULL);2513 err = PTR_ERR(pcdev->mclk_clk);
2514 if (IS_ERR(pcdev->mclk_clk)) {2514 goto exit_notifier_cleanup;
2515 err = PTR_ERR(pcdev->mclk_clk);
2516 goto exit_notifier_cleanup;
2517 }
2518 }2515 }
2519 2516
2520 err = v4l2_async_notifier_register(&pcdev->v4l2_dev, &pcdev->notifier);2517 err = v4l2_async_notifier_register(&pcdev->v4l2_dev, &pcdev->notifier);
@@ -2588,7 +2585,7 @@ static struct platform_driver pxa_camera_driver = { · 67 unmodified lines
2588 2585
2589module_platform_driver(pxa_camera_driver);2586module_platform_driver(pxa_camera_driver);
2590 2587
2591MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");2588MODULE_DESCRIPTION("PXA27x Camera Driver");
2592MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");2589MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
2593MODULE_LICENSE("GPL");2590MODULE_LICENSE("GPL");
2594MODULE_VERSION(PXA_CAM_VERSION);2591MODULE_VERSION(PXA_CAM_VERSION);
drivers/media/platform/qcom/camss/camss-csid.c+4−2
@@ -562,8 +562,10 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) · 561 unmodified lines
562 u32 hw_version;562 u32 hw_version;
563 563
564 ret = pm_runtime_get_sync(dev);564 ret = pm_runtime_get_sync(dev);
565 if (ret < 0)565 if (ret < 0) {
566 pm_runtime_put_sync(dev);
566 return ret;567 return ret;
568 }
567 569
568 ret = regulator_enable(csid->vdda);570 ret = regulator_enable(csid->vdda);
569 if (ret < 0) {571 if (ret < 0) {
@@ -1356,7 +1358,7 @@ int msm_csid_register_entity(struct csid_device *csid, · 786 unmodified lines
1356 pads[MSM_CSID_PAD_SINK].flags = MEDIA_PAD_FL_SINK;1358 pads[MSM_CSID_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1357 pads[MSM_CSID_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;1359 pads[MSM_CSID_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
1358 1360
1359 sd->entity.function = MEDIA_ENT_F_IO_V4L;1361 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1360 sd->entity.ops = &csid_media_ops;1362 sd->entity.ops = &csid_media_ops;
1361 ret = media_entity_pads_init(&sd->entity, MSM_CSID_PADS_NUM, pads);1363 ret = media_entity_pads_init(&sd->entity, MSM_CSID_PADS_NUM, pads);
1362 if (ret < 0) {1364 if (ret < 0) {
drivers/media/platform/qcom/camss/camss-csiphy.c+1−1
@@ -737,7 +737,7 @@ int msm_csiphy_register_entity(struct csiphy_device *csiphy, · 736 unmodified lines
737 pads[MSM_CSIPHY_PAD_SINK].flags = MEDIA_PAD_FL_SINK;737 pads[MSM_CSIPHY_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
738 pads[MSM_CSIPHY_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;738 pads[MSM_CSIPHY_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
739 739
740 sd->entity.function = MEDIA_ENT_F_IO_V4L;740 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
741 sd->entity.ops = &csiphy_media_ops;741 sd->entity.ops = &csiphy_media_ops;
742 ret = media_entity_pads_init(&sd->entity, MSM_CSIPHY_PADS_NUM, pads);742 ret = media_entity_pads_init(&sd->entity, MSM_CSIPHY_PADS_NUM, pads);
743 if (ret < 0) {743 if (ret < 0) {
drivers/media/platform/qcom/camss/camss-ispif.c+4−2
@@ -344,8 +344,10 @@ static int ispif_set_power(struct v4l2_subdev *sd, int on) · 343 unmodified lines
344 }344 }
345 345
346 ret = pm_runtime_get_sync(dev);346 ret = pm_runtime_get_sync(dev);
347 if (ret < 0)347 if (ret < 0) {
348 pm_runtime_put_sync(dev);
348 goto exit;349 goto exit;
350 }
349 351
350 ret = camss_enable_clocks(ispif->nclocks, ispif->clock, dev);352 ret = camss_enable_clocks(ispif->nclocks, ispif->clock, dev);
351 if (ret < 0) {353 if (ret < 0) {
@@ -1323,7 +1325,7 @@ int msm_ispif_register_entities(struct ispif_device *ispif, · 971 unmodified lines
1323 pads[MSM_ISPIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;1325 pads[MSM_ISPIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1324 pads[MSM_ISPIF_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;1326 pads[MSM_ISPIF_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
1325 1327
1326 sd->entity.function = MEDIA_ENT_F_IO_V4L;1328 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1327 sd->entity.ops = &ispif_media_ops;1329 sd->entity.ops = &ispif_media_ops;
1328 ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM,1330 ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM,
1329 pads);1331 pads);
drivers/media/platform/qcom/camss/camss-vfe.c+4−6
@@ -1265,12 +1265,12 @@ static int vfe_get(struct vfe_device *vfe) · 1264 unmodified lines
1265 1265
1266 ret = vfe_set_clock_rates(vfe);1266 ret = vfe_set_clock_rates(vfe);
1267 if (ret < 0)1267 if (ret < 0)
1268 goto error_clocks;1268 goto error_pm_runtime_get;
1269 1269
1270 ret = camss_enable_clocks(vfe->nclocks, vfe->clock,1270 ret = camss_enable_clocks(vfe->nclocks, vfe->clock,
1271 vfe->camss->dev);1271 vfe->camss->dev);
1272 if (ret < 0)1272 if (ret < 0)
1273 goto error_clocks;1273 goto error_pm_runtime_get;
1274 1274
1275 ret = vfe_reset(vfe);1275 ret = vfe_reset(vfe);
1276 if (ret < 0)1276 if (ret < 0)
@@ -1282,7 +1282,7 @@ static int vfe_get(struct vfe_device *vfe) · 5 unmodified lines
1282 } else {1282 } else {
1283 ret = vfe_check_clock_rates(vfe);1283 ret = vfe_check_clock_rates(vfe);
1284 if (ret < 0)1284 if (ret < 0)
1285 goto error_clocks;1285 goto error_pm_runtime_get;
1286 }1286 }
1287 vfe->power_count++;1287 vfe->power_count++;
1288 1288
@@ -1293,10 +1293,8 @@ static int vfe_get(struct vfe_device *vfe) · 4 unmodified lines
1293error_reset:1293error_reset:
1294 camss_disable_clocks(vfe->nclocks, vfe->clock);1294 camss_disable_clocks(vfe->nclocks, vfe->clock);
1295 1295
1296error_clocks:
1297 pm_runtime_put_sync(vfe->camss->dev);
1298
1299error_pm_runtime_get:1296error_pm_runtime_get:
1297 pm_runtime_put_sync(vfe->camss->dev);
1300 camss_pm_domain_off(vfe->camss, vfe->id);1298 camss_pm_domain_off(vfe->camss, vfe->id);
1301 1299
1302error_pm_domain:1300error_pm_domain:
drivers/media/platform/qcom/camss/camss.c+20−10
@@ -504,7 +504,6 @@ static int camss_of_parse_ports(struct camss *camss) · 503 unmodified lines
504 return num_subdevs;504 return num_subdevs;
505 505
506err_cleanup:506err_cleanup:
507 v4l2_async_notifier_cleanup(&camss->notifier);
508 of_node_put(node);507 of_node_put(node);
509 return ret;508 return ret;
510}509}
@@ -835,29 +834,38 @@ static int camss_probe(struct platform_device *pdev) · 324 unmodified lines
835 camss->csid_num = 4;834 camss->csid_num = 4;
836 camss->vfe_num = 2;835 camss->vfe_num = 2;
837 } else {836 } else {
838 return -EINVAL;837 ret = -EINVAL;
838 goto err_free;
839 }839 }
840 840
841 camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,841 camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
842 sizeof(*camss->csiphy), GFP_KERNEL);842 sizeof(*camss->csiphy), GFP_KERNEL);
843 if (!camss->csiphy)843 if (!camss->csiphy) {
844 return -ENOMEM;844 ret = -ENOMEM;
845 goto err_free;
846 }
845 847
846 camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),848 camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
847 GFP_KERNEL);849 GFP_KERNEL);
848 if (!camss->csid)850 if (!camss->csid) {
849 return -ENOMEM;851 ret = -ENOMEM;
852 goto err_free;
853 }
850 854
851 camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),855 camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
852 GFP_KERNEL);856 GFP_KERNEL);
853 if (!camss->vfe)857 if (!camss->vfe) {
854 return -ENOMEM;858 ret = -ENOMEM;
859 goto err_free;
860 }
855 861
856 v4l2_async_notifier_init(&camss->notifier);862 v4l2_async_notifier_init(&camss->notifier);
857 863
858 num_subdevs = camss_of_parse_ports(camss);864 num_subdevs = camss_of_parse_ports(camss);
859 if (num_subdevs < 0)865 if (num_subdevs < 0) {
860 return num_subdevs;866 ret = num_subdevs;
867 goto err_cleanup;
868 }
861 869
862 ret = camss_init_subdevices(camss);870 ret = camss_init_subdevices(camss);
863 if (ret < 0)871 if (ret < 0)
@@ -936,6 +944,8 @@ err_register_entities: · 72 unmodified lines
936 v4l2_device_unregister(&camss->v4l2_dev);944 v4l2_device_unregister(&camss->v4l2_dev);
937err_cleanup:945err_cleanup:
938 v4l2_async_notifier_cleanup(&camss->notifier);946 v4l2_async_notifier_cleanup(&camss->notifier);
947err_free:
948 kfree(camss);
939 949
940 return ret;950 return ret;
941}951}
drivers/media/platform/qcom/venus/pm_helpers.c+4−0
@@ -496,6 +496,10 @@ min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load) · 495 unmodified lines
496 list_for_each_entry(inst_pos, &core->instances, list) {496 list_for_each_entry(inst_pos, &core->instances, list) {
497 if (inst_pos == inst)497 if (inst_pos == inst)
498 continue;498 continue;
499
500 if (inst_pos->state != INST_START)
501 continue;
502
499 vpp_freq = inst_pos->clk_data.codec_freq_data->vpp_freq;503 vpp_freq = inst_pos->clk_data.codec_freq_data->vpp_freq;
500 coreid = inst_pos->clk_data.core_id;504 coreid = inst_pos->clk_data.core_id;
501 505
drivers/media/platform/qcom/venus/venc.c+1−2
@@ -1177,7 +1177,7 @@ static int venc_open(struct file *file) · 1176 unmodified lines
1177 1177
1178 ret = pm_runtime_get_sync(core->dev_enc);1178 ret = pm_runtime_get_sync(core->dev_enc);
1179 if (ret < 0)1179 if (ret < 0)
1180 goto err_free_inst;1180 goto err_put_sync;
1181 1181
1182 ret = venc_ctrl_init(inst);1182 ret = venc_ctrl_init(inst);
1183 if (ret)1183 if (ret)
@@ -1222,7 +1222,6 @@ err_ctrl_deinit: · 38 unmodified lines
1222 venc_ctrl_deinit(inst);1222 venc_ctrl_deinit(inst);
1223err_put_sync:1223err_put_sync:
1224 pm_runtime_put_sync(core->dev_enc);1224 pm_runtime_put_sync(core->dev_enc);
1225err_free_inst:
1226 kfree(inst);1225 kfree(inst);
1227 return ret;1226 return ret;
1228}1227}
drivers/media/platform/rcar-vin/rcar-csi2.c+8−7
@@ -320,6 +320,7 @@ static const struct rcar_csi2_format rcar_csi2_formats[] = { · 319 unmodified lines
320 { .code = MEDIA_BUS_FMT_YUYV8_1X16, .datatype = 0x1e, .bpp = 16 },320 { .code = MEDIA_BUS_FMT_YUYV8_1X16, .datatype = 0x1e, .bpp = 16 },
321 { .code = MEDIA_BUS_FMT_UYVY8_2X8, .datatype = 0x1e, .bpp = 16 },321 { .code = MEDIA_BUS_FMT_UYVY8_2X8, .datatype = 0x1e, .bpp = 16 },
322 { .code = MEDIA_BUS_FMT_YUYV10_2X10, .datatype = 0x1e, .bpp = 20 },322 { .code = MEDIA_BUS_FMT_YUYV10_2X10, .datatype = 0x1e, .bpp = 20 },
323 { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .datatype = 0x2a, .bpp = 8 },
323};324};
324 325
325static const struct rcar_csi2_format *rcsi2_code_to_fmt(unsigned int code)326static const struct rcar_csi2_format *rcsi2_code_to_fmt(unsigned int code)
@@ -344,7 +345,7 @@ enum rcar_csi2_pads { · 18 unmodified lines
344 345
345struct rcar_csi2_info {346struct rcar_csi2_info {
346 int (*init_phtw)(struct rcar_csi2 *priv, unsigned int mbps);347 int (*init_phtw)(struct rcar_csi2 *priv, unsigned int mbps);
347 int (*confirm_start)(struct rcar_csi2 *priv);348 int (*phy_post_init)(struct rcar_csi2 *priv);
348 const struct rcsi2_mbps_reg *hsfreqrange;349 const struct rcsi2_mbps_reg *hsfreqrange;
349 unsigned int csi0clkfreqrange;350 unsigned int csi0clkfreqrange;
350 unsigned int num_channels;351 unsigned int num_channels;
@@ -575,9 +576,9 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) · 224 unmodified lines
575 if (ret)576 if (ret)
576 return ret;577 return ret;
577 578
578 /* Confirm start */579 /* Run post PHY start initialization, if needed. */
579 if (priv->info->confirm_start) {580 if (priv->info->phy_post_init) {
580 ret = priv->info->confirm_start(priv);581 ret = priv->info->phy_post_init(priv);
581 if (ret)582 if (ret)
582 return ret;583 return ret;
583 }584 }
@@ -975,7 +976,7 @@ static int rcsi2_init_phtw_v3m_e3(struct rcar_csi2 *priv, unsigned int mbps) · 391 unmodified lines
975 return rcsi2_phtw_write_mbps(priv, mbps, phtw_mbps_v3m_e3, 0x44);976 return rcsi2_phtw_write_mbps(priv, mbps, phtw_mbps_v3m_e3, 0x44);
976}977}
977 978
978static int rcsi2_confirm_start_v3m_e3(struct rcar_csi2 *priv)979static int rcsi2_phy_post_init_v3m_e3(struct rcar_csi2 *priv)
979{980{
980 static const struct phtw_value step1[] = {981 static const struct phtw_value step1[] = {
981 { .data = 0xee, .code = 0x34 },982 { .data = 0xee, .code = 0x34 },
@@ -1059,7 +1060,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { · 77 unmodified lines
1059 1060
1060static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = {1061static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = {
1061 .init_phtw = rcsi2_init_phtw_v3m_e3,1062 .init_phtw = rcsi2_init_phtw_v3m_e3,
1062 .confirm_start = rcsi2_confirm_start_v3m_e3,1063 .phy_post_init = rcsi2_phy_post_init_v3m_e3,
1063 .num_channels = 4,1064 .num_channels = 4,
1064};1065};
1065 1066
@@ -1072,7 +1073,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { · 6 unmodified lines
1072 1073
1073static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {1074static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
1074 .init_phtw = rcsi2_init_phtw_v3m_e3,1075 .init_phtw = rcsi2_init_phtw_v3m_e3,
1075 .confirm_start = rcsi2_confirm_start_v3m_e3,1076 .phy_post_init = rcsi2_phy_post_init_v3m_e3,
1076 .num_channels = 2,1077 .num_channels = 2,
1077};1078};
1078 1079
drivers/media/platform/rcar-vin/rcar-dma.c+19−2
@@ -85,6 +85,7 @@ · 84 unmodified lines
85#define VNMC_INF_YUV8_BT601 (1 << 16)85#define VNMC_INF_YUV8_BT601 (1 << 16)
86#define VNMC_INF_YUV10_BT656 (2 << 16)86#define VNMC_INF_YUV10_BT656 (2 << 16)
87#define VNMC_INF_YUV10_BT601 (3 << 16)87#define VNMC_INF_YUV10_BT601 (3 << 16)
88#define VNMC_INF_RAW8 (4 << 16)
88#define VNMC_INF_YUV16 (5 << 16)89#define VNMC_INF_YUV16 (5 << 16)
89#define VNMC_INF_RGB888 (6 << 16)90#define VNMC_INF_RGB888 (6 << 16)
90#define VNMC_VUP (1 << 10)91#define VNMC_VUP (1 << 10)
@@ -587,13 +588,19 @@ void rvin_crop_scale_comp(struct rvin_dev *vin) · 496 unmodified lines
587 rvin_write(vin, vin->crop.top, VNSLPRC_REG);588 rvin_write(vin, vin->crop.top, VNSLPRC_REG);
588 rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);589 rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);
589 590
590
591 /* TODO: Add support for the UDS scaler. */591 /* TODO: Add support for the UDS scaler. */
592 if (vin->info->model != RCAR_GEN3)592 if (vin->info->model != RCAR_GEN3)
593 rvin_crop_scale_comp_gen2(vin);593 rvin_crop_scale_comp_gen2(vin);
594 594
595 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);595 fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
596 stride = vin->format.bytesperline / fmt->bpp;596 stride = vin->format.bytesperline / fmt->bpp;
597
598 /* For RAW8 format bpp is 1, but the hardware process RAW8
599 * format in 2 pixel unit hence configure VNIS_REG as stride / 2.
600 */
601 if (vin->format.pixelformat == V4L2_PIX_FMT_SRGGB8)
602 stride /= 2;
603
597 rvin_write(vin, stride, VNIS_REG);604 rvin_write(vin, stride, VNIS_REG);
598}605}
599 606
@@ -676,6 +683,9 @@ static int rvin_setup(struct rvin_dev *vin) · 76 unmodified lines
676 683
677 input_is_yuv = true;684 input_is_yuv = true;
678 break;685 break;
686 case MEDIA_BUS_FMT_SRGGB8_1X8:
687 vnmc |= VNMC_INF_RAW8;
688 break;
679 default:689 default:
680 break;690 break;
681 }691 }
@@ -737,6 +747,9 @@ static int rvin_setup(struct rvin_dev *vin) · 55 unmodified lines
737 case V4L2_PIX_FMT_ABGR32:747 case V4L2_PIX_FMT_ABGR32:
738 dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;748 dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
739 break;749 break;
750 case V4L2_PIX_FMT_SRGGB8:
751 dmr = 0;
752 break;
740 default:753 default:
741 vin_err(vin, "Invalid pixelformat (0x%x)\n",754 vin_err(vin, "Invalid pixelformat (0x%x)\n",
742 vin->format.pixelformat);755 vin->format.pixelformat);
@@ -1110,11 +1123,15 @@ static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd, · 367 unmodified lines
1110 case MEDIA_BUS_FMT_UYVY8_2X8:1123 case MEDIA_BUS_FMT_UYVY8_2X8:
1111 case MEDIA_BUS_FMT_UYVY10_2X10:1124 case MEDIA_BUS_FMT_UYVY10_2X10:
1112 case MEDIA_BUS_FMT_RGB888_1X24:1125 case MEDIA_BUS_FMT_RGB888_1X24:
1113 vin->mbus_code = fmt.format.code;1126 break;
1127 case MEDIA_BUS_FMT_SRGGB8_1X8:
1128 if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8)
1129 return -EPIPE;
1114 break;1130 break;
1115 default:1131 default:
1116 return -EPIPE;1132 return -EPIPE;
1117 }1133 }
1134 vin->mbus_code = fmt.format.code;
1118 1135
1119 switch (fmt.format.field) {1136 switch (fmt.format.field) {
1120 case V4L2_FIELD_TOP:1137 case V4L2_FIELD_TOP:
drivers/media/platform/rcar-vin/rcar-v4l2.c+12−3
@@ -66,6 +66,10 @@ static const struct rvin_video_format rvin_formats[] = { · 65 unmodified lines
66 .fourcc = V4L2_PIX_FMT_ABGR32,66 .fourcc = V4L2_PIX_FMT_ABGR32,
67 .bpp = 4,67 .bpp = 4,
68 },68 },
69 {
70 .fourcc = V4L2_PIX_FMT_SRGGB8,
71 .bpp = 1,
72 },
69};73};
70 74
71const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,75const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
@@ -350,9 +354,9 @@ static int rvin_enum_fmt_vid_cap(struct file *file, void *priv, · 278 unmodified lines
350 * all of the related pixel formats. If mbus_code is not set enumerate354 * all of the related pixel formats. If mbus_code is not set enumerate
351 * all possible pixelformats.355 * all possible pixelformats.
352 *356 *
353 * TODO: Once raw capture formats are added to the driver this needs357 * TODO: Once raw MEDIA_BUS_FMT_SRGGB12_1X12 format is added to the
354 * to be extended so raw media bus codes only result in raw pixel358 * driver this needs to be extended so raw media bus code only result in
355 * formats.359 * raw pixel format.
356 */360 */
357 switch (f->mbus_code) {361 switch (f->mbus_code) {
358 case 0:362 case 0:
@@ -362,6 +366,11 @@ static int rvin_enum_fmt_vid_cap(struct file *file, void *priv, · 3 unmodified lines
362 case MEDIA_BUS_FMT_UYVY10_2X10:366 case MEDIA_BUS_FMT_UYVY10_2X10:
363 case MEDIA_BUS_FMT_RGB888_1X24:367 case MEDIA_BUS_FMT_RGB888_1X24:
364 break;368 break;
369 case MEDIA_BUS_FMT_SRGGB8_1X8:
370 if (f->index)
371 return -EINVAL;
372 f->pixelformat = V4L2_PIX_FMT_SRGGB8;
373 return 0;
365 default:374 default:
366 return -EINVAL;375 return -EINVAL;
367 }376 }
drivers/media/platform/rcar_jpu.c+1−1
@@ -1066,7 +1066,7 @@ static int jpu_buf_prepare(struct vb2_buffer *vb) · 1065 unmodified lines
1066 }1066 }
1067 1067
1068 /* decoder capture queue */1068 /* decoder capture queue */
1069 if (!ctx->encoder && !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))1069 if (!ctx->encoder && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type))
1070 vb2_set_plane_payload(vb, i, size);1070 vb2_set_plane_payload(vb, i, size);
1071 }1071 }
1072 1072
drivers/media/platform/rockchip/rga/rga-hw.c+16−13
@@ -200,22 +200,25 @@ static void rga_cmd_set_trans_info(struct rga_ctx *ctx) · 199 unmodified lines
200 dst_info.data.format = ctx->out.fmt->hw_format;200 dst_info.data.format = ctx->out.fmt->hw_format;
201 dst_info.data.swap = ctx->out.fmt->color_swap;201 dst_info.data.swap = ctx->out.fmt->color_swap;
202 202
203 if (ctx->in.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) {203 /*
204 if (ctx->out.fmt->hw_format < RGA_COLOR_FMT_YUV422SP) {204 * CSC mode must only be set when the colorspace families differ between
205 switch (ctx->in.colorspace) {205 * input and output. It must remain unset (zeroed) if both are the same.
206 case V4L2_COLORSPACE_REC709:206 */
207 src_info.data.csc_mode =207
208 RGA_SRC_CSC_MODE_BT709_R0;208 if (RGA_COLOR_FMT_IS_YUV(ctx->in.fmt->hw_format) &&
209 break;209 RGA_COLOR_FMT_IS_RGB(ctx->out.fmt->hw_format)) {
210 default:210 switch (ctx->in.colorspace) {
211 src_info.data.csc_mode =211 case V4L2_COLORSPACE_REC709:
212 RGA_SRC_CSC_MODE_BT601_R0;212 src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0;
213 break;213 break;
214 }214 default:
215 src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT601_R0;
216 break;
215 }217 }
216 }218 }
217 219
218 if (ctx->out.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) {220 if (RGA_COLOR_FMT_IS_RGB(ctx->in.fmt->hw_format) &&
221 RGA_COLOR_FMT_IS_YUV(ctx->out.fmt->hw_format)) {
219 switch (ctx->out.colorspace) {222 switch (ctx->out.colorspace) {
220 case V4L2_COLORSPACE_REC709:223 case V4L2_COLORSPACE_REC709:
221 dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0;224 dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0;
drivers/media/platform/rockchip/rga/rga-hw.h+5−0
@@ -95,6 +95,11 @@ · 94 unmodified lines
95#define RGA_COLOR_FMT_CP_8BPP 1595#define RGA_COLOR_FMT_CP_8BPP 15
96#define RGA_COLOR_FMT_MASK 1596#define RGA_COLOR_FMT_MASK 15
97 97
98#define RGA_COLOR_FMT_IS_YUV(fmt) \
99 (((fmt) >= RGA_COLOR_FMT_YUV422SP) && ((fmt) < RGA_COLOR_FMT_CP_1BPP))
100#define RGA_COLOR_FMT_IS_RGB(fmt) \
101 ((fmt) < RGA_COLOR_FMT_YUV422SP)
102
98#define RGA_COLOR_NONE_SWAP 0103#define RGA_COLOR_NONE_SWAP 0
99#define RGA_COLOR_RB_SWAP 1104#define RGA_COLOR_RB_SWAP 1
100#define RGA_COLOR_ALPHA_SWAP 2105#define RGA_COLOR_ALPHA_SWAP 2
drivers/media/platform/s3c-camif/camif-core.c+1−1
@@ -304,7 +304,7 @@ static int camif_media_dev_init(struct camif_dev *camif) · 303 unmodified lines
304 int ret;304 int ret;
305 305
306 memset(md, 0, sizeof(*md));306 memset(md, 0, sizeof(*md));
307 snprintf(md->model, sizeof(md->model), "SAMSUNG S3C%s CAMIF",307 snprintf(md->model, sizeof(md->model), "Samsung S3C%s CAMIF",
308 ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X");308 ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X");
309 strscpy(md->bus_info, "platform", sizeof(md->bus_info));309 strscpy(md->bus_info, "platform", sizeof(md->bus_info));
310 md->hw_revision = ip_rev;310 md->hw_revision = ip_rev;
drivers/media/platform/s5p-g2d/g2d.c+15−13
@@ -695,21 +695,13 @@ 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_VIDEO, 0);698
699 if (ret) {
700 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
701 goto rel_vdev;
702 }
703 video_set_drvdata(vfd, dev);
704 dev->vfd = vfd;
705 v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
706 vfd->num);
707 platform_set_drvdata(pdev, dev);699 platform_set_drvdata(pdev, dev);
708 dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops);700 dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops);
709 if (IS_ERR(dev->m2m_dev)) {701 if (IS_ERR(dev->m2m_dev)) {
710 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");702 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
711 ret = PTR_ERR(dev->m2m_dev);703 ret = PTR_ERR(dev->m2m_dev);
712 goto unreg_video_dev;704 goto rel_vdev;
713 }705 }
714 706
715 def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;707 def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
@@ -717,14 +709,24 @@ static int g2d_probe(struct platform_device *pdev) · 1 unmodified line
717 of_id = of_match_node(exynos_g2d_match, pdev->dev.of_node);709 of_id = of_match_node(exynos_g2d_match, pdev->dev.of_node);
718 if (!of_id) {710 if (!of_id) {
719 ret = -ENODEV;711 ret = -ENODEV;
720 goto unreg_video_dev;712 goto free_m2m;
721 }713 }
722 dev->variant = (struct g2d_variant *)of_id->data;714 dev->variant = (struct g2d_variant *)of_id->data;
723 715
716 ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
717 if (ret) {
718 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
719 goto free_m2m;
720 }
721 video_set_drvdata(vfd, dev);
722 dev->vfd = vfd;
723 v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
724 vfd->num);
725
724 return 0;726 return 0;
725 727
726unreg_video_dev:728free_m2m:
727 video_unregister_device(dev->vfd);729 v4l2_m2m_release(dev->m2m_dev);
728rel_vdev:730rel_vdev:
729 video_device_release(vfd);731 video_device_release(vfd);
730unreg_v4l2_dev:732unreg_v4l2_dev:
drivers/media/platform/s5p-jpeg/jpeg-core.c+2−14
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include <media/v4l2-event.h>24#include <media/v4l2-event.h>
25#include <media/v4l2-mem2mem.h>25#include <media/v4l2-mem2mem.h>
26#include <media/v4l2-ioctl.h>26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-rect.h>
27#include <media/videobuf2-v4l2.h>28#include <media/videobuf2-v4l2.h>
28#include <media/videobuf2-dma-contig.h>29#include <media/videobuf2-dma-contig.h>
29 30
@@ -1735,19 +1736,6 @@ static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, · 1705 unmodified lines
1735 return 0;1736 return 0;
1736}1737}
1737 1738
1738/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1739static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1740{
1741 if (a->left < b->left || a->top < b->top)
1742 return 0;
1743 if (a->left + a->width > b->left + b->width)
1744 return 0;
1745 if (a->top + a->height > b->top + b->height)
1746 return 0;
1747
1748 return 1;
1749}
1750
1751static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,1739static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1752 struct v4l2_rect *r)1740 struct v4l2_rect *r)
1753{1741{
@@ -1780,7 +1768,7 @@ static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx, · 26 unmodified lines
1780 r->left = round_down(r->left, 2);1768 r->left = round_down(r->left, 2);
1781 r->top = round_down(r->top, 2);1769 r->top = round_down(r->top, 2);
1782 1770
1783 if (!enclosed_rectangle(r, &base_rect))1771 if (!v4l2_rect_enclosed(r, &base_rect))
1784 return -EINVAL;1772 return -EINVAL;
1785 1773
1786 ctx->crop_rect.left = r->left;1774 ctx->crop_rect.left = r->left;
drivers/media/platform/sti/hva/hva-v4l2.c+1−1
@@ -1087,7 +1087,7 @@ static void hva_stop_streaming(struct vb2_queue *vq) · 1086 unmodified lines
1087 1087
1088 if ((V4L2_TYPE_IS_OUTPUT(vq->type) &&1088 if ((V4L2_TYPE_IS_OUTPUT(vq->type) &&
1089 vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q)) ||1089 vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q)) ||
1090 (!V4L2_TYPE_IS_OUTPUT(vq->type) &&1090 (V4L2_TYPE_IS_CAPTURE(vq->type) &&
1091 vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))) {1091 vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))) {
1092 dev_dbg(dev, "%s %s out=%d cap=%d\n",1092 dev_dbg(dev, "%s %s out=%d cap=%d\n",
1093 ctx->name, to_type_str(vq->type),1093 ctx->name, to_type_str(vq->type),
drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c+2−0
@@ -191,6 +191,8 @@ static int sun4i_csi_probe(struct platform_device *pdev) · 190 unmodified lines
191 strscpy(csi->mdev.model, "Allwinner Video Capture Device",191 strscpy(csi->mdev.model, "Allwinner Video Capture Device",
192 sizeof(csi->mdev.model));192 sizeof(csi->mdev.model));
193 csi->mdev.hw_revision = 0;193 csi->mdev.hw_revision = 0;
194 snprintf(csi->mdev.bus_info, sizeof(csi->mdev.bus_info), "platform:%s",
195 dev_name(csi->dev));
194 media_device_init(&csi->mdev);196 media_device_init(&csi->mdev);
195 csi->v4l.mdev = &csi->mdev;197 csi->v4l.mdev = &csi->mdev;
196 198
drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c+1−1
@@ -413,7 +413,7 @@ int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq) · 412 unmodified lines
413 413
414 q->min_buffers_needed = 3;414 q->min_buffers_needed = 3;
415 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;415 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
416 q->io_modes = VB2_MMAP;416 q->io_modes = VB2_MMAP | VB2_DMABUF;
417 q->lock = &csi->lock;417 q->lock = &csi->lock;
418 q->drv_priv = csi;418 q->drv_priv = csi;
419 q->buf_struct_size = sizeof(struct sun4i_csi_buffer);419 q->buf_struct_size = sizeof(struct sun4i_csi_buffer);
drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c+2−3
@@ -242,7 +242,8 @@ static int sun4i_csi_release(struct file *file) · 241 unmodified lines
242 242
243 mutex_lock(&csi->lock);243 mutex_lock(&csi->lock);
244 244
245 v4l2_fh_release(file);245 _vb2_fop_release(file, NULL);
246
246 v4l2_pipeline_pm_put(&csi->vdev.entity);247 v4l2_pipeline_pm_put(&csi->vdev.entity);
247 pm_runtime_put(csi->dev);248 pm_runtime_put(csi->dev);
248 249
@@ -256,8 +257,6 @@ static const struct v4l2_file_operations sun4i_csi_fops = { · 7 unmodified lines
256 .open = sun4i_csi_open,257 .open = sun4i_csi_open,
257 .release = sun4i_csi_release,258 .release = sun4i_csi_release,
258 .unlocked_ioctl = video_ioctl2,259 .unlocked_ioctl = video_ioctl2,
259 .read = vb2_fop_read,
260 .write = vb2_fop_write,
261 .poll = vb2_fop_poll,260 .poll = vb2_fop_poll,
262 .mmap = vb2_fop_mmap,261 .mmap = vb2_fop_mmap,
263};262};
drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c+2−0
@@ -733,6 +733,8 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) · 732 unmodified lines
733 strscpy(csi->media_dev.model, "Allwinner Video Capture Device",733 strscpy(csi->media_dev.model, "Allwinner Video Capture Device",
734 sizeof(csi->media_dev.model));734 sizeof(csi->media_dev.model));
735 csi->media_dev.hw_revision = 0;735 csi->media_dev.hw_revision = 0;
736 snprintf(csi->media_dev.bus_info, sizeof(csi->media_dev.bus_info),
737 "platform:%s", dev_name(csi->dev));
736 738
737 media_device_init(&csi->media_dev);739 media_device_init(&csi->media_dev);
738 v4l2_async_notifier_init(&csi->notifier);740 v4l2_async_notifier_init(&csi->notifier);
drivers/media/platform/ti-vpe/Makefile+1−1
@@ -13,4 +13,4 @@ ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG · 12 unmodified lines
13 13
14obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o14obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
15 15
16ti-cal-y := cal.o16ti-cal-y := cal.o cal-camerarx.o cal-video.o
drivers/media/platform/ti-vpe/cal-camerarx.c+649−0
@@ -0,0 +1,649 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * TI Camera Access Layer (CAL) - CAMERARX
4 *
5 * Copyright (c) 2015-2020 Texas Instruments Inc.
6 *
7 * Authors:
8 * Benoit Parrot <bparrot@ti.com>
9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/mfd/syscon.h>
15#include <linux/module.h>
16#include <linux/of_graph.h>
17#include <linux/platform_device.h>
18#include <linux/regmap.h>
19#include <linux/slab.h>
20
21#include <media/v4l2-ctrls.h>
22#include <media/v4l2-fwnode.h>
23#include <media/v4l2-subdev.h>
24
25#include "cal.h"
26#include "cal_regs.h"
27
28/* ------------------------------------------------------------------
29 * I/O Register Accessors
30 * ------------------------------------------------------------------
31 */
32
33static inline u32 camerarx_read(struct cal_camerarx *phy, u32 offset)
34{
35 return ioread32(phy->base + offset);
36}
37
38static inline void camerarx_write(struct cal_camerarx *phy, u32 offset, u32 val)
39{
40 iowrite32(val, phy->base + offset);
41}
42
43/* ------------------------------------------------------------------
44 * CAMERARX Management
45 * ------------------------------------------------------------------
46 */
47
48static s64 cal_camerarx_get_external_rate(struct cal_camerarx *phy)
49{
50 struct v4l2_ctrl *ctrl;
51 s64 rate;
52
53 ctrl = v4l2_ctrl_find(phy->sensor->ctrl_handler, V4L2_CID_PIXEL_RATE);
54 if (!ctrl) {
55 phy_err(phy, "no pixel rate control in subdev: %s\n",
56 phy->sensor->name);
57 return -EPIPE;
58 }
59
60 rate = v4l2_ctrl_g_ctrl_int64(ctrl);
61 phy_dbg(3, phy, "sensor Pixel Rate: %llu\n", rate);
62
63 return rate;
64}
65
66static void cal_camerarx_lane_config(struct cal_camerarx *phy)
67{
68 u32 val = cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance));
69 u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
70 u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
71 struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
72 &phy->endpoint.bus.mipi_csi2;
73 int lane;
74
75 cal_set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
76 cal_set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask);
77 for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) {
78 /*
79 * Every lane are one nibble apart starting with the
80 * clock followed by the data lanes so shift masks by 4.
81 */
82 lane_mask <<= 4;
83 polarity_mask <<= 4;
84 cal_set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask);
85 cal_set_field(&val, mipi_csi2->lane_polarities[lane + 1],
86 polarity_mask);
87 }
88
89 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), val);
90 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n",
91 phy->instance, val);
92}
93
94static void cal_camerarx_enable(struct cal_camerarx *phy)
95{
96 u32 num_lanes = phy->cal->data->camerarx[phy->instance].num_lanes;
97
98 regmap_field_write(phy->fields[F_CAMMODE], 0);
99 /* Always enable all lanes at the phy control level */
100 regmap_field_write(phy->fields[F_LANEENABLE], (1 << num_lanes) - 1);
101 /* F_CSI_MODE is not present on every architecture */
102 if (phy->fields[F_CSI_MODE])
103 regmap_field_write(phy->fields[F_CSI_MODE], 1);
104 regmap_field_write(phy->fields[F_CTRLCLKEN], 1);
105}
106
107void cal_camerarx_disable(struct cal_camerarx *phy)
108{
109 regmap_field_write(phy->fields[F_CTRLCLKEN], 0);
110}
111
112/*
113 * TCLK values are OK at their reset values
114 */
115#define TCLK_TERM 0
116#define TCLK_MISS 1
117#define TCLK_SETTLE 14
118
119static void cal_camerarx_config(struct cal_camerarx *phy, s64 external_rate,
120 const struct cal_fmt *fmt)
121{
122 unsigned int reg0, reg1;
123 unsigned int ths_term, ths_settle;
124 unsigned int csi2_ddrclk_khz;
125 struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
126 &phy->endpoint.bus.mipi_csi2;
127 u32 num_lanes = mipi_csi2->num_data_lanes;
128
129 /* DPHY timing configuration */
130
131 /*
132 * CSI-2 is DDR and we only count used lanes.
133 *
134 * csi2_ddrclk_khz = external_rate / 1000
135 * / (2 * num_lanes) * fmt->bpp;
136 */
137 csi2_ddrclk_khz = div_s64(external_rate * fmt->bpp,
138 2 * num_lanes * 1000);
139
140 phy_dbg(1, phy, "csi2_ddrclk_khz: %d\n", csi2_ddrclk_khz);
141
142 /* THS_TERM: Programmed value = floor(20 ns/DDRClk period) */
143 ths_term = 20 * csi2_ddrclk_khz / 1000000;
144 phy_dbg(1, phy, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
145
146 /* THS_SETTLE: Programmed value = floor(105 ns/DDRClk period) + 4 */
147 ths_settle = (105 * csi2_ddrclk_khz / 1000000) + 4;
148 phy_dbg(1, phy, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
149
150 reg0 = camerarx_read(phy, CAL_CSI2_PHY_REG0);
151 cal_set_field(&reg0, CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE,
152 CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK);
153 cal_set_field(&reg0, ths_term, CAL_CSI2_PHY_REG0_THS_TERM_MASK);
154 cal_set_field(&reg0, ths_settle, CAL_CSI2_PHY_REG0_THS_SETTLE_MASK);
155
156 phy_dbg(1, phy, "CSI2_%d_REG0 = 0x%08x\n", phy->instance, reg0);
157 camerarx_write(phy, CAL_CSI2_PHY_REG0, reg0);
158
159 reg1 = camerarx_read(phy, CAL_CSI2_PHY_REG1);
160 cal_set_field(&reg1, TCLK_TERM, CAL_CSI2_PHY_REG1_TCLK_TERM_MASK);
161 cal_set_field(&reg1, 0xb8, CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK);
162 cal_set_field(&reg1, TCLK_MISS,
163 CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK);
164 cal_set_field(&reg1, TCLK_SETTLE, CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK);
165
166 phy_dbg(1, phy, "CSI2_%d_REG1 = 0x%08x\n", phy->instance, reg1);
167 camerarx_write(phy, CAL_CSI2_PHY_REG1, reg1);
168}
169
170static void cal_camerarx_power(struct cal_camerarx *phy, bool enable)
171{
172 u32 target_state;
173 unsigned int i;
174
175 target_state = enable ? CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON :
176 CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF;
177
178 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
179 target_state, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
180
181 for (i = 0; i < 10; i++) {
182 u32 current_state;
183
184 current_state = cal_read_field(phy->cal,
185 CAL_CSI2_COMPLEXIO_CFG(phy->instance),
186 CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK);
187
188 if (current_state == target_state)
189 break;
190
191 usleep_range(1000, 1100);
192 }
193
194 if (i == 10)
195 phy_err(phy, "Failed to power %s complexio\n",
196 enable ? "up" : "down");
197}
198
199static void cal_camerarx_wait_reset(struct cal_camerarx *phy)
200{
201 unsigned long timeout;
202
203 timeout = jiffies + msecs_to_jiffies(750);
204 while (time_before(jiffies, timeout)) {
205 if (cal_read_field(phy->cal,
206 CAL_CSI2_COMPLEXIO_CFG(phy->instance),
207 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
208 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
209 break;
210 usleep_range(500, 5000);
211 }
212
213 if (cal_read_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
214 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) !=
215 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
216 phy_err(phy, "Timeout waiting for Complex IO reset done\n");
217}
218
219static void cal_camerarx_wait_stop_state(struct cal_camerarx *phy)
220{
221 unsigned long timeout;
222
223 timeout = jiffies + msecs_to_jiffies(750);
224 while (time_before(jiffies, timeout)) {
225 if (cal_read_field(phy->cal,
226 CAL_CSI2_TIMING(phy->instance),
227 CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) == 0)
228 break;
229 usleep_range(500, 5000);
230 }
231
232 if (cal_read_field(phy->cal, CAL_CSI2_TIMING(phy->instance),
233 CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) != 0)
234 phy_err(phy, "Timeout waiting for stop state\n");
235}
236
237int cal_camerarx_start(struct cal_camerarx *phy, const struct cal_fmt *fmt)
238{
239 s64 external_rate;
240 u32 sscounter;
241 u32 val;
242 int ret;
243
244 external_rate = cal_camerarx_get_external_rate(phy);
245 if (external_rate < 0)
246 return external_rate;
247
248 ret = v4l2_subdev_call(phy->sensor, core, s_power, 1);
249 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
250 phy_err(phy, "power on failed in subdev\n");
251 return ret;
252 }
253
254 /*
255 * CSI-2 PHY Link Initialization Sequence, according to the DRA74xP /
256 * DRA75xP / DRA76xP / DRA77xP TRM. The DRA71x / DRA72x and the AM65x /
257 * DRA80xM TRMs have a a slightly simplified sequence.
258 */
259
260 /*
261 * 1. Configure all CSI-2 low level protocol registers to be ready to
262 * receive signals/data from the CSI-2 PHY.
263 *
264 * i.-v. Configure the lanes position and polarity.
265 */
266 cal_camerarx_lane_config(phy);
267
268 /*
269 * vi.-vii. Configure D-PHY mode, enable the required lanes and
270 * enable the CAMERARX clock.
271 */
272 cal_camerarx_enable(phy);
273
274 /*
275 * 2. CSI PHY and link initialization sequence.
276 *
277 * a. Deassert the CSI-2 PHY reset. Do not wait for reset completion
278 * at this point, as it requires the external sensor to send the
279 * CSI-2 HS clock.
280 */
281 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
282 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
283 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
284 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n",
285 phy->instance,
286 cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)));
287
288 /* Dummy read to allow SCP reset to complete. */
289 camerarx_read(phy, CAL_CSI2_PHY_REG0);
290
291 /* Program the PHY timing parameters. */
292 cal_camerarx_config(phy, external_rate, fmt);
293
294 /*
295 * b. Assert the FORCERXMODE signal.
296 *
297 * The stop-state-counter is based on fclk cycles, and we always use
298 * the x16 and x4 settings, so stop-state-timeout =
299 * fclk-cycle * 16 * 4 * counter.
300 *
301 * Stop-state-timeout must be more than 100us as per CSI-2 spec, so we
302 * calculate a timeout that's 100us (rounding up).
303 */
304 sscounter = DIV_ROUND_UP(clk_get_rate(phy->cal->fclk), 10000 * 16 * 4);
305
306 val = cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance));
307 cal_set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
308 cal_set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
309 cal_set_field(&val, sscounter,
310 CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
311 cal_write(phy->cal, CAL_CSI2_TIMING(phy->instance), val);
312 phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Stop States\n",
313 phy->instance,
314 cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)));
315
316 /* Assert the FORCERXMODE signal. */
317 cal_write_field(phy->cal, CAL_CSI2_TIMING(phy->instance),
318 1, CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
319 phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Force RXMODE\n",
320 phy->instance,
321 cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)));
322
323 /*
324 * c. Connect pull-down on CSI-2 PHY link (using pad control).
325 *
326 * This is not required on DRA71x, DRA72x, AM65x and DRA80xM. Not
327 * implemented.
328 */
329
330 /*
331 * d. Power up the CSI-2 PHY.
332 * e. Check whether the state status reaches the ON state.
333 */
334 cal_camerarx_power(phy, true);
335
336 /*
337 * Start the sensor to enable the CSI-2 HS clock. We can now wait for
338 * CSI-2 PHY reset to complete.
339 */
340 ret = v4l2_subdev_call(phy->sensor, video, s_stream, 1);
341 if (ret) {
342 v4l2_subdev_call(phy->sensor, core, s_power, 0);
343 phy_err(phy, "stream on failed in subdev\n");
344 return ret;
345 }
346
347 cal_camerarx_wait_reset(phy);
348
349 /* f. Wait for STOPSTATE=1 for all enabled lane modules. */
350 cal_camerarx_wait_stop_state(phy);
351
352 phy_dbg(1, phy, "CSI2_%u_REG1 = 0x%08x (bits 31-28 should be set)\n",
353 phy->instance, camerarx_read(phy, CAL_CSI2_PHY_REG1));
354
355 /*
356 * g. Disable pull-down on CSI-2 PHY link (using pad control).
357 *
358 * This is not required on DRA71x, DRA72x, AM65x and DRA80xM. Not
359 * implemented.
360 */
361
362 return 0;
363}
364
365void cal_camerarx_stop(struct cal_camerarx *phy)
366{
367 unsigned int i;
368 int ret;
369
370 cal_camerarx_power(phy, false);
371
372 /* Assert Complex IO Reset */
373 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
374 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
375 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
376
377 /* Wait for power down completion */
378 for (i = 0; i < 10; i++) {
379 if (cal_read_field(phy->cal,
380 CAL_CSI2_COMPLEXIO_CFG(phy->instance),
381 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
382 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETONGOING)
383 break;
384 usleep_range(1000, 1100);
385 }
386 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset (%d) %s\n",
387 phy->instance,
388 cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)), i,
389 (i >= 10) ? "(timeout)" : "");
390
391 /* Disable the phy */
392 cal_camerarx_disable(phy);
393
394 if (v4l2_subdev_call(phy->sensor, video, s_stream, 0))
395 phy_err(phy, "stream off failed in subdev\n");
396
397 ret = v4l2_subdev_call(phy->sensor, core, s_power, 0);
398 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
399 phy_err(phy, "power off failed in subdev\n");
400}
401
402/*
403 * Errata i913: CSI2 LDO Needs to be disabled when module is powered on
404 *
405 * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
406 * LDOs on the device are disabled if CSI-2 module is powered on
407 * (0x4845 B304 | 0x4845 B384 [28:27] = 0x1) or in ULPS (0x4845 B304
408 * | 0x4845 B384 [28:27] = 0x2) mode. Common concerns include: high
409 * current draw on the module supply in active mode.
410 *
411 * Errata does not apply when CSI-2 module is powered off
412 * (0x4845 B304 | 0x4845 B384 [28:27] = 0x0).
413 *
414 * SW Workaround:
415 * Set the following register bits to disable the LDO,
416 * which is essentially CSI2 REG10 bit 6:
417 *
418 * Core 0: 0x4845 B828 = 0x0000 0040
419 * Core 1: 0x4845 B928 = 0x0000 0040
420 */
421void cal_camerarx_i913_errata(struct cal_camerarx *phy)
422{
423 u32 reg10 = camerarx_read(phy, CAL_CSI2_PHY_REG10);
424
425 cal_set_field(&reg10, 1, CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK);
426
427 phy_dbg(1, phy, "CSI2_%d_REG10 = 0x%08x\n", phy->instance, reg10);
428 camerarx_write(phy, CAL_CSI2_PHY_REG10, reg10);
429}
430
431/*
432 * Enable the expected IRQ sources
433 */
434void cal_camerarx_enable_irqs(struct cal_camerarx *phy)
435{
436 u32 val;
437
438 const u32 cio_err_mask =
439 CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK |
440 CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
441 CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
442 CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
443
444 /* Enable CIO error irqs */
445 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0),
446 CAL_HL_IRQ_CIO_MASK(phy->instance));
447 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance),
448 cio_err_mask);
449
450 /* Always enable OCPO error */
451 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK);
452
453 /* Enable IRQ_WDMA_END 0/1 */
454 val = 0;
455 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance));
456 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(1), val);
457 /* Enable IRQ_WDMA_START 0/1 */
458 val = 0;
459 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance));
460 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(2), val);
461 /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
462 cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(0), 0xFF000000);
463}
464
465void cal_camerarx_disable_irqs(struct cal_camerarx *phy)
466{
467 u32 val;
468
469 /* Disable CIO error irqs */
470 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0),
471 CAL_HL_IRQ_CIO_MASK(phy->instance));
472 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0);
473
474 /* Disable IRQ_WDMA_END 0/1 */
475 val = 0;
476 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance));
477 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(1), val);
478 /* Disable IRQ_WDMA_START 0/1 */
479 val = 0;
480 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance));
481 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(2), val);
482 /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
483 cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(0), 0);
484}
485
486void cal_camerarx_ppi_enable(struct cal_camerarx *phy)
487{
488 cal_write(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), BIT(3));
489 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
490 1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
491}
492
493void cal_camerarx_ppi_disable(struct cal_camerarx *phy)
494{
495 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
496 0, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
497}
498
499static int cal_camerarx_regmap_init(struct cal_dev *cal,
500 struct cal_camerarx *phy)
501{
502 const struct cal_camerarx_data *phy_data;
503 unsigned int i;
504
505 if (!cal->data)
506 return -EINVAL;
507
508 phy_data = &cal->data->camerarx[phy->instance];
509
510 for (i = 0; i < F_MAX_FIELDS; i++) {
511 struct reg_field field = {
512 .reg = cal->syscon_camerrx_offset,
513 .lsb = phy_data->fields[i].lsb,
514 .msb = phy_data->fields[i].msb,
515 };
516
517 /*
518 * Here we update the reg offset with the
519 * value found in DT
520 */
521 phy->fields[i] = devm_regmap_field_alloc(cal->dev,
522 cal->syscon_camerrx,
523 field);
524 if (IS_ERR(phy->fields[i])) {
525 cal_err(cal, "Unable to allocate regmap fields\n");
526 return PTR_ERR(phy->fields[i]);
527 }
528 }
529
530 return 0;
531}
532
533static int cal_camerarx_parse_dt(struct cal_camerarx *phy)
534{
535 struct v4l2_fwnode_endpoint *endpoint = &phy->endpoint;
536 struct device_node *ep_node;
537 char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES * 2];
538 unsigned int i;
539 int ret;
540
541 /*
542 * Find the endpoint node for the port corresponding to the PHY
543 * instance, and parse its CSI-2-related properties.
544 */
545 ep_node = of_graph_get_endpoint_by_regs(phy->cal->dev->of_node,
546 phy->instance, 0);
547 if (!ep_node) {
548 /*
549 * The endpoint is not mandatory, not all PHY instances need to
550 * be connected in DT.
551 */
552 phy_dbg(3, phy, "Port has no endpoint\n");
553 return 0;
554 }
555
556 endpoint->bus_type = V4L2_MBUS_CSI2_DPHY;
557 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint);
558 if (ret < 0) {
559 phy_err(phy, "Failed to parse endpoint\n");
560 goto done;
561 }
562
563 for (i = 0; i < endpoint->bus.mipi_csi2.num_data_lanes; i++) {
564 unsigned int lane = endpoint->bus.mipi_csi2.data_lanes[i];
565
566 if (lane > 4) {
567 phy_err(phy, "Invalid position %u for data lane %u\n",
568 lane, i);
569 ret = -EINVAL;
570 goto done;
571 }
572
573 data_lanes[i*2] = '0' + lane;
574 data_lanes[i*2+1] = ' ';
575 }
576
577 data_lanes[i*2-1] = '\0';
578
579 phy_dbg(3, phy,
580 "CSI-2 bus: clock lane <%u>, data lanes <%s>, flags 0x%08x\n",
581 endpoint->bus.mipi_csi2.clock_lane, data_lanes,
582 endpoint->bus.mipi_csi2.flags);
583
584 /* Retrieve the connected device and store it for later use. */
585 phy->sensor_node = of_graph_get_remote_port_parent(ep_node);
586 if (!phy->sensor_node) {
587 phy_dbg(3, phy, "Can't get remote parent\n");
588 ret = -EINVAL;
589 goto done;
590 }
591
592 phy_dbg(1, phy, "Found connected device %pOFn\n", phy->sensor_node);
593
594done:
595 of_node_put(ep_node);
596 return ret;
597}
598
599struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
600 unsigned int instance)
601{
602 struct platform_device *pdev = to_platform_device(cal->dev);
603 struct cal_camerarx *phy;
604 int ret;
605
606 phy = kzalloc(sizeof(*phy), GFP_KERNEL);
607 if (!phy)
608 return ERR_PTR(-ENOMEM);
609
610 phy->cal = cal;
611 phy->instance = instance;
612
613 phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
614 (instance == 0) ?
615 "cal_rx_core0" :
616 "cal_rx_core1");
617 phy->base = devm_ioremap_resource(cal->dev, phy->res);
618 if (IS_ERR(phy->base)) {
619 cal_err(cal, "failed to ioremap\n");
620 ret = PTR_ERR(phy->base);
621 goto error;
622 }
623
624 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
625 phy->res->name, &phy->res->start, &phy->res->end);
626
627 ret = cal_camerarx_regmap_init(cal, phy);
628 if (ret)
629 goto error;
630
631 ret = cal_camerarx_parse_dt(phy);
632 if (ret)
633 goto error;
634
635 return phy;
636
637error:
638 kfree(phy);
639 return ERR_PTR(ret);
640}
641
642void cal_camerarx_destroy(struct cal_camerarx *phy)
643{
644 if (!phy)
645 return;
646
647 of_node_put(phy->sensor_node);
648 kfree(phy);
649}
drivers/media/platform/ti-vpe/cal-video.c+886−0
@@ -0,0 +1,886 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * TI Camera Access Layer (CAL) - Video Device
4 *
5 * Copyright (c) 2015-2020 Texas Instruments Inc.
6 *
7 * Authors:
8 * Benoit Parrot <bparrot@ti.com>
9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 */
11
12#include <linux/delay.h>
13#include <linux/ioctl.h>
14#include <linux/pm_runtime.h>
15#include <linux/videodev2.h>
16
17#include <media/media-device.h>
18#include <media/v4l2-common.h>
19#include <media/v4l2-ctrls.h>
20#include <media/v4l2-device.h>
21#include <media/v4l2-event.h>
22#include <media/v4l2-fh.h>
23#include <media/v4l2-ioctl.h>
24#include <media/videobuf2-core.h>
25#include <media/videobuf2-dma-contig.h>
26
27#include "cal.h"
28
29/* ------------------------------------------------------------------
30 * Format Handling
31 * ------------------------------------------------------------------
32 */
33
34static const struct cal_fmt cal_formats[] = {
35 {
36 .fourcc = V4L2_PIX_FMT_YUYV,
37 .code = MEDIA_BUS_FMT_YUYV8_2X8,
38 .bpp = 16,
39 }, {
40 .fourcc = V4L2_PIX_FMT_UYVY,
41 .code = MEDIA_BUS_FMT_UYVY8_2X8,
42 .bpp = 16,
43 }, {
44 .fourcc = V4L2_PIX_FMT_YVYU,
45 .code = MEDIA_BUS_FMT_YVYU8_2X8,
46 .bpp = 16,
47 }, {
48 .fourcc = V4L2_PIX_FMT_VYUY,
49 .code = MEDIA_BUS_FMT_VYUY8_2X8,
50 .bpp = 16,
51 }, {
52 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
53 .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
54 .bpp = 16,
55 }, {
56 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
57 .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
58 .bpp = 16,
59 }, {
60 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
61 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
62 .bpp = 16,
63 }, {
64 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
65 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
66 .bpp = 16,
67 }, {
68 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
69 .code = MEDIA_BUS_FMT_RGB888_2X12_LE,
70 .bpp = 24,
71 }, {
72 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
73 .code = MEDIA_BUS_FMT_RGB888_2X12_BE,
74 .bpp = 24,
75 }, {
76 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
77 .code = MEDIA_BUS_FMT_ARGB8888_1X32,
78 .bpp = 32,
79 }, {
80 .fourcc = V4L2_PIX_FMT_SBGGR8,
81 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
82 .bpp = 8,
83 }, {
84 .fourcc = V4L2_PIX_FMT_SGBRG8,
85 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
86 .bpp = 8,
87 }, {
88 .fourcc = V4L2_PIX_FMT_SGRBG8,
89 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
90 .bpp = 8,
91 }, {
92 .fourcc = V4L2_PIX_FMT_SRGGB8,
93 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
94 .bpp = 8,
95 }, {
96 .fourcc = V4L2_PIX_FMT_SBGGR10,
97 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
98 .bpp = 10,
99 }, {
100 .fourcc = V4L2_PIX_FMT_SGBRG10,
101 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
102 .bpp = 10,
103 }, {
104 .fourcc = V4L2_PIX_FMT_SGRBG10,
105 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
106 .bpp = 10,
107 }, {
108 .fourcc = V4L2_PIX_FMT_SRGGB10,
109 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
110 .bpp = 10,
111 }, {
112 .fourcc = V4L2_PIX_FMT_SBGGR12,
113 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
114 .bpp = 12,
115 }, {
116 .fourcc = V4L2_PIX_FMT_SGBRG12,
117 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
118 .bpp = 12,
119 }, {
120 .fourcc = V4L2_PIX_FMT_SGRBG12,
121 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
122 .bpp = 12,
123 }, {
124 .fourcc = V4L2_PIX_FMT_SRGGB12,
125 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
126 .bpp = 12,
127 },
128};
129
130/* Print Four-character-code (FOURCC) */
131static char *fourcc_to_str(u32 fmt)
132{
133 static char code[5];
134
135 code[0] = (unsigned char)(fmt & 0xff);
136 code[1] = (unsigned char)((fmt >> 8) & 0xff);
137 code[2] = (unsigned char)((fmt >> 16) & 0xff);
138 code[3] = (unsigned char)((fmt >> 24) & 0xff);
139 code[4] = '\0';
140
141 return code;
142}
143
144/* ------------------------------------------------------------------
145 * V4L2 Video IOCTLs
146 * ------------------------------------------------------------------
147 */
148
149static const struct cal_fmt *find_format_by_pix(struct cal_ctx *ctx,
150 u32 pixelformat)
151{
152 const struct cal_fmt *fmt;
153 unsigned int k;
154
155 for (k = 0; k < ctx->num_active_fmt; k++) {
156 fmt = ctx->active_fmt[k];
157 if (fmt->fourcc == pixelformat)
158 return fmt;
159 }
160
161 return NULL;
162}
163
164static const struct cal_fmt *find_format_by_code(struct cal_ctx *ctx,
165 u32 code)
166{
167 const struct cal_fmt *fmt;
168 unsigned int k;
169
170 for (k = 0; k < ctx->num_active_fmt; k++) {
171 fmt = ctx->active_fmt[k];
172 if (fmt->code == code)
173 return fmt;
174 }
175
176 return NULL;
177}
178
179static int cal_querycap(struct file *file, void *priv,
180 struct v4l2_capability *cap)
181{
182 struct cal_ctx *ctx = video_drvdata(file);
183
184 strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));
185 strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));
186
187 snprintf(cap->bus_info, sizeof(cap->bus_info),
188 "platform:%s", dev_name(ctx->cal->dev));
189 return 0;
190}
191
192static int cal_enum_fmt_vid_cap(struct file *file, void *priv,
193 struct v4l2_fmtdesc *f)
194{
195 struct cal_ctx *ctx = video_drvdata(file);
196 const struct cal_fmt *fmt;
197
198 if (f->index >= ctx->num_active_fmt)
199 return -EINVAL;
200
201 fmt = ctx->active_fmt[f->index];
202
203 f->pixelformat = fmt->fourcc;
204 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
205 return 0;
206}
207
208static int __subdev_get_format(struct cal_ctx *ctx,
209 struct v4l2_mbus_framefmt *fmt)
210{
211 struct v4l2_subdev_format sd_fmt;
212 struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
213 int ret;
214
215 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
216 sd_fmt.pad = 0;
217
218 ret = v4l2_subdev_call(ctx->phy->sensor, pad, get_fmt, NULL, &sd_fmt);
219 if (ret)
220 return ret;
221
222 *fmt = *mbus_fmt;
223
224 ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
225 fmt->width, fmt->height, fmt->code);
226
227 return 0;
228}
229
230static int __subdev_set_format(struct cal_ctx *ctx,
231 struct v4l2_mbus_framefmt *fmt)
232{
233 struct v4l2_subdev_format sd_fmt;
234 struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
235 int ret;
236
237 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
238 sd_fmt.pad = 0;
239 *mbus_fmt = *fmt;
240
241 ret = v4l2_subdev_call(ctx->phy->sensor, pad, set_fmt, NULL, &sd_fmt);
242 if (ret)
243 return ret;
244
245 ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
246 fmt->width, fmt->height, fmt->code);
247
248 return 0;
249}
250
251static int cal_calc_format_size(struct cal_ctx *ctx,
252 const struct cal_fmt *fmt,
253 struct v4l2_format *f)
254{
255 u32 bpl, max_width;
256
257 if (!fmt) {
258 ctx_dbg(3, ctx, "No cal_fmt provided!\n");
259 return -EINVAL;
260 }
261
262 /*
263 * Maximum width is bound by the DMA max width in bytes.
264 * We need to recalculate the actual maxi width depending on the
265 * number of bytes per pixels required.
266 */
267 max_width = MAX_WIDTH_BYTES / (ALIGN(fmt->bpp, 8) >> 3);
268 v4l_bound_align_image(&f->fmt.pix.width, 48, max_width, 2,
269 &f->fmt.pix.height, 32, MAX_HEIGHT_LINES, 0, 0);
270
271 bpl = (f->fmt.pix.width * ALIGN(fmt->bpp, 8)) >> 3;
272 f->fmt.pix.bytesperline = ALIGN(bpl, 16);
273
274 f->fmt.pix.sizeimage = f->fmt.pix.height *
275 f->fmt.pix.bytesperline;
276
277 ctx_dbg(3, ctx, "%s: fourcc: %s size: %dx%d bpl:%d img_size:%d\n",
278 __func__, fourcc_to_str(f->fmt.pix.pixelformat),
279 f->fmt.pix.width, f->fmt.pix.height,
280 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
281
282 return 0;
283}
284
285static int cal_g_fmt_vid_cap(struct file *file, void *priv,
286 struct v4l2_format *f)
287{
288 struct cal_ctx *ctx = video_drvdata(file);
289
290 *f = ctx->v_fmt;
291
292 return 0;
293}
294
295static int cal_try_fmt_vid_cap(struct file *file, void *priv,
296 struct v4l2_format *f)
297{
298 struct cal_ctx *ctx = video_drvdata(file);
299 const struct cal_fmt *fmt;
300 struct v4l2_subdev_frame_size_enum fse;
301 int ret, found;
302
303 fmt = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
304 if (!fmt) {
305 ctx_dbg(3, ctx, "Fourcc format (0x%08x) not found.\n",
306 f->fmt.pix.pixelformat);
307
308 /* Just get the first one enumerated */
309 fmt = ctx->active_fmt[0];
310 f->fmt.pix.pixelformat = fmt->fourcc;
311 }
312
313 f->fmt.pix.field = ctx->v_fmt.fmt.pix.field;
314
315 /* check for/find a valid width/height */
316 ret = 0;
317 found = false;
318 fse.pad = 0;
319 fse.code = fmt->code;
320 fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
321 for (fse.index = 0; ; fse.index++) {
322 ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_frame_size,
323 NULL, &fse);
324 if (ret)
325 break;
326
327 if ((f->fmt.pix.width == fse.max_width) &&
328 (f->fmt.pix.height == fse.max_height)) {
329 found = true;
330 break;
331 } else if ((f->fmt.pix.width >= fse.min_width) &&
332 (f->fmt.pix.width <= fse.max_width) &&
333 (f->fmt.pix.height >= fse.min_height) &&
334 (f->fmt.pix.height <= fse.max_height)) {
335 found = true;
336 break;
337 }
338 }
339
340 if (!found) {
341 /* use existing values as default */
342 f->fmt.pix.width = ctx->v_fmt.fmt.pix.width;
343 f->fmt.pix.height = ctx->v_fmt.fmt.pix.height;
344 }
345
346 /*
347 * Use current colorspace for now, it will get
348 * updated properly during s_fmt
349 */
350 f->fmt.pix.colorspace = ctx->v_fmt.fmt.pix.colorspace;
351 return cal_calc_format_size(ctx, fmt, f);
352}
353
354static int cal_s_fmt_vid_cap(struct file *file, void *priv,
355 struct v4l2_format *f)
356{
357 struct cal_ctx *ctx = video_drvdata(file);
358 struct vb2_queue *q = &ctx->vb_vidq;
359 const struct cal_fmt *fmt;
360 struct v4l2_mbus_framefmt mbus_fmt;
361 int ret;
362
363 if (vb2_is_busy(q)) {
364 ctx_dbg(3, ctx, "%s device busy\n", __func__);
365 return -EBUSY;
366 }
367
368 ret = cal_try_fmt_vid_cap(file, priv, f);
369 if (ret < 0)
370 return ret;
371
372 fmt = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
373
374 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code);
375
376 ret = __subdev_set_format(ctx, &mbus_fmt);
377 if (ret)
378 return ret;
379
380 /* Just double check nothing has gone wrong */
381 if (mbus_fmt.code != fmt->code) {
382 ctx_dbg(3, ctx,
383 "%s subdev changed format on us, this should not happen\n",
384 __func__);
385 return -EINVAL;
386 }
387
388 v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
389 ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
390 ctx->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
391 cal_calc_format_size(ctx, fmt, &ctx->v_fmt);
392 ctx->fmt = fmt;
393 ctx->m_fmt = mbus_fmt;
394 *f = ctx->v_fmt;
395
396 return 0;
397}
398
399static int cal_enum_framesizes(struct file *file, void *fh,
400 struct v4l2_frmsizeenum *fsize)
401{
402 struct cal_ctx *ctx = video_drvdata(file);
403 const struct cal_fmt *fmt;
404 struct v4l2_subdev_frame_size_enum fse;
405 int ret;
406
407 /* check for valid format */
408 fmt = find_format_by_pix(ctx, fsize->pixel_format);
409 if (!fmt) {
410 ctx_dbg(3, ctx, "Invalid pixel code: %x\n",
411 fsize->pixel_format);
412 return -EINVAL;
413 }
414
415 fse.index = fsize->index;
416 fse.pad = 0;
417 fse.code = fmt->code;
418 fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
419
420 ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_frame_size, NULL,
421 &fse);
422 if (ret)
423 return ret;
424
425 ctx_dbg(1, ctx, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
426 __func__, fse.index, fse.code, fse.min_width, fse.max_width,
427 fse.min_height, fse.max_height);
428
429 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
430 fsize->discrete.width = fse.max_width;
431 fsize->discrete.height = fse.max_height;
432
433 return 0;
434}
435
436static int cal_enum_input(struct file *file, void *priv,
437 struct v4l2_input *inp)
438{
439 if (inp->index > 0)
440 return -EINVAL;
441
442 inp->type = V4L2_INPUT_TYPE_CAMERA;
443 sprintf(inp->name, "Camera %u", inp->index);
444 return 0;
445}
446
447static int cal_g_input(struct file *file, void *priv, unsigned int *i)
448{
449 *i = 0;
450 return 0;
451}
452
453static int cal_s_input(struct file *file, void *priv, unsigned int i)
454{
455 return i > 0 ? -EINVAL : 0;
456}
457
458/* timeperframe is arbitrary and continuous */
459static int cal_enum_frameintervals(struct file *file, void *priv,
460 struct v4l2_frmivalenum *fival)
461{
462 struct cal_ctx *ctx = video_drvdata(file);
463 const struct cal_fmt *fmt;
464 struct v4l2_subdev_frame_interval_enum fie = {
465 .index = fival->index,
466 .width = fival->width,
467 .height = fival->height,
468 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
469 };
470 int ret;
471
472 fmt = find_format_by_pix(ctx, fival->pixel_format);
473 if (!fmt)
474 return -EINVAL;
475
476 fie.code = fmt->code;
477 ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_frame_interval,
478 NULL, &fie);
479 if (ret)
480 return ret;
481 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
482 fival->discrete = fie.interval;
483
484 return 0;
485}
486
487static const struct v4l2_file_operations cal_fops = {
488 .owner = THIS_MODULE,
489 .open = v4l2_fh_open,
490 .release = vb2_fop_release,
491 .read = vb2_fop_read,
492 .poll = vb2_fop_poll,
493 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
494 .mmap = vb2_fop_mmap,
495};
496
497static const struct v4l2_ioctl_ops cal_ioctl_ops = {
498 .vidioc_querycap = cal_querycap,
499 .vidioc_enum_fmt_vid_cap = cal_enum_fmt_vid_cap,
500 .vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
501 .vidioc_try_fmt_vid_cap = cal_try_fmt_vid_cap,
502 .vidioc_s_fmt_vid_cap = cal_s_fmt_vid_cap,
503 .vidioc_enum_framesizes = cal_enum_framesizes,
504 .vidioc_reqbufs = vb2_ioctl_reqbufs,
505 .vidioc_create_bufs = vb2_ioctl_create_bufs,
506 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
507 .vidioc_querybuf = vb2_ioctl_querybuf,
508 .vidioc_qbuf = vb2_ioctl_qbuf,
509 .vidioc_dqbuf = vb2_ioctl_dqbuf,
510 .vidioc_expbuf = vb2_ioctl_expbuf,
511 .vidioc_enum_input = cal_enum_input,
512 .vidioc_g_input = cal_g_input,
513 .vidioc_s_input = cal_s_input,
514 .vidioc_enum_frameintervals = cal_enum_frameintervals,
515 .vidioc_streamon = vb2_ioctl_streamon,
516 .vidioc_streamoff = vb2_ioctl_streamoff,
517 .vidioc_log_status = v4l2_ctrl_log_status,
518 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
519 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
520};
521
522/* ------------------------------------------------------------------
523 * videobuf2 Operations
524 * ------------------------------------------------------------------
525 */
526
527static int cal_queue_setup(struct vb2_queue *vq,
528 unsigned int *nbuffers, unsigned int *nplanes,
529 unsigned int sizes[], struct device *alloc_devs[])
530{
531 struct cal_ctx *ctx = vb2_get_drv_priv(vq);
532 unsigned int size = ctx->v_fmt.fmt.pix.sizeimage;
533
534 if (vq->num_buffers + *nbuffers < 3)
535 *nbuffers = 3 - vq->num_buffers;
536
537 if (*nplanes) {
538 if (sizes[0] < size)
539 return -EINVAL;
540 size = sizes[0];
541 }
542
543 *nplanes = 1;
544 sizes[0] = size;
545
546 ctx_dbg(3, ctx, "nbuffers=%d, size=%d\n", *nbuffers, sizes[0]);
547
548 return 0;
549}
550
551static int cal_buffer_prepare(struct vb2_buffer *vb)
552{
553 struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
554 struct cal_buffer *buf = container_of(vb, struct cal_buffer,
555 vb.vb2_buf);
556 unsigned long size;
557
558 if (WARN_ON(!ctx->fmt))
559 return -EINVAL;
560
561 size = ctx->v_fmt.fmt.pix.sizeimage;
562 if (vb2_plane_size(vb, 0) < size) {
563 ctx_err(ctx,
564 "data will not fit into plane (%lu < %lu)\n",
565 vb2_plane_size(vb, 0), size);
566 return -EINVAL;
567 }
568
569 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
570 return 0;
571}
572
573static void cal_buffer_queue(struct vb2_buffer *vb)
574{
575 struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
576 struct cal_buffer *buf = container_of(vb, struct cal_buffer,
577 vb.vb2_buf);
578 struct cal_dmaqueue *vidq = &ctx->vidq;
579 unsigned long flags;
580
581 /* recheck locking */
582 spin_lock_irqsave(&ctx->slock, flags);
583 list_add_tail(&buf->list, &vidq->active);
584 spin_unlock_irqrestore(&ctx->slock, flags);
585}
586
587static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
588{
589 struct cal_ctx *ctx = vb2_get_drv_priv(vq);
590 struct cal_dmaqueue *dma_q = &ctx->vidq;
591 struct cal_buffer *buf, *tmp;
592 unsigned long addr;
593 unsigned long flags;
594 int ret;
595
596 spin_lock_irqsave(&ctx->slock, flags);
597 if (list_empty(&dma_q->active)) {
598 spin_unlock_irqrestore(&ctx->slock, flags);
599 ctx_dbg(3, ctx, "buffer queue is empty\n");
600 return -EIO;
601 }
602
603 buf = list_entry(dma_q->active.next, struct cal_buffer, list);
604 ctx->cur_frm = buf;
605 ctx->next_frm = buf;
606 list_del(&buf->list);
607 spin_unlock_irqrestore(&ctx->slock, flags);
608
609 addr = vb2_dma_contig_plane_dma_addr(&ctx->cur_frm->vb.vb2_buf, 0);
610 ctx->sequence = 0;
611
612 pm_runtime_get_sync(ctx->cal->dev);
613
614 cal_ctx_csi2_config(ctx);
615 cal_ctx_pix_proc_config(ctx);
616 cal_ctx_wr_dma_config(ctx, ctx->v_fmt.fmt.pix.bytesperline,
617 ctx->v_fmt.fmt.pix.height);
618
619 cal_camerarx_enable_irqs(ctx->phy);
620
621 ret = cal_camerarx_start(ctx->phy, ctx->fmt);
622 if (ret)
623 goto err;
624
625 cal_ctx_wr_dma_addr(ctx, addr);
626 cal_camerarx_ppi_enable(ctx->phy);
627
628 if (cal_debug >= 4)
629 cal_quickdump_regs(ctx->cal);
630
631 return 0;
632
633err:
634 spin_lock_irqsave(&ctx->slock, flags);
635 vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
636 ctx->cur_frm = NULL;
637 ctx->next_frm = NULL;
638 list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
639 list_del(&buf->list);
640 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
641 }
642 spin_unlock_irqrestore(&ctx->slock, flags);
643 return ret;
644}
645
646static void cal_stop_streaming(struct vb2_queue *vq)
647{
648 struct cal_ctx *ctx = vb2_get_drv_priv(vq);
649 struct cal_dmaqueue *dma_q = &ctx->vidq;
650 struct cal_buffer *buf, *tmp;
651 unsigned long timeout;
652 unsigned long flags;
653 bool dma_act;
654
655 cal_camerarx_ppi_disable(ctx->phy);
656
657 /* wait for stream and dma to finish */
658 dma_act = true;
659 timeout = jiffies + msecs_to_jiffies(500);
660 while (dma_act && time_before(jiffies, timeout)) {
661 msleep(50);
662
663 spin_lock_irqsave(&ctx->slock, flags);
664 dma_act = ctx->dma_act;
665 spin_unlock_irqrestore(&ctx->slock, flags);
666 }
667
668 if (dma_act)
669 ctx_err(ctx, "failed to disable dma cleanly\n");
670
671 cal_camerarx_disable_irqs(ctx->phy);
672 cal_camerarx_stop(ctx->phy);
673
674 /* Release all active buffers */
675 spin_lock_irqsave(&ctx->slock, flags);
676 list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
677 list_del(&buf->list);
678 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
679 }
680
681 if (ctx->cur_frm == ctx->next_frm) {
682 vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR);
683 } else {
684 vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR);
685 vb2_buffer_done(&ctx->next_frm->vb.vb2_buf,
686 VB2_BUF_STATE_ERROR);
687 }
688 ctx->cur_frm = NULL;
689 ctx->next_frm = NULL;
690 spin_unlock_irqrestore(&ctx->slock, flags);
691
692 pm_runtime_put_sync(ctx->cal->dev);
693}
694
695static const struct vb2_ops cal_video_qops = {
696 .queue_setup = cal_queue_setup,
697 .buf_prepare = cal_buffer_prepare,
698 .buf_queue = cal_buffer_queue,
699 .start_streaming = cal_start_streaming,
700 .stop_streaming = cal_stop_streaming,
701 .wait_prepare = vb2_ops_wait_prepare,
702 .wait_finish = vb2_ops_wait_finish,
703};
704
705/* ------------------------------------------------------------------
706 * V4L2 Initialization and Registration
707 * ------------------------------------------------------------------
708 */
709
710static const struct video_device cal_videodev = {
711 .name = CAL_MODULE_NAME,
712 .fops = &cal_fops,
713 .ioctl_ops = &cal_ioctl_ops,
714 .minor = -1,
715 .release = video_device_release_empty,
716 .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
717 V4L2_CAP_READWRITE,
718};
719
720static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
721{
722 struct v4l2_subdev_mbus_code_enum mbus_code;
723 struct v4l2_mbus_framefmt mbus_fmt;
724 const struct cal_fmt *fmt;
725 unsigned int i, j, k;
726 int ret = 0;
727
728 /* Enumerate sub device formats and enable all matching local formats */
729 ctx->active_fmt = devm_kcalloc(ctx->cal->dev, ARRAY_SIZE(cal_formats),
730 sizeof(*ctx->active_fmt), GFP_KERNEL);
731 ctx->num_active_fmt = 0;
732
733 for (j = 0, i = 0; ret != -EINVAL; ++j) {
734
735 memset(&mbus_code, 0, sizeof(mbus_code));
736 mbus_code.index = j;
737 mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
738 ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_mbus_code,
739 NULL, &mbus_code);
740 if (ret)
741 continue;
742
743 ctx_dbg(2, ctx,
744 "subdev %s: code: %04x idx: %u\n",
745 ctx->phy->sensor->name, mbus_code.code, j);
746
747 for (k = 0; k < ARRAY_SIZE(cal_formats); k++) {
748 const struct cal_fmt *fmt = &cal_formats[k];
749
750 if (mbus_code.code == fmt->code) {
751 ctx->active_fmt[i] = fmt;
752 ctx_dbg(2, ctx,
753 "matched fourcc: %s: code: %04x idx: %u\n",
754 fourcc_to_str(fmt->fourcc),
755 fmt->code, i);
756 ctx->num_active_fmt = ++i;
757 }
758 }
759 }
760
761 if (i == 0) {
762 ctx_err(ctx, "No suitable format reported by subdev %s\n",
763 ctx->phy->sensor->name);
764 return -EINVAL;
765 }
766
767 ret = __subdev_get_format(ctx, &mbus_fmt);
768 if (ret)
769 return ret;
770
771 fmt = find_format_by_code(ctx, mbus_fmt.code);
772 if (!fmt) {
773 ctx_dbg(3, ctx, "mbus code format (0x%08x) not found.\n",
774 mbus_fmt.code);
775 return -EINVAL;
776 }
777
778 /* Save current subdev format */
779 v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
780 ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
781 ctx->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
782 cal_calc_format_size(ctx, fmt, &ctx->v_fmt);
783 ctx->fmt = fmt;
784 ctx->m_fmt = mbus_fmt;
785
786 return 0;
787}
788
789int cal_ctx_v4l2_register(struct cal_ctx *ctx)
790{
791 struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
792 struct video_device *vfd = &ctx->vdev;
793 int ret;
794
795 ret = cal_ctx_v4l2_init_formats(ctx);
796 if (ret)
797 return ret;
798
799 ret = v4l2_ctrl_add_handler(hdl, ctx->phy->sensor->ctrl_handler, NULL,
800 true);
801 if (ret < 0) {
802 ctx_err(ctx, "Failed to add sensor ctrl handler\n");
803 return ret;
804 }
805
806 ret = video_register_device(vfd, VFL_TYPE_VIDEO, cal_video_nr);
807 if (ret < 0) {
808 ctx_err(ctx, "Failed to register video device\n");
809 return ret;
810 }
811
812 ctx_info(ctx, "V4L2 device registered as %s\n",
813 video_device_node_name(vfd));
814
815 return 0;
816}
817
818void cal_ctx_v4l2_unregister(struct cal_ctx *ctx)
819{
820 ctx_dbg(1, ctx, "unregistering %s\n",
821 video_device_node_name(&ctx->vdev));
822
823 video_unregister_device(&ctx->vdev);
824}
825
826int cal_ctx_v4l2_init(struct cal_ctx *ctx)
827{
828 struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
829 struct video_device *vfd = &ctx->vdev;
830 struct vb2_queue *q = &ctx->vb_vidq;
831 int ret;
832
833 INIT_LIST_HEAD(&ctx->vidq.active);
834 spin_lock_init(&ctx->slock);
835 mutex_init(&ctx->mutex);
836
837 /* Initialize the vb2 queue. */
838 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
839 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
840 q->drv_priv = ctx;
841 q->buf_struct_size = sizeof(struct cal_buffer);
842 q->ops = &cal_video_qops;
843 q->mem_ops = &vb2_dma_contig_memops;
844 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
845 q->lock = &ctx->mutex;
846 q->min_buffers_needed = 3;
847 q->dev = ctx->cal->dev;
848
849 ret = vb2_queue_init(q);
850 if (ret)
851 return ret;
852
853 /* Initialize the video device and media entity. */
854 *vfd = cal_videodev;
855 vfd->v4l2_dev = &ctx->cal->v4l2_dev;
856 vfd->queue = q;
857 snprintf(vfd->name, sizeof(vfd->name), "CAL output %u", ctx->index);
858 vfd->lock = &ctx->mutex;
859 video_set_drvdata(vfd, ctx);
860
861 ctx->pad.flags = MEDIA_PAD_FL_SINK;
862 ret = media_entity_pads_init(&vfd->entity, 1, &ctx->pad);
863 if (ret < 0)
864 return ret;
865
866 /* Initialize the control handler. */
867 ret = v4l2_ctrl_handler_init(hdl, 11);
868 if (ret < 0) {
869 ctx_err(ctx, "Failed to init ctrl handler\n");
870 goto error;
871 }
872
873 vfd->ctrl_handler = hdl;
874
875 return 0;
876
877error:
878 media_entity_cleanup(&vfd->entity);
879 return ret;
880}
881
882void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx)
883{
884 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
885 media_entity_cleanup(&ctx->vdev.entity);
886}
drivers/media/platform/ti-vpe/cal.c+489−2034
@@ -1,976 +1,167 @@
1// SPDX-License-Identifier: GPL-2.0-only1// SPDX-License-Identifier: GPL-2.0-only
2/*2/*
3 * TI CAL camera interface driver3 * TI Camera Access Layer (CAL) - Driver
4 *4 *
5 * Copyright (c) 2015 Texas Instruments Inc.5 * Copyright (c) 2015-2020 Texas Instruments Inc.
6 * Benoit Parrot, <bparrot@ti.com>6 *
7 * Authors:
8 * Benoit Parrot <bparrot@ti.com>
9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 */10 */
8 11
9#include <linux/clk.h>12#include <linux/clk.h>
10#include <linux/interrupt.h>13#include <linux/interrupt.h>
11#include <linux/io.h>14#include <linux/mfd/syscon.h>
12#include <linux/ioctl.h>
13#include <linux/module.h>15#include <linux/module.h>
16#include <linux/of_device.h>
14#include <linux/platform_device.h>17#include <linux/platform_device.h>
15#include <linux/delay.h>
16#include <linux/pm_runtime.h>18#include <linux/pm_runtime.h>
17#include <linux/slab.h>
18#include <linux/mfd/syscon.h>
19#include <linux/regmap.h>19#include <linux/regmap.h>
20#include <linux/slab.h>
20#include <linux/videodev2.h>21#include <linux/videodev2.h>
21#include <linux/of_device.h>
22#include <linux/of_graph.h>
23 22
24#include <media/v4l2-fwnode.h>23#include <media/media-device.h>
25#include <media/v4l2-async.h>24#include <media/v4l2-async.h>
26#include <media/v4l2-common.h>25#include <media/v4l2-common.h>
27#include <media/v4l2-ctrls.h>
28#include <media/v4l2-device.h>26#include <media/v4l2-device.h>
29#include <media/v4l2-event.h>
30#include <media/v4l2-ioctl.h>
31#include <media/v4l2-fh.h>
32#include <media/videobuf2-core.h>27#include <media/videobuf2-core.h>
33#include <media/videobuf2-dma-contig.h>28#include <media/videobuf2-dma-contig.h>
34#include "cal_regs.h"
35 29
36#define CAL_MODULE_NAME "cal"30#include "cal.h"
37 31#include "cal_regs.h"
38#define MAX_WIDTH_BYTES (8192 * 8)
39#define MAX_HEIGHT_LINES 16383
40
41#define CAL_VERSION "0.1.0"
42 32
43MODULE_DESCRIPTION("TI CAL driver");33MODULE_DESCRIPTION("TI CAL driver");
44MODULE_AUTHOR("Benoit Parrot, <bparrot@ti.com>");34MODULE_AUTHOR("Benoit Parrot, <bparrot@ti.com>");
45MODULE_LICENSE("GPL v2");35MODULE_LICENSE("GPL v2");
46MODULE_VERSION(CAL_VERSION);36MODULE_VERSION("0.1.0");
47 37
48static unsigned video_nr = -1;38int cal_video_nr = -1;
49module_param(video_nr, uint, 0644);39module_param_named(video_nr, cal_video_nr, uint, 0644);
50MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");40MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
51 41
52static unsigned debug;42unsigned int cal_debug;
53module_param(debug, uint, 0644);43module_param_named(debug, cal_debug, uint, 0644);
54MODULE_PARM_DESC(debug, "activates debug info");44MODULE_PARM_DESC(debug, "activates debug info");
55 45
56/* timeperframe: min/max and default */
57static const struct v4l2_fract
58 tpf_default = {.numerator = 1001, .denominator = 30000};
59
60#define cal_dbg(level, caldev, fmt, arg...) \
61 v4l2_dbg(level, debug, &caldev->v4l2_dev, fmt, ##arg)
62#define cal_info(caldev, fmt, arg...) \
63 v4l2_info(&caldev->v4l2_dev, fmt, ##arg)
64#define cal_err(caldev, fmt, arg...) \
65 v4l2_err(&caldev->v4l2_dev, fmt, ##arg)
66
67#define ctx_dbg(level, ctx, fmt, arg...) \
68 v4l2_dbg(level, debug, &ctx->v4l2_dev, fmt, ##arg)
69#define ctx_info(ctx, fmt, arg...) \
70 v4l2_info(&ctx->v4l2_dev, fmt, ##arg)
71#define ctx_err(ctx, fmt, arg...) \
72 v4l2_err(&ctx->v4l2_dev, fmt, ##arg)
73
74#define CAL_NUM_INPUT 1
75#define CAL_NUM_CONTEXT 2
76
77#define reg_read(dev, offset) ioread32(dev->base + offset)
78#define reg_write(dev, offset, val) iowrite32(val, dev->base + offset)
79
80#define reg_read_field(dev, offset, mask) get_field(reg_read(dev, offset), \
81 mask)
82#define reg_write_field(dev, offset, field, mask) { \
83 u32 val = reg_read(dev, offset); \
84 set_field(&val, field, mask); \
85 reg_write(dev, offset, val); }
86
87/* ------------------------------------------------------------------46/* ------------------------------------------------------------------
88 * Basic structures47 * Platform Data
89 * ------------------------------------------------------------------48 * ------------------------------------------------------------------
90 */49 */
91 50
92struct cal_fmt {51static const struct cal_camerarx_data dra72x_cal_camerarx[] = {
93 u32 fourcc;
94 u32 code;
95 /* Bits per pixel */
96 u8 bpp;
97};
98
99static struct cal_fmt cal_formats[] = {
100 {
101 .fourcc = V4L2_PIX_FMT_YUYV,
102 .code = MEDIA_BUS_FMT_YUYV8_2X8,
103 .bpp = 16,
104 }, {
105 .fourcc = V4L2_PIX_FMT_UYVY,
106 .code = MEDIA_BUS_FMT_UYVY8_2X8,
107 .bpp = 16,
108 }, {
109 .fourcc = V4L2_PIX_FMT_YVYU,
110 .code = MEDIA_BUS_FMT_YVYU8_2X8,
111 .bpp = 16,
112 }, {
113 .fourcc = V4L2_PIX_FMT_VYUY,
114 .code = MEDIA_BUS_FMT_VYUY8_2X8,
115 .bpp = 16,
116 }, {
117 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
118 .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
119 .bpp = 16,
120 }, {
121 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
122 .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
123 .bpp = 16,
124 }, {
125 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
126 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
127 .bpp = 16,
128 }, {
129 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
130 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
131 .bpp = 16,
132 }, {
133 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
134 .code = MEDIA_BUS_FMT_RGB888_2X12_LE,
135 .bpp = 24,
136 }, {
137 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
138 .code = MEDIA_BUS_FMT_RGB888_2X12_BE,
139 .bpp = 24,
140 }, {
141 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
142 .code = MEDIA_BUS_FMT_ARGB8888_1X32,
143 .bpp = 32,
144 }, {
145 .fourcc = V4L2_PIX_FMT_SBGGR8,
146 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
147 .bpp = 8,
148 }, {
149 .fourcc = V4L2_PIX_FMT_SGBRG8,
150 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
151 .bpp = 8,
152 }, {
153 .fourcc = V4L2_PIX_FMT_SGRBG8,
154 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
155 .bpp = 8,
156 }, {
157 .fourcc = V4L2_PIX_FMT_SRGGB8,
158 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
159 .bpp = 8,
160 }, {
161 .fourcc = V4L2_PIX_FMT_SBGGR10,
162 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
163 .bpp = 10,
164 }, {
165 .fourcc = V4L2_PIX_FMT_SGBRG10,
166 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
167 .bpp = 10,
168 }, {
169 .fourcc = V4L2_PIX_FMT_SGRBG10,
170 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
171 .bpp = 10,
172 }, {
173 .fourcc = V4L2_PIX_FMT_SRGGB10,
174 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
175 .bpp = 10,
176 }, {
177 .fourcc = V4L2_PIX_FMT_SBGGR12,
178 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
179 .bpp = 12,
180 }, {
181 .fourcc = V4L2_PIX_FMT_SGBRG12,
182 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
183 .bpp = 12,
184 }, {
185 .fourcc = V4L2_PIX_FMT_SGRBG12,
186 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
187 .bpp = 12,
188 }, {
189 .fourcc = V4L2_PIX_FMT_SRGGB12,
190 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
191 .bpp = 12,
192 },
193};
194
195/* Print Four-character-code (FOURCC) */
196static char *fourcc_to_str(u32 fmt)
197{
198 static char code[5];
199
200 code[0] = (unsigned char)(fmt & 0xff);
201 code[1] = (unsigned char)((fmt >> 8) & 0xff);
202 code[2] = (unsigned char)((fmt >> 16) & 0xff);
203 code[3] = (unsigned char)((fmt >> 24) & 0xff);
204 code[4] = '\0';
205
206 return code;
207}
208
209/* buffer for one video frame */
210struct cal_buffer {
211 /* common v4l buffer stuff -- must be first */
212 struct vb2_v4l2_buffer vb;
213 struct list_head list;
214 const struct cal_fmt *fmt;
215};
216
217struct cal_dmaqueue {
218 struct list_head active;
219
220 /* Counters to control fps rate */
221 int frame;
222 int ini_jiffies;
223};
224
225struct cc_data {
226 void __iomem *base;
227 struct resource *res;
228
229 struct platform_device *pdev;
230};
231
232/* CTRL_CORE_CAMERRX_CONTROL register field id */
233enum cal_camerarx_field {
234 F_CTRLCLKEN,
235 F_CAMMODE,
236 F_LANEENABLE,
237 F_CSI_MODE,
238
239 F_MAX_FIELDS,
240};
241
242struct cal_csi2_phy {
243 struct regmap_field *fields[F_MAX_FIELDS];
244 struct reg_field *base_fields;
245 const int num_lanes;
246};
247
248struct cal_data {
249 const int num_csi2_phy;
250 struct cal_csi2_phy *csi2_phy_core;
251
252 const unsigned int flags;
253};
254
255static struct reg_field dra72x_ctrl_core_csi0_reg_fields[F_MAX_FIELDS] = {
256 [F_CTRLCLKEN] = REG_FIELD(0, 10, 10),
257 [F_CAMMODE] = REG_FIELD(0, 11, 12),
258 [F_LANEENABLE] = REG_FIELD(0, 13, 16),
259 [F_CSI_MODE] = REG_FIELD(0, 17, 17),
260};
261
262static struct reg_field dra72x_ctrl_core_csi1_reg_fields[F_MAX_FIELDS] = {
263 [F_CTRLCLKEN] = REG_FIELD(0, 0, 0),
264 [F_CAMMODE] = REG_FIELD(0, 1, 2),
265 [F_LANEENABLE] = REG_FIELD(0, 3, 4),
266 [F_CSI_MODE] = REG_FIELD(0, 5, 5),
267};
268
269static struct cal_csi2_phy dra72x_cal_csi_phy[] = {
270 {52 {
271 .base_fields = dra72x_ctrl_core_csi0_reg_fields,53 .fields = {
54 [F_CTRLCLKEN] = { 10, 10 },
55 [F_CAMMODE] = { 11, 12 },
56 [F_LANEENABLE] = { 13, 16 },
57 [F_CSI_MODE] = { 17, 17 },
58 },
272 .num_lanes = 4,59 .num_lanes = 4,
273 },60 },
274 {61 {
275 .base_fields = dra72x_ctrl_core_csi1_reg_fields,62 .fields = {
63 [F_CTRLCLKEN] = { 0, 0 },
64 [F_CAMMODE] = { 1, 2 },
65 [F_LANEENABLE] = { 3, 4 },
66 [F_CSI_MODE] = { 5, 5 },
67 },
276 .num_lanes = 2,68 .num_lanes = 2,
277 },69 },
278};70};
279 71
280static const struct cal_data dra72x_cal_data = {72static const struct cal_data dra72x_cal_data = {
281 .csi2_phy_core = dra72x_cal_csi_phy,73 .camerarx = dra72x_cal_camerarx,
282 .num_csi2_phy = ARRAY_SIZE(dra72x_cal_csi_phy),74 .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx),
283};75};
284 76
285static const struct cal_data dra72x_es1_cal_data = {77static const struct cal_data dra72x_es1_cal_data = {
286 .csi2_phy_core = dra72x_cal_csi_phy,78 .camerarx = dra72x_cal_camerarx,
287 .num_csi2_phy = ARRAY_SIZE(dra72x_cal_csi_phy),79 .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx),
288 .flags = DRA72_CAL_PRE_ES2_LDO_DISABLE,80 .flags = DRA72_CAL_PRE_ES2_LDO_DISABLE,
289};81};
290 82
291static struct reg_field dra76x_ctrl_core_csi0_reg_fields[F_MAX_FIELDS] = {83static const struct cal_camerarx_data dra76x_cal_csi_phy[] = {
292 [F_CTRLCLKEN] = REG_FIELD(0, 8, 8),
293 [F_CAMMODE] = REG_FIELD(0, 9, 10),
294 [F_CSI_MODE] = REG_FIELD(0, 11, 11),
295 [F_LANEENABLE] = REG_FIELD(0, 27, 31),
296};
297
298static struct reg_field dra76x_ctrl_core_csi1_reg_fields[F_MAX_FIELDS] = {
299 [F_CTRLCLKEN] = REG_FIELD(0, 0, 0),
300 [F_CAMMODE] = REG_FIELD(0, 1, 2),
301 [F_CSI_MODE] = REG_FIELD(0, 3, 3),
302 [F_LANEENABLE] = REG_FIELD(0, 24, 26),
303};
304
305static struct cal_csi2_phy dra76x_cal_csi_phy[] = {
306 {84 {
307 .base_fields = dra76x_ctrl_core_csi0_reg_fields,85 .fields = {
86 [F_CTRLCLKEN] = { 8, 8 },
87 [F_CAMMODE] = { 9, 10 },
88 [F_CSI_MODE] = { 11, 11 },
89 [F_LANEENABLE] = { 27, 31 },
90 },
308 .num_lanes = 5,91 .num_lanes = 5,
309 },92 },
310 {93 {
311 .base_fields = dra76x_ctrl_core_csi1_reg_fields,94 .fields = {
95 [F_CTRLCLKEN] = { 0, 0 },
96 [F_CAMMODE] = { 1, 2 },
97 [F_CSI_MODE] = { 3, 3 },
98 [F_LANEENABLE] = { 24, 26 },
99 },
312 .num_lanes = 3,100 .num_lanes = 3,
313 },101 },
314};102};
315 103
316static const struct cal_data dra76x_cal_data = {104static const struct cal_data dra76x_cal_data = {
317 .csi2_phy_core = dra76x_cal_csi_phy,105 .camerarx = dra76x_cal_csi_phy,
318 .num_csi2_phy = ARRAY_SIZE(dra76x_cal_csi_phy),106 .num_csi2_phy = ARRAY_SIZE(dra76x_cal_csi_phy),
319};107};
320 108
321static struct reg_field am654_ctrl_core_csi0_reg_fields[F_MAX_FIELDS] = {109static const struct cal_camerarx_data am654_cal_csi_phy[] = {
322 [F_CTRLCLKEN] = REG_FIELD(0, 15, 15),
323 [F_CAMMODE] = REG_FIELD(0, 24, 25),
324 [F_LANEENABLE] = REG_FIELD(0, 0, 4),
325};
326
327static struct cal_csi2_phy am654_cal_csi_phy[] = {
328 {110 {
329 .base_fields = am654_ctrl_core_csi0_reg_fields,111 .fields = {
112 [F_CTRLCLKEN] = { 15, 15 },
113 [F_CAMMODE] = { 24, 25 },
114 [F_LANEENABLE] = { 0, 4 },
115 },
330 .num_lanes = 5,116 .num_lanes = 5,
331 },117 },
332};118};
333 119
334static const struct cal_data am654_cal_data = {120static const struct cal_data am654_cal_data = {
335 .csi2_phy_core = am654_cal_csi_phy,121 .camerarx = am654_cal_csi_phy,
336 .num_csi2_phy = ARRAY_SIZE(am654_cal_csi_phy),122 .num_csi2_phy = ARRAY_SIZE(am654_cal_csi_phy),
337};123};
338 124
339/*125/* ------------------------------------------------------------------
340 * there is one cal_dev structure in the driver, it is shared by126 * I/O Register Accessors
341 * all instances.127 * ------------------------------------------------------------------
342 */
343struct cal_dev {
344 struct clk *fclk;
345 int irq;
346 void __iomem *base;
347 struct resource *res;
348 struct platform_device *pdev;
349 struct v4l2_device v4l2_dev;
350
351 /* Controller flags for special cases */
352 unsigned int flags;
353
354 const struct cal_data *data;
355
356 /* Control Module handle */
357 struct regmap *syscon_camerrx;
358 u32 syscon_camerrx_offset;
359
360 /* Camera Core Module handle */
361 struct cc_data *cc[CAL_NUM_CSI2_PORTS];
362
363 struct cal_ctx *ctx[CAL_NUM_CONTEXT];
364};
365
366/*
367 * There is one cal_ctx structure for each camera core context.
368 */
369struct cal_ctx {
370 struct v4l2_device v4l2_dev;
371 struct v4l2_ctrl_handler ctrl_handler;
372 struct video_device vdev;
373 struct v4l2_async_notifier notifier;
374 struct v4l2_subdev *sensor;
375 struct v4l2_fwnode_endpoint endpoint;
376
377 struct v4l2_fh fh;
378 struct cal_dev *dev;
379 struct cc_data *cc;
380
381 /* v4l2_ioctl mutex */
382 struct mutex mutex;
383 /* v4l2 buffers lock */
384 spinlock_t slock;
385
386 /* Several counters */
387 unsigned long jiffies;
388
389 struct cal_dmaqueue vidq;
390
391 /* Input Number */
392 int input;
393
394 /* video capture */
395 const struct cal_fmt *fmt;
396 /* Used to store current pixel format */
397 struct v4l2_format v_fmt;
398 /* Used to store current mbus frame format */
399 struct v4l2_mbus_framefmt m_fmt;
400
401 /* Current subdev enumerated format */
402 struct cal_fmt *active_fmt[ARRAY_SIZE(cal_formats)];
403 int num_active_fmt;
404
405 struct v4l2_fract timeperframe;
406 unsigned int sequence;
407 unsigned int external_rate;
408 struct vb2_queue vb_vidq;
409 unsigned int seq_count;
410 unsigned int csi2_port;
411 unsigned int virtual_channel;
412
413 /* Pointer pointing to current v4l2_buffer */
414 struct cal_buffer *cur_frm;
415 /* Pointer pointing to next v4l2_buffer */
416 struct cal_buffer *next_frm;
417
418 bool dma_act;
419};
420
421static const struct cal_fmt *find_format_by_pix(struct cal_ctx *ctx,
422 u32 pixelformat)
423{
424 const struct cal_fmt *fmt;
425 unsigned int k;
426
427 for (k = 0; k < ctx->num_active_fmt; k++) {
428 fmt = ctx->active_fmt[k];
429 if (fmt->fourcc == pixelformat)
430 return fmt;
431 }
432
433 return NULL;
434}
435
436static const struct cal_fmt *find_format_by_code(struct cal_ctx *ctx,
437 u32 code)
438{
439 const struct cal_fmt *fmt;
440 unsigned int k;
441
442 for (k = 0; k < ctx->num_active_fmt; k++) {
443 fmt = ctx->active_fmt[k];
444 if (fmt->code == code)
445 return fmt;
446 }
447
448 return NULL;
449}
450
451static inline struct cal_ctx *notifier_to_ctx(struct v4l2_async_notifier *n)
452{
453 return container_of(n, struct cal_ctx, notifier);
454}
455
456static inline int get_field(u32 value, u32 mask)
457{
458 return (value & mask) >> __ffs(mask);
459}
460
461static inline void set_field(u32 *valp, u32 field, u32 mask)
462{
463 u32 val = *valp;
464
465 val &= ~mask;
466 val |= (field << __ffs(mask)) & mask;
467 *valp = val;
468}
469
470static u32 cal_data_get_phy_max_lanes(struct cal_ctx *ctx)
471{
472 struct cal_dev *dev = ctx->dev;
473 u32 phy_id = ctx->csi2_port - 1;
474
475 return dev->data->csi2_phy_core[phy_id].num_lanes;
476}
477
478static u32 cal_data_get_num_csi2_phy(struct cal_dev *dev)
479{
480 return dev->data->num_csi2_phy;
481}
482
483static int cal_camerarx_regmap_init(struct cal_dev *dev)
484{
485 struct reg_field *field;
486 struct cal_csi2_phy *phy;
487 int i, j;
488
489 if (!dev->data)
490 return -EINVAL;
491
492 for (i = 0; i < cal_data_get_num_csi2_phy(dev); i++) {
493 phy = &dev->data->csi2_phy_core[i];
494 for (j = 0; j < F_MAX_FIELDS; j++) {
495 field = &phy->base_fields[j];
496 /*
497 * Here we update the reg offset with the
498 * value found in DT
499 */
500 field->reg = dev->syscon_camerrx_offset;
501 phy->fields[j] =
502 devm_regmap_field_alloc(&dev->pdev->dev,
503 dev->syscon_camerrx,
504 *field);
505 if (IS_ERR(phy->fields[j])) {
506 cal_err(dev, "Unable to allocate regmap fields\n");
507 return PTR_ERR(phy->fields[j]);
508 }
509 }
510 }
511 return 0;
512}
513
514static const struct regmap_config cal_regmap_config = {
515 .reg_bits = 32,
516 .val_bits = 32,
517 .reg_stride = 4,
518};
519
520static struct regmap *cal_get_camerarx_regmap(struct cal_dev *dev)
521{
522 struct platform_device *pdev = dev->pdev;
523 struct regmap *regmap;
524 void __iomem *base;
525 u32 reg_io_width;
526 struct regmap_config r_config = cal_regmap_config;
527 struct resource *res;
528
529 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
530 "camerrx_control");
531 base = devm_ioremap_resource(&pdev->dev, res);
532 if (IS_ERR(base)) {
533 cal_err(dev, "failed to ioremap\n");
534 return ERR_CAST(base);
535 }
536
537 cal_dbg(1, dev, "ioresource %s at %pa - %pa\n",
538 res->name, &res->start, &res->end);
539
540 reg_io_width = 4;
541 r_config.reg_stride = reg_io_width;
542 r_config.val_bits = reg_io_width * 8;
543 r_config.max_register = resource_size(res) - reg_io_width;
544
545 regmap = regmap_init_mmio(NULL, base, &r_config);
546 if (IS_ERR(regmap))
547 pr_err("regmap init failed\n");
548
549 return regmap;
550}
551
552/*
553 * Control Module CAMERARX block access
554 */
555static void camerarx_phy_enable(struct cal_ctx *ctx)
556{
557 struct cal_csi2_phy *phy;
558 u32 phy_id = ctx->csi2_port - 1;
559 u32 max_lanes;
560
561 phy = &ctx->dev->data->csi2_phy_core[phy_id];
562 regmap_field_write(phy->fields[F_CAMMODE], 0);
563 /* Always enable all lanes at the phy control level */
564 max_lanes = (1 << cal_data_get_phy_max_lanes(ctx)) - 1;
565 regmap_field_write(phy->fields[F_LANEENABLE], max_lanes);
566 /* F_CSI_MODE is not present on every architecture */
567 if (phy->fields[F_CSI_MODE])
568 regmap_field_write(phy->fields[F_CSI_MODE], 1);
569 regmap_field_write(phy->fields[F_CTRLCLKEN], 1);
570}
571
572static void camerarx_phy_disable(struct cal_ctx *ctx)
573{
574 struct cal_csi2_phy *phy;
575 u32 phy_id = ctx->csi2_port - 1;
576
577 phy = &ctx->dev->data->csi2_phy_core[phy_id];
578 regmap_field_write(phy->fields[F_CTRLCLKEN], 0);
579}
580
581/*
582 * Camera Instance access block
583 */
584static struct cc_data *cc_create(struct cal_dev *dev, unsigned int core)
585{
586 struct platform_device *pdev = dev->pdev;
587 struct cc_data *cc;
588
589 cc = devm_kzalloc(&pdev->dev, sizeof(*cc), GFP_KERNEL);
590 if (!cc)
591 return ERR_PTR(-ENOMEM);
592
593 cc->res = platform_get_resource_byname(pdev,
594 IORESOURCE_MEM,
595 (core == 0) ?
596 "cal_rx_core0" :
597 "cal_rx_core1");
598 cc->base = devm_ioremap_resource(&pdev->dev, cc->res);
599 if (IS_ERR(cc->base)) {
600 cal_err(dev, "failed to ioremap\n");
601 return ERR_CAST(cc->base);
602 }
603
604 cal_dbg(1, dev, "ioresource %s at %pa - %pa\n",
605 cc->res->name, &cc->res->start, &cc->res->end);
606
607 return cc;
608}
609
610/*
611 * Get Revision and HW info
612 */128 */
613static void cal_get_hwinfo(struct cal_dev *dev)
614{
615 u32 revision = 0;
616 u32 hwinfo = 0;
617
618 revision = reg_read(dev, CAL_HL_REVISION);
619 cal_dbg(3, dev, "CAL_HL_REVISION = 0x%08x (expecting 0x40000200)\n",
620 revision);
621
622 hwinfo = reg_read(dev, CAL_HL_HWINFO);
623 cal_dbg(3, dev, "CAL_HL_HWINFO = 0x%08x (expecting 0xA3C90469)\n",
624 hwinfo);
625}
626 129
627/*130void cal_quickdump_regs(struct cal_dev *cal)
628 * Errata i913: CSI2 LDO Needs to be disabled when module is powered on
629 *
630 * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
631 * LDOs on the device are disabled if CSI-2 module is powered on
632 * (0x4845 B304 | 0x4845 B384 [28:27] = 0x1) or in ULPS (0x4845 B304
633 * | 0x4845 B384 [28:27] = 0x2) mode. Common concerns include: high
634 * current draw on the module supply in active mode.
635 *
636 * Errata does not apply when CSI-2 module is powered off
637 * (0x4845 B304 | 0x4845 B384 [28:27] = 0x0).
638 *
639 * SW Workaround:
640 * Set the following register bits to disable the LDO,
641 * which is essentially CSI2 REG10 bit 6:
642 *
643 * Core 0: 0x4845 B828 = 0x0000 0040
644 * Core 1: 0x4845 B928 = 0x0000 0040
645 */
646static void i913_errata(struct cal_dev *dev, unsigned int port)
647{131{
648 u32 reg10 = reg_read(dev->cc[port], CAL_CSI2_PHY_REG10);132 unsigned int i;
649
650 set_field(&reg10, 1, CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK);
651
652 cal_dbg(1, dev, "CSI2_%d_REG10 = 0x%08x\n", port, reg10);
653 reg_write(dev->cc[port], CAL_CSI2_PHY_REG10, reg10);
654}
655 133
656static void cal_quickdump_regs(struct cal_dev *dev)134 cal_info(cal, "CAL Registers @ 0x%pa:\n", &cal->res->start);
657{
658 cal_info(dev, "CAL Registers @ 0x%pa:\n", &dev->res->start);
659 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,135 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
660 (__force const void *)dev->base,136 (__force const void *)cal->base,
661 resource_size(dev->res), false);137 resource_size(cal->res), false);
662 138
663 if (dev->ctx[0]) {139 for (i = 0; i < ARRAY_SIZE(cal->phy); ++i) {
664 cal_info(dev, "CSI2 Core 0 Registers @ %pa:\n",140 struct cal_camerarx *phy = cal->phy[i];
665 &dev->ctx[0]->cc->res->start);141
666 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,142 if (!phy)
667 (__force const void *)dev->ctx[0]->cc->base,143 continue;
668 resource_size(dev->ctx[0]->cc->res),
669 false);
670 }
671 144
672 if (dev->ctx[1]) {145 cal_info(cal, "CSI2 Core %u Registers @ %pa:\n", i,
673 cal_info(dev, "CSI2 Core 1 Registers @ %pa:\n",146 &phy->res->start);
674 &dev->ctx[1]->cc->res->start);
675 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,147 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
676 (__force const void *)dev->ctx[1]->cc->base,148 (__force const void *)phy->base,
677 resource_size(dev->ctx[1]->cc->res),149 resource_size(phy->res),
678 false);150 false);
679 }151 }
680}152}
681 153
682/*154/* ------------------------------------------------------------------
683 * Enable the expected IRQ sources155 * Context Management
156 * ------------------------------------------------------------------
684 */157 */
685static void enable_irqs(struct cal_ctx *ctx)
686{
687 u32 val;
688
689 const u32 cio_err_mask =
690 CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK |
691 CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
692 CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
693 CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
694
695 /* Enable CIO error irqs */
696 reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(1),
697 CAL_HL_IRQ_CIO_MASK(ctx->csi2_port));
698 reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_IRQENABLE(ctx->csi2_port),
699 cio_err_mask);
700
701 /* Always enable OCPO error */
702 reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(1), CAL_HL_IRQ_OCPO_ERR_MASK);
703
704 /* Enable IRQ_WDMA_END 0/1 */
705 val = 0;
706 set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
707 reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(2), val);
708 /* Enable IRQ_WDMA_START 0/1 */
709 val = 0;
710 set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
711 reg_write(ctx->dev, CAL_HL_IRQENABLE_SET(3), val);
712 /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
713 reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0xFF000000);
714}
715
716static void disable_irqs(struct cal_ctx *ctx)
717{
718 u32 val;
719
720 /* Disable CIO error irqs */
721 reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(1),
722 CAL_HL_IRQ_CIO_MASK(ctx->csi2_port));
723 reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_IRQENABLE(ctx->csi2_port),
724 0);
725
726 /* Disable IRQ_WDMA_END 0/1 */
727 val = 0;
728 set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
729 reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(2), val);
730 /* Disable IRQ_WDMA_START 0/1 */
731 val = 0;
732 set_field(&val, 1, CAL_HL_IRQ_MASK(ctx->csi2_port));
733 reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(3), val);
734 /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
735 reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0);
736}
737
738static void csi2_cio_power(struct cal_ctx *ctx, bool enable)
739{
740 u32 target_state;
741 unsigned int i;
742
743 target_state = enable ? CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON :
744 CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF;
745
746 reg_write_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
747 target_state, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
748
749 for (i = 0; i < 10; i++) {
750 u32 current_state;
751
752 current_state = reg_read_field(ctx->dev,
753 CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
754 CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK);
755
756 if (current_state == target_state)
757 break;
758
759 usleep_range(1000, 1100);
760 }
761
762 if (i == 10)
763 ctx_err(ctx, "Failed to power %s complexio\n",
764 enable ? "up" : "down");
765}
766
767static void csi2_phy_config(struct cal_ctx *ctx);
768
769static void csi2_phy_init(struct cal_ctx *ctx)
770{
771 u32 val;
772 u32 sscounter;
773
774 /* Steps
775 * 1. Configure D-PHY mode and enable required lanes
776 * 2. Reset complex IO - Wait for completion of reset
777 * Note if the external sensor is not sending byte clock,
778 * the reset will timeout
779 * 3 Program Stop States
780 * A. Program THS_TERM, THS_SETTLE, etc... Timings parameters
781 * in terms of DDR clock periods
782 * B. Enable stop state transition timeouts
783 * 4.Force FORCERXMODE
784 * D. Enable pull down using pad control
785 * E. Power up PHY
786 * F. Wait for power up completion
787 * G. Wait for all enabled lane to reach stop state
788 * H. Disable pull down using pad control
789 */
790
791 /* 1. Configure D-PHY mode and enable required lanes */
792 camerarx_phy_enable(ctx);
793
794 /* 2. Reset complex IO - Do not wait for reset completion */
795 reg_write_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
796 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
797 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
798 ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n",
799 ctx->csi2_port,
800 reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)));
801
802 /* Dummy read to allow SCP reset to complete */
803 reg_read(ctx->cc, CAL_CSI2_PHY_REG0);
804
805 /* 3.A. Program Phy Timing Parameters */
806 csi2_phy_config(ctx);
807
808 /* 3.B. Program Stop States */
809 /*
810 * The stop-state-counter is based on fclk cycles, and we always use
811 * the x16 and x4 settings, so stop-state-timeout =
812 * fclk-cycle * 16 * 4 * counter.
813 *
814 * Stop-state-timeout must be more than 100us as per CSI2 spec, so we
815 * calculate a timeout that's 100us (rounding up).
816 */
817 sscounter = DIV_ROUND_UP(clk_get_rate(ctx->dev->fclk), 10000 * 16 * 4);
818
819 val = reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port));
820 set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
821 set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
822 set_field(&val, sscounter, CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
823 reg_write(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port), val);
824 ctx_dbg(3, ctx, "CAL_CSI2_TIMING(%d) = 0x%08x Stop States\n",
825 ctx->csi2_port,
826 reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port)));
827
828 /* 4. Force FORCERXMODE */
829 reg_write_field(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port),
830 1, CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
831 ctx_dbg(3, ctx, "CAL_CSI2_TIMING(%d) = 0x%08x Force RXMODE\n",
832 ctx->csi2_port,
833 reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port)));
834
835 /* E. Power up the PHY using the complex IO */
836 csi2_cio_power(ctx, true);
837}
838
839static void csi2_wait_complexio_reset(struct cal_ctx *ctx)
840{
841 unsigned long timeout;
842
843 timeout = jiffies + msecs_to_jiffies(750);
844 while (time_before(jiffies, timeout)) {
845 if (reg_read_field(ctx->dev,
846 CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
847 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
848 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
849 break;
850 usleep_range(500, 5000);
851 }
852
853 if (reg_read_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
854 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) !=
855 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
856 ctx_err(ctx, "Timeout waiting for Complex IO reset done\n");
857}
858
859static void csi2_wait_stop_state(struct cal_ctx *ctx)
860{
861 unsigned long timeout;
862
863 timeout = jiffies + msecs_to_jiffies(750);
864 while (time_before(jiffies, timeout)) {
865 if (reg_read_field(ctx->dev,
866 CAL_CSI2_TIMING(ctx->csi2_port),
867 CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) == 0)
868 break;
869 usleep_range(500, 5000);
870 }
871
872 if (reg_read_field(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port),
873 CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) != 0)
874 ctx_err(ctx, "Timeout waiting for stop state\n");
875}
876
877static void csi2_wait_for_phy(struct cal_ctx *ctx)
878{
879 /* Steps
880 * 2. Wait for completion of reset
881 * Note if the external sensor is not sending byte clock,
882 * the reset will timeout
883 * 4.Force FORCERXMODE
884 * G. Wait for all enabled lane to reach stop state
885 * H. Disable pull down using pad control
886 */
887
888 /* 2. Wait for reset completion */
889 csi2_wait_complexio_reset(ctx);
890
891 /* 4. G. Wait for all enabled lane to reach stop state */
892 csi2_wait_stop_state(ctx);
893
894 ctx_dbg(1, ctx, "CSI2_%d_REG1 = 0x%08x (Bit(31,28) should be set!)\n",
895 (ctx->csi2_port - 1), reg_read(ctx->cc, CAL_CSI2_PHY_REG1));
896}
897
898static void csi2_phy_deinit(struct cal_ctx *ctx)
899{
900 int i;
901
902 csi2_cio_power(ctx, false);
903
904 /* Assert Comple IO Reset */
905 reg_write_field(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
906 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
907 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
908
909 /* Wait for power down completion */
910 for (i = 0; i < 10; i++) {
911 if (reg_read_field(ctx->dev,
912 CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
913 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
914 CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETONGOING)
915 break;
916 usleep_range(1000, 1100);
917 }
918 ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset (%d) %s\n",
919 ctx->csi2_port,
920 reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)), i,
921 (i >= 10) ? "(timeout)" : "");
922
923 /* Disable the phy */
924 camerarx_phy_disable(ctx);
925}
926
927static void csi2_lane_config(struct cal_ctx *ctx)
928{
929 u32 val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
930 u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
931 u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
932 struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
933 &ctx->endpoint.bus.mipi_csi2;
934 int lane;
935
936 set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
937 set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask);
938 for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) {
939 /*
940 * Every lane are one nibble apart starting with the
941 * clock followed by the data lanes so shift masks by 4.
942 */
943 lane_mask <<= 4;
944 polarity_mask <<= 4;
945 set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask);
946 set_field(&val, mipi_csi2->lane_polarities[lane + 1],
947 polarity_mask);
948 }
949
950 reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
951 ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n",
952 ctx->csi2_port, val);
953}
954
955static void csi2_ppi_enable(struct cal_ctx *ctx)
956{
957 reg_write(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port), BIT(3));
958 reg_write_field(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port),
959 1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
960}
961
962static void csi2_ppi_disable(struct cal_ctx *ctx)
963{
964 reg_write_field(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port),
965 0, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
966}
967 158
968static void csi2_ctx_config(struct cal_ctx *ctx)159void cal_ctx_csi2_config(struct cal_ctx *ctx)
969{160{
970 u32 val;161 u32 val;
971 162
972 val = reg_read(ctx->dev, CAL_CSI2_CTX0(ctx->csi2_port));163 val = cal_read(ctx->cal, CAL_CSI2_CTX0(ctx->index));
973 set_field(&val, ctx->csi2_port, CAL_CSI2_CTX_CPORT_MASK);164 cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK);
974 /*165 /*
975 * DT type: MIPI CSI-2 Specs166 * DT type: MIPI CSI-2 Specs
976 * 0x1: All - DT filter is disabled167 * 0x1: All - DT filter is disabled
@@ -979,19 +170,18 @@ static void csi2_ctx_config(struct cal_ctx *ctx) · 2 unmodified lines
979 * 0x2A: RAW8 1 pixel = 1 byte170 * 0x2A: RAW8 1 pixel = 1 byte
980 * 0x1E: YUV422 2 pixels = 4 bytes171 * 0x1E: YUV422 2 pixels = 4 bytes
981 */172 */
982 set_field(&val, 0x1, CAL_CSI2_CTX_DT_MASK);173 cal_set_field(&val, 0x1, CAL_CSI2_CTX_DT_MASK);
983 /* Virtual Channel from the CSI2 sensor usually 0! */174 cal_set_field(&val, 0, CAL_CSI2_CTX_VC_MASK);
984 set_field(&val, ctx->virtual_channel, CAL_CSI2_CTX_VC_MASK);175 cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
985 set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);176 cal_set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
986 set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);177 cal_set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
987 set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,178 CAL_CSI2_CTX_PACK_MODE_MASK);
988 CAL_CSI2_CTX_PACK_MODE_MASK);179 cal_write(ctx->cal, CAL_CSI2_CTX0(ctx->index), val);
989 reg_write(ctx->dev, CAL_CSI2_CTX0(ctx->csi2_port), val);180 ctx_dbg(3, ctx, "CAL_CSI2_CTX0(%d) = 0x%08x\n", ctx->index,
990 ctx_dbg(3, ctx, "CAL_CSI2_CTX0(%d) = 0x%08x\n", ctx->csi2_port,181 cal_read(ctx->cal, CAL_CSI2_CTX0(ctx->index)));
991 reg_read(ctx->dev, CAL_CSI2_CTX0(ctx->csi2_port)));
992}182}
993 183
994static void pix_proc_config(struct cal_ctx *ctx)184void cal_ctx_pix_proc_config(struct cal_ctx *ctx)
995{185{
996 u32 val, extract, pack;186 u32 val, extract, pack;
997 187
@@ -1022,7 +212,7 @@ static void pix_proc_config(struct cal_ctx *ctx) · 24 unmodified lines
1022 *212 *
1023 * Instead of failing here just use 8 bpp as a default.213 * Instead of failing here just use 8 bpp as a default.
1024 */214 */
1025 dev_warn_once(&ctx->dev->pdev->dev,215 dev_warn_once(ctx->cal->dev,
1026 "%s:%d:%s: bpp:%d unsupported! Overwritten with 8.\n",216 "%s:%d:%s: bpp:%d unsupported! Overwritten with 8.\n",
1027 __FILE__, __LINE__, __func__, ctx->fmt->bpp);217 __FILE__, __LINE__, __func__, ctx->fmt->bpp);
1028 extract = CAL_PIX_PROC_EXTRACT_B8;218 extract = CAL_PIX_PROC_EXTRACT_B8;
@@ -1030,145 +220,82 @@ static void pix_proc_config(struct cal_ctx *ctx) · 1 unmodified line
1030 break;220 break;
1031 }221 }
1032 222
1033 val = reg_read(ctx->dev, CAL_PIX_PROC(ctx->csi2_port));223 val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->index));
1034 set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK);224 cal_set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK);
1035 set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);225 cal_set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);
1036 set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);226 cal_set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
1037 set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);227 cal_set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);
1038 set_field(&val, ctx->csi2_port, CAL_PIX_PROC_CPORT_MASK);228 cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK);
1039 set_field(&val, 1, CAL_PIX_PROC_EN_MASK);229 cal_set_field(&val, 1, CAL_PIX_PROC_EN_MASK);
1040 reg_write(ctx->dev, CAL_PIX_PROC(ctx->csi2_port), val);230 cal_write(ctx->cal, CAL_PIX_PROC(ctx->index), val);
1041 ctx_dbg(3, ctx, "CAL_PIX_PROC(%d) = 0x%08x\n", ctx->csi2_port,231 ctx_dbg(3, ctx, "CAL_PIX_PROC(%d) = 0x%08x\n", ctx->index,
1042 reg_read(ctx->dev, CAL_PIX_PROC(ctx->csi2_port)));232 cal_read(ctx->cal, CAL_PIX_PROC(ctx->index)));
1043}233}
1044 234
1045static void cal_wr_dma_config(struct cal_ctx *ctx,235void cal_ctx_wr_dma_config(struct cal_ctx *ctx, unsigned int width,
1046 unsigned int width, unsigned int height)236 unsigned int height)
1047{237{
1048 u32 val;238 u32 val;
1049 239
1050 val = reg_read(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port));240 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->index));
1051 set_field(&val, ctx->csi2_port, CAL_WR_DMA_CTRL_CPORT_MASK);241 cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK);
1052 set_field(&val, height, CAL_WR_DMA_CTRL_YSIZE_MASK);242 cal_set_field(&val, height, CAL_WR_DMA_CTRL_YSIZE_MASK);
1053 set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,243 cal_set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,
1054 CAL_WR_DMA_CTRL_DTAG_MASK);244 CAL_WR_DMA_CTRL_DTAG_MASK);
1055 set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,245 cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,
1056 CAL_WR_DMA_CTRL_MODE_MASK);246 CAL_WR_DMA_CTRL_MODE_MASK);
1057 set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,247 cal_set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
1058 CAL_WR_DMA_CTRL_PATTERN_MASK);248 CAL_WR_DMA_CTRL_PATTERN_MASK);
1059 set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);249 cal_set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);
1060 reg_write(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port), val);250 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->index), val);
1061 ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->csi2_port,251 ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->index,
1062 reg_read(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port)));252 cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->index)));
1063 253
1064 /*254 /*
1065 * width/16 not sure but giving it a whirl.255 * width/16 not sure but giving it a whirl.
1066 * zero does not work right256 * zero does not work right
1067 */257 */
1068 reg_write_field(ctx->dev,258 cal_write_field(ctx->cal,
1069 CAL_WR_DMA_OFST(ctx->csi2_port),259 CAL_WR_DMA_OFST(ctx->index),
1070 (width / 16),260 (width / 16),
1071 CAL_WR_DMA_OFST_MASK);261 CAL_WR_DMA_OFST_MASK);
1072 ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->csi2_port,262 ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->index,
1073 reg_read(ctx->dev, CAL_WR_DMA_OFST(ctx->csi2_port)));263 cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->index)));
1074 264
1075 val = reg_read(ctx->dev, CAL_WR_DMA_XSIZE(ctx->csi2_port));265 val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->index));
1076 /* 64 bit word means no skipping */266 /* 64 bit word means no skipping */
1077 set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);267 cal_set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);
1078 /*268 /*
1079 * (width*8)/64 this should be size of an entire line269 * (width*8)/64 this should be size of an entire line
1080 * in 64bit word but 0 means all data until the end270 * in 64bit word but 0 means all data until the end
1081 * is detected automagically271 * is detected automagically
1082 */272 */
1083 set_field(&val, (width / 8), CAL_WR_DMA_XSIZE_MASK);273 cal_set_field(&val, (width / 8), CAL_WR_DMA_XSIZE_MASK);
1084 reg_write(ctx->dev, CAL_WR_DMA_XSIZE(ctx->csi2_port), val);274 cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->index), val);
1085 ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->csi2_port,275 ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->index,
1086 reg_read(ctx->dev, CAL_WR_DMA_XSIZE(ctx->csi2_port)));276 cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->index)));
1087
1088 val = reg_read(ctx->dev, CAL_CTRL);
1089 set_field(&val, CAL_CTRL_BURSTSIZE_BURST128, CAL_CTRL_BURSTSIZE_MASK);
1090 set_field(&val, 0xF, CAL_CTRL_TAGCNT_MASK);
1091 set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
1092 CAL_CTRL_POSTED_WRITES_MASK);
1093 set_field(&val, 0xFF, CAL_CTRL_MFLAGL_MASK);
1094 set_field(&val, 0xFF, CAL_CTRL_MFLAGH_MASK);
1095 reg_write(ctx->dev, CAL_CTRL, val);
1096 ctx_dbg(3, ctx, "CAL_CTRL = 0x%08x\n", reg_read(ctx->dev, CAL_CTRL));
1097}
1098 277
1099static void cal_wr_dma_addr(struct cal_ctx *ctx, unsigned int dmaaddr)278 val = cal_read(ctx->cal, CAL_CTRL);
1100{279 cal_set_field(&val, CAL_CTRL_BURSTSIZE_BURST128,
1101 reg_write(ctx->dev, CAL_WR_DMA_ADDR(ctx->csi2_port), dmaaddr);280 CAL_CTRL_BURSTSIZE_MASK);
281 cal_set_field(&val, 0xF, CAL_CTRL_TAGCNT_MASK);
282 cal_set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
283 CAL_CTRL_POSTED_WRITES_MASK);
284 cal_set_field(&val, 0xFF, CAL_CTRL_MFLAGL_MASK);
285 cal_set_field(&val, 0xFF, CAL_CTRL_MFLAGH_MASK);
286 cal_write(ctx->cal, CAL_CTRL, val);
287 ctx_dbg(3, ctx, "CAL_CTRL = 0x%08x\n", cal_read(ctx->cal, CAL_CTRL));
1102}288}
1103 289
1104/*290void cal_ctx_wr_dma_addr(struct cal_ctx *ctx, unsigned int dmaaddr)
1105 * TCLK values are OK at their reset values
1106 */
1107#define TCLK_TERM 0
1108#define TCLK_MISS 1
1109#define TCLK_SETTLE 14
1110
1111static void csi2_phy_config(struct cal_ctx *ctx)
1112{291{
1113 unsigned int reg0, reg1;292 cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->index), dmaaddr);
1114 unsigned int ths_term, ths_settle;
1115 unsigned int csi2_ddrclk_khz;
1116 struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
1117 &ctx->endpoint.bus.mipi_csi2;
1118 u32 num_lanes = mipi_csi2->num_data_lanes;
1119
1120 /* DPHY timing configuration */
1121 /* CSI-2 is DDR and we only count used lanes. */
1122 csi2_ddrclk_khz = ctx->external_rate / 1000
1123 / (2 * num_lanes) * ctx->fmt->bpp;
1124 ctx_dbg(1, ctx, "csi2_ddrclk_khz: %d\n", csi2_ddrclk_khz);
1125
1126 /* THS_TERM: Programmed value = floor(20 ns/DDRClk period) */
1127 ths_term = 20 * csi2_ddrclk_khz / 1000000;
1128 ctx_dbg(1, ctx, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
1129
1130 /* THS_SETTLE: Programmed value = floor(105 ns/DDRClk period) + 4 */
1131 ths_settle = (105 * csi2_ddrclk_khz / 1000000) + 4;
1132 ctx_dbg(1, ctx, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
1133
1134 reg0 = reg_read(ctx->cc, CAL_CSI2_PHY_REG0);
1135 set_field(&reg0, CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE,
1136 CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK);
1137 set_field(&reg0, ths_term, CAL_CSI2_PHY_REG0_THS_TERM_MASK);
1138 set_field(&reg0, ths_settle, CAL_CSI2_PHY_REG0_THS_SETTLE_MASK);
1139
1140 ctx_dbg(1, ctx, "CSI2_%d_REG0 = 0x%08x\n", (ctx->csi2_port - 1), reg0);
1141 reg_write(ctx->cc, CAL_CSI2_PHY_REG0, reg0);
1142
1143 reg1 = reg_read(ctx->cc, CAL_CSI2_PHY_REG1);
1144 set_field(&reg1, TCLK_TERM, CAL_CSI2_PHY_REG1_TCLK_TERM_MASK);
1145 set_field(&reg1, 0xb8, CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK);
1146 set_field(&reg1, TCLK_MISS, CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK);
1147 set_field(&reg1, TCLK_SETTLE, CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK);
1148
1149 ctx_dbg(1, ctx, "CSI2_%d_REG1 = 0x%08x\n", (ctx->csi2_port - 1), reg1);
1150 reg_write(ctx->cc, CAL_CSI2_PHY_REG1, reg1);
1151}293}
1152 294
1153static int cal_get_external_info(struct cal_ctx *ctx)295/* ------------------------------------------------------------------
1154{296 * IRQ Handling
1155 struct v4l2_ctrl *ctrl;297 * ------------------------------------------------------------------
1156 298 */
1157 if (!ctx->sensor)
1158 return -ENODEV;
1159
1160 ctrl = v4l2_ctrl_find(ctx->sensor->ctrl_handler, V4L2_CID_PIXEL_RATE);
1161 if (!ctrl) {
1162 ctx_err(ctx, "no pixel rate control in subdev: %s\n",
1163 ctx->sensor->name);
1164 return -EPIPE;
1165 }
1166
1167 ctx->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
1168 ctx_dbg(3, ctx, "sensor Pixel Rate: %d\n", ctx->external_rate);
1169
1170 return 0;
1171}
1172 299
1173static inline void cal_schedule_next_buffer(struct cal_ctx *ctx)300static inline void cal_schedule_next_buffer(struct cal_ctx *ctx)
1174{301{
@@ -1181,7 +308,7 @@ static inline void cal_schedule_next_buffer(struct cal_ctx *ctx) · 6 unmodified lines
1181 list_del(&buf->list);308 list_del(&buf->list);
1182 309
1183 addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);310 addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
1184 cal_wr_dma_addr(ctx, addr);311 cal_ctx_wr_dma_addr(ctx, addr);
1185}312}
1186 313
1187static inline void cal_process_buffer_complete(struct cal_ctx *ctx)314static inline void cal_process_buffer_complete(struct cal_ctx *ctx)
@@ -1194,52 +321,47 @@ static inline void cal_process_buffer_complete(struct cal_ctx *ctx) · 6 unmodified lines
1194 ctx->cur_frm = ctx->next_frm;321 ctx->cur_frm = ctx->next_frm;
1195}322}
1196 323
1197#define isvcirqset(irq, vc, ff) (irq & \
1198 (CAL_CSI2_VC_IRQENABLE_ ##ff ##_IRQ_##vc ##_MASK))
1199
1200#define isportirqset(irq, port) (irq & CAL_HL_IRQ_MASK(port))
1201
1202static irqreturn_t cal_irq(int irq_cal, void *data)324static irqreturn_t cal_irq(int irq_cal, void *data)
1203{325{
1204 struct cal_dev *dev = (struct cal_dev *)data;326 struct cal_dev *cal = data;
1205 struct cal_ctx *ctx;327 struct cal_ctx *ctx;
1206 struct cal_dmaqueue *dma_q;328 struct cal_dmaqueue *dma_q;
1207 u32 irqst1, irqst2, irqst3;329 u32 status;
1208 330
1209 irqst1 = reg_read(dev, CAL_HL_IRQSTATUS(1));331 status = cal_read(cal, CAL_HL_IRQSTATUS(0));
1210 if (irqst1) {332 if (status) {
1211 int i;333 unsigned int i;
1212 334
1213 reg_write(dev, CAL_HL_IRQSTATUS(1), irqst1);335 cal_write(cal, CAL_HL_IRQSTATUS(0), status);
1214 336
1215 if (irqst1 & CAL_HL_IRQ_OCPO_ERR_MASK)337 if (status & CAL_HL_IRQ_OCPO_ERR_MASK)
1216 dev_err_ratelimited(&dev->pdev->dev, "OCPO ERROR\n");338 dev_err_ratelimited(cal->dev, "OCPO ERROR\n");
1217 339
1218 for (i = 1; i <= 2; ++i) {340 for (i = 0; i < CAL_NUM_CSI2_PORTS; ++i) {
1219 if (irqst1 & CAL_HL_IRQ_CIO_MASK(i)) {341 if (status & CAL_HL_IRQ_CIO_MASK(i)) {
1220 u32 cio_stat = reg_read(dev,342 u32 cio_stat = cal_read(cal,
1221 CAL_CSI2_COMPLEXIO_IRQSTATUS(i));343 CAL_CSI2_COMPLEXIO_IRQSTATUS(i));
1222 344
1223 dev_err_ratelimited(&dev->pdev->dev,345 dev_err_ratelimited(cal->dev,
1224 "CIO%d error: %#08x\n", i, cio_stat);346 "CIO%u error: %#08x\n", i, cio_stat);
1225 347
1226 reg_write(dev, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),348 cal_write(cal, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),
1227 cio_stat);349 cio_stat);
1228 }350 }
1229 }351 }
1230 }352 }
1231 353
1232 /* Check which DMA just finished */354 /* Check which DMA just finished */
1233 irqst2 = reg_read(dev, CAL_HL_IRQSTATUS(2));355 status = cal_read(cal, CAL_HL_IRQSTATUS(1));
1234 if (irqst2) {356 if (status) {
1235 int i;357 unsigned int i;
1236 358
1237 /* Clear Interrupt status */359 /* Clear Interrupt status */
1238 reg_write(dev, CAL_HL_IRQSTATUS(2), irqst2);360 cal_write(cal, CAL_HL_IRQSTATUS(1), status);
1239 361
1240 for (i = 1; i <= 2; ++i) {362 for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
1241 if (isportirqset(irqst2, i)) {363 if (status & CAL_HL_IRQ_MASK(i)) {
1242 ctx = dev->ctx[i - 1];364 ctx = cal->ctx[i];
1243 365
1244 spin_lock(&ctx->slock);366 spin_lock(&ctx->slock);
1245 ctx->dma_act = false;367 ctx->dma_act = false;
@@ -1253,16 +375,16 @@ static irqreturn_t cal_irq(int irq_cal, void *data) · 7 unmodified lines
1253 }375 }
1254 376
1255 /* Check which DMA just started */377 /* Check which DMA just started */
1256 irqst3 = reg_read(dev, CAL_HL_IRQSTATUS(3));378 status = cal_read(cal, CAL_HL_IRQSTATUS(2));
1257 if (irqst3) {379 if (status) {
1258 int i;380 unsigned int i;
1259 381
1260 /* Clear Interrupt status */382 /* Clear Interrupt status */
1261 reg_write(dev, CAL_HL_IRQSTATUS(3), irqst3);383 cal_write(cal, CAL_HL_IRQSTATUS(2), status);
1262 384
1263 for (i = 1; i <= 2; ++i) {385 for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
1264 if (isportirqset(irqst3, i)) {386 if (status & CAL_HL_IRQ_MASK(i)) {
1265 ctx = dev->ctx[i - 1];387 ctx = cal->ctx[i];
1266 dma_q = &ctx->vidq;388 dma_q = &ctx->vidq;
1267 389
1268 spin_lock(&ctx->slock);390 spin_lock(&ctx->slock);
@@ -1278,963 +400,234 @@ static irqreturn_t cal_irq(int irq_cal, void *data) · 9 unmodified lines
1278 return IRQ_HANDLED;400 return IRQ_HANDLED;
1279}401}
1280 402
1281/*403/* ------------------------------------------------------------------
1282 * video ioctls404 * Asynchronous V4L2 subdev binding
405 * ------------------------------------------------------------------
1283 */406 */
1284static int cal_querycap(struct file *file, void *priv,
1285 struct v4l2_capability *cap)
1286{
1287 struct cal_ctx *ctx = video_drvdata(file);
1288 407
1289 strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));408struct cal_v4l2_async_subdev {
1290 strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));409 struct v4l2_async_subdev asd;
410 struct cal_camerarx *phy;
411};
1291 412
1292 snprintf(cap->bus_info, sizeof(cap->bus_info),413static inline struct cal_v4l2_async_subdev *
1293 "platform:%s", ctx->v4l2_dev.name);414to_cal_asd(struct v4l2_async_subdev *asd)
1294 return 0;415{
416 return container_of(asd, struct cal_v4l2_async_subdev, asd);
1295}417}
1296 418
1297static int cal_enum_fmt_vid_cap(struct file *file, void *priv,419static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier,
1298 struct v4l2_fmtdesc *f)420 struct v4l2_subdev *subdev,
421 struct v4l2_async_subdev *asd)
1299{422{
1300 struct cal_ctx *ctx = video_drvdata(file);423 struct cal_camerarx *phy = to_cal_asd(asd)->phy;
1301 const struct cal_fmt *fmt = NULL;
1302
1303 if (f->index >= ctx->num_active_fmt)
1304 return -EINVAL;
1305
1306 fmt = ctx->active_fmt[f->index];
1307 424
1308 f->pixelformat = fmt->fourcc;425 if (phy->sensor) {
1309 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;426 phy_info(phy, "Rejecting subdev %s (Already set!!)",
1310 return 0;427 subdev->name);
1311}428 return 0;
1312
1313static int __subdev_get_format(struct cal_ctx *ctx,
1314 struct v4l2_mbus_framefmt *fmt)
1315{
1316 struct v4l2_subdev_format sd_fmt;
1317 struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
1318 int ret;
1319
1320 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1321 sd_fmt.pad = 0;
1322
1323 ret = v4l2_subdev_call(ctx->sensor, pad, get_fmt, NULL, &sd_fmt);
1324 if (ret)
1325 return ret;
1326
1327 *fmt = *mbus_fmt;
1328
1329 ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
1330 fmt->width, fmt->height, fmt->code);
1331
1332 return 0;
1333}
1334
1335static int __subdev_set_format(struct cal_ctx *ctx,
1336 struct v4l2_mbus_framefmt *fmt)
1337{
1338 struct v4l2_subdev_format sd_fmt;
1339 struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
1340 int ret;
1341
1342 sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1343 sd_fmt.pad = 0;
1344 *mbus_fmt = *fmt;
1345
1346 ret = v4l2_subdev_call(ctx->sensor, pad, set_fmt, NULL, &sd_fmt);
1347 if (ret)
1348 return ret;
1349
1350 ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
1351 fmt->width, fmt->height, fmt->code);
1352
1353 return 0;
1354}
1355
1356static int cal_calc_format_size(struct cal_ctx *ctx,
1357 const struct cal_fmt *fmt,
1358 struct v4l2_format *f)
1359{
1360 u32 bpl, max_width;
1361
1362 if (!fmt) {
1363 ctx_dbg(3, ctx, "No cal_fmt provided!\n");
1364 return -EINVAL;
1365 }
1366
1367 /*
1368 * Maximum width is bound by the DMA max width in bytes.
1369 * We need to recalculate the actual maxi width depending on the
1370 * number of bytes per pixels required.
1371 */
1372 max_width = MAX_WIDTH_BYTES / (ALIGN(fmt->bpp, 8) >> 3);
1373 v4l_bound_align_image(&f->fmt.pix.width, 48, max_width, 2,
1374 &f->fmt.pix.height, 32, MAX_HEIGHT_LINES, 0, 0);
1375
1376 bpl = (f->fmt.pix.width * ALIGN(fmt->bpp, 8)) >> 3;
1377 f->fmt.pix.bytesperline = ALIGN(bpl, 16);
1378
1379 f->fmt.pix.sizeimage = f->fmt.pix.height *
1380 f->fmt.pix.bytesperline;
1381
1382 ctx_dbg(3, ctx, "%s: fourcc: %s size: %dx%d bpl:%d img_size:%d\n",
1383 __func__, fourcc_to_str(f->fmt.pix.pixelformat),
1384 f->fmt.pix.width, f->fmt.pix.height,
1385 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
1386
1387 return 0;
1388}
1389
1390static int cal_g_fmt_vid_cap(struct file *file, void *priv,
1391 struct v4l2_format *f)
1392{
1393 struct cal_ctx *ctx = video_drvdata(file);
1394
1395 *f = ctx->v_fmt;
1396
1397 return 0;
1398}
1399
1400static int cal_try_fmt_vid_cap(struct file *file, void *priv,
1401 struct v4l2_format *f)
1402{
1403 struct cal_ctx *ctx = video_drvdata(file);
1404 const struct cal_fmt *fmt;
1405 struct v4l2_subdev_frame_size_enum fse;
1406 int ret, found;
1407
1408 fmt = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
1409 if (!fmt) {
1410 ctx_dbg(3, ctx, "Fourcc format (0x%08x) not found.\n",
1411 f->fmt.pix.pixelformat);
1412
1413 /* Just get the first one enumerated */
1414 fmt = ctx->active_fmt[0];
1415 f->fmt.pix.pixelformat = fmt->fourcc;
1416 }
1417
1418 f->fmt.pix.field = ctx->v_fmt.fmt.pix.field;
1419
1420 /* check for/find a valid width/height */
1421 ret = 0;
1422 found = false;
1423 fse.pad = 0;
1424 fse.code = fmt->code;
1425 fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1426 for (fse.index = 0; ; fse.index++) {
1427 ret = v4l2_subdev_call(ctx->sensor, pad, enum_frame_size,
1428 NULL, &fse);
1429 if (ret)
1430 break;
1431
1432 if ((f->fmt.pix.width == fse.max_width) &&
1433 (f->fmt.pix.height == fse.max_height)) {
1434 found = true;
1435 break;
1436 } else if ((f->fmt.pix.width >= fse.min_width) &&
1437 (f->fmt.pix.width <= fse.max_width) &&
1438 (f->fmt.pix.height >= fse.min_height) &&
1439 (f->fmt.pix.height <= fse.max_height)) {
1440 found = true;
1441 break;
1442 }
1443 }
1444
1445 if (!found) {
1446 /* use existing values as default */
1447 f->fmt.pix.width = ctx->v_fmt.fmt.pix.width;
1448 f->fmt.pix.height = ctx->v_fmt.fmt.pix.height;
1449 }
1450
1451 /*
1452 * Use current colorspace for now, it will get
1453 * updated properly during s_fmt
1454 */
1455 f->fmt.pix.colorspace = ctx->v_fmt.fmt.pix.colorspace;
1456 return cal_calc_format_size(ctx, fmt, f);
1457}
1458
1459static int cal_s_fmt_vid_cap(struct file *file, void *priv,
1460 struct v4l2_format *f)
1461{
1462 struct cal_ctx *ctx = video_drvdata(file);
1463 struct vb2_queue *q = &ctx->vb_vidq;
1464 const struct cal_fmt *fmt;
1465 struct v4l2_mbus_framefmt mbus_fmt;
1466 int ret;
1467
1468 if (vb2_is_busy(q)) {
1469 ctx_dbg(3, ctx, "%s device busy\n", __func__);
1470 return -EBUSY;
1471 }
1472
1473 ret = cal_try_fmt_vid_cap(file, priv, f);
1474 if (ret < 0)
1475 return ret;
1476
1477 fmt = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
1478
1479 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code);
1480
1481 ret = __subdev_set_format(ctx, &mbus_fmt);
1482 if (ret)
1483 return ret;
1484
1485 /* Just double check nothing has gone wrong */
1486 if (mbus_fmt.code != fmt->code) {
1487 ctx_dbg(3, ctx,
1488 "%s subdev changed format on us, this should not happen\n",
1489 __func__);
1490 return -EINVAL;
1491 }
1492
1493 v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
1494 ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1495 ctx->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
1496 cal_calc_format_size(ctx, fmt, &ctx->v_fmt);
1497 ctx->fmt = fmt;
1498 ctx->m_fmt = mbus_fmt;
1499 *f = ctx->v_fmt;
1500
1501 return 0;
1502}
1503
1504static int cal_enum_framesizes(struct file *file, void *fh,
1505 struct v4l2_frmsizeenum *fsize)
1506{
1507 struct cal_ctx *ctx = video_drvdata(file);
1508 const struct cal_fmt *fmt;
1509 struct v4l2_subdev_frame_size_enum fse;
1510 int ret;
1511
1512 /* check for valid format */
1513 fmt = find_format_by_pix(ctx, fsize->pixel_format);
1514 if (!fmt) {
1515 ctx_dbg(3, ctx, "Invalid pixel code: %x\n",
1516 fsize->pixel_format);
1517 return -EINVAL;
1518 }429 }
1519 430
1520 fse.index = fsize->index;431 phy->sensor = subdev;
1521 fse.pad = 0;432 phy_dbg(1, phy, "Using sensor %s for capture\n", subdev->name);
1522 fse.code = fmt->code;
1523 fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1524
1525 ret = v4l2_subdev_call(ctx->sensor, pad, enum_frame_size, NULL, &fse);
1526 if (ret)
1527 return ret;
1528
1529 ctx_dbg(1, ctx, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
1530 __func__, fse.index, fse.code, fse.min_width, fse.max_width,
1531 fse.min_height, fse.max_height);
1532
1533 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1534 fsize->discrete.width = fse.max_width;
1535 fsize->discrete.height = fse.max_height;
1536
1537 return 0;
1538}
1539
1540static int cal_enum_input(struct file *file, void *priv,
1541 struct v4l2_input *inp)
1542{
1543 if (inp->index >= CAL_NUM_INPUT)
1544 return -EINVAL;
1545
1546 inp->type = V4L2_INPUT_TYPE_CAMERA;
1547 sprintf(inp->name, "Camera %u", inp->index);
1548 return 0;
1549}
1550
1551static int cal_g_input(struct file *file, void *priv, unsigned int *i)
1552{
1553 struct cal_ctx *ctx = video_drvdata(file);
1554
1555 *i = ctx->input;
1556 return 0;
1557}
1558
1559static int cal_s_input(struct file *file, void *priv, unsigned int i)
1560{
1561 struct cal_ctx *ctx = video_drvdata(file);
1562
1563 if (i >= CAL_NUM_INPUT)
1564 return -EINVAL;
1565
1566 ctx->input = i;
1567 return 0;
1568}
1569
1570/* timeperframe is arbitrary and continuous */
1571static int cal_enum_frameintervals(struct file *file, void *priv,
1572 struct v4l2_frmivalenum *fival)
1573{
1574 struct cal_ctx *ctx = video_drvdata(file);
1575 const struct cal_fmt *fmt;
1576 struct v4l2_subdev_frame_interval_enum fie = {
1577 .index = fival->index,
1578 .width = fival->width,
1579 .height = fival->height,
1580 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1581 };
1582 int ret;
1583
1584 fmt = find_format_by_pix(ctx, fival->pixel_format);
1585 if (!fmt)
1586 return -EINVAL;
1587
1588 fie.code = fmt->code;
1589 ret = v4l2_subdev_call(ctx->sensor, pad, enum_frame_interval,
1590 NULL, &fie);
1591 if (ret)
1592 return ret;
1593 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1594 fival->discrete = fie.interval;
1595 433
1596 return 0;434 return 0;
1597}435}
1598 436
1599/*437static int cal_async_notifier_complete(struct v4l2_async_notifier *notifier)
1600 * Videobuf operations
1601 */
1602static int cal_queue_setup(struct vb2_queue *vq,
1603 unsigned int *nbuffers, unsigned int *nplanes,
1604 unsigned int sizes[], struct device *alloc_devs[])
1605{438{
1606 struct cal_ctx *ctx = vb2_get_drv_priv(vq);439 struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier);
1607 unsigned size = ctx->v_fmt.fmt.pix.sizeimage;440 unsigned int i;
1608
1609 if (vq->num_buffers + *nbuffers < 3)
1610 *nbuffers = 3 - vq->num_buffers;
1611
1612 if (*nplanes) {
1613 if (sizes[0] < size)
1614 return -EINVAL;
1615 size = sizes[0];
1616 }
1617
1618 *nplanes = 1;
1619 sizes[0] = size;
1620
1621 ctx_dbg(3, ctx, "nbuffers=%d, size=%d\n", *nbuffers, sizes[0]);
1622
1623 return 0;
1624}
1625 441
1626static int cal_buffer_prepare(struct vb2_buffer *vb)442 for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
1627{443 if (cal->ctx[i])
1628 struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);444 cal_ctx_v4l2_register(cal->ctx[i]);
1629 struct cal_buffer *buf = container_of(vb, struct cal_buffer,
1630 vb.vb2_buf);
1631 unsigned long size;
1632
1633 if (WARN_ON(!ctx->fmt))
1634 return -EINVAL;
1635
1636 size = ctx->v_fmt.fmt.pix.sizeimage;
1637 if (vb2_plane_size(vb, 0) < size) {
1638 ctx_err(ctx,
1639 "data will not fit into plane (%lu < %lu)\n",
1640 vb2_plane_size(vb, 0), size);
1641 return -EINVAL;
1642 }445 }
1643 446
1644 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
1645 return 0;447 return 0;
1646}448}
1647 449
1648static void cal_buffer_queue(struct vb2_buffer *vb)450static const struct v4l2_async_notifier_operations cal_async_notifier_ops = {
1649{451 .bound = cal_async_notifier_bound,
1650 struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);452 .complete = cal_async_notifier_complete,
1651 struct cal_buffer *buf = container_of(vb, struct cal_buffer,453};
1652 vb.vb2_buf);
1653 struct cal_dmaqueue *vidq = &ctx->vidq;
1654 unsigned long flags = 0;
1655
1656 /* recheck locking */
1657 spin_lock_irqsave(&ctx->slock, flags);
1658 list_add_tail(&buf->list, &vidq->active);
1659 spin_unlock_irqrestore(&ctx->slock, flags);
1660}
1661 454
1662static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)455static int cal_async_notifier_register(struct cal_dev *cal)
1663{456{
1664 struct cal_ctx *ctx = vb2_get_drv_priv(vq);457 unsigned int i;
1665 struct cal_dmaqueue *dma_q = &ctx->vidq;
1666 struct cal_buffer *buf, *tmp;
1667 unsigned long addr = 0;
1668 unsigned long flags;
1669 int ret;458 int ret;
1670 459
1671 spin_lock_irqsave(&ctx->slock, flags);460 v4l2_async_notifier_init(&cal->notifier);
1672 if (list_empty(&dma_q->active)) {461 cal->notifier.ops = &cal_async_notifier_ops;
1673 spin_unlock_irqrestore(&ctx->slock, flags);
1674 ctx_dbg(3, ctx, "buffer queue is empty\n");
1675 return -EIO;
1676 }
1677 462
1678 buf = list_entry(dma_q->active.next, struct cal_buffer, list);463 for (i = 0; i < ARRAY_SIZE(cal->phy); ++i) {
1679 ctx->cur_frm = buf;464 struct cal_camerarx *phy = cal->phy[i];
1680 ctx->next_frm = buf;465 struct cal_v4l2_async_subdev *casd;
1681 list_del(&buf->list);466 struct v4l2_async_subdev *asd;
1682 spin_unlock_irqrestore(&ctx->slock, flags);467 struct fwnode_handle *fwnode;
1683 468
1684 addr = vb2_dma_contig_plane_dma_addr(&ctx->cur_frm->vb.vb2_buf, 0);469 if (!phy || !phy->sensor_node)
1685 ctx->sequence = 0;470 continue;
1686 471
1687 ret = cal_get_external_info(ctx);472 fwnode = of_fwnode_handle(phy->sensor_node);
1688 if (ret < 0)473 asd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier,
1689 goto err;474 fwnode,
475 sizeof(*asd));
476 if (IS_ERR(asd)) {
477 phy_err(phy, "Failed to add subdev to notifier\n");
478 ret = PTR_ERR(asd);
479 goto error;
480 }
1690 481
1691 ret = v4l2_subdev_call(ctx->sensor, core, s_power, 1);482 casd = to_cal_asd(asd);
1692 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {483 casd->phy = phy;
1693 ctx_err(ctx, "power on failed in subdev\n");
1694 goto err;
1695 }484 }
1696 485
1697 pm_runtime_get_sync(&ctx->dev->pdev->dev);486 ret = v4l2_async_notifier_register(&cal->v4l2_dev, &cal->notifier);
1698
1699 csi2_ctx_config(ctx);
1700 pix_proc_config(ctx);
1701 cal_wr_dma_config(ctx, ctx->v_fmt.fmt.pix.bytesperline,
1702 ctx->v_fmt.fmt.pix.height);
1703 csi2_lane_config(ctx);
1704
1705 enable_irqs(ctx);
1706 csi2_phy_init(ctx);
1707
1708 ret = v4l2_subdev_call(ctx->sensor, video, s_stream, 1);
1709 if (ret) {487 if (ret) {
1710 v4l2_subdev_call(ctx->sensor, core, s_power, 0);488 cal_err(cal, "Error registering async notifier\n");
1711 ctx_err(ctx, "stream on failed in subdev\n");489 goto error;
1712 pm_runtime_put_sync(&ctx->dev->pdev->dev);
1713 goto err;
1714 }490 }
1715 491
1716 csi2_wait_for_phy(ctx);
1717 cal_wr_dma_addr(ctx, addr);
1718 csi2_ppi_enable(ctx);
1719
1720 if (debug >= 4)
1721 cal_quickdump_regs(ctx->dev);
1722
1723 return 0;492 return 0;
1724 493
1725err:494error:
1726 spin_lock_irqsave(&ctx->slock, flags);495 v4l2_async_notifier_cleanup(&cal->notifier);
1727 vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
1728 ctx->cur_frm = NULL;
1729 ctx->next_frm = NULL;
1730 list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
1731 list_del(&buf->list);
1732 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
1733 }
1734 spin_unlock_irqrestore(&ctx->slock, flags);
1735 return ret;496 return ret;
1736}497}
1737 498
1738static void cal_stop_streaming(struct vb2_queue *vq)499static void cal_async_notifier_unregister(struct cal_dev *cal)
1739{500{
1740 struct cal_ctx *ctx = vb2_get_drv_priv(vq);501 v4l2_async_notifier_unregister(&cal->notifier);
1741 struct cal_dmaqueue *dma_q = &ctx->vidq;502 v4l2_async_notifier_cleanup(&cal->notifier);
1742 struct cal_buffer *buf, *tmp;
1743 unsigned long timeout;
1744 unsigned long flags;
1745 int ret;
1746 bool dma_act;
1747
1748 csi2_ppi_disable(ctx);
1749
1750 /* wait for stream and dma to finish */
1751 dma_act = true;
1752 timeout = jiffies + msecs_to_jiffies(500);
1753 while (dma_act && time_before(jiffies, timeout)) {
1754 msleep(50);
1755
1756 spin_lock_irqsave(&ctx->slock, flags);
1757 dma_act = ctx->dma_act;
1758 spin_unlock_irqrestore(&ctx->slock, flags);
1759 }
1760
1761 if (dma_act)
1762 ctx_err(ctx, "failed to disable dma cleanly\n");
1763
1764 disable_irqs(ctx);
1765 csi2_phy_deinit(ctx);
1766
1767 if (v4l2_subdev_call(ctx->sensor, video, s_stream, 0))
1768 ctx_err(ctx, "stream off failed in subdev\n");
1769
1770 ret = v4l2_subdev_call(ctx->sensor, core, s_power, 0);
1771 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
1772 ctx_err(ctx, "power off failed in subdev\n");
1773
1774 /* Release all active buffers */
1775 spin_lock_irqsave(&ctx->slock, flags);
1776 list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
1777 list_del(&buf->list);
1778 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
1779 }
1780
1781 if (ctx->cur_frm == ctx->next_frm) {
1782 vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR);
1783 } else {
1784 vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR);
1785 vb2_buffer_done(&ctx->next_frm->vb.vb2_buf,
1786 VB2_BUF_STATE_ERROR);
1787 }
1788 ctx->cur_frm = NULL;
1789 ctx->next_frm = NULL;
1790 spin_unlock_irqrestore(&ctx->slock, flags);
1791
1792 pm_runtime_put_sync(&ctx->dev->pdev->dev);
1793}503}
1794 504
1795static const struct vb2_ops cal_video_qops = {505/* ------------------------------------------------------------------
1796 .queue_setup = cal_queue_setup,506 * Media and V4L2 device handling
1797 .buf_prepare = cal_buffer_prepare,
1798 .buf_queue = cal_buffer_queue,
1799 .start_streaming = cal_start_streaming,
1800 .stop_streaming = cal_stop_streaming,
1801 .wait_prepare = vb2_ops_wait_prepare,
1802 .wait_finish = vb2_ops_wait_finish,
1803};
1804
1805static const struct v4l2_file_operations cal_fops = {
1806 .owner = THIS_MODULE,
1807 .open = v4l2_fh_open,
1808 .release = vb2_fop_release,
1809 .read = vb2_fop_read,
1810 .poll = vb2_fop_poll,
1811 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
1812 .mmap = vb2_fop_mmap,
1813};
1814
1815static const struct v4l2_ioctl_ops cal_ioctl_ops = {
1816 .vidioc_querycap = cal_querycap,
1817 .vidioc_enum_fmt_vid_cap = cal_enum_fmt_vid_cap,
1818 .vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
1819 .vidioc_try_fmt_vid_cap = cal_try_fmt_vid_cap,
1820 .vidioc_s_fmt_vid_cap = cal_s_fmt_vid_cap,
1821 .vidioc_enum_framesizes = cal_enum_framesizes,
1822 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1823 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1824 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1825 .vidioc_querybuf = vb2_ioctl_querybuf,
1826 .vidioc_qbuf = vb2_ioctl_qbuf,
1827 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1828 .vidioc_expbuf = vb2_ioctl_expbuf,
1829 .vidioc_enum_input = cal_enum_input,
1830 .vidioc_g_input = cal_g_input,
1831 .vidioc_s_input = cal_s_input,
1832 .vidioc_enum_frameintervals = cal_enum_frameintervals,
1833 .vidioc_streamon = vb2_ioctl_streamon,
1834 .vidioc_streamoff = vb2_ioctl_streamoff,
1835 .vidioc_log_status = v4l2_ctrl_log_status,
1836 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1837 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1838};
1839
1840static const struct video_device cal_videodev = {
1841 .name = CAL_MODULE_NAME,
1842 .fops = &cal_fops,
1843 .ioctl_ops = &cal_ioctl_ops,
1844 .minor = -1,
1845 .release = video_device_release_empty,
1846 .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1847 V4L2_CAP_READWRITE,
1848};
1849
1850/* -----------------------------------------------------------------
1851 * Initialization and module stuff
1852 * ------------------------------------------------------------------507 * ------------------------------------------------------------------
1853 */508 */
1854static int cal_complete_ctx(struct cal_ctx *ctx);
1855 509
1856static int cal_async_bound(struct v4l2_async_notifier *notifier,510/*
1857 struct v4l2_subdev *subdev,511 * Register user-facing devices. To be called at the end of the probe function
1858 struct v4l2_async_subdev *asd)512 * when all resources are initialized and ready.
513 */
514static int cal_media_register(struct cal_dev *cal)
1859{515{
1860 struct cal_ctx *ctx = notifier_to_ctx(notifier);516 int ret;
1861 struct v4l2_subdev_mbus_code_enum mbus_code;
1862 int ret = 0;
1863 int i, j, k;
1864
1865 if (ctx->sensor) {
1866 ctx_info(ctx, "Rejecting subdev %s (Already set!!)",
1867 subdev->name);
1868 return 0;
1869 }
1870
1871 ctx->sensor = subdev;
1872 ctx_dbg(1, ctx, "Using sensor %s for capture\n", subdev->name);
1873
1874 /* Enumerate sub device formats and enable all matching local formats */
1875 ctx->num_active_fmt = 0;
1876 for (j = 0, i = 0; ret != -EINVAL; ++j) {
1877 struct cal_fmt *fmt;
1878
1879 memset(&mbus_code, 0, sizeof(mbus_code));
1880 mbus_code.index = j;
1881 mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1882 ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
1883 NULL, &mbus_code);
1884 if (ret)
1885 continue;
1886
1887 ctx_dbg(2, ctx,
1888 "subdev %s: code: %04x idx: %d\n",
1889 subdev->name, mbus_code.code, j);
1890
1891 for (k = 0; k < ARRAY_SIZE(cal_formats); k++) {
1892 fmt = &cal_formats[k];
1893 517
1894 if (mbus_code.code == fmt->code) {518 ret = media_device_register(&cal->mdev);
1895 ctx->active_fmt[i] = fmt;519 if (ret) {
1896 ctx_dbg(2, ctx,520 cal_err(cal, "Failed to register media device\n");
1897 "matched fourcc: %s: code: %04x idx: %d\n",521 return ret;
1898 fourcc_to_str(fmt->fourcc),
1899 fmt->code, i);
1900 ctx->num_active_fmt = ++i;
1901 }
1902 }
1903 }522 }
1904 523
1905 if (i == 0) {524 /*
1906 ctx_err(ctx, "No suitable format reported by subdev %s\n",525 * Register the async notifier. This may trigger registration of the
1907 subdev->name);526 * V4L2 video devices if all subdevs are ready.
1908 return -EINVAL;527 */
528 ret = cal_async_notifier_register(cal);
529 if (ret) {
530 media_device_unregister(&cal->mdev);
531 return ret;
1909 }532 }
1910 533
1911 cal_complete_ctx(ctx);
1912
1913 return 0;534 return 0;
1914}535}
1915 536
1916static int cal_async_complete(struct v4l2_async_notifier *notifier)537/*
538 * Unregister the user-facing devices, but don't free memory yet. To be called
539 * at the beginning of the remove function, to disallow access from userspace.
540 */
541static void cal_media_unregister(struct cal_dev *cal)
1917{542{
1918 struct cal_ctx *ctx = notifier_to_ctx(notifier);543 unsigned int i;
1919 const struct cal_fmt *fmt;
1920 struct v4l2_mbus_framefmt mbus_fmt;
1921 int ret;
1922
1923 ret = __subdev_get_format(ctx, &mbus_fmt);
1924 if (ret)
1925 return ret;
1926 544
1927 fmt = find_format_by_code(ctx, mbus_fmt.code);545 /* Unregister all the V4L2 video devices. */
1928 if (!fmt) {546 for (i = 0; i < ARRAY_SIZE(cal->ctx); i++) {
1929 ctx_dbg(3, ctx, "mbus code format (0x%08x) not found.\n",547 if (cal->ctx[i])
1930 mbus_fmt.code);548 cal_ctx_v4l2_unregister(cal->ctx[i]);
1931 return -EINVAL;
1932 }549 }
1933 550
1934 /* Save current subdev format */551 cal_async_notifier_unregister(cal);
1935 v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);552 media_device_unregister(&cal->mdev);
1936 ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1937 ctx->v_fmt.fmt.pix.pixelformat = fmt->fourcc;
1938 cal_calc_format_size(ctx, fmt, &ctx->v_fmt);
1939 ctx->fmt = fmt;
1940 ctx->m_fmt = mbus_fmt;
1941
1942 return 0;
1943}553}
1944 554
1945static const struct v4l2_async_notifier_operations cal_async_ops = {555/*
1946 .bound = cal_async_bound,556 * Initialize the in-kernel objects. To be called at the beginning of the probe
1947 .complete = cal_async_complete,557 * function, before the V4L2 device is used by the driver.
1948};558 */
1949 559static int cal_media_init(struct cal_dev *cal)
1950static int cal_complete_ctx(struct cal_ctx *ctx)
1951{560{
1952 struct video_device *vfd;561 struct media_device *mdev = &cal->mdev;
1953 struct vb2_queue *q;
1954 int ret;562 int ret;
1955 563
1956 ctx->timeperframe = tpf_default;564 mdev->dev = cal->dev;
1957 ctx->external_rate = 192000000;565 mdev->hw_revision = cal->revision;
1958 566 strscpy(mdev->model, "CAL", sizeof(mdev->model));
1959 /* initialize locks */567 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
1960 spin_lock_init(&ctx->slock);568 dev_name(mdev->dev));
1961 mutex_init(&ctx->mutex);569 media_device_init(mdev);
1962
1963 /* initialize queue */
1964 q = &ctx->vb_vidq;
1965 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1966 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
1967 q->drv_priv = ctx;
1968 q->buf_struct_size = sizeof(struct cal_buffer);
1969 q->ops = &cal_video_qops;
1970 q->mem_ops = &vb2_dma_contig_memops;
1971 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1972 q->lock = &ctx->mutex;
1973 q->min_buffers_needed = 3;
1974 q->dev = ctx->v4l2_dev.dev;
1975
1976 ret = vb2_queue_init(q);
1977 if (ret)
1978 return ret;
1979
1980 /* init video dma queues */
1981 INIT_LIST_HEAD(&ctx->vidq.active);
1982
1983 vfd = &ctx->vdev;
1984 *vfd = cal_videodev;
1985 vfd->v4l2_dev = &ctx->v4l2_dev;
1986 vfd->queue = q;
1987 570
1988 /*571 /*
1989 * Provide a mutex to v4l2 core. It will be used to protect572 * Initialize the V4L2 device (despite the function name, this performs
1990 * all fops and v4l2 ioctls.573 * initialization, not registration).
1991 */574 */
1992 vfd->lock = &ctx->mutex;575 cal->v4l2_dev.mdev = mdev;
1993 video_set_drvdata(vfd, ctx);576 ret = v4l2_device_register(cal->dev, &cal->v4l2_dev);
1994 577 if (ret) {
1995 ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr);578 cal_err(cal, "Failed to register V4L2 device\n");
1996 if (ret < 0)
1997 return ret;579 return ret;
580 }
1998 581
1999 v4l2_info(&ctx->v4l2_dev, "V4L2 device registered as %s\n",582 vb2_dma_contig_set_max_seg_size(cal->dev, DMA_BIT_MASK(32));
2000 video_device_node_name(vfd));
2001 583
2002 return 0;584 return 0;
2003}585}
2004 586
2005static struct device_node *587/*
2006of_get_next_port(const struct device_node *parent,588 * Cleanup the in-kernel objects, freeing memory. To be called at the very end
2007 struct device_node *prev)589 * of the remove sequence, when nothing (including userspace) can access the
590 * objects anymore.
591 */
592static void cal_media_cleanup(struct cal_dev *cal)
2008{593{
2009 struct device_node *port = NULL;594 unsigned int i;
2010
2011 if (!parent)
2012 return NULL;
2013 595
2014 if (!prev) {596 for (i = 0; i < ARRAY_SIZE(cal->ctx); i++) {
2015 struct device_node *ports;597 if (cal->ctx[i])
2016 /*598 cal_ctx_v4l2_cleanup(cal->ctx[i]);
2017 * It's the first call, we have to find a port subnode
2018 * within this node or within an optional 'ports' node.
2019 */
2020 ports = of_get_child_by_name(parent, "ports");
2021 if (ports)
2022 parent = ports;
2023
2024 port = of_get_child_by_name(parent, "port");
2025
2026 /* release the 'ports' node */
2027 of_node_put(ports);
2028 } else {
2029 struct device_node *ports;
2030
2031 ports = of_get_parent(prev);
2032 if (!ports)
2033 return NULL;
2034
2035 do {
2036 port = of_get_next_child(ports, prev);
2037 if (!port) {
2038 of_node_put(ports);
2039 return NULL;
2040 }
2041 prev = port;
2042 } while (!of_node_name_eq(port, "port"));
2043 of_node_put(ports);
2044 }599 }
2045 600
2046 return port;601 v4l2_device_unregister(&cal->v4l2_dev);
2047}602 media_device_cleanup(&cal->mdev);
2048
2049static struct device_node *
2050of_get_next_endpoint(const struct device_node *parent,
2051 struct device_node *prev)
2052{
2053 struct device_node *ep = NULL;
2054
2055 if (!parent)
2056 return NULL;
2057 603
2058 do {604 vb2_dma_contig_clear_max_seg_size(cal->dev);
2059 ep = of_get_next_child(parent, prev);
2060 if (!ep)
2061 return NULL;
2062 prev = ep;
2063 } while (!of_node_name_eq(ep, "endpoint"));
2064
2065 return ep;
2066}605}
2067 606
2068static int of_cal_create_instance(struct cal_ctx *ctx, int inst)607/* ------------------------------------------------------------------
2069{608 * Initialization and module stuff
2070 struct platform_device *pdev = ctx->dev->pdev;609 * ------------------------------------------------------------------
2071 struct device_node *ep_node, *port, *sensor_node, *parent;610 */
2072 struct v4l2_fwnode_endpoint *endpoint;
2073 struct v4l2_async_subdev *asd;
2074 u32 regval = 0;
2075 int ret, index, found_port = 0, lane;
2076
2077 parent = pdev->dev.of_node;
2078
2079 endpoint = &ctx->endpoint;
2080
2081 ep_node = NULL;
2082 port = NULL;
2083 sensor_node = NULL;
2084 ret = -EINVAL;
2085
2086 ctx_dbg(3, ctx, "Scanning Port node for csi2 port: %d\n", inst);
2087 for (index = 0; index < CAL_NUM_CSI2_PORTS; index++) {
2088 port = of_get_next_port(parent, port);
2089 if (!port) {
2090 ctx_dbg(1, ctx, "No port node found for csi2 port:%d\n",
2091 index);
2092 goto cleanup_exit;
2093 }
2094
2095 /* Match the slice number with <REG> */
2096 of_property_read_u32(port, "reg", &regval);
2097 ctx_dbg(3, ctx, "port:%d inst:%d <reg>:%d\n",
2098 index, inst, regval);
2099 if ((regval == inst) && (index == inst)) {
2100 found_port = 1;
2101 break;
2102 }
2103 }
2104
2105 if (!found_port) {
2106 ctx_dbg(1, ctx, "No port node matches csi2 port:%d\n",
2107 inst);
2108 goto cleanup_exit;
2109 }
2110
2111 ctx_dbg(3, ctx, "Scanning sub-device for csi2 port: %d\n",
2112 inst);
2113
2114 ep_node = of_get_next_endpoint(port, ep_node);
2115 if (!ep_node) {
2116 ctx_dbg(3, ctx, "can't get next endpoint\n");
2117 goto cleanup_exit;
2118 }
2119
2120 sensor_node = of_graph_get_remote_port_parent(ep_node);
2121 if (!sensor_node) {
2122 ctx_dbg(3, ctx, "can't get remote parent\n");
2123 goto cleanup_exit;
2124 }
2125
2126 v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint);
2127
2128 if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) {
2129 ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n",
2130 inst, sensor_node);
2131 goto cleanup_exit;
2132 }
2133
2134 /* Store Virtual Channel number */
2135 ctx->virtual_channel = endpoint->base.id;
2136
2137 ctx_dbg(3, ctx, "Port:%d v4l2-endpoint: CSI2\n", inst);
2138 ctx_dbg(3, ctx, "Virtual Channel=%d\n", ctx->virtual_channel);
2139 ctx_dbg(3, ctx, "flags=0x%08x\n", endpoint->bus.mipi_csi2.flags);
2140 ctx_dbg(3, ctx, "clock_lane=%d\n", endpoint->bus.mipi_csi2.clock_lane);
2141 ctx_dbg(3, ctx, "num_data_lanes=%d\n",
2142 endpoint->bus.mipi_csi2.num_data_lanes);
2143 ctx_dbg(3, ctx, "data_lanes= <\n");
2144 for (lane = 0; lane < endpoint->bus.mipi_csi2.num_data_lanes; lane++)
2145 ctx_dbg(3, ctx, "\t%d\n",
2146 endpoint->bus.mipi_csi2.data_lanes[lane]);
2147 ctx_dbg(3, ctx, "\t>\n");
2148
2149 ctx_dbg(1, ctx, "Port: %d found sub-device %pOFn\n",
2150 inst, sensor_node);
2151
2152 v4l2_async_notifier_init(&ctx->notifier);
2153
2154 asd = kzalloc(sizeof(*asd), GFP_KERNEL);
2155 if (!asd)
2156 goto cleanup_exit;
2157
2158 asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
2159 asd->match.fwnode = of_fwnode_handle(sensor_node);
2160
2161 ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd);
2162 if (ret) {
2163 ctx_err(ctx, "Error adding asd\n");
2164 kfree(asd);
2165 goto cleanup_exit;
2166 }
2167
2168 ctx->notifier.ops = &cal_async_ops;
2169 ret = v4l2_async_notifier_register(&ctx->v4l2_dev,
2170 &ctx->notifier);
2171 if (ret) {
2172 ctx_err(ctx, "Error registering async notifier\n");
2173 v4l2_async_notifier_cleanup(&ctx->notifier);
2174 ret = -EINVAL;
2175 }
2176
2177 /*
2178 * On success we need to keep reference on sensor_node, or
2179 * if notifier_cleanup was called above, sensor_node was
2180 * already put.
2181 */
2182 sensor_node = NULL;
2183
2184cleanup_exit:
2185 of_node_put(sensor_node);
2186 of_node_put(ep_node);
2187 of_node_put(port);
2188
2189 return ret;
2190}
2191 611
2192static struct cal_ctx *cal_create_instance(struct cal_dev *dev, int inst)612static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
2193{613{
2194 struct cal_ctx *ctx;614 struct cal_ctx *ctx;
2195 struct v4l2_ctrl_handler *hdl;
2196 int ret;615 int ret;
2197 616
2198 ctx = devm_kzalloc(&dev->pdev->dev, sizeof(*ctx), GFP_KERNEL);617 ctx = devm_kzalloc(cal->dev, sizeof(*ctx), GFP_KERNEL);
2199 if (!ctx)618 if (!ctx)
2200 return NULL;619 return NULL;
2201 620
2202 /* save the cal_dev * for future ref */621 ctx->cal = cal;
2203 ctx->dev = dev;622 ctx->phy = cal->phy[inst];
623 ctx->index = inst;
624 ctx->cport = inst;
2204 625
2205 snprintf(ctx->v4l2_dev.name, sizeof(ctx->v4l2_dev.name),626 ret = cal_ctx_v4l2_init(ctx);
2206 "%s-%03d", CAL_MODULE_NAME, inst);
2207 ret = v4l2_device_register(&dev->pdev->dev, &ctx->v4l2_dev);
2208 if (ret)627 if (ret)
2209 goto err_exit;628 return NULL;
2210
2211 hdl = &ctx->ctrl_handler;
2212 ret = v4l2_ctrl_handler_init(hdl, 11);
2213 if (ret) {
2214 ctx_err(ctx, "Failed to init ctrl handler\n");
2215 goto unreg_dev;
2216 }
2217 ctx->v4l2_dev.ctrl_handler = hdl;
2218
2219 /* Make sure Camera Core H/W register area is available */
2220 ctx->cc = dev->cc[inst];
2221
2222 /* Store the instance id */
2223 ctx->csi2_port = inst + 1;
2224 629
2225 ret = of_cal_create_instance(ctx, inst);
2226 if (ret) {
2227 ret = -EINVAL;
2228 goto free_hdl;
2229 }
2230 return ctx;630 return ctx;
2231
2232free_hdl:
2233 v4l2_ctrl_handler_free(hdl);
2234unreg_dev:
2235 v4l2_device_unregister(&ctx->v4l2_dev);
2236err_exit:
2237 return NULL;
2238}631}
2239 632
2240static const struct of_device_id cal_of_match[] = {633static const struct of_device_id cal_of_match[] = {
@@ -2258,191 +651,253 @@ static const struct of_device_id cal_of_match[] = { · 17 unmodified lines
2258};651};
2259MODULE_DEVICE_TABLE(of, cal_of_match);652MODULE_DEVICE_TABLE(of, cal_of_match);
2260 653
654/* Get hardware revision and info. */
655
656#define CAL_HL_HWINFO_VALUE 0xa3c90469
657
658static void cal_get_hwinfo(struct cal_dev *cal)
659{
660 u32 hwinfo;
661
662 cal->revision = cal_read(cal, CAL_HL_REVISION);
663 switch (FIELD_GET(CAL_HL_REVISION_SCHEME_MASK, cal->revision)) {
664 case CAL_HL_REVISION_SCHEME_H08:
665 cal_dbg(3, cal, "CAL HW revision %lu.%lu.%lu (0x%08x)\n",
666 FIELD_GET(CAL_HL_REVISION_MAJOR_MASK, cal->revision),
667 FIELD_GET(CAL_HL_REVISION_MINOR_MASK, cal->revision),
668 FIELD_GET(CAL_HL_REVISION_RTL_MASK, cal->revision),
669 cal->revision);
670 break;
671
672 case CAL_HL_REVISION_SCHEME_LEGACY:
673 default:
674 cal_info(cal, "Unexpected CAL HW revision 0x%08x\n",
675 cal->revision);
676 break;
677 }
678
679 hwinfo = cal_read(cal, CAL_HL_HWINFO);
680 if (hwinfo != CAL_HL_HWINFO_VALUE)
681 cal_info(cal, "CAL_HL_HWINFO = 0x%08x, expected 0x%08x\n",
682 hwinfo, CAL_HL_HWINFO_VALUE);
683}
684
685static int cal_init_camerarx_regmap(struct cal_dev *cal)
686{
687 struct platform_device *pdev = to_platform_device(cal->dev);
688 struct device_node *np = cal->dev->of_node;
689 struct regmap_config config = { };
690 struct regmap *syscon;
691 struct resource *res;
692 unsigned int offset;
693 void __iomem *base;
694
695 syscon = syscon_regmap_lookup_by_phandle_args(np, "ti,camerrx-control",
696 1, &offset);
697 if (!IS_ERR(syscon)) {
698 cal->syscon_camerrx = syscon;
699 cal->syscon_camerrx_offset = offset;
700 return 0;
701 }
702
703 dev_warn(cal->dev, "failed to get ti,camerrx-control: %ld\n",
704 PTR_ERR(syscon));
705
706 /*
707 * Backward DTS compatibility. If syscon entry is not present then
708 * check if the camerrx_control resource is present.
709 */
710 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
711 "camerrx_control");
712 base = devm_ioremap_resource(cal->dev, res);
713 if (IS_ERR(base)) {
714 cal_err(cal, "failed to ioremap camerrx_control\n");
715 return PTR_ERR(base);
716 }
717
718 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
719 res->name, &res->start, &res->end);
720
721 config.reg_bits = 32;
722 config.reg_stride = 4;
723 config.val_bits = 32;
724 config.max_register = resource_size(res) - 4;
725
726 syscon = regmap_init_mmio(NULL, base, &config);
727 if (IS_ERR(syscon)) {
728 pr_err("regmap init failed\n");
729 return PTR_ERR(syscon);
730 }
731
732 /*
733 * In this case the base already point to the direct CM register so no
734 * need for an offset.
735 */
736 cal->syscon_camerrx = syscon;
737 cal->syscon_camerrx_offset = 0;
738
739 return 0;
740}
741
2261static int cal_probe(struct platform_device *pdev)742static int cal_probe(struct platform_device *pdev)
2262{743{
2263 struct cal_dev *dev;744 struct cal_dev *cal;
2264 struct cal_ctx *ctx;745 struct cal_ctx *ctx;
2265 struct device_node *parent = pdev->dev.of_node;746 bool connected = false;
2266 struct regmap *syscon_camerrx = NULL;747 unsigned int i;
2267 u32 syscon_camerrx_offset = 0;
2268 int ret;748 int ret;
2269 int irq;749 int irq;
2270 int i;
2271 750
2272 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);751 cal = devm_kzalloc(&pdev->dev, sizeof(*cal), GFP_KERNEL);
2273 if (!dev)752 if (!cal)
2274 return -ENOMEM;753 return -ENOMEM;
2275 754
2276 dev->data = of_device_get_match_data(&pdev->dev);755 cal->data = of_device_get_match_data(&pdev->dev);
2277 if (!dev->data) {756 if (!cal->data) {
2278 dev_err(&pdev->dev, "Could not get feature data based on compatible version\n");757 dev_err(&pdev->dev, "Could not get feature data based on compatible version\n");
2279 return -ENODEV;758 return -ENODEV;
2280 }759 }
2281 760
2282 dev->flags = dev->data->flags;761 cal->dev = &pdev->dev;
762 platform_set_drvdata(pdev, cal);
2283 763
2284 /* set pseudo v4l2 device name so we can use v4l2_printk */764 /* Acquire resources: clocks, CAMERARX regmap, I/O memory and IRQ. */
2285 strscpy(dev->v4l2_dev.name, CAL_MODULE_NAME,765 cal->fclk = devm_clk_get(&pdev->dev, "fck");
2286 sizeof(dev->v4l2_dev.name));766 if (IS_ERR(cal->fclk)) {
2287
2288 /* save pdev pointer */
2289 dev->pdev = pdev;
2290
2291 dev->fclk = devm_clk_get(&pdev->dev, "fck");
2292 if (IS_ERR(dev->fclk)) {
2293 dev_err(&pdev->dev, "cannot get CAL fclk\n");767 dev_err(&pdev->dev, "cannot get CAL fclk\n");
2294 return PTR_ERR(dev->fclk);768 return PTR_ERR(cal->fclk);
2295 }
2296
2297 syscon_camerrx = syscon_regmap_lookup_by_phandle(parent,
2298 "ti,camerrx-control");
2299 ret = of_property_read_u32_index(parent, "ti,camerrx-control", 1,
2300 &syscon_camerrx_offset);
2301 if (IS_ERR(syscon_camerrx))
2302 ret = PTR_ERR(syscon_camerrx);
2303 if (ret) {
2304 dev_warn(&pdev->dev, "failed to get ti,camerrx-control: %d\n",
2305 ret);
2306
2307 /*
2308 * Backward DTS compatibility.
2309 * If syscon entry is not present then check if the
2310 * camerrx_control resource is present.
2311 */
2312 syscon_camerrx = cal_get_camerarx_regmap(dev);
2313 if (IS_ERR(syscon_camerrx)) {
2314 dev_err(&pdev->dev, "failed to get camerrx_control regmap\n");
2315 return PTR_ERR(syscon_camerrx);
2316 }
2317 /* In this case the base already point to the direct
2318 * CM register so no need for an offset
2319 */
2320 syscon_camerrx_offset = 0;
2321 }769 }
2322 770
2323 dev->syscon_camerrx = syscon_camerrx;771 ret = cal_init_camerarx_regmap(cal);
2324 dev->syscon_camerrx_offset = syscon_camerrx_offset;772 if (ret < 0)
2325 ret = cal_camerarx_regmap_init(dev);
2326 if (ret)
2327 return ret;773 return ret;
2328 774
2329 dev->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,775 cal->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2330 "cal_top");776 "cal_top");
2331 dev->base = devm_ioremap_resource(&pdev->dev, dev->res);777 cal->base = devm_ioremap_resource(&pdev->dev, cal->res);
2332 if (IS_ERR(dev->base))778 if (IS_ERR(cal->base))
2333 return PTR_ERR(dev->base);779 return PTR_ERR(cal->base);
2334 780
2335 cal_dbg(1, dev, "ioresource %s at %pa - %pa\n",781 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
2336 dev->res->name, &dev->res->start, &dev->res->end);782 cal->res->name, &cal->res->start, &cal->res->end);
2337 783
2338 irq = platform_get_irq(pdev, 0);784 irq = platform_get_irq(pdev, 0);
2339 cal_dbg(1, dev, "got irq# %d\n", irq);785 cal_dbg(1, cal, "got irq# %d\n", irq);
2340 ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME,786 ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME,
2341 dev);787 cal);
2342 if (ret)788 if (ret)
2343 return ret;789 return ret;
2344 790
2345 platform_set_drvdata(pdev, dev);791 /* Read the revision and hardware info to verify hardware access. */
792 pm_runtime_enable(&pdev->dev);
793 ret = pm_runtime_get_sync(&pdev->dev);
794 if (ret)
795 goto error_pm_runtime;
2346 796
2347 dev->cc[0] = cc_create(dev, 0);797 cal_get_hwinfo(cal);
2348 if (IS_ERR(dev->cc[0]))798 pm_runtime_put_sync(&pdev->dev);
2349 return PTR_ERR(dev->cc[0]);
2350 799
2351 if (cal_data_get_num_csi2_phy(dev) > 1) {800 /* Create CAMERARX PHYs. */
2352 dev->cc[1] = cc_create(dev, 1);801 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
2353 if (IS_ERR(dev->cc[1]))802 cal->phy[i] = cal_camerarx_create(cal, i);
2354 return PTR_ERR(dev->cc[1]);803 if (IS_ERR(cal->phy[i])) {
2355 } else {804 ret = PTR_ERR(cal->phy[i]);
2356 dev->cc[1] = NULL;805 cal->phy[i] = NULL;
2357 }806 goto error_camerarx;
807 }
2358 808
2359 dev->ctx[0] = NULL;809 if (cal->phy[i]->sensor_node)
2360 dev->ctx[1] = NULL;810 connected = true;
811 }
2361 812
2362 dev->ctx[0] = cal_create_instance(dev, 0);813 if (!connected) {
2363 if (cal_data_get_num_csi2_phy(dev) > 1)814 cal_err(cal, "Neither port is configured, no point in staying up\n");
2364 dev->ctx[1] = cal_create_instance(dev, 1);815 ret = -ENODEV;
2365 if (!dev->ctx[0] && !dev->ctx[1]) {816 goto error_camerarx;
2366 cal_err(dev, "Neither port is configured, no point in staying up\n");
2367 return -ENODEV;
2368 }817 }
2369 818
2370 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));819 /* Initialize the media device. */
820 ret = cal_media_init(cal);
821 if (ret < 0)
822 goto error_camerarx;
2371 823
2372 pm_runtime_enable(&pdev->dev);824 /* Create contexts. */
825 for (i = 0; i < cal->data->num_csi2_phy; ++i) {
826 if (!cal->phy[i]->sensor_node)
827 continue;
2373 828
2374 ret = pm_runtime_get_sync(&pdev->dev);829 cal->ctx[i] = cal_ctx_create(cal, i);
830 if (!cal->ctx[i]) {
831 cal_err(cal, "Failed to create context %u\n", i);
832 ret = -ENODEV;
833 goto error_context;
834 }
835 }
836
837 /* Register the media device. */
838 ret = cal_media_register(cal);
2375 if (ret)839 if (ret)
2376 goto runtime_disable;840 goto error_context;
2377 841
2378 /* Just check we can actually access the module */842 return 0;
2379 cal_get_hwinfo(dev);
2380 843
2381 pm_runtime_put_sync(&pdev->dev);844error_context:
845 for (i = 0; i < ARRAY_SIZE(cal->ctx); i++) {
846 ctx = cal->ctx[i];
847 if (ctx)
848 cal_ctx_v4l2_cleanup(ctx);
849 }
2382 850
2383 return 0;851 cal_media_cleanup(cal);
2384 852
2385runtime_disable:853error_camerarx:
2386 vb2_dma_contig_clear_max_seg_size(&pdev->dev);854 for (i = 0; i < ARRAY_SIZE(cal->phy); i++)
855 cal_camerarx_destroy(cal->phy[i]);
2387 856
857error_pm_runtime:
2388 pm_runtime_disable(&pdev->dev);858 pm_runtime_disable(&pdev->dev);
2389 for (i = 0; i < CAL_NUM_CONTEXT; i++) {
2390 ctx = dev->ctx[i];
2391 if (ctx) {
2392 v4l2_async_notifier_unregister(&ctx->notifier);
2393 v4l2_async_notifier_cleanup(&ctx->notifier);
2394 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2395 v4l2_device_unregister(&ctx->v4l2_dev);
2396 }
2397 }
2398 859
2399 return ret;860 return ret;
2400}861}
2401 862
2402static int cal_remove(struct platform_device *pdev)863static int cal_remove(struct platform_device *pdev)
2403{864{
2404 struct cal_dev *dev =865 struct cal_dev *cal = platform_get_drvdata(pdev);
2405 (struct cal_dev *)platform_get_drvdata(pdev);866 unsigned int i;
2406 struct cal_ctx *ctx;
2407 int i;
2408 867
2409 cal_dbg(1, dev, "Removing %s\n", CAL_MODULE_NAME);868 cal_dbg(1, cal, "Removing %s\n", CAL_MODULE_NAME);
2410 869
2411 pm_runtime_get_sync(&pdev->dev);870 pm_runtime_get_sync(&pdev->dev);
2412 871
2413 for (i = 0; i < CAL_NUM_CONTEXT; i++) {872 cal_media_unregister(cal);
2414 ctx = dev->ctx[i];873
2415 if (ctx) {874 for (i = 0; i < ARRAY_SIZE(cal->phy); i++) {
2416 ctx_dbg(1, ctx, "unregistering %s\n",875 if (cal->phy[i])
2417 video_device_node_name(&ctx->vdev));876 cal_camerarx_disable(cal->phy[i]);
2418 camerarx_phy_disable(ctx);
2419 v4l2_async_notifier_unregister(&ctx->notifier);
2420 v4l2_async_notifier_cleanup(&ctx->notifier);
2421 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2422 v4l2_device_unregister(&ctx->v4l2_dev);
2423 video_unregister_device(&ctx->vdev);
2424 }
2425 }877 }
2426 878
879 cal_media_cleanup(cal);
880
881 for (i = 0; i < ARRAY_SIZE(cal->phy); i++)
882 cal_camerarx_destroy(cal->phy[i]);
883
2427 pm_runtime_put_sync(&pdev->dev);884 pm_runtime_put_sync(&pdev->dev);
2428 pm_runtime_disable(&pdev->dev);885 pm_runtime_disable(&pdev->dev);
2429 886
2430 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
2431
2432 return 0;887 return 0;
2433}888}
2434 889
2435static int cal_runtime_resume(struct device *dev)890static int cal_runtime_resume(struct device *dev)
2436{891{
2437 struct cal_dev *caldev = dev_get_drvdata(dev);892 struct cal_dev *cal = dev_get_drvdata(dev);
2438 893
2439 if (caldev->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {894 if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
2440 /*895 /*
2441 * Apply errata on both port everytime we (re-)enable896 * Apply errata on both port everytime we (re-)enable
2442 * the clock897 * the clock
2443 */898 */
2444 i913_errata(caldev, 0);899 cal_camerarx_i913_errata(cal->phy[0]);
2445 i913_errata(caldev, 1);900 cal_camerarx_i913_errata(cal->phy[1]);
2446 }901 }
2447 902
2448 return 0;903 return 0;
drivers/media/platform/ti-vpe/cal.h+267−0
@@ -0,0 +1,267 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * TI Camera Access Layer (CAL)
4 *
5 * Copyright (c) 2015-2020 Texas Instruments Inc.
6 *
7 * Authors:
8 * Benoit Parrot <bparrot@ti.com>
9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 */
11#ifndef __TI_CAL_H__
12#define __TI_CAL_H__
13
14#include <linux/bitfield.h>
15#include <linux/io.h>
16#include <linux/list.h>
17#include <linux/mutex.h>
18#include <linux/spinlock.h>
19#include <linux/videodev2.h>
20
21#include <media/media-device.h>
22#include <media/v4l2-async.h>
23#include <media/v4l2-ctrls.h>
24#include <media/v4l2-dev.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-fwnode.h>
27#include <media/videobuf2-v4l2.h>
28
29#define CAL_MODULE_NAME "cal"
30#define CAL_NUM_CONTEXT 2
31#define CAL_NUM_CSI2_PORTS 2
32
33#define MAX_WIDTH_BYTES (8192 * 8)
34#define MAX_HEIGHT_LINES 16383
35
36struct device;
37struct device_node;
38struct resource;
39struct regmap;
40struct regmap_fied;
41struct v4l2_subdev;
42
43/* CTRL_CORE_CAMERRX_CONTROL register field id */
44enum cal_camerarx_field {
45 F_CTRLCLKEN,
46 F_CAMMODE,
47 F_LANEENABLE,
48 F_CSI_MODE,
49 F_MAX_FIELDS,
50};
51
52struct cal_fmt {
53 u32 fourcc;
54 u32 code;
55 /* Bits per pixel */
56 u8 bpp;
57};
58
59/* buffer for one video frame */
60struct cal_buffer {
61 /* common v4l buffer stuff -- must be first */
62 struct vb2_v4l2_buffer vb;
63 struct list_head list;
64};
65
66struct cal_dmaqueue {
67 struct list_head active;
68};
69
70struct cal_camerarx_data {
71 struct {
72 unsigned int lsb;
73 unsigned int msb;
74 } fields[F_MAX_FIELDS];
75 unsigned int num_lanes;
76};
77
78struct cal_data {
79 const struct cal_camerarx_data *camerarx;
80 unsigned int num_csi2_phy;
81 unsigned int flags;
82};
83
84/*
85 * The Camera Adaptation Layer (CAL) module is paired with one or more complex
86 * I/O PHYs (CAMERARX). It contains multiple instances of CSI-2, processing and
87 * DMA contexts.
88 *
89 * The cal_dev structure represents the whole subsystem, including the CAL and
90 * the CAMERARX instances. Instances of struct cal_dev are named cal through the
91 * driver.
92 *
93 * The cal_camerarx structure represents one CAMERARX instance. Instances of
94 * cal_camerarx are named phy through the driver.
95 *
96 * The cal_ctx structure represents the combination of one CSI-2 context, one
97 * processing context and one DMA context. Instance of struct cal_ctx are named
98 * ctx through the driver.
99 */
100
101struct cal_camerarx {
102 void __iomem *base;
103 struct resource *res;
104 struct device *dev;
105 struct regmap_field *fields[F_MAX_FIELDS];
106
107 struct cal_dev *cal;
108 unsigned int instance;
109
110 struct v4l2_fwnode_endpoint endpoint;
111 struct device_node *sensor_node;
112 struct v4l2_subdev *sensor;
113};
114
115struct cal_dev {
116 struct clk *fclk;
117 int irq;
118 void __iomem *base;
119 struct resource *res;
120 struct device *dev;
121
122 const struct cal_data *data;
123 u32 revision;
124
125 /* Control Module handle */
126 struct regmap *syscon_camerrx;
127 u32 syscon_camerrx_offset;
128
129 /* Camera Core Module handle */
130 struct cal_camerarx *phy[CAL_NUM_CSI2_PORTS];
131
132 struct cal_ctx *ctx[CAL_NUM_CONTEXT];
133
134 struct media_device mdev;
135 struct v4l2_device v4l2_dev;
136 struct v4l2_async_notifier notifier;
137};
138
139/*
140 * There is one cal_ctx structure for each camera core context.
141 */
142struct cal_ctx {
143 struct v4l2_ctrl_handler ctrl_handler;
144 struct video_device vdev;
145 struct media_pad pad;
146
147 struct cal_dev *cal;
148 struct cal_camerarx *phy;
149
150 /* v4l2_ioctl mutex */
151 struct mutex mutex;
152 /* v4l2 buffers lock */
153 spinlock_t slock;
154
155 struct cal_dmaqueue vidq;
156
157 /* video capture */
158 const struct cal_fmt *fmt;
159 /* Used to store current pixel format */
160 struct v4l2_format v_fmt;
161 /* Used to store current mbus frame format */
162 struct v4l2_mbus_framefmt m_fmt;
163
164 /* Current subdev enumerated format */
165 const struct cal_fmt **active_fmt;
166 unsigned int num_active_fmt;
167
168 unsigned int sequence;
169 struct vb2_queue vb_vidq;
170 unsigned int index;
171 unsigned int cport;
172
173 /* Pointer pointing to current v4l2_buffer */
174 struct cal_buffer *cur_frm;
175 /* Pointer pointing to next v4l2_buffer */
176 struct cal_buffer *next_frm;
177
178 bool dma_act;
179};
180
181extern unsigned int cal_debug;
182extern int cal_video_nr;
183
184#define cal_dbg(level, cal, fmt, arg...) \
185 do { \
186 if (cal_debug >= (level)) \
187 dev_printk(KERN_DEBUG, (cal)->dev, fmt, ##arg); \
188 } while (0)
189#define cal_info(cal, fmt, arg...) \
190 dev_info((cal)->dev, fmt, ##arg)
191#define cal_err(cal, fmt, arg...) \
192 dev_err((cal)->dev, fmt, ##arg)
193
194#define ctx_dbg(level, ctx, fmt, arg...) \
195 cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg)
196#define ctx_info(ctx, fmt, arg...) \
197 cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg)
198#define ctx_err(ctx, fmt, arg...) \
199 cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg)
200
201#define phy_dbg(level, phy, fmt, arg...) \
202 cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
203#define phy_info(phy, fmt, arg...) \
204 cal_info((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
205#define phy_err(phy, fmt, arg...) \
206 cal_err((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
207
208static inline u32 cal_read(struct cal_dev *cal, u32 offset)
209{
210 return ioread32(cal->base + offset);
211}
212
213static inline void cal_write(struct cal_dev *cal, u32 offset, u32 val)
214{
215 iowrite32(val, cal->base + offset);
216}
217
218static inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
219{
220 return FIELD_GET(mask, cal_read(cal, offset));
221}
222
223static inline void cal_write_field(struct cal_dev *cal, u32 offset, u32 value,
224 u32 mask)
225{
226 u32 val = cal_read(cal, offset);
227
228 val &= ~mask;
229 val |= FIELD_PREP(mask, value);
230 cal_write(cal, offset, val);
231}
232
233static inline void cal_set_field(u32 *valp, u32 field, u32 mask)
234{
235 u32 val = *valp;
236
237 val &= ~mask;
238 val |= (field << __ffs(mask)) & mask;
239 *valp = val;
240}
241
242void cal_quickdump_regs(struct cal_dev *cal);
243
244void cal_camerarx_disable(struct cal_camerarx *phy);
245int cal_camerarx_start(struct cal_camerarx *phy, const struct cal_fmt *fmt);
246void cal_camerarx_stop(struct cal_camerarx *phy);
247void cal_camerarx_enable_irqs(struct cal_camerarx *phy);
248void cal_camerarx_disable_irqs(struct cal_camerarx *phy);
249void cal_camerarx_ppi_enable(struct cal_camerarx *phy);
250void cal_camerarx_ppi_disable(struct cal_camerarx *phy);
251void cal_camerarx_i913_errata(struct cal_camerarx *phy);
252struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
253 unsigned int instance);
254void cal_camerarx_destroy(struct cal_camerarx *phy);
255
256void cal_ctx_csi2_config(struct cal_ctx *ctx);
257void cal_ctx_pix_proc_config(struct cal_ctx *ctx);
258void cal_ctx_wr_dma_config(struct cal_ctx *ctx, unsigned int width,
259 unsigned int height);
260void cal_ctx_wr_dma_addr(struct cal_ctx *ctx, unsigned int dmaaddr);
261
262int cal_ctx_v4l2_register(struct cal_ctx *ctx);
263void cal_ctx_v4l2_unregister(struct cal_ctx *ctx);
264int cal_ctx_v4l2_init(struct cal_ctx *ctx);
265void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx);
266
267#endif /* __TI_CAL_H__ */
drivers/media/platform/ti-vpe/cal_regs.h+36−38
@@ -34,19 +34,17 @@ · 33 unmodified lines
34 */34 */
35#define DRA72_CAL_PRE_ES2_LDO_DISABLE BIT(0)35#define DRA72_CAL_PRE_ES2_LDO_DISABLE BIT(0)
36 36
37#define CAL_NUM_CSI2_PORTS 2
38
39/* CAL register offsets */37/* CAL register offsets */
40 38
41#define CAL_HL_REVISION 0x000039#define CAL_HL_REVISION 0x0000
42#define CAL_HL_HWINFO 0x000440#define CAL_HL_HWINFO 0x0004
43#define CAL_HL_SYSCONFIG 0x001041#define CAL_HL_SYSCONFIG 0x0010
44#define CAL_HL_IRQ_EOI 0x001c42#define CAL_HL_IRQ_EOI 0x001c
45#define CAL_HL_IRQSTATUS_RAW(m) (0x20U + ((m-1) * 0x10U))43#define CAL_HL_IRQSTATUS_RAW(m) (0x20U + (m) * 0x10U)
46#define CAL_HL_IRQSTATUS(m) (0x24U + ((m-1) * 0x10U))44#define CAL_HL_IRQSTATUS(m) (0x24U + (m) * 0x10U)
47#define CAL_HL_IRQENABLE_SET(m) (0x28U + ((m-1) * 0x10U))45#define CAL_HL_IRQENABLE_SET(m) (0x28U + (m) * 0x10U)
48#define CAL_HL_IRQENABLE_CLR(m) (0x2cU + ((m-1) * 0x10U))46#define CAL_HL_IRQENABLE_CLR(m) (0x2cU + (m) * 0x10U)
49#define CAL_PIX_PROC(m) (0xc0U + ((m-1) * 0x4U))47#define CAL_PIX_PROC(m) (0xc0U + (m) * 0x4U)
50#define CAL_CTRL 0x10048#define CAL_CTRL 0x100
51#define CAL_CTRL1 0x10449#define CAL_CTRL1 0x104
52#define CAL_LINE_NUMBER_EVT 0x10850#define CAL_LINE_NUMBER_EVT 0x108
@@ -62,34 +60,34 @@ · 9 unmodified lines
62#define CAL_RD_DMA_INIT_ADDR 0x15460#define CAL_RD_DMA_INIT_ADDR 0x154
63#define CAL_RD_DMA_INIT_OFST 0x16861#define CAL_RD_DMA_INIT_OFST 0x168
64#define CAL_RD_DMA_CTRL2 0x16c62#define CAL_RD_DMA_CTRL2 0x16c
65#define CAL_WR_DMA_CTRL(m) (0x200U + ((m-1) * 0x10U))63#define CAL_WR_DMA_CTRL(m) (0x200U + (m) * 0x10U)
66#define CAL_WR_DMA_ADDR(m) (0x204U + ((m-1) * 0x10U))64#define CAL_WR_DMA_ADDR(m) (0x204U + (m) * 0x10U)
67#define CAL_WR_DMA_OFST(m) (0x208U + ((m-1) * 0x10U))65#define CAL_WR_DMA_OFST(m) (0x208U + (m) * 0x10U)
68#define CAL_WR_DMA_XSIZE(m) (0x20cU + ((m-1) * 0x10U))66#define CAL_WR_DMA_XSIZE(m) (0x20cU + (m) * 0x10U)
69#define CAL_CSI2_PPI_CTRL(m) (0x300U + ((m-1) * 0x80U))67#define CAL_CSI2_PPI_CTRL(m) (0x300U + (m) * 0x80U)
70#define CAL_CSI2_COMPLEXIO_CFG(m) (0x304U + ((m-1) * 0x80U))68#define CAL_CSI2_COMPLEXIO_CFG(m) (0x304U + (m) * 0x80U)
71#define CAL_CSI2_COMPLEXIO_IRQSTATUS(m) (0x308U + ((m-1) * 0x80U))69#define CAL_CSI2_COMPLEXIO_IRQSTATUS(m) (0x308U + (m) * 0x80U)
72#define CAL_CSI2_SHORT_PACKET(m) (0x30cU + ((m-1) * 0x80U))70#define CAL_CSI2_SHORT_PACKET(m) (0x30cU + (m) * 0x80U)
73#define CAL_CSI2_COMPLEXIO_IRQENABLE(m) (0x310U + ((m-1) * 0x80U))71#define CAL_CSI2_COMPLEXIO_IRQENABLE(m) (0x310U + (m) * 0x80U)
74#define CAL_CSI2_TIMING(m) (0x314U + ((m-1) * 0x80U))72#define CAL_CSI2_TIMING(m) (0x314U + (m) * 0x80U)
75#define CAL_CSI2_VC_IRQENABLE(m) (0x318U + ((m-1) * 0x80U))73#define CAL_CSI2_VC_IRQENABLE(m) (0x318U + (m) * 0x80U)
76#define CAL_CSI2_VC_IRQSTATUS(m) (0x328U + ((m-1) * 0x80U))74#define CAL_CSI2_VC_IRQSTATUS(m) (0x328U + (m) * 0x80U)
77#define CAL_CSI2_CTX0(m) (0x330U + ((m-1) * 0x80U))75#define CAL_CSI2_CTX0(m) (0x330U + (m) * 0x80U)
78#define CAL_CSI2_CTX1(m) (0x334U + ((m-1) * 0x80U))76#define CAL_CSI2_CTX1(m) (0x334U + (m) * 0x80U)
79#define CAL_CSI2_CTX2(m) (0x338U + ((m-1) * 0x80U))77#define CAL_CSI2_CTX2(m) (0x338U + (m) * 0x80U)
80#define CAL_CSI2_CTX3(m) (0x33cU + ((m-1) * 0x80U))78#define CAL_CSI2_CTX3(m) (0x33cU + (m) * 0x80U)
81#define CAL_CSI2_CTX4(m) (0x340U + ((m-1) * 0x80U))79#define CAL_CSI2_CTX4(m) (0x340U + (m) * 0x80U)
82#define CAL_CSI2_CTX5(m) (0x344U + ((m-1) * 0x80U))80#define CAL_CSI2_CTX5(m) (0x344U + (m) * 0x80U)
83#define CAL_CSI2_CTX6(m) (0x348U + ((m-1) * 0x80U))81#define CAL_CSI2_CTX6(m) (0x348U + (m) * 0x80U)
84#define CAL_CSI2_CTX7(m) (0x34cU + ((m-1) * 0x80U))82#define CAL_CSI2_CTX7(m) (0x34cU + (m) * 0x80U)
85#define CAL_CSI2_STATUS0(m) (0x350U + ((m-1) * 0x80U))83#define CAL_CSI2_STATUS0(m) (0x350U + (m) * 0x80U)
86#define CAL_CSI2_STATUS1(m) (0x354U + ((m-1) * 0x80U))84#define CAL_CSI2_STATUS1(m) (0x354U + (m) * 0x80U)
87#define CAL_CSI2_STATUS2(m) (0x358U + ((m-1) * 0x80U))85#define CAL_CSI2_STATUS2(m) (0x358U + (m) * 0x80U)
88#define CAL_CSI2_STATUS3(m) (0x35cU + ((m-1) * 0x80U))86#define CAL_CSI2_STATUS3(m) (0x35cU + (m) * 0x80U)
89#define CAL_CSI2_STATUS4(m) (0x360U + ((m-1) * 0x80U))87#define CAL_CSI2_STATUS4(m) (0x360U + (m) * 0x80U)
90#define CAL_CSI2_STATUS5(m) (0x364U + ((m-1) * 0x80U))88#define CAL_CSI2_STATUS5(m) (0x364U + (m) * 0x80U)
91#define CAL_CSI2_STATUS6(m) (0x368U + ((m-1) * 0x80U))89#define CAL_CSI2_STATUS6(m) (0x368U + (m) * 0x80U)
92#define CAL_CSI2_STATUS7(m) (0x36cU + ((m-1) * 0x80U))90#define CAL_CSI2_STATUS7(m) (0x36cU + (m) * 0x80U)
93 91
94/* CAL CSI2 PHY register offsets */92/* CAL CSI2 PHY register offsets */
95#define CAL_CSI2_PHY_REG0 0x00093#define CAL_CSI2_PHY_REG0 0x000
@@ -141,12 +139,12 @@ · 45 unmodified lines
141#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0 0139#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0 0
142#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0 0140#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0 0
143 141
144#define CAL_HL_IRQ_MASK(m) BIT((m) - 1)142#define CAL_HL_IRQ_MASK(m) BIT(m)
145 143
146#define CAL_HL_IRQ_OCPO_ERR_MASK BIT(6)144#define CAL_HL_IRQ_OCPO_ERR_MASK BIT(6)
147 145
148#define CAL_HL_IRQ_CIO_MASK(i) BIT(16 + ((i) - 1) * 8)146#define CAL_HL_IRQ_CIO_MASK(i) BIT(16 + (i) * 8)
149#define CAL_HL_IRQ_VC_MASK(i) BIT(17 + ((i) - 1) * 8)147#define CAL_HL_IRQ_VC_MASK(i) BIT(17 + (i) * 8)
150 148
151#define CAL_PIX_PROC_EN_MASK BIT(0)149#define CAL_PIX_PROC_EN_MASK BIT(0)
152#define CAL_PIX_PROC_EXTRACT_MASK GENMASK(4, 1)150#define CAL_PIX_PROC_EXTRACT_MASK GENMASK(4, 1)
drivers/media/platform/ti-vpe/vpe.c+1−1
@@ -1576,7 +1576,7 @@ static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f) · 1575 unmodified lines
1576 1576
1577 *f = q_data->format;1577 *f = q_data->format;
1578 1578
1579 if (!V4L2_TYPE_IS_OUTPUT(f->type)) {1579 if (V4L2_TYPE_IS_CAPTURE(f->type)) {
1580 struct vpe_q_data *s_q_data;1580 struct vpe_q_data *s_q_data;
1581 struct v4l2_pix_format_mplane *spix;1581 struct v4l2_pix_format_mplane *spix;
1582 1582
drivers/media/platform/vsp1/vsp1_dl.c+2−0
@@ -431,6 +431,8 @@ vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type, · 430 unmodified lines
431 if (!pool)431 if (!pool)
432 return NULL;432 return NULL;
433 433
434 pool->vsp1 = vsp1;
435
434 spin_lock_init(&pool->lock);436 spin_lock_init(&pool->lock);
435 INIT_LIST_HEAD(&pool->free);437 INIT_LIST_HEAD(&pool->free);
436 438
drivers/media/platform/xilinx/Kconfig+7−0
@@ -12,6 +12,13 @@ config VIDEO_XILINX · 11 unmodified lines
12 12
13if VIDEO_XILINX13if VIDEO_XILINX
14 14
15config VIDEO_XILINX_CSI2RXSS
16 tristate "Xilinx CSI-2 Rx Subsystem"
17 help
18 Driver for Xilinx MIPI CSI-2 Rx Subsystem. This is a V4L sub-device
19 based driver that takes input from CSI-2 Tx source and converts
20 it into an AXI4-Stream.
21
15config VIDEO_XILINX_TPG22config VIDEO_XILINX_TPG
16 tristate "Xilinx Video Test Pattern Generator"23 tristate "Xilinx Video Test Pattern Generator"
17 depends on VIDEO_XILINX24 depends on VIDEO_XILINX
drivers/media/platform/xilinx/Makefile+1−0
@@ -3,5 +3,6 @@ · 2 unmodified lines
3xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o3xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
4 4
5obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o5obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
6obj-$(CONFIG_VIDEO_XILINX_CSI2RXSS) += xilinx-csi2rxss.o
6obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o7obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
7obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o8obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
drivers/media/platform/xilinx/xilinx-csi2rxss.c+1111−0
@@ -0,0 +1,1111 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for Xilinx MIPI CSI-2 Rx Subsystem
4 *
5 * Copyright (C) 2016 - 2020 Xilinx, Inc.
6 *
7 * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
8 *
9 */
10#include <linux/clk.h>
11#include <linux/delay.h>
12#include <linux/gpio/consumer.h>
13#include <linux/interrupt.h>
14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/of.h>
17#include <linux/of_irq.h>
18#include <linux/platform_device.h>
19#include <linux/v4l2-subdev.h>
20#include <media/media-entity.h>
21#include <media/v4l2-common.h>
22#include <media/v4l2-ctrls.h>
23#include <media/v4l2-fwnode.h>
24#include <media/v4l2-subdev.h>
25#include "xilinx-vip.h"
26
27/* Register register map */
28#define XCSI_CCR_OFFSET 0x00
29#define XCSI_CCR_SOFTRESET BIT(1)
30#define XCSI_CCR_ENABLE BIT(0)
31
32#define XCSI_PCR_OFFSET 0x04
33#define XCSI_PCR_MAXLANES_MASK GENMASK(4, 3)
34#define XCSI_PCR_ACTLANES_MASK GENMASK(1, 0)
35
36#define XCSI_CSR_OFFSET 0x10
37#define XCSI_CSR_PKTCNT GENMASK(31, 16)
38#define XCSI_CSR_SPFIFOFULL BIT(3)
39#define XCSI_CSR_SPFIFONE BIT(2)
40#define XCSI_CSR_SLBF BIT(1)
41#define XCSI_CSR_RIPCD BIT(0)
42
43#define XCSI_GIER_OFFSET 0x20
44#define XCSI_GIER_GIE BIT(0)
45
46#define XCSI_ISR_OFFSET 0x24
47#define XCSI_IER_OFFSET 0x28
48
49#define XCSI_ISR_FR BIT(31)
50#define XCSI_ISR_VCXFE BIT(30)
51#define XCSI_ISR_WCC BIT(22)
52#define XCSI_ISR_ILC BIT(21)
53#define XCSI_ISR_SPFIFOF BIT(20)
54#define XCSI_ISR_SPFIFONE BIT(19)
55#define XCSI_ISR_SLBF BIT(18)
56#define XCSI_ISR_STOP BIT(17)
57#define XCSI_ISR_SOTERR BIT(13)
58#define XCSI_ISR_SOTSYNCERR BIT(12)
59#define XCSI_ISR_ECC2BERR BIT(11)
60#define XCSI_ISR_ECC1BERR BIT(10)
61#define XCSI_ISR_CRCERR BIT(9)
62#define XCSI_ISR_DATAIDERR BIT(8)
63#define XCSI_ISR_VC3FSYNCERR BIT(7)
64#define XCSI_ISR_VC3FLVLERR BIT(6)
65#define XCSI_ISR_VC2FSYNCERR BIT(5)
66#define XCSI_ISR_VC2FLVLERR BIT(4)
67#define XCSI_ISR_VC1FSYNCERR BIT(3)
68#define XCSI_ISR_VC1FLVLERR BIT(2)
69#define XCSI_ISR_VC0FSYNCERR BIT(1)
70#define XCSI_ISR_VC0FLVLERR BIT(0)
71
72#define XCSI_ISR_ALLINTR_MASK (0xc07e3fff)
73
74/*
75 * Removed VCXFE mask as it doesn't exist in IER
76 * Removed STOP state irq as this will keep driver in irq handler only
77 */
78#define XCSI_IER_INTR_MASK (XCSI_ISR_ALLINTR_MASK &\
79 ~(XCSI_ISR_STOP | XCSI_ISR_VCXFE))
80
81#define XCSI_SPKTR_OFFSET 0x30
82#define XCSI_SPKTR_DATA GENMASK(23, 8)
83#define XCSI_SPKTR_VC GENMASK(7, 6)
84#define XCSI_SPKTR_DT GENMASK(5, 0)
85#define XCSI_SPKT_FIFO_DEPTH 31
86
87#define XCSI_VCXR_OFFSET 0x34
88#define XCSI_VCXR_VCERR GENMASK(23, 0)
89#define XCSI_VCXR_FSYNCERR BIT(1)
90#define XCSI_VCXR_FLVLERR BIT(0)
91
92#define XCSI_CLKINFR_OFFSET 0x3C
93#define XCSI_CLKINFR_STOP BIT(1)
94
95#define XCSI_DLXINFR_OFFSET 0x40
96#define XCSI_DLXINFR_STOP BIT(5)
97#define XCSI_DLXINFR_SOTERR BIT(1)
98#define XCSI_DLXINFR_SOTSYNCERR BIT(0)
99#define XCSI_MAXDL_COUNT 0x4
100
101#define XCSI_VCXINF1R_OFFSET 0x60
102#define XCSI_VCXINF1R_LINECOUNT GENMASK(31, 16)
103#define XCSI_VCXINF1R_LINECOUNT_SHIFT 16
104#define XCSI_VCXINF1R_BYTECOUNT GENMASK(15, 0)
105
106#define XCSI_VCXINF2R_OFFSET 0x64
107#define XCSI_VCXINF2R_DT GENMASK(5, 0)
108#define XCSI_MAXVCX_COUNT 16
109
110/*
111 * Sink pad connected to sensor source pad.
112 * Source pad connected to next module like demosaic.
113 */
114#define XCSI_MEDIA_PADS 2
115#define XCSI_DEFAULT_WIDTH 1920
116#define XCSI_DEFAULT_HEIGHT 1080
117
118/* MIPI CSI-2 Data Types from spec */
119#define XCSI_DT_YUV4228B 0x1e
120#define XCSI_DT_YUV42210B 0x1f
121#define XCSI_DT_RGB444 0x20
122#define XCSI_DT_RGB555 0x21
123#define XCSI_DT_RGB565 0x22
124#define XCSI_DT_RGB666 0x23
125#define XCSI_DT_RGB888 0x24
126#define XCSI_DT_RAW6 0x28
127#define XCSI_DT_RAW7 0x29
128#define XCSI_DT_RAW8 0x2a
129#define XCSI_DT_RAW10 0x2b
130#define XCSI_DT_RAW12 0x2c
131#define XCSI_DT_RAW14 0x2d
132#define XCSI_DT_RAW16 0x2e
133#define XCSI_DT_RAW20 0x2f
134
135#define XCSI_VCX_START 4
136#define XCSI_MAX_VC 4
137#define XCSI_MAX_VCX 16
138
139#define XCSI_NEXTREG_OFFSET 4
140
141/* There are 2 events frame sync and frame level error per VC */
142#define XCSI_VCX_NUM_EVENTS ((XCSI_MAX_VCX - XCSI_MAX_VC) * 2)
143
144/**
145 * struct xcsi2rxss_event - Event log structure
146 * @mask: Event mask
147 * @name: Name of the event
148 */
149struct xcsi2rxss_event {
150 u32 mask;
151 const char *name;
152};
153
154static const struct xcsi2rxss_event xcsi2rxss_events[] = {
155 { XCSI_ISR_FR, "Frame Received" },
156 { XCSI_ISR_VCXFE, "VCX Frame Errors" },
157 { XCSI_ISR_WCC, "Word Count Errors" },
158 { XCSI_ISR_ILC, "Invalid Lane Count Error" },
159 { XCSI_ISR_SPFIFOF, "Short Packet FIFO OverFlow Error" },
160 { XCSI_ISR_SPFIFONE, "Short Packet FIFO Not Empty" },
161 { XCSI_ISR_SLBF, "Streamline Buffer Full Error" },
162 { XCSI_ISR_STOP, "Lane Stop State" },
163 { XCSI_ISR_SOTERR, "SOT Error" },
164 { XCSI_ISR_SOTSYNCERR, "SOT Sync Error" },
165 { XCSI_ISR_ECC2BERR, "2 Bit ECC Unrecoverable Error" },
166 { XCSI_ISR_ECC1BERR, "1 Bit ECC Recoverable Error" },
167 { XCSI_ISR_CRCERR, "CRC Error" },
168 { XCSI_ISR_DATAIDERR, "Data Id Error" },
169 { XCSI_ISR_VC3FSYNCERR, "Virtual Channel 3 Frame Sync Error" },
170 { XCSI_ISR_VC3FLVLERR, "Virtual Channel 3 Frame Level Error" },
171 { XCSI_ISR_VC2FSYNCERR, "Virtual Channel 2 Frame Sync Error" },
172 { XCSI_ISR_VC2FLVLERR, "Virtual Channel 2 Frame Level Error" },
173 { XCSI_ISR_VC1FSYNCERR, "Virtual Channel 1 Frame Sync Error" },
174 { XCSI_ISR_VC1FLVLERR, "Virtual Channel 1 Frame Level Error" },
175 { XCSI_ISR_VC0FSYNCERR, "Virtual Channel 0 Frame Sync Error" },
176 { XCSI_ISR_VC0FLVLERR, "Virtual Channel 0 Frame Level Error" }
177};
178
179#define XCSI_NUM_EVENTS ARRAY_SIZE(xcsi2rxss_events)
180
181/*
182 * This table provides a mapping between CSI-2 Data type
183 * and media bus formats
184 */
185static const u32 xcsi2dt_mbus_lut[][2] = {
186 { XCSI_DT_YUV4228B, MEDIA_BUS_FMT_UYVY8_1X16 },
187 { XCSI_DT_YUV42210B, MEDIA_BUS_FMT_UYVY10_1X20 },
188 { XCSI_DT_RGB444, 0 },
189 { XCSI_DT_RGB555, 0 },
190 { XCSI_DT_RGB565, 0 },
191 { XCSI_DT_RGB666, 0 },
192 { XCSI_DT_RGB888, MEDIA_BUS_FMT_RBG888_1X24 },
193 { XCSI_DT_RAW6, 0 },
194 { XCSI_DT_RAW7, 0 },
195 { XCSI_DT_RAW8, MEDIA_BUS_FMT_SRGGB8_1X8 },
196 { XCSI_DT_RAW8, MEDIA_BUS_FMT_SBGGR8_1X8 },
197 { XCSI_DT_RAW8, MEDIA_BUS_FMT_SGBRG8_1X8 },
198 { XCSI_DT_RAW8, MEDIA_BUS_FMT_SGRBG8_1X8 },
199 { XCSI_DT_RAW10, MEDIA_BUS_FMT_SRGGB10_1X10 },
200 { XCSI_DT_RAW10, MEDIA_BUS_FMT_SBGGR10_1X10 },
201 { XCSI_DT_RAW10, MEDIA_BUS_FMT_SGBRG10_1X10 },
202 { XCSI_DT_RAW10, MEDIA_BUS_FMT_SGRBG10_1X10 },
203 { XCSI_DT_RAW12, MEDIA_BUS_FMT_SRGGB12_1X12 },
204 { XCSI_DT_RAW12, MEDIA_BUS_FMT_SBGGR12_1X12 },
205 { XCSI_DT_RAW12, MEDIA_BUS_FMT_SGBRG12_1X12 },
206 { XCSI_DT_RAW12, MEDIA_BUS_FMT_SGRBG12_1X12 },
207 { XCSI_DT_RAW16, MEDIA_BUS_FMT_SRGGB16_1X16 },
208 { XCSI_DT_RAW16, MEDIA_BUS_FMT_SBGGR16_1X16 },
209 { XCSI_DT_RAW16, MEDIA_BUS_FMT_SGBRG16_1X16 },
210 { XCSI_DT_RAW16, MEDIA_BUS_FMT_SGRBG16_1X16 },
211 { XCSI_DT_RAW20, 0 },
212};
213
214/**
215 * struct xcsi2rxss_state - CSI-2 Rx Subsystem device structure
216 * @subdev: The v4l2 subdev structure
217 * @format: Active V4L2 formats on each pad
218 * @default_format: Default V4L2 format
219 * @events: counter for events
220 * @vcx_events: counter for vcx_events
221 * @dev: Platform structure
222 * @rsubdev: Remote subdev connected to sink pad
223 * @rst_gpio: reset to video_aresetn
224 * @clks: array of clocks
225 * @iomem: Base address of subsystem
226 * @max_num_lanes: Maximum number of lanes present
227 * @datatype: Data type filter
228 * @lock: mutex for accessing this structure
229 * @pads: media pads
230 * @streaming: Flag for storing streaming state
231 * @enable_active_lanes: If number of active lanes can be modified
232 * @en_vcx: If more than 4 VC are enabled
233 *
234 * This structure contains the device driver related parameters
235 */
236struct xcsi2rxss_state {
237 struct v4l2_subdev subdev;
238 struct v4l2_mbus_framefmt format;
239 struct v4l2_mbus_framefmt default_format;
240 u32 events[XCSI_NUM_EVENTS];
241 u32 vcx_events[XCSI_VCX_NUM_EVENTS];
242 struct device *dev;
243 struct v4l2_subdev *rsubdev;
244 struct gpio_desc *rst_gpio;
245 struct clk_bulk_data *clks;
246 void __iomem *iomem;
247 u32 max_num_lanes;
248 u32 datatype;
249 /* used to protect access to this struct */
250 struct mutex lock;
251 struct media_pad pads[XCSI_MEDIA_PADS];
252 bool streaming;
253 bool enable_active_lanes;
254 bool en_vcx;
255};
256
257static const struct clk_bulk_data xcsi2rxss_clks[] = {
258 { .id = "lite_aclk" },
259 { .id = "video_aclk" },
260};
261
262static inline struct xcsi2rxss_state *
263to_xcsi2rxssstate(struct v4l2_subdev *subdev)
264{
265 return container_of(subdev, struct xcsi2rxss_state, subdev);
266}
267
268/*
269 * Register related operations
270 */
271static inline u32 xcsi2rxss_read(struct xcsi2rxss_state *xcsi2rxss, u32 addr)
272{
273 return ioread32(xcsi2rxss->iomem + addr);
274}
275
276static inline void xcsi2rxss_write(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
277 u32 value)
278{
279 iowrite32(value, xcsi2rxss->iomem + addr);
280}
281
282static inline void xcsi2rxss_clr(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
283 u32 clr)
284{
285 xcsi2rxss_write(xcsi2rxss, addr,
286 xcsi2rxss_read(xcsi2rxss, addr) & ~clr);
287}
288
289static inline void xcsi2rxss_set(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
290 u32 set)
291{
292 xcsi2rxss_write(xcsi2rxss, addr, xcsi2rxss_read(xcsi2rxss, addr) | set);
293}
294
295/*
296 * This function returns the nth mbus for a data type.
297 * In case of error, mbus code returned is 0.
298 */
299static u32 xcsi2rxss_get_nth_mbus(u32 dt, u32 n)
300{
301 unsigned int i;
302
303 for (i = 0; i < ARRAY_SIZE(xcsi2dt_mbus_lut); i++) {
304 if (xcsi2dt_mbus_lut[i][0] == dt) {
305 if (n-- == 0)
306 return xcsi2dt_mbus_lut[i][1];
307 }
308 }
309
310 return 0;
311}
312
313/* This returns the data type for a media bus format else 0 */
314static u32 xcsi2rxss_get_dt(u32 mbus)
315{
316 unsigned int i;
317
318 for (i = 0; i < ARRAY_SIZE(xcsi2dt_mbus_lut); i++) {
319 if (xcsi2dt_mbus_lut[i][1] == mbus)
320 return xcsi2dt_mbus_lut[i][0];
321 }
322
323 return 0;
324}
325
326/**
327 * xcsi2rxss_soft_reset - Does a soft reset of the MIPI CSI-2 Rx Subsystem
328 * @state: Xilinx CSI-2 Rx Subsystem structure pointer
329 *
330 * Core takes less than 100 video clock cycles to reset.
331 * So a larger timeout value is chosen for margin.
332 *
333 * Return: 0 - on success OR -ETIME if reset times out
334 */
335static int xcsi2rxss_soft_reset(struct xcsi2rxss_state *state)
336{
337 u32 timeout = 1000; /* us */
338
339 xcsi2rxss_set(state, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
340
341 while (xcsi2rxss_read(state, XCSI_CSR_OFFSET) & XCSI_CSR_RIPCD) {
342 if (timeout == 0) {
343 dev_err(state->dev, "soft reset timed out!\n");
344 return -ETIME;
345 }
346
347 timeout--;
348 udelay(1);
349 }
350
351 xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET);
352 return 0;
353}
354
355static void xcsi2rxss_hard_reset(struct xcsi2rxss_state *state)
356{
357 if (!state->rst_gpio)
358 return;
359
360 /* minimum of 40 dphy_clk_200M cycles */
361 gpiod_set_value_cansleep(state->rst_gpio, 1);
362 usleep_range(1, 2);
363 gpiod_set_value_cansleep(state->rst_gpio, 0);
364}
365
366static void xcsi2rxss_reset_event_counters(struct xcsi2rxss_state *state)
367{
368 unsigned int i;
369
370 for (i = 0; i < XCSI_NUM_EVENTS; i++)
371 state->events[i] = 0;
372
373 for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++)
374 state->vcx_events[i] = 0;
375}
376
377/* Print event counters */
378static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
379{
380 struct device *dev = state->dev;
381 unsigned int i;
382
383 for (i = 0; i < XCSI_NUM_EVENTS; i++) {
384 if (state->events[i] > 0) {
385 dev_info(dev, "%s events: %d\n",
386 xcsi2rxss_events[i].name,
387 state->events[i]);
388 }
389 }
390
391 if (state->en_vcx) {
392 for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
393 if (state->vcx_events[i] > 0) {
394 dev_info(dev,
395 "VC %d Frame %s err vcx events: %d\n",
396 (i / 2) + XCSI_VCX_START,
397 i & 1 ? "Sync" : "Level",
398 state->vcx_events[i]);
399 }
400 }
401 }
402}
403
404/**
405 * xcsi2rxss_log_status - Logs the status of the CSI-2 Receiver
406 * @sd: Pointer to V4L2 subdevice structure
407 *
408 * This function prints the current status of Xilinx MIPI CSI-2
409 *
410 * Return: 0 on success
411 */
412static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
413{
414 struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
415 struct device *dev = xcsi2rxss->dev;
416 u32 reg, data;
417 unsigned int i, max_vc;
418
419 mutex_lock(&xcsi2rxss->lock);
420
421 xcsi2rxss_log_counters(xcsi2rxss);
422
423 dev_info(dev, "***** Core Status *****\n");
424 data = xcsi2rxss_read(xcsi2rxss, XCSI_CSR_OFFSET);
425 dev_info(dev, "Short Packet FIFO Full = %s\n",
426 data & XCSI_CSR_SPFIFOFULL ? "true" : "false");
427 dev_info(dev, "Short Packet FIFO Not Empty = %s\n",
428 data & XCSI_CSR_SPFIFONE ? "true" : "false");
429 dev_info(dev, "Stream line buffer full = %s\n",
430 data & XCSI_CSR_SLBF ? "true" : "false");
431 dev_info(dev, "Soft reset/Core disable in progress = %s\n",
432 data & XCSI_CSR_RIPCD ? "true" : "false");
433
434 /* Clk & Lane Info */
435 dev_info(dev, "******** Clock Lane Info *********\n");
436 data = xcsi2rxss_read(xcsi2rxss, XCSI_CLKINFR_OFFSET);
437 dev_info(dev, "Clock Lane in Stop State = %s\n",
438 data & XCSI_CLKINFR_STOP ? "true" : "false");
439
440 dev_info(dev, "******** Data Lane Info *********\n");
441 dev_info(dev, "Lane\tSoT Error\tSoT Sync Error\tStop State\n");
442 reg = XCSI_DLXINFR_OFFSET;
443 for (i = 0; i < XCSI_MAXDL_COUNT; i++) {
444 data = xcsi2rxss_read(xcsi2rxss, reg);
445
446 dev_info(dev, "%d\t%s\t\t%s\t\t%s\n", i,
447 data & XCSI_DLXINFR_SOTERR ? "true" : "false",
448 data & XCSI_DLXINFR_SOTSYNCERR ? "true" : "false",
449 data & XCSI_DLXINFR_STOP ? "true" : "false");
450
451 reg += XCSI_NEXTREG_OFFSET;
452 }
453
454 /* Virtual Channel Image Information */
455 dev_info(dev, "********** Virtual Channel Info ************\n");
456 dev_info(dev, "VC\tLine Count\tByte Count\tData Type\n");
457 if (xcsi2rxss->en_vcx)
458 max_vc = XCSI_MAX_VCX;
459 else
460 max_vc = XCSI_MAX_VC;
461
462 reg = XCSI_VCXINF1R_OFFSET;
463 for (i = 0; i < max_vc; i++) {
464 u32 line_count, byte_count, data_type;
465
466 /* Get line and byte count from VCXINFR1 Register */
467 data = xcsi2rxss_read(xcsi2rxss, reg);
468 byte_count = data & XCSI_VCXINF1R_BYTECOUNT;
469 line_count = data & XCSI_VCXINF1R_LINECOUNT;
470 line_count >>= XCSI_VCXINF1R_LINECOUNT_SHIFT;
471
472 /* Get data type from VCXINFR2 Register */
473 reg += XCSI_NEXTREG_OFFSET;
474 data = xcsi2rxss_read(xcsi2rxss, reg);
475 data_type = data & XCSI_VCXINF2R_DT;
476
477 dev_info(dev, "%d\t%d\t\t%d\t\t0x%x\n", i, line_count,
478 byte_count, data_type);
479
480 /* Move to next pair of VC Info registers */
481 reg += XCSI_NEXTREG_OFFSET;
482 }
483
484 mutex_unlock(&xcsi2rxss->lock);
485
486 return 0;
487}
488
489static struct v4l2_subdev *xcsi2rxss_get_remote_subdev(struct media_pad *local)
490{
491 struct media_pad *remote;
492
493 remote = media_entity_remote_pad(local);
494 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
495 return NULL;
496
497 return media_entity_to_v4l2_subdev(remote->entity);
498}
499
500static int xcsi2rxss_start_stream(struct xcsi2rxss_state *state)
501{
502 int ret = 0;
503
504 /* enable core */
505 xcsi2rxss_set(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
506
507 ret = xcsi2rxss_soft_reset(state);
508 if (ret) {
509 state->streaming = false;
510 return ret;
511 }
512
513 /* enable interrupts */
514 xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
515 xcsi2rxss_write(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
516 xcsi2rxss_set(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
517
518 state->streaming = true;
519
520 state->rsubdev =
521 xcsi2rxss_get_remote_subdev(&state->pads[XVIP_PAD_SINK]);
522
523 ret = v4l2_subdev_call(state->rsubdev, video, s_stream, 1);
524 if (ret) {
525 /* disable interrupts */
526 xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
527 xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
528
529 /* disable core */
530 xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
531 state->streaming = false;
532 }
533
534 return ret;
535}
536
537static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *state)
538{
539 v4l2_subdev_call(state->rsubdev, video, s_stream, 0);
540
541 /* disable interrupts */
542 xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
543 xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
544
545 /* disable core */
546 xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
547 state->streaming = false;
548}
549
550/**
551 * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
552 * @irq: IRQ number
553 * @data: Pointer to device state
554 *
555 * In the interrupt handler, a list of event counters are updated for
556 * corresponding interrupts. This is useful to get status / debug.
557 *
558 * Return: IRQ_HANDLED after handling interrupts
559 */
560static irqreturn_t xcsi2rxss_irq_handler(int irq, void *data)
561{
562 struct xcsi2rxss_state *state = (struct xcsi2rxss_state *)data;
563 struct device *dev = state->dev;
564 u32 status;
565
566 status = xcsi2rxss_read(state, XCSI_ISR_OFFSET) & XCSI_ISR_ALLINTR_MASK;
567 xcsi2rxss_write(state, XCSI_ISR_OFFSET, status);
568
569 /* Received a short packet */
570 if (status & XCSI_ISR_SPFIFONE) {
571 u32 count = 0;
572
573 /*
574 * Drain generic short packet FIFO by reading max 31
575 * (fifo depth) short packets from fifo or till fifo is empty.
576 */
577 for (count = 0; count < XCSI_SPKT_FIFO_DEPTH; ++count) {
578 u32 spfifostat, spkt;
579
580 spkt = xcsi2rxss_read(state, XCSI_SPKTR_OFFSET);
581 dev_dbg(dev, "Short packet = 0x%08x\n", spkt);
582 spfifostat = xcsi2rxss_read(state, XCSI_ISR_OFFSET);
583 spfifostat &= XCSI_ISR_SPFIFONE;
584 if (!spfifostat)
585 break;
586 xcsi2rxss_write(state, XCSI_ISR_OFFSET, spfifostat);
587 }
588 }
589
590 /* Short packet FIFO overflow */
591 if (status & XCSI_ISR_SPFIFOF)
592 dev_dbg_ratelimited(dev, "Short packet FIFO overflowed\n");
593
594 /*
595 * Stream line buffer full
596 * This means there is a backpressure from downstream IP
597 */
598 if (status & XCSI_ISR_SLBF) {
599 dev_alert_ratelimited(dev, "Stream Line Buffer Full!\n");
600
601 /* disable interrupts */
602 xcsi2rxss_clr(state, XCSI_IER_OFFSET, XCSI_IER_INTR_MASK);
603 xcsi2rxss_clr(state, XCSI_GIER_OFFSET, XCSI_GIER_GIE);
604
605 /* disable core */
606 xcsi2rxss_clr(state, XCSI_CCR_OFFSET, XCSI_CCR_ENABLE);
607
608 /*
609 * The IP needs to be hard reset before it can be used now.
610 * This will be done in streamoff.
611 */
612
613 /*
614 * TODO: Notify the whole pipeline with v4l2_subdev_notify() to
615 * inform userspace.
616 */
617 }
618
619 /* Increment event counters */
620 if (status & XCSI_ISR_ALLINTR_MASK) {
621 unsigned int i;
622
623 for (i = 0; i < XCSI_NUM_EVENTS; i++) {
624 if (!(status & xcsi2rxss_events[i].mask))
625 continue;
626 state->events[i]++;
627 dev_dbg_ratelimited(dev, "%s: %u\n",
628 xcsi2rxss_events[i].name,
629 state->events[i]);
630 }
631
632 if (status & XCSI_ISR_VCXFE && state->en_vcx) {
633 u32 vcxstatus;
634
635 vcxstatus = xcsi2rxss_read(state, XCSI_VCXR_OFFSET);
636 vcxstatus &= XCSI_VCXR_VCERR;
637 for (i = 0; i < XCSI_VCX_NUM_EVENTS; i++) {
638 if (!(vcxstatus & BIT(i)))
639 continue;
640 state->vcx_events[i]++;
641 }
642 xcsi2rxss_write(state, XCSI_VCXR_OFFSET, vcxstatus);
643 }
644 }
645
646 return IRQ_HANDLED;
647}
648
649/**
650 * xcsi2rxss_s_stream - It is used to start/stop the streaming.
651 * @sd: V4L2 Sub device
652 * @enable: Flag (True / False)
653 *
654 * This function controls the start or stop of streaming for the
655 * Xilinx MIPI CSI-2 Rx Subsystem.
656 *
657 * Return: 0 on success, errors otherwise
658 */
659static int xcsi2rxss_s_stream(struct v4l2_subdev *sd, int enable)
660{
661 struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
662 int ret = 0;
663
664 mutex_lock(&xcsi2rxss->lock);
665
666 if (enable == xcsi2rxss->streaming)
667 goto stream_done;
668
669 if (enable) {
670 xcsi2rxss_reset_event_counters(xcsi2rxss);
671 ret = xcsi2rxss_start_stream(xcsi2rxss);
672 } else {
673 xcsi2rxss_stop_stream(xcsi2rxss);
674 xcsi2rxss_hard_reset(xcsi2rxss);
675 }
676
677stream_done:
678 mutex_unlock(&xcsi2rxss->lock);
679 return ret;
680}
681
682static struct v4l2_mbus_framefmt *
683__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
684 struct v4l2_subdev_pad_config *cfg,
685 unsigned int pad, u32 which)
686{
687 switch (which) {
688 case V4L2_SUBDEV_FORMAT_TRY:
689 return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad);
690 case V4L2_SUBDEV_FORMAT_ACTIVE:
691 return &xcsi2rxss->format;
692 default:
693 return NULL;
694 }
695}
696
697/**
698 * xcsi2rxss_init_cfg - Initialise the pad format config to default
699 * @sd: Pointer to V4L2 Sub device structure
700 * @cfg: Pointer to sub device pad information structure
701 *
702 * This function is used to initialize the pad format with the default
703 * values.
704 *
705 * Return: 0 on success
706 */
707static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd,
708 struct v4l2_subdev_pad_config *cfg)
709{
710 struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
711 struct v4l2_mbus_framefmt *format;
712 unsigned int i;
713
714 mutex_lock(&xcsi2rxss->lock);
715 for (i = 0; i < XCSI_MEDIA_PADS; i++) {
716 format = v4l2_subdev_get_try_format(sd, cfg, i);
717 *format = xcsi2rxss->default_format;
718 }
719 mutex_unlock(&xcsi2rxss->lock);
720
721 return 0;
722}
723
724/**
725 * xcsi2rxss_get_format - Get the pad format
726 * @sd: Pointer to V4L2 Sub device structure
727 * @cfg: Pointer to sub device pad information structure
728 * @fmt: Pointer to pad level media bus format
729 *
730 * This function is used to get the pad format information.
731 *
732 * Return: 0 on success
733 */
734static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
735 struct v4l2_subdev_pad_config *cfg,
736 struct v4l2_subdev_format *fmt)
737{
738 struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
739
740 mutex_lock(&xcsi2rxss->lock);
741 fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg, fmt->pad,
742 fmt->which);
743 mutex_unlock(&xcsi2rxss->lock);
744
745 return 0;
746}
747
748/**
749 * xcsi2rxss_set_format - This is used to set the pad format
750 * @sd: Pointer to V4L2 Sub device structure
751 * @cfg: Pointer to sub device pad information structure
752 * @fmt: Pointer to pad level media bus format
753 *
754 * This function is used to set the pad format. Since the pad format is fixed
755 * in hardware, it can't be modified on run time. So when a format set is
756 * requested by application, all parameters except the format type is saved
757 * for the pad and the original pad format is sent back to the application.
758 *
759 * Return: 0 on success
760 */
761static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
762 struct v4l2_subdev_pad_config *cfg,
763 struct v4l2_subdev_format *fmt)
764{
765 struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
766 struct v4l2_mbus_framefmt *__format;
767 u32 dt;
768
769 mutex_lock(&xcsi2rxss->lock);
770
771 /*
772 * Only the format->code parameter matters for CSI as the
773 * CSI format cannot be changed at runtime.
774 * Ensure that format to set is copied to over to CSI pad format
775 */
776 __format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
777 fmt->pad, fmt->which);
778
779 /* only sink pad format can be updated */
780 if (fmt->pad == XVIP_PAD_SOURCE) {
781 fmt->format = *__format;
782 mutex_unlock(&xcsi2rxss->lock);
783 return 0;
784 }
785
786 /*
787 * RAW8 is supported in all datatypes. So if requested media bus format
788 * is of RAW8 type, then allow to be set. In case core is configured to
789 * other RAW, YUV422 8/10 or RGB888, set appropriate media bus format.
790 */
791 dt = xcsi2rxss_get_dt(fmt->format.code);
792 if (dt != xcsi2rxss->datatype && dt != XCSI_DT_RAW8) {
793 dev_dbg(xcsi2rxss->dev, "Unsupported media bus format");
794 /* set the default format for the data type */
795 fmt->format.code = xcsi2rxss_get_nth_mbus(xcsi2rxss->datatype,
796 0);
797 }
798
799 *__format = fmt->format;
800 mutex_unlock(&xcsi2rxss->lock);
801
802 return 0;
803}
804
805/*
806 * xcsi2rxss_enum_mbus_code - Handle pixel format enumeration
807 * @sd: pointer to v4l2 subdev structure
808 * @cfg: V4L2 subdev pad configuration
809 * @code: pointer to v4l2_subdev_mbus_code_enum structure
810 *
811 * Return: -EINVAL or zero on success
812 */
813static int xcsi2rxss_enum_mbus_code(struct v4l2_subdev *sd,
814 struct v4l2_subdev_pad_config *cfg,
815 struct v4l2_subdev_mbus_code_enum *code)
816{
817 struct xcsi2rxss_state *state = to_xcsi2rxssstate(sd);
818 u32 dt, n;
819 int ret = 0;
820
821 /* RAW8 dt packets are available in all DT configurations */
822 if (code->index < 4) {
823 n = code->index;
824 dt = XCSI_DT_RAW8;
825 } else if (state->datatype != XCSI_DT_RAW8) {
826 n = code->index - 4;
827 dt = state->datatype;
828 } else {
829 return -EINVAL;
830 }
831
832 code->code = xcsi2rxss_get_nth_mbus(dt, n);
833 if (!code->code)
834 ret = -EINVAL;
835
836 return ret;
837}
838
839/* -----------------------------------------------------------------------------
840 * Media Operations
841 */
842
843static const struct media_entity_operations xcsi2rxss_media_ops = {
844 .link_validate = v4l2_subdev_link_validate
845};
846
847static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops = {
848 .log_status = xcsi2rxss_log_status,
849};
850
851static const struct v4l2_subdev_video_ops xcsi2rxss_video_ops = {
852 .s_stream = xcsi2rxss_s_stream
853};
854
855static const struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops = {
856 .init_cfg = xcsi2rxss_init_cfg,
857 .get_fmt = xcsi2rxss_get_format,
858 .set_fmt = xcsi2rxss_set_format,
859 .enum_mbus_code = xcsi2rxss_enum_mbus_code,
860 .link_validate = v4l2_subdev_link_validate_default,
861};
862
863static const struct v4l2_subdev_ops xcsi2rxss_ops = {
864 .core = &xcsi2rxss_core_ops,
865 .video = &xcsi2rxss_video_ops,
866 .pad = &xcsi2rxss_pad_ops
867};
868
869static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
870{
871 struct device *dev = xcsi2rxss->dev;
872 struct device_node *node = dev->of_node;
873
874 struct fwnode_handle *ep;
875 struct v4l2_fwnode_endpoint vep = {
876 .bus_type = V4L2_MBUS_CSI2_DPHY
877 };
878 bool en_csi_v20, vfb;
879 int ret;
880
881 en_csi_v20 = of_property_read_bool(node, "xlnx,en-csi-v2-0");
882 if (en_csi_v20)
883 xcsi2rxss->en_vcx = of_property_read_bool(node, "xlnx,en-vcx");
884
885 xcsi2rxss->enable_active_lanes =
886 of_property_read_bool(node, "xlnx,en-active-lanes");
887
888 ret = of_property_read_u32(node, "xlnx,csi-pxl-format",
889 &xcsi2rxss->datatype);
890 if (ret < 0) {
891 dev_err(dev, "missing xlnx,csi-pxl-format property\n");
892 return ret;
893 }
894
895 switch (xcsi2rxss->datatype) {
896 case XCSI_DT_YUV4228B:
897 case XCSI_DT_RGB444:
898 case XCSI_DT_RGB555:
899 case XCSI_DT_RGB565:
900 case XCSI_DT_RGB666:
901 case XCSI_DT_RGB888:
902 case XCSI_DT_RAW6:
903 case XCSI_DT_RAW7:
904 case XCSI_DT_RAW8:
905 case XCSI_DT_RAW10:
906 case XCSI_DT_RAW12:
907 case XCSI_DT_RAW14:
908 break;
909 case XCSI_DT_YUV42210B:
910 case XCSI_DT_RAW16:
911 case XCSI_DT_RAW20:
912 if (!en_csi_v20) {
913 ret = -EINVAL;
914 dev_dbg(dev, "enable csi v2 for this pixel format");
915 }
916 break;
917 default:
918 ret = -EINVAL;
919 }
920 if (ret < 0) {
921 dev_err(dev, "invalid csi-pxl-format property!\n");
922 return ret;
923 }
924
925 vfb = of_property_read_bool(node, "xlnx,vfb");
926 if (!vfb) {
927 dev_err(dev, "operation without VFB is not supported\n");
928 return -EINVAL;
929 }
930
931 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
932 XVIP_PAD_SINK, 0,
933 FWNODE_GRAPH_ENDPOINT_NEXT);
934 if (!ep) {
935 dev_err(dev, "no sink port found");
936 return -EINVAL;
937 }
938
939 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
940 fwnode_handle_put(ep);
941 if (ret) {
942 dev_err(dev, "error parsing sink port");
943 return ret;
944 }
945
946 dev_dbg(dev, "mipi number lanes = %d\n",
947 vep.bus.mipi_csi2.num_data_lanes);
948
949 xcsi2rxss->max_num_lanes = vep.bus.mipi_csi2.num_data_lanes;
950
951 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
952 XVIP_PAD_SOURCE, 0,
953 FWNODE_GRAPH_ENDPOINT_NEXT);
954 if (!ep) {
955 dev_err(dev, "no source port found");
956 return -EINVAL;
957 }
958
959 fwnode_handle_put(ep);
960
961 dev_dbg(dev, "vcx %s, %u data lanes (%s), data type 0x%02x\n",
962 xcsi2rxss->en_vcx ? "enabled" : "disabled",
963 xcsi2rxss->max_num_lanes,
964 xcsi2rxss->enable_active_lanes ? "dynamic" : "static",
965 xcsi2rxss->datatype);
966
967 return 0;
968}
969
970static int xcsi2rxss_probe(struct platform_device *pdev)
971{
972 struct v4l2_subdev *subdev;
973 struct xcsi2rxss_state *xcsi2rxss;
974 int num_clks = ARRAY_SIZE(xcsi2rxss_clks);
975 struct device *dev = &pdev->dev;
976 int irq, ret;
977
978 xcsi2rxss = devm_kzalloc(dev, sizeof(*xcsi2rxss), GFP_KERNEL);
979 if (!xcsi2rxss)
980 return -ENOMEM;
981
982 xcsi2rxss->dev = dev;
983
984 xcsi2rxss->clks = devm_kmemdup(dev, xcsi2rxss_clks,
985 sizeof(xcsi2rxss_clks), GFP_KERNEL);
986 if (!xcsi2rxss->clks)
987 return -ENOMEM;
988
989 /* Reset GPIO */
990 xcsi2rxss->rst_gpio = devm_gpiod_get_optional(dev, "video-reset",
991 GPIOD_OUT_HIGH);
992 if (IS_ERR(xcsi2rxss->rst_gpio)) {
993 if (PTR_ERR(xcsi2rxss->rst_gpio) != -EPROBE_DEFER)
994 dev_err(dev, "Video Reset GPIO not setup in DT");
995 return PTR_ERR(xcsi2rxss->rst_gpio);
996 }
997
998 ret = xcsi2rxss_parse_of(xcsi2rxss);
999 if (ret < 0)
1000 return ret;
1001
1002 xcsi2rxss->iomem = devm_platform_ioremap_resource(pdev, 0);
1003 if (IS_ERR(xcsi2rxss->iomem))
1004 return PTR_ERR(xcsi2rxss->iomem);
1005
1006 irq = platform_get_irq(pdev, 0);
1007 if (irq < 0)
1008 return irq;
1009
1010 ret = devm_request_threaded_irq(dev, irq, NULL,
1011 xcsi2rxss_irq_handler, IRQF_ONESHOT,
1012 dev_name(dev), xcsi2rxss);
1013 if (ret) {
1014 dev_err(dev, "Err = %d Interrupt handler reg failed!\n", ret);
1015 return ret;
1016 }
1017
1018 ret = clk_bulk_get(dev, num_clks, xcsi2rxss->clks);
1019 if (ret)
1020 return ret;
1021
1022 /* TODO: Enable/disable clocks at stream on/off time. */
1023 ret = clk_bulk_prepare_enable(num_clks, xcsi2rxss->clks);
1024 if (ret)
1025 goto err_clk_put;
1026
1027 mutex_init(&xcsi2rxss->lock);
1028
1029 xcsi2rxss_hard_reset(xcsi2rxss);
1030 xcsi2rxss_soft_reset(xcsi2rxss);
1031
1032 /* Initialize V4L2 subdevice and media entity */
1033 xcsi2rxss->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1034 xcsi2rxss->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1035
1036 /* Initialize the default format */
1037 xcsi2rxss->default_format.code =
1038 xcsi2rxss_get_nth_mbus(xcsi2rxss->datatype, 0);
1039 xcsi2rxss->default_format.field = V4L2_FIELD_NONE;
1040 xcsi2rxss->default_format.colorspace = V4L2_COLORSPACE_SRGB;
1041 xcsi2rxss->default_format.width = XCSI_DEFAULT_WIDTH;
1042 xcsi2rxss->default_format.height = XCSI_DEFAULT_HEIGHT;
1043 xcsi2rxss->format = xcsi2rxss->default_format;
1044
1045 /* Initialize V4L2 subdevice and media entity */
1046 subdev = &xcsi2rxss->subdev;
1047 v4l2_subdev_init(subdev, &xcsi2rxss_ops);
1048 subdev->dev = dev;
1049 strscpy(subdev->name, dev_name(dev), sizeof(subdev->name));
1050 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1051 subdev->entity.ops = &xcsi2rxss_media_ops;
1052 v4l2_set_subdevdata(subdev, xcsi2rxss);
1053
1054 ret = media_entity_pads_init(&subdev->entity, XCSI_MEDIA_PADS,
1055 xcsi2rxss->pads);
1056 if (ret < 0)
1057 goto error;
1058
1059 platform_set_drvdata(pdev, xcsi2rxss);
1060
1061 ret = v4l2_async_register_subdev(subdev);
1062 if (ret < 0) {
1063 dev_err(dev, "failed to register subdev\n");
1064 goto error;
1065 }
1066
1067 return 0;
1068error:
1069 media_entity_cleanup(&subdev->entity);
1070 mutex_destroy(&xcsi2rxss->lock);
1071 clk_bulk_disable_unprepare(num_clks, xcsi2rxss->clks);
1072err_clk_put:
1073 clk_bulk_put(num_clks, xcsi2rxss->clks);
1074 return ret;
1075}
1076
1077static int xcsi2rxss_remove(struct platform_device *pdev)
1078{
1079 struct xcsi2rxss_state *xcsi2rxss = platform_get_drvdata(pdev);
1080 struct v4l2_subdev *subdev = &xcsi2rxss->subdev;
1081 int num_clks = ARRAY_SIZE(xcsi2rxss_clks);
1082
1083 v4l2_async_unregister_subdev(subdev);
1084 media_entity_cleanup(&subdev->entity);
1085 mutex_destroy(&xcsi2rxss->lock);
1086 clk_bulk_disable_unprepare(num_clks, xcsi2rxss->clks);
1087 clk_bulk_put(num_clks, xcsi2rxss->clks);
1088
1089 return 0;
1090}
1091
1092static const struct of_device_id xcsi2rxss_of_id_table[] = {
1093 { .compatible = "xlnx,mipi-csi2-rx-subsystem-5.0", },
1094 { }
1095};
1096MODULE_DEVICE_TABLE(of, xcsi2rxss_of_id_table);
1097
1098static struct platform_driver xcsi2rxss_driver = {
1099 .driver = {
1100 .name = "xilinx-csi2rxss",
1101 .of_match_table = xcsi2rxss_of_id_table,
1102 },
1103 .probe = xcsi2rxss_probe,
1104 .remove = xcsi2rxss_remove,
1105};
1106
1107module_platform_driver(xcsi2rxss_driver);
1108
1109MODULE_AUTHOR("Vishal Sagar <vsagar@xilinx.com>");
1110MODULE_DESCRIPTION("Xilinx MIPI CSI-2 Rx Subsystem Driver");
1111MODULE_LICENSE("GPL v2");
drivers/media/radio/si4713/radio-usb-si4713.c+1−1
@@ -414,7 +414,7 @@ static int usb_si4713_probe(struct usb_interface *intf, · 413 unmodified lines
414 struct si4713_usb_device *radio;414 struct si4713_usb_device *radio;
415 struct i2c_adapter *adapter;415 struct i2c_adapter *adapter;
416 struct v4l2_subdev *sd;416 struct v4l2_subdev *sd;
417 int retval = -ENOMEM;417 int retval;
418 418
419 dev_info(&intf->dev, "Si4713 development board discovered: (%04X:%04X)\n",419 dev_info(&intf->dev, "Si4713 development board discovered: (%04X:%04X)\n",
420 id->idVendor, id->idProduct);420 id->idVendor, id->idProduct);
drivers/media/rc/Kconfig+11−0
@@ -530,6 +530,17 @@ config IR_ZX · 529 unmodified lines
530 To compile this driver as a module, choose M here: the530 To compile this driver as a module, choose M here: the
531 module will be called zx-irdec.531 module will be called zx-irdec.
532 532
533config IR_TOY
534 tristate "Infrared Toy and IR Droid"
535 depends on RC_CORE
536 depends on USB_ARCH_HAS_HCD
537 help
538 Say Y here if you want to use the Infrared Toy or IR Droid, USB
539 versions.
540
541 To compile this driver as a module, choose M here: the module will be
542 called ir_toy.
543
533endif #RC_DEVICES544endif #RC_DEVICES
534 545
535endif #RC_CORE546endif #RC_CORE
drivers/media/rc/Makefile+1−0
@@ -50,3 +50,4 @@ obj-$(CONFIG_IR_MTK) += mtk-cir.o · 49 unmodified lines
50obj-$(CONFIG_IR_ZX) += zx-irdec.o50obj-$(CONFIG_IR_ZX) += zx-irdec.o
51obj-$(CONFIG_IR_TANGO) += tango-ir.o51obj-$(CONFIG_IR_TANGO) += tango-ir.o
52obj-$(CONFIG_RC_XBOX_DVD) += xbox_remote.o52obj-$(CONFIG_RC_XBOX_DVD) += xbox_remote.o
53obj-$(CONFIG_IR_TOY) += ir_toy.o
drivers/media/rc/fintek-cir.c+0−7
@@ -51,13 +51,6 @@ static inline void fintek_set_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg) · 50 unmodified lines
51 fintek_cr_write(fintek, tmp, reg);51 fintek_cr_write(fintek, tmp, reg);
52}52}
53 53
54/* clear config register bit without changing other bits */
55static inline void fintek_clear_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
56{
57 u8 tmp = fintek_cr_read(fintek, reg) & ~val;
58 fintek_cr_write(fintek, tmp, reg);
59}
60
61/* enter config mode */54/* enter config mode */
62static inline void fintek_config_mode_enable(struct fintek_dev *fintek)55static inline void fintek_config_mode_enable(struct fintek_dev *fintek)
63{56{
drivers/media/rc/imon.c+1−1
@@ -795,7 +795,7 @@ static ssize_t show_associate_remote(struct device *d, · 794 unmodified lines
795 else795 else
796 strscpy(buf, "closed\n", PAGE_SIZE);796 strscpy(buf, "closed\n", PAGE_SIZE);
797 797
798 dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for instructions on how to associate your iMON 2.4G DT/LT remote\n");798 dev_info(d, "Visit https://www.lirc.org/html/imon-24g.html for instructions on how to associate your iMON 2.4G DT/LT remote\n");
799 mutex_unlock(&ictx->lock);799 mutex_unlock(&ictx->lock);
800 return strlen(buf);800 return strlen(buf);
801}801}
drivers/media/rc/ir_toy.c+509−0
@@ -0,0 +1,509 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3/*
4 * Infrared Toy and IR Droid RC core driver
5 *
6 * Copyright (C) 2020 Sean Young <sean@mess.org>
7
8 * This driver is based on the lirc driver which can be found here:
9 * https://sourceforge.net/p/lirc/git/ci/master/tree/plugins/irtoy.c
10 * Copyright (C) 2011 Peter Kooiman <pkooiman@gmail.com>
11 */
12
13#include <asm/unaligned.h>
14#include <linux/completion.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/usb.h>
18#include <linux/slab.h>
19#include <linux/usb/input.h>
20
21#include <media/rc-core.h>
22
23static const u8 COMMAND_VERSION[] = { 'v' };
24// End transmit and repeat reset command so we exit sump mode
25static const u8 COMMAND_RESET[] = { 0xff, 0xff, 0, 0, 0, 0, 0 };
26static const u8 COMMAND_SMODE_ENTER[] = { 's' };
27static const u8 COMMAND_TXSTART[] = { 0x26, 0x24, 0x25, 0x03 };
28
29#define REPLY_XMITCOUNT 't'
30#define REPLY_XMITSUCCESS 'C'
31#define REPLY_VERSION 'V'
32#define REPLY_SAMPLEMODEPROTO 'S'
33
34#define TIMEOUT 500
35
36#define LEN_XMITRES 3
37#define LEN_VERSION 4
38#define LEN_SAMPLEMODEPROTO 3
39
40#define MIN_FW_VERSION 20
41#define UNIT_NS 21333
42#define MAX_TIMEOUT_NS (UNIT_NS * U16_MAX)
43
44#define MAX_PACKET 64
45
46enum state {
47 STATE_IRDATA,
48 STATE_RESET,
49 STATE_COMMAND,
50 STATE_TX,
51};
52
53struct irtoy {
54 struct device *dev;
55 struct usb_device *usbdev;
56
57 struct rc_dev *rc;
58 struct urb *urb_in, *urb_out;
59
60 u8 *in;
61 u8 *out;
62 struct completion command_done;
63
64 bool pulse;
65 enum state state;
66
67 void *tx_buf;
68 uint tx_len;
69
70 uint emitted;
71 uint hw_version;
72 uint sw_version;
73 uint proto_version;
74
75 char phys[64];
76};
77
78static void irtoy_response(struct irtoy *irtoy, u32 len)
79{
80 switch (irtoy->state) {
81 case STATE_COMMAND:
82 if (len == LEN_VERSION && irtoy->in[0] == REPLY_VERSION) {
83 uint version;
84
85 irtoy->in[LEN_VERSION] = 0;
86
87 if (kstrtouint(irtoy->in + 1, 10, &version)) {
88 dev_err(irtoy->dev, "invalid version %*phN. Please make sure you are using firmware v20 or higher",
89 LEN_VERSION, irtoy->in);
90 break;
91 }
92
93 dev_dbg(irtoy->dev, "version %s\n", irtoy->in);
94
95 irtoy->hw_version = version / 100;
96 irtoy->sw_version = version % 100;
97
98 irtoy->state = STATE_IRDATA;
99 complete(&irtoy->command_done);
100 } else if (len == LEN_SAMPLEMODEPROTO &&
101 irtoy->in[0] == REPLY_SAMPLEMODEPROTO) {
102 uint version;
103
104 irtoy->in[LEN_SAMPLEMODEPROTO] = 0;
105
106 if (kstrtouint(irtoy->in + 1, 10, &version)) {
107 dev_err(irtoy->dev, "invalid sample mode response %*phN",
108 LEN_SAMPLEMODEPROTO, irtoy->in);
109 return;
110 }
111
112 dev_dbg(irtoy->dev, "protocol %s\n", irtoy->in);
113
114 irtoy->proto_version = version;
115
116 irtoy->state = STATE_IRDATA;
117 complete(&irtoy->command_done);
118 } else {
119 dev_err(irtoy->dev, "unexpected response to command: %*phN\n",
120 len, irtoy->in);
121 }
122 break;
123 case STATE_IRDATA: {
124 struct ir_raw_event rawir = { .pulse = irtoy->pulse };
125 __be16 *in = (__be16 *)irtoy->in;
126 int i;
127
128 for (i = 0; i < len / sizeof(__be16); i++) {
129 u16 v = be16_to_cpu(in[i]);
130
131 if (v == 0xffff) {
132 rawir.pulse = false;
133 } else {
134 rawir.duration = v * UNIT_NS;
135 ir_raw_event_store_with_timeout(irtoy->rc,
136 &rawir);
137 }
138
139 rawir.pulse = !rawir.pulse;
140 }
141
142 irtoy->pulse = rawir.pulse;
143
144 ir_raw_event_handle(irtoy->rc);
145 break;
146 }
147 case STATE_TX:
148 if (irtoy->tx_len == 0) {
149 if (len == LEN_XMITRES &&
150 irtoy->in[0] == REPLY_XMITCOUNT) {
151 u16 emitted = get_unaligned_be16(irtoy->in + 1);
152
153 dev_dbg(irtoy->dev, "emitted:%u\n", emitted);
154
155 irtoy->emitted = emitted;
156 } else if (len == 1 &&
157 irtoy->in[0] == REPLY_XMITSUCCESS) {
158 irtoy->state = STATE_IRDATA;
159 complete(&irtoy->command_done);
160 }
161 } else {
162 // send next part of tx buffer
163 uint space = irtoy->in[0];
164 uint buf_len;
165 int err;
166
167 if (len != 1 || space > MAX_PACKET || space == 0) {
168 dev_err(irtoy->dev, "packet length expected: %*phN\n",
169 len, irtoy->in);
170 irtoy->state = STATE_IRDATA;
171 complete(&irtoy->command_done);
172 break;
173 }
174
175 buf_len = min(space, irtoy->tx_len);
176
177 dev_dbg(irtoy->dev, "remaining:%u sending:%u\n",
178 irtoy->tx_len, buf_len);
179
180 memcpy(irtoy->out, irtoy->tx_buf, buf_len);
181 irtoy->urb_out->transfer_buffer_length = buf_len;
182 err = usb_submit_urb(irtoy->urb_out, GFP_ATOMIC);
183 if (err != 0) {
184 dev_err(irtoy->dev, "fail to submit tx buf urb: %d\n",
185 err);
186 irtoy->state = STATE_IRDATA;
187 complete(&irtoy->command_done);
188 break;
189 }
190
191 irtoy->tx_buf += buf_len;
192 irtoy->tx_len -= buf_len;
193 }
194 break;
195 case STATE_RESET:
196 dev_err(irtoy->dev, "unexpected response to reset: %*phN\n",
197 len, irtoy->in);
198 }
199}
200
201static void irtoy_out_callback(struct urb *urb)
202{
203 struct irtoy *irtoy = urb->context;
204
205 if (urb->status == 0) {
206 if (irtoy->state == STATE_RESET)
207 complete(&irtoy->command_done);
208 } else {
209 dev_warn(irtoy->dev, "out urb status: %d\n", urb->status);
210 }
211}
212
213static void irtoy_in_callback(struct urb *urb)
214{
215 struct irtoy *irtoy = urb->context;
216 int ret;
217
218 if (urb->status == 0)
219 irtoy_response(irtoy, urb->actual_length);
220 else
221 dev_dbg(irtoy->dev, "in urb status: %d\n", urb->status);
222
223 ret = usb_submit_urb(urb, GFP_ATOMIC);
224 if (ret && ret != -ENODEV)
225 dev_warn(irtoy->dev, "failed to resubmit urb: %d\n", ret);
226}
227
228static int irtoy_command(struct irtoy *irtoy, const u8 *cmd, int cmd_len,
229 enum state state)
230{
231 int err;
232
233 init_completion(&irtoy->command_done);
234
235 irtoy->state = state;
236
237 memcpy(irtoy->out, cmd, cmd_len);
238 irtoy->urb_out->transfer_buffer_length = cmd_len;
239
240 err = usb_submit_urb(irtoy->urb_out, GFP_KERNEL);
241 if (err != 0)
242 return err;
243
244 if (!wait_for_completion_timeout(&irtoy->command_done,
245 msecs_to_jiffies(TIMEOUT))) {
246 usb_kill_urb(irtoy->urb_out);
247 return -ETIMEDOUT;
248 }
249
250 return 0;
251}
252
253static int irtoy_setup(struct irtoy *irtoy)
254{
255 int err;
256
257 err = irtoy_command(irtoy, COMMAND_RESET, sizeof(COMMAND_RESET),
258 STATE_RESET);
259 if (err != 0) {
260 dev_err(irtoy->dev, "could not write reset command: %d\n",
261 err);
262 return err;
263 }
264
265 usleep_range(50, 50);
266
267 // get version
268 err = irtoy_command(irtoy, COMMAND_VERSION, sizeof(COMMAND_VERSION),
269 STATE_COMMAND);
270 if (err) {
271 dev_err(irtoy->dev, "could not write version command: %d\n",
272 err);
273 return err;
274 }
275
276 // enter sample mode
277 err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
278 sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
279 if (err)
280 dev_err(irtoy->dev, "could not write sample command: %d\n",
281 err);
282
283 return err;
284}
285
286/*
287 * When sending IR, it is imperative that we send the IR data as quickly
288 * as possible to the device, so it does not run out of IR data and
289 * introduce gaps. Allocate the buffer here, and then feed the data from
290 * the urb callback handler.
291 */
292static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count)
293{
294 struct irtoy *irtoy = rc->priv;
295 unsigned int i, size;
296 __be16 *buf;
297 int err;
298
299 size = sizeof(u16) * (count + 1);
300 buf = kmalloc(size, GFP_KERNEL);
301 if (!buf)
302 return -ENOMEM;
303
304 for (i = 0; i < count; i++) {
305 u16 v = DIV_ROUND_CLOSEST(US_TO_NS(txbuf[i]), UNIT_NS);
306
307 if (!v)
308 v = 1;
309 buf[i] = cpu_to_be16(v);
310 }
311
312 buf[count] = cpu_to_be16(0xffff);
313
314 irtoy->tx_buf = buf;
315 irtoy->tx_len = size;
316 irtoy->emitted = 0;
317
318 err = irtoy_command(irtoy, COMMAND_TXSTART, sizeof(COMMAND_TXSTART),
319 STATE_TX);
320 kfree(buf);
321
322 if (err) {
323 dev_err(irtoy->dev, "failed to send tx start command: %d\n",
324 err);
325 // not sure what state the device is in, reset it
326 irtoy_setup(irtoy);
327 return err;
328 }
329
330 if (size != irtoy->emitted) {
331 dev_err(irtoy->dev, "expected %u emitted, got %u\n", size,
332 irtoy->emitted);
333 // not sure what state the device is in, reset it
334 irtoy_setup(irtoy);
335 return -EINVAL;
336 }
337
338 return count;
339}
340
341static int irtoy_probe(struct usb_interface *intf,
342 const struct usb_device_id *id)
343{
344 struct usb_host_interface *idesc = intf->cur_altsetting;
345 struct usb_device *usbdev = interface_to_usbdev(intf);
346 struct usb_endpoint_descriptor *ep_in = NULL;
347 struct usb_endpoint_descriptor *ep_out = NULL;
348 struct usb_endpoint_descriptor *ep = NULL;
349 struct irtoy *irtoy;
350 struct rc_dev *rc;
351 struct urb *urb;
352 int i, pipe, err = -ENOMEM;
353
354 for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
355 ep = &idesc->endpoint[i].desc;
356
357 if (!ep_in && usb_endpoint_is_bulk_in(ep) &&
358 usb_endpoint_maxp(ep) == MAX_PACKET)
359 ep_in = ep;
360
361 if (!ep_out && usb_endpoint_is_bulk_out(ep) &&
362 usb_endpoint_maxp(ep) == MAX_PACKET)
363 ep_out = ep;
364 }
365
366 if (!ep_in || !ep_out) {
367 dev_err(&intf->dev, "required endpoints not found\n");
368 return -ENODEV;
369 }
370
371 irtoy = kzalloc(sizeof(*irtoy), GFP_KERNEL);
372 if (!irtoy)
373 return -ENOMEM;
374
375 irtoy->in = kmalloc(MAX_PACKET, GFP_KERNEL);
376 if (!irtoy->in)
377 goto free_irtoy;
378
379 irtoy->out = kmalloc(MAX_PACKET, GFP_KERNEL);
380 if (!irtoy->out)
381 goto free_irtoy;
382
383 rc = rc_allocate_device(RC_DRIVER_IR_RAW);
384 if (!rc)
385 goto free_irtoy;
386
387 urb = usb_alloc_urb(0, GFP_KERNEL);
388 if (!urb)
389 goto free_rcdev;
390
391 pipe = usb_rcvbulkpipe(usbdev, ep_in->bEndpointAddress);
392 usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->in, MAX_PACKET,
393 irtoy_in_callback, irtoy);
394 irtoy->urb_in = urb;
395
396 urb = usb_alloc_urb(0, GFP_KERNEL);
397 if (!urb)
398 goto free_rcdev;
399
400 pipe = usb_sndbulkpipe(usbdev, ep_out->bEndpointAddress);
401 usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->out, MAX_PACKET,
402 irtoy_out_callback, irtoy);
403
404 irtoy->dev = &intf->dev;
405 irtoy->usbdev = usbdev;
406 irtoy->rc = rc;
407 irtoy->urb_out = urb;
408 irtoy->pulse = true;
409
410 err = usb_submit_urb(irtoy->urb_in, GFP_KERNEL);
411 if (err != 0) {
412 dev_err(irtoy->dev, "fail to submit in urb: %d\n", err);
413 return err;
414 }
415
416 err = irtoy_setup(irtoy);
417 if (err)
418 goto free_rcdev;
419
420 dev_info(irtoy->dev, "version: hardware %u, firmware %u, protocol %u",
421 irtoy->hw_version, irtoy->sw_version, irtoy->proto_version);
422
423 if (irtoy->sw_version < MIN_FW_VERSION) {
424 dev_err(irtoy->dev, "need firmware V%02u or higher",
425 MIN_FW_VERSION);
426 err = -ENODEV;
427 goto free_rcdev;
428 }
429
430 usb_make_path(usbdev, irtoy->phys, sizeof(irtoy->phys));
431
432 rc->device_name = "Infrared Toy";
433 rc->driver_name = KBUILD_MODNAME;
434 rc->input_phys = irtoy->phys;
435 usb_to_input_id(usbdev, &rc->input_id);
436 rc->dev.parent = &intf->dev;
437 rc->priv = irtoy;
438 rc->tx_ir = irtoy_tx;
439 rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
440 rc->map_name = RC_MAP_RC6_MCE;
441 rc->rx_resolution = UNIT_NS;
442 rc->timeout = IR_DEFAULT_TIMEOUT;
443
444 /*
445 * end of transmission is detected by absence of a usb packet
446 * with more pulse/spaces. However, each usb packet sent can
447 * contain 32 pulse/spaces, which can be quite lengthy, so there
448 * can be a delay between usb packets. For example with nec there is a
449 * 17ms gap between packets.
450 *
451 * So, make timeout a largish minimum which works with most protocols.
452 */
453 rc->min_timeout = MS_TO_NS(40);
454 rc->max_timeout = MAX_TIMEOUT_NS;
455
456 err = rc_register_device(rc);
457 if (err)
458 goto free_rcdev;
459
460 usb_set_intfdata(intf, irtoy);
461
462 return 0;
463
464free_rcdev:
465 usb_kill_urb(irtoy->urb_out);
466 usb_free_urb(irtoy->urb_out);
467 usb_kill_urb(irtoy->urb_in);
468 usb_free_urb(irtoy->urb_in);
469 rc_free_device(rc);
470free_irtoy:
471 kfree(irtoy->in);
472 kfree(irtoy->out);
473 kfree(irtoy);
474 return err;
475}
476
477static void irtoy_disconnect(struct usb_interface *intf)
478{
479 struct irtoy *ir = usb_get_intfdata(intf);
480
481 rc_unregister_device(ir->rc);
482 usb_set_intfdata(intf, NULL);
483 usb_kill_urb(ir->urb_out);
484 usb_free_urb(ir->urb_out);
485 usb_kill_urb(ir->urb_in);
486 usb_free_urb(ir->urb_in);
487 kfree(ir->in);
488 kfree(ir->out);
489 kfree(ir);
490}
491
492static const struct usb_device_id irtoy_table[] = {
493 { USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xfd08, USB_CLASS_CDC_DATA) },
494 { }
495};
496
497static struct usb_driver irtoy_driver = {
498 .name = KBUILD_MODNAME,
499 .probe = irtoy_probe,
500 .disconnect = irtoy_disconnect,
501 .id_table = irtoy_table,
502};
503
504module_usb_driver(irtoy_driver);
505
506MODULE_AUTHOR("Sean Young <sean@mess.org>");
507MODULE_DESCRIPTION("Infrared Toy and IR Droid driver");
508MODULE_LICENSE("GPL");
509MODULE_DEVICE_TABLE(usb, irtoy_table);
drivers/media/rc/nuvoton-cir.c+0−32
@@ -74,13 +74,6 @@ static inline void nvt_set_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg) · 73 unmodified lines
74 nvt_cr_write(nvt, tmp, reg);74 nvt_cr_write(nvt, tmp, reg);
75}75}
76 76
77/* clear config register bit without changing other bits */
78static inline void nvt_clear_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg)
79{
80 u8 tmp = nvt_cr_read(nvt, reg) & ~val;
81 nvt_cr_write(nvt, tmp, reg);
82}
83
84/* enter extended function mode */77/* enter extended function mode */
85static inline int nvt_efm_enable(struct nvt_dev *nvt)78static inline int nvt_efm_enable(struct nvt_dev *nvt)
86{79{
@@ -631,30 +624,6 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt) · 544 unmodified lines
631 return carrier;624 return carrier;
632}625}
633#endif626#endif
634/*
635 * set carrier frequency
636 *
637 * set carrier on 2 registers: CP & CC
638 * always set CP as 0x81
639 * set CC by SPEC, CC = 3MHz/carrier - 1
640 */
641static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
642{
643 struct nvt_dev *nvt = dev->priv;
644 u16 val;
645
646 if (carrier == 0)
647 return -EINVAL;
648
649 nvt_cir_reg_write(nvt, 1, CIR_CP);
650 val = 3000000 / (carrier) - 1;
651 nvt_cir_reg_write(nvt, val & 0xff, CIR_CC);
652
653 nvt_dbg("cp: 0x%x cc: 0x%x\n",
654 nvt_cir_reg_read(nvt, CIR_CP), nvt_cir_reg_read(nvt, CIR_CC));
655
656 return 0;
657}
658 627
659static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev,628static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev,
660 struct rc_scancode_filter *sc_filter)629 struct rc_scancode_filter *sc_filter)
@@ -1022,7 +991,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) · 361 unmodified lines
1022 rdev->encode_wakeup = true;991 rdev->encode_wakeup = true;
1023 rdev->open = nvt_open;992 rdev->open = nvt_open;
1024 rdev->close = nvt_close;993 rdev->close = nvt_close;
1025 rdev->s_tx_carrier = nvt_set_tx_carrier;
1026 rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter;994 rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter;
1027 rdev->device_name = "Nuvoton w836x7hg Infrared Remote Transceiver";995 rdev->device_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
1028 rdev->input_phys = "nuvoton/cir0";996 rdev->input_phys = "nuvoton/cir0";
drivers/media/rc/rc-main.c+1−1
@@ -2052,7 +2052,7 @@ static int __init rc_core_init(void) · 2051 unmodified lines
2052 if (rc) {2052 if (rc) {
2053 pr_err("rc_core: unable to init lirc\n");2053 pr_err("rc_core: unable to init lirc\n");
2054 class_unregister(&rc_class);2054 class_unregister(&rc_class);
2055 return 0;2055 return rc;
2056 }2056 }
2057 2057
2058 led_trigger_register_simple("rc-feedback", &led_feedback);2058 led_trigger_register_simple("rc-feedback", &led_feedback);
drivers/media/test-drivers/vicodec/vicodec-core.c+3−3
@@ -1442,7 +1442,7 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) · 1441 unmodified lines
1442 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,1442 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1443 };1443 };
1444 1444
1445 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) &&1445 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1446 vb2_is_streaming(vb->vb2_queue) &&1446 vb2_is_streaming(vb->vb2_queue) &&
1447 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {1447 v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
1448 unsigned int i;1448 unsigned int i;
@@ -1479,7 +1479,7 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) · 30 unmodified lines
1479 * in the compressed stream1479 * in the compressed stream
1480 */1480 */
1481 if (ctx->is_stateless || ctx->is_enc ||1481 if (ctx->is_stateless || ctx->is_enc ||
1482 !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {1482 V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
1483 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);1483 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1484 return;1484 return;
1485 }1485 }
@@ -1574,7 +1574,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, · 88 unmodified lines
1574 state->gop_cnt = 0;1574 state->gop_cnt = 0;
1575 1575
1576 if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||1576 if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
1577 (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc))1577 (V4L2_TYPE_IS_CAPTURE(q->type) && ctx->is_enc))
1578 return 0;1578 return 0;
1579 1579
1580 if (info->id == V4L2_PIX_FMT_FWHT ||1580 if (info->id == V4L2_PIX_FMT_FWHT ||
drivers/media/test-drivers/vimc/Kconfig+2−0
@@ -2,6 +2,8 @@ · 1 unmodified line
2config VIDEO_VIMC2config VIDEO_VIMC
3 tristate "Virtual Media Controller Driver (VIMC)"3 tristate "Virtual Media Controller Driver (VIMC)"
4 depends on VIDEO_DEV && VIDEO_V4L24 depends on VIDEO_DEV && VIDEO_V4L2
5 select FONT_SUPPORT
6 select FONT_8x16
5 select MEDIA_CONTROLLER7 select MEDIA_CONTROLLER
6 select VIDEO_V4L2_SUBDEV_API8 select VIDEO_V4L2_SUBDEV_API
7 select VIDEOBUF2_VMALLOC9 select VIDEOBUF2_VMALLOC
drivers/media/test-drivers/vimc/vimc-common.h+1−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#define VIMC_CID_VIMC_CLASS (0x00f00000 | 1)20#define VIMC_CID_VIMC_CLASS (0x00f00000 | 1)
21#define VIMC_CID_TEST_PATTERN (VIMC_CID_VIMC_BASE + 0)21#define VIMC_CID_TEST_PATTERN (VIMC_CID_VIMC_BASE + 0)
22#define VIMC_CID_MEAN_WIN_SIZE (VIMC_CID_VIMC_BASE + 1)22#define VIMC_CID_MEAN_WIN_SIZE (VIMC_CID_VIMC_BASE + 1)
23#define VIMC_CID_OSD_TEXT_MODE (VIMC_CID_VIMC_BASE + 2)
23 24
24#define VIMC_FRAME_MAX_WIDTH 409625#define VIMC_FRAME_MAX_WIDTH 4096
25#define VIMC_FRAME_MAX_HEIGHT 216026#define VIMC_FRAME_MAX_HEIGHT 2160
drivers/media/test-drivers/vimc/vimc-core.c+10−0
@@ -5,10 +5,12 @@ · 4 unmodified lines
5 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>5 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
6 */6 */
7 7
8#include <linux/font.h>
8#include <linux/init.h>9#include <linux/init.h>
9#include <linux/module.h>10#include <linux/module.h>
10#include <linux/platform_device.h>11#include <linux/platform_device.h>
11#include <media/media-device.h>12#include <media/media-device.h>
13#include <media/tpg/v4l2-tpg.h>
12#include <media/v4l2-device.h>14#include <media/v4l2-device.h>
13 15
14#include "vimc-common.h"16#include "vimc-common.h"
@@ -263,11 +265,19 @@ err_v4l2_unregister: · 248 unmodified lines
263 265
264static int vimc_probe(struct platform_device *pdev)266static int vimc_probe(struct platform_device *pdev)
265{267{
268 const struct font_desc *font = find_font("VGA8x16");
266 struct vimc_device *vimc;269 struct vimc_device *vimc;
267 int ret;270 int ret;
268 271
269 dev_dbg(&pdev->dev, "probe");272 dev_dbg(&pdev->dev, "probe");
270 273
274 if (!font) {
275 dev_err(&pdev->dev, "could not find font\n");
276 return -ENODEV;
277 }
278
279 tpg_set_font(font->data);
280
271 vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);281 vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
272 if (!vimc)282 if (!vimc)
273 return -ENOMEM;283 return -ENOMEM;
drivers/media/test-drivers/vimc/vimc-sensor.c+71−0
@@ -14,11 +14,19 @@ · 13 unmodified lines
14 14
15#include "vimc-common.h"15#include "vimc-common.h"
16 16
17enum vimc_sen_osd_mode {
18 VIMC_SEN_OSD_SHOW_ALL = 0,
19 VIMC_SEN_OSD_SHOW_COUNTERS = 1,
20 VIMC_SEN_OSD_SHOW_NONE = 2
21};
22
17struct vimc_sen_device {23struct vimc_sen_device {
18 struct vimc_ent_device ved;24 struct vimc_ent_device ved;
19 struct v4l2_subdev sd;25 struct v4l2_subdev sd;
20 struct tpg_data tpg;26 struct tpg_data tpg;
21 u8 *frame;27 u8 *frame;
28 enum vimc_sen_osd_mode osd_value;
29 u64 start_stream_ts;
22 /* The active format */30 /* The active format */
23 struct v4l2_mbus_framefmt mbus_format;31 struct v4l2_mbus_framefmt mbus_format;
24 struct v4l2_ctrl_handler hdl;32 struct v4l2_ctrl_handler hdl;
@@ -187,8 +195,49 @@ static void *vimc_sen_process_frame(struct vimc_ent_device *ved, · 162 unmodified lines
187{195{
188 struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,196 struct vimc_sen_device *vsen = container_of(ved, struct vimc_sen_device,
189 ved);197 ved);
198 const unsigned int line_height = 16;
199 u8 *basep[TPG_MAX_PLANES][2];
200 unsigned int line = 1;
201 char str[100];
190 202
191 tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);203 tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
204 tpg_calc_text_basep(&vsen->tpg, basep, 0, vsen->frame);
205 switch (vsen->osd_value) {
206 case VIMC_SEN_OSD_SHOW_ALL: {
207 const char *order = tpg_g_color_order(&vsen->tpg);
208
209 tpg_gen_text(&vsen->tpg, basep, line++ * line_height,
210 16, order);
211 snprintf(str, sizeof(str),
212 "brightness %3d, contrast %3d, saturation %3d, hue %d ",
213 vsen->tpg.brightness,
214 vsen->tpg.contrast,
215 vsen->tpg.saturation,
216 vsen->tpg.hue);
217 tpg_gen_text(&vsen->tpg, basep, line++ * line_height, 16, str);
218 snprintf(str, sizeof(str), "sensor size: %dx%d",
219 vsen->mbus_format.width,
220 vsen->mbus_format.height);
221 tpg_gen_text(&vsen->tpg, basep, line++ * line_height, 16, str);
222 fallthrough;
223 }
224 case VIMC_SEN_OSD_SHOW_COUNTERS: {
225 unsigned int ms;
226
227 ms = div_u64(ktime_get_ns() - vsen->start_stream_ts, 1000000);
228 snprintf(str, sizeof(str), "%02d:%02d:%02d:%03d",
229 (ms / (60 * 60 * 1000)) % 24,
230 (ms / (60 * 1000)) % 60,
231 (ms / 1000) % 60,
232 ms % 1000);
233 tpg_gen_text(&vsen->tpg, basep, line++ * line_height, 16, str);
234 break;
235 }
236 case VIMC_SEN_OSD_SHOW_NONE:
237 default:
238 break;
239 }
240
192 return vsen->frame;241 return vsen->frame;
193}242}
194 243
@@ -201,6 +250,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) · 6 unmodified lines
201 const struct vimc_pix_map *vpix;250 const struct vimc_pix_map *vpix;
202 unsigned int frame_size;251 unsigned int frame_size;
203 252
253 vsen->start_stream_ts = ktime_get_ns();
254
204 /* Calculate the frame size */255 /* Calculate the frame size */
205 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);256 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
206 frame_size = vsen->mbus_format.width * vpix->bpp *257 frame_size = vsen->mbus_format.width * vpix->bpp *
@@ -269,6 +320,9 @@ static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl) · 62 unmodified lines
269 case V4L2_CID_SATURATION:320 case V4L2_CID_SATURATION:
270 tpg_s_saturation(&vsen->tpg, ctrl->val);321 tpg_s_saturation(&vsen->tpg, ctrl->val);
271 break;322 break;
323 case VIMC_CID_OSD_TEXT_MODE:
324 vsen->osd_value = ctrl->val;
325 break;
272 default:326 default:
273 return -EINVAL;327 return -EINVAL;
274 }328 }
@@ -307,6 +361,22 @@ static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = { · 32 unmodified lines
307 .qmenu = tpg_pattern_strings,361 .qmenu = tpg_pattern_strings,
308};362};
309 363
364static const char * const vimc_ctrl_osd_mode_strings[] = {
365 "All",
366 "Counters Only",
367 "None",
368 NULL,
369};
370
371static const struct v4l2_ctrl_config vimc_sen_ctrl_osd_mode = {
372 .ops = &vimc_sen_ctrl_ops,
373 .id = VIMC_CID_OSD_TEXT_MODE,
374 .name = "Show Information",
375 .type = V4L2_CTRL_TYPE_MENU,
376 .max = ARRAY_SIZE(vimc_ctrl_osd_mode_strings) - 2,
377 .qmenu = vimc_ctrl_osd_mode_strings,
378};
379
310static struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,380static struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
311 const char *vcfg_name)381 const char *vcfg_name)
312{382{
@@ -323,6 +393,7 @@ static struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc, · 10 unmodified lines
323 393
324 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);394 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);
325 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);395 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);
396 v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_osd_mode, NULL);
326 v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,397 v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
327 V4L2_CID_VFLIP, 0, 1, 1, 0);398 V4L2_CID_VFLIP, 0, 1, 1, 0);
328 v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,399 v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
drivers/media/test-drivers/vivid/vivid-core.c+11−2
@@ -169,6 +169,14 @@ MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n" · 168 unmodified lines
169 "\t\t 0 == vmalloc\n"169 "\t\t 0 == vmalloc\n"
170 "\t\t 1 == dma-contig");170 "\t\t 1 == dma-contig");
171 171
172static unsigned int cache_hints[VIVID_MAX_DEVS] = {
173 [0 ... (VIVID_MAX_DEVS - 1)] = 0
174};
175module_param_array(cache_hints, uint, NULL, 0444);
176MODULE_PARM_DESC(cache_hints, " user-space cache hints, default is 0.\n"
177 "\t\t 0 == forbid\n"
178 "\t\t 1 == allow");
179
172static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];180static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
173 181
174const struct v4l2_rect vivid_min_rect = {182const struct v4l2_rect vivid_min_rect = {
@@ -819,6 +827,7 @@ static int vivid_create_queue(struct vivid_dev *dev, · 644 unmodified lines
819 q->lock = &dev->mutex;827 q->lock = &dev->mutex;
820 q->dev = dev->v4l2_dev.dev;828 q->dev = dev->v4l2_dev.dev;
821 q->supports_requests = true;829 q->supports_requests = true;
830 q->allow_cache_hints = (cache_hints[dev->inst] == 1);
822 831
823 return vb2_queue_init(q);832 return vb2_queue_init(q);
824}833}
@@ -1117,7 +1126,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 292 unmodified lines
1117 ret = -ENOMEM;1126 ret = -ENOMEM;
1118 /* initialize the test pattern generator */1127 /* initialize the test pattern generator */
1119 tpg_init(&dev->tpg, 640, 360);1128 tpg_init(&dev->tpg, 640, 360);
1120 if (tpg_alloc(&dev->tpg, MAX_ZOOM * MAX_WIDTH))1129 if (tpg_alloc(&dev->tpg, array_size(MAX_WIDTH, MAX_ZOOM)))
1121 goto free_dev;1130 goto free_dev;
1122 dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));1131 dev->scaled_line = vzalloc(array_size(MAX_WIDTH, MAX_ZOOM));
1123 if (!dev->scaled_line)1132 if (!dev->scaled_line)
@@ -1127,7 +1136,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 3 unmodified lines
1127 goto free_dev;1136 goto free_dev;
1128 1137
1129 /* load the edid */1138 /* load the edid */
1130 dev->edid = vmalloc(256 * 128);1139 dev->edid = vmalloc(array_size(256, 128));
1131 if (!dev->edid)1140 if (!dev->edid)
1132 goto free_dev;1141 goto free_dev;
1133 1142
drivers/media/usb/cx231xx/cx231xx-417.c+1−1
@@ -1734,7 +1734,7 @@ static void cx231xx_video_dev_init( · 1733 unmodified lines
1734int cx231xx_417_register(struct cx231xx *dev)1734int cx231xx_417_register(struct cx231xx *dev)
1735{1735{
1736 /* FIXME: Port1 hardcoded here */1736 /* FIXME: Port1 hardcoded here */
1737 int err = -ENODEV;1737 int err;
1738 struct cx231xx_tsport *tsport = &dev->ts1;1738 struct cx231xx_tsport *tsport = &dev->ts1;
1739 struct vb2_queue *q;1739 struct vb2_queue *q;
1740 1740
drivers/media/usb/dvb-usb-v2/dvbsky.c+4−4
@@ -778,16 +778,16 @@ static const struct usb_device_id dvbsky_id_table[] = { · 777 unmodified lines
778 &dvbsky_s960_props, "Terratec Cinergy S2 Rev.4",778 &dvbsky_s960_props, "Terratec Cinergy S2 Rev.4",
779 RC_MAP_DVBSKY) },779 RC_MAP_DVBSKY) },
780 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230,780 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230,
781 &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230",781 &mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230",
782 RC_MAP_TOTAL_MEDIA_IN_HAND_02) },782 RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
783 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C,783 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C,
784 &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C",784 &mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230C",
785 RC_MAP_TOTAL_MEDIA_IN_HAND_02) },785 RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
786 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C_LITE,786 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C_LITE,
787 &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C Lite",787 &mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230C Lite",
788 NULL) },788 NULL) },
789 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2,789 { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2,
790 &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C v2",790 &mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230C v2",
791 RC_MAP_TOTAL_MEDIA_IN_HAND_02) },791 RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
792 { }792 { }
793};793};
drivers/media/usb/dvb-usb/Kconfig+1−0
@@ -151,6 +151,7 @@ config DVB_USB_CXUSB · 150 unmodified lines
151config DVB_USB_CXUSB_ANALOG151config DVB_USB_CXUSB_ANALOG
152 bool "Analog support for the Conexant USB2.0 hybrid reference design"152 bool "Analog support for the Conexant USB2.0 hybrid reference design"
153 depends on DVB_USB_CXUSB && VIDEO_V4L2153 depends on DVB_USB_CXUSB && VIDEO_V4L2
154 depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_USB_CXUSB
154 select VIDEO_CX25840155 select VIDEO_CX25840
155 select VIDEOBUF2_VMALLOC156 select VIDEOBUF2_VMALLOC
156 help157 help
drivers/media/usb/go7007/go7007-usb.c+10−1
@@ -1132,6 +1132,10 @@ static int go7007_usb_probe(struct usb_interface *intf, · 1131 unmodified lines
1132 go->hpi_ops = &go7007_usb_onboard_hpi_ops;1132 go->hpi_ops = &go7007_usb_onboard_hpi_ops;
1133 go->hpi_context = usb;1133 go->hpi_context = usb;
1134 1134
1135 ep = usb->usbdev->ep_in[4];
1136 if (!ep)
1137 return -ENODEV;
1138
1135 /* Allocate the URB and buffer for receiving incoming interrupts */1139 /* Allocate the URB and buffer for receiving incoming interrupts */
1136 usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);1140 usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
1137 if (usb->intr_urb == NULL)1141 if (usb->intr_urb == NULL)
@@ -1141,7 +1145,6 @@ static int go7007_usb_probe(struct usb_interface *intf, · 3 unmodified lines
1141 if (usb->intr_urb->transfer_buffer == NULL)1145 if (usb->intr_urb->transfer_buffer == NULL)
1142 goto allocfail;1146 goto allocfail;
1143 1147
1144 ep = usb->usbdev->ep_in[4];
1145 if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK)1148 if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK)
1146 usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,1149 usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
1147 usb_rcvbulkpipe(usb->usbdev, 4),1150 usb_rcvbulkpipe(usb->usbdev, 4),
@@ -1263,9 +1266,13 @@ static int go7007_usb_probe(struct usb_interface *intf, · 115 unmodified lines
1263 1266
1264 /* Allocate the URBs and buffers for receiving the video stream */1267 /* Allocate the URBs and buffers for receiving the video stream */
1265 if (board->flags & GO7007_USB_EZUSB) {1268 if (board->flags & GO7007_USB_EZUSB) {
1269 if (!usb->usbdev->ep_in[6])
1270 goto allocfail;
1266 v_urb_len = 1024;1271 v_urb_len = 1024;
1267 video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);1272 video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
1268 } else {1273 } else {
1274 if (!usb->usbdev->ep_in[1])
1275 goto allocfail;
1269 v_urb_len = 512;1276 v_urb_len = 512;
1270 video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);1277 video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
1271 }1278 }
@@ -1285,6 +1292,8 @@ static int go7007_usb_probe(struct usb_interface *intf, · 13 unmodified lines
1285 /* Allocate the URBs and buffers for receiving the audio stream */1292 /* Allocate the URBs and buffers for receiving the audio stream */
1286 if ((board->flags & GO7007_USB_EZUSB) &&1293 if ((board->flags & GO7007_USB_EZUSB) &&
1287 (board->main_info.flags & GO7007_BOARD_HAS_AUDIO)) {1294 (board->main_info.flags & GO7007_BOARD_HAS_AUDIO)) {
1295 if (!usb->usbdev->ep_in[8])
1296 goto allocfail;
1288 for (i = 0; i < 8; ++i) {1297 for (i = 0; i < 8; ++i) {
1289 usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);1298 usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1290 if (usb->audio_urbs[i] == NULL)1299 if (usb->audio_urbs[i] == NULL)
drivers/media/usb/gspca/gspca.c+1−1
@@ -925,7 +925,7 @@ static int wxh_to_nearest_mode(struct gspca_dev *gspca_dev, · 924 unmodified lines
925{925{
926 int i;926 int i;
927 927
928 for (i = gspca_dev->cam.nmodes; --i > 0; ) {928 for (i = gspca_dev->cam.nmodes; --i >= 0; ) {
929 if (width >= gspca_dev->cam.cam_mode[i].width929 if (width >= gspca_dev->cam.cam_mode[i].width
930 && height >= gspca_dev->cam.cam_mode[i].height930 && height >= gspca_dev->cam.cam_mode[i].height
931 && pixelformat == gspca_dev->cam.cam_mode[i].pixelformat)931 && pixelformat == gspca_dev->cam.cam_mode[i].pixelformat)
drivers/media/usb/gspca/jl2005bcd.c+1−1
@@ -165,7 +165,7 @@ static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev) · 164 unmodified lines
165{165{
166 struct sd *sd = (struct sd *)gspca_dev;166 struct sd *sd = (struct sd *)gspca_dev;
167 int i = 0;167 int i = 0;
168 int retval = -1;168 int retval;
169 unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f};169 unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f};
170 170
171 gspca_dbg(gspca_dev, D_PROBE, "Running jl2005c_get_firmware_id\n");171 gspca_dbg(gspca_dev, D_PROBE, "Running jl2005c_get_firmware_id\n");
drivers/media/usb/gspca/ov534.c+1−1
@@ -14,7 +14,7 @@ · 13 unmodified lines
14 * PS3 Eye camera - brightness, contrast, awb, agc, aec controls14 * PS3 Eye camera - brightness, contrast, awb, agc, aec controls
15 * added by Max Thrun <bear24rw@gmail.com>15 * added by Max Thrun <bear24rw@gmail.com>
16 * PS3 Eye camera - FPS range extended by Joseph Howse16 * PS3 Eye camera - FPS range extended by Joseph Howse
17 * <josephhowse@nummist.com> http://nummist.com17 * <josephhowse@nummist.com> https://nummist.com
18 */18 */
19 19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/media/usb/gspca/sn9c2028.c+1−1
@@ -215,7 +215,7 @@ static int sd_config(struct gspca_dev *gspca_dev, · 214 unmodified lines
215/* this function is called at probe and resume time */215/* this function is called at probe and resume time */
216static int sd_init(struct gspca_dev *gspca_dev)216static int sd_init(struct gspca_dev *gspca_dev)
217{217{
218 int status = -1;218 int status;
219 219
220 sn9c2028_read1(gspca_dev);220 sn9c2028_read1(gspca_dev);
221 sn9c2028_read1(gspca_dev);221 sn9c2028_read1(gspca_dev);
drivers/media/v4l2-core/v4l2-async.c+75−8
@@ -50,7 +50,8 @@ static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n) · 49 unmodified lines
50 return n->ops->complete(n);50 return n->ops->complete(n);
51}51}
52 52
53static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)53static bool match_i2c(struct v4l2_async_notifier *notifier,
54 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
54{55{
55#if IS_ENABLED(CONFIG_I2C)56#if IS_ENABLED(CONFIG_I2C)
56 struct i2c_client *client = i2c_verify_client(sd->dev);57 struct i2c_client *client = i2c_verify_client(sd->dev);
@@ -63,18 +64,83 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) · 6 unmodified lines
63#endif64#endif
64}65}
65 66
66static bool match_devname(struct v4l2_subdev *sd,67static bool match_devname(struct v4l2_async_notifier *notifier,
67 struct v4l2_async_subdev *asd)68 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
68{69{
69 return !strcmp(asd->match.device_name, dev_name(sd->dev));70 return !strcmp(asd->match.device_name, dev_name(sd->dev));
70}71}
71 72
72static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)73static bool match_fwnode(struct v4l2_async_notifier *notifier,
74 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
73{75{
74 return sd->fwnode == asd->match.fwnode;76 struct fwnode_handle *other_fwnode;
77 struct fwnode_handle *dev_fwnode;
78 bool asd_fwnode_is_ep;
79 bool sd_fwnode_is_ep;
80 struct device *dev;
81
82 /*
83 * Both the subdev and the async subdev can provide either an endpoint
84 * fwnode or a device fwnode. Start with the simple case of direct
85 * fwnode matching.
86 */
87 if (sd->fwnode == asd->match.fwnode)
88 return true;
89
90 /*
91 * Otherwise, check if the sd fwnode and the asd fwnode refer to an
92 * endpoint or a device. If they're of the same type, there's no match.
93 * Technically speaking this checks if the nodes refer to a connected
94 * endpoint, which is the simplest check that works for both OF and
95 * ACPI. This won't make a difference, as drivers should not try to
96 * match unconnected endpoints.
97 */
98 sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd->fwnode);
99 asd_fwnode_is_ep = fwnode_graph_is_endpoint(asd->match.fwnode);
100
101 if (sd_fwnode_is_ep == asd_fwnode_is_ep)
102 return false;
103
104 /*
105 * The sd and asd fwnodes are of different types. Get the device fwnode
106 * parent of the endpoint fwnode, and compare it with the other fwnode.
107 */
108 if (sd_fwnode_is_ep) {
109 dev_fwnode = fwnode_graph_get_port_parent(sd->fwnode);
110 other_fwnode = asd->match.fwnode;
111 } else {
112 dev_fwnode = fwnode_graph_get_port_parent(asd->match.fwnode);
113 other_fwnode = sd->fwnode;
114 }
115
116 fwnode_handle_put(dev_fwnode);
117
118 if (dev_fwnode != other_fwnode)
119 return false;
120
121 /*
122 * We have a heterogeneous match. Retrieve the struct device of the side
123 * that matched on a device fwnode to print its driver name.
124 */
125 if (sd_fwnode_is_ep)
126 dev = notifier->v4l2_dev ? notifier->v4l2_dev->dev
127 : notifier->sd->dev;
128 else
129 dev = sd->dev;
130
131 if (dev && dev->driver) {
132 if (sd_fwnode_is_ep)
133 dev_warn(dev, "Driver %s uses device fwnode, incorrect match may occur\n",
134 dev->driver->name);
135 dev_notice(dev, "Consider updating driver %s to match on endpoints\n",
136 dev->driver->name);
137 }
138
139 return true;
75}140}
76 141
77static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)142static bool match_custom(struct v4l2_async_notifier *notifier,
143 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
78{144{
79 if (!asd->match.custom.match)145 if (!asd->match.custom.match)
80 /* Match always */146 /* Match always */
@@ -91,7 +157,8 @@ static struct v4l2_async_subdev * · 10 unmodified lines
91v4l2_async_find_match(struct v4l2_async_notifier *notifier,157v4l2_async_find_match(struct v4l2_async_notifier *notifier,
92 struct v4l2_subdev *sd)158 struct v4l2_subdev *sd)
93{159{
94 bool (*match)(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd);160 bool (*match)(struct v4l2_async_notifier *notifier,
161 struct v4l2_subdev *sd, struct v4l2_async_subdev *asd);
95 struct v4l2_async_subdev *asd;162 struct v4l2_async_subdev *asd;
96 163
97 list_for_each_entry(asd, &notifier->waiting, list) {164 list_for_each_entry(asd, &notifier->waiting, list) {
@@ -116,7 +183,7 @@ v4l2_async_find_match(struct v4l2_async_notifier *notifier, · 18 unmodified lines
116 }183 }
117 184
118 /* match cannot be NULL here */185 /* match cannot be NULL here */
119 if (match(sd, asd))186 if (match(notifier, sd, asd))
120 return asd;187 return asd;
121 }188 }
122 189
drivers/media/v4l2-core/v4l2-compat-ioctl32.c+8−2
@@ -246,6 +246,9 @@ struct v4l2_format32 { · 245 unmodified lines
246 * @memory: buffer memory type246 * @memory: buffer memory type
247 * @format: frame format, for which buffers are requested247 * @format: frame format, for which buffers are requested
248 * @capabilities: capabilities of this buffer type.248 * @capabilities: capabilities of this buffer type.
249 * @flags: additional buffer management attributes (ignored unless the
250 * queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability and
251 * configured for MMAP streaming I/O).
249 * @reserved: future extensions252 * @reserved: future extensions
250 */253 */
251struct v4l2_create_buffers32 {254struct v4l2_create_buffers32 {
@@ -254,7 +257,8 @@ struct v4l2_create_buffers32 { · 2 unmodified lines
254 __u32 memory; /* enum v4l2_memory */257 __u32 memory; /* enum v4l2_memory */
255 struct v4l2_format32 format;258 struct v4l2_format32 format;
256 __u32 capabilities;259 __u32 capabilities;
257 __u32 reserved[7];260 __u32 flags;
261 __u32 reserved[6];
258};262};
259 263
260static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)264static int __bufsize_v4l2_format(struct v4l2_format32 __user *p32, u32 *size)
@@ -355,7 +359,8 @@ static int get_v4l2_create32(struct v4l2_create_buffers __user *p64, · 94 unmodified lines
355{359{
356 if (!access_ok(p32, sizeof(*p32)) ||360 if (!access_ok(p32, sizeof(*p32)) ||
357 copy_in_user(p64, p32,361 copy_in_user(p64, p32,
358 offsetof(struct v4l2_create_buffers32, format)))362 offsetof(struct v4l2_create_buffers32, format)) ||
363 assign_in_user(&p64->flags, &p32->flags))
359 return -EFAULT;364 return -EFAULT;
360 return __get_v4l2_format32(&p64->format, &p32->format,365 return __get_v4l2_format32(&p64->format, &p32->format,
361 aux_buf, aux_space);366 aux_buf, aux_space);
@@ -417,6 +422,7 @@ static int put_v4l2_create32(struct v4l2_create_buffers __user *p64, · 55 unmodified lines
417 copy_in_user(p32, p64,422 copy_in_user(p32, p64,
418 offsetof(struct v4l2_create_buffers32, format)) ||423 offsetof(struct v4l2_create_buffers32, format)) ||
419 assign_in_user(&p32->capabilities, &p64->capabilities) ||424 assign_in_user(&p32->capabilities, &p64->capabilities) ||
425 assign_in_user(&p32->flags, &p64->flags) ||
420 copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))426 copy_in_user(p32->reserved, p64->reserved, sizeof(p64->reserved)))
421 return -EFAULT;427 return -EFAULT;
422 return __put_v4l2_format32(&p64->format, &p32->format);428 return __put_v4l2_format32(&p64->format, &p32->format);
drivers/media/v4l2-core/v4l2-ioctl.c+11−8
@@ -582,7 +582,10 @@ static void v4l_print_querymenu(const void *arg, bool write_only) · 581 unmodified lines
582static void v4l_print_control(const void *arg, bool write_only)582static void v4l_print_control(const void *arg, bool write_only)
583{583{
584 const struct v4l2_control *p = arg;584 const struct v4l2_control *p = arg;
585 const char *name = v4l2_ctrl_get_name(p->id);
585 586
587 if (name)
588 pr_cont("name=%s, ", name);
586 pr_cont("id=0x%x, value=%d\n", p->id, p->value);589 pr_cont("id=0x%x, value=%d\n", p->id, p->value);
587}590}
588 591
@@ -594,12 +597,15 @@ static void v4l_print_ext_controls(const void *arg, bool write_only) · 5 unmodified lines
594 pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",597 pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d",
595 p->which, p->count, p->error_idx, p->request_fd);598 p->which, p->count, p->error_idx, p->request_fd);
596 for (i = 0; i < p->count; i++) {599 for (i = 0; i < p->count; i++) {
600 unsigned int id = p->controls[i].id;
601 const char *name = v4l2_ctrl_get_name(id);
602
603 if (name)
604 pr_cont(", name=%s", name);
597 if (!p->controls[i].size)605 if (!p->controls[i].size)
598 pr_cont(", id/val=0x%x/0x%x",606 pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value);
599 p->controls[i].id, p->controls[i].value);
600 else607 else
601 pr_cont(", id/size=0x%x/%u",608 pr_cont(", id/size=0x%x/%u", id, p->controls[i].size);
602 p->controls[i].id, p->controls[i].size);
603 }609 }
604 pr_cont("\n");610 pr_cont("\n");
605}611}
@@ -2038,9 +2044,6 @@ static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, · 1432 unmodified lines
2038 2044
2039 if (ret)2045 if (ret)
2040 return ret;2046 return ret;
2041
2042 CLEAR_AFTER_FIELD(p, capabilities);
2043
2044 return ops->vidioc_reqbufs(file, fh, p);2047 return ops->vidioc_reqbufs(file, fh, p);
2045}2048}
2046 2049
@@ -2080,7 +2083,7 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, · 33 unmodified lines
2080 if (ret)2083 if (ret)
2081 return ret;2084 return ret;
2082 2085
2083 CLEAR_AFTER_FIELD(create, capabilities);2086 CLEAR_AFTER_FIELD(create, flags);
2084 2087
2085 v4l_sanitize_format(&create->format);2088 v4l_sanitize_format(&create->format);
2086 2089
drivers/media/v4l2-core/v4l2-mem2mem.c+3−3
@@ -556,7 +556,7 @@ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, · 555 unmodified lines
556 ret = vb2_querybuf(vq, buf);556 ret = vb2_querybuf(vq, buf);
557 557
558 /* Adjust MMAP memory offsets for the CAPTURE queue */558 /* Adjust MMAP memory offsets for the CAPTURE queue */
559 if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) {559 if (buf->memory == V4L2_MEMORY_MMAP && V4L2_TYPE_IS_CAPTURE(vq->type)) {
560 if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) {560 if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) {
561 for (i = 0; i < buf->length; ++i)561 for (i = 0; i < buf->length; ++i)
562 buf->m.planes[i].m.mem_offset562 buf->m.planes[i].m.mem_offset
@@ -712,7 +712,7 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, · 149 unmodified lines
712 int ret;712 int ret;
713 713
714 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);714 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
715 if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&715 if (V4L2_TYPE_IS_CAPTURE(vq->type) &&
716 (buf->flags & V4L2_BUF_FLAG_REQUEST_FD)) {716 (buf->flags & V4L2_BUF_FLAG_REQUEST_FD)) {
717 dprintk("%s: requests cannot be used with capture buffers\n",717 dprintk("%s: requests cannot be used with capture buffers\n",
718 __func__);718 __func__);
@@ -729,7 +729,7 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, · 10 unmodified lines
729 * buffer as DONE with LAST flag since it won't be queued on the729 * buffer as DONE with LAST flag since it won't be queued on the
730 * device.730 * device.
731 */731 */
732 if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&732 if (V4L2_TYPE_IS_CAPTURE(vq->type) &&
733 vb2_is_streaming(vq) && !vb2_start_streaming_called(vq) &&733 vb2_is_streaming(vq) && !vb2_start_streaming_called(vq) &&
734 (v4l2_m2m_has_stopped(m2m_ctx) || v4l2_m2m_dst_buf_is_last(m2m_ctx)))734 (v4l2_m2m_has_stopped(m2m_ctx) || v4l2_m2m_dst_buf_is_last(m2m_ctx)))
735 v4l2_m2m_force_last_buf_done(m2m_ctx, vq);735 v4l2_m2m_force_last_buf_done(m2m_ctx, vq);
drivers/staging/media/Kconfig+0−2
@@ -42,8 +42,6 @@ source "drivers/staging/media/tegra-video/Kconfig" · 41 unmodified lines
42 42
43source "drivers/staging/media/ipu3/Kconfig"43source "drivers/staging/media/ipu3/Kconfig"
44 44
45source "drivers/staging/media/soc_camera/Kconfig"
46
47source "drivers/staging/media/phy-rockchip-dphy-rx0/Kconfig"45source "drivers/staging/media/phy-rockchip-dphy-rx0/Kconfig"
48 46
49source "drivers/staging/media/rkisp1/Kconfig"47source "drivers/staging/media/rkisp1/Kconfig"
drivers/staging/media/Makefile+0−1
@@ -10,7 +10,6 @@ obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/ · 9 unmodified lines
10obj-$(CONFIG_TEGRA_VDE) += tegra-vde/10obj-$(CONFIG_TEGRA_VDE) += tegra-vde/
11obj-$(CONFIG_VIDEO_HANTRO) += hantro/11obj-$(CONFIG_VIDEO_HANTRO) += hantro/
12obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/12obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
13obj-$(CONFIG_SOC_CAMERA) += soc_camera/
14obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0/13obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0) += phy-rockchip-dphy-rx0/
15obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rkisp1/14obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rkisp1/
16obj-$(CONFIG_VIDEO_USBVISION) += usbvision/15obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
drivers/staging/media/allegro-dvt/allegro-core.c+228−163
@@ -105,9 +105,11 @@ struct allegro_buffer { · 104 unmodified lines
105 struct list_head head;105 struct list_head head;
106};106};
107 107
108struct allegro_dev;
108struct allegro_channel;109struct allegro_channel;
109 110
110struct allegro_mbox {111struct allegro_mbox {
112 struct allegro_dev *dev;
111 unsigned int head;113 unsigned int head;
112 unsigned int tail;114 unsigned int tail;
113 unsigned int data;115 unsigned int data;
@@ -128,14 +130,15 @@ struct allegro_dev { · 14 unmodified lines
128 struct regmap *regmap;130 struct regmap *regmap;
129 struct regmap *sram;131 struct regmap *sram;
130 132
133 const struct fw_info *fw_info;
131 struct allegro_buffer firmware;134 struct allegro_buffer firmware;
132 struct allegro_buffer suballocator;135 struct allegro_buffer suballocator;
133 136
134 struct completion init_complete;137 struct completion init_complete;
135 138
136 /* The mailbox interface */139 /* The mailbox interface */
137 struct allegro_mbox mbox_command;140 struct allegro_mbox *mbox_command;
138 struct allegro_mbox mbox_status;141 struct allegro_mbox *mbox_status;
139 142
140 /*143 /*
141 * The downstream driver limits the users to 64 users, thus I can use144 * The downstream driver limits the users to 64 users, thus I can use
@@ -204,6 +207,11 @@ struct allegro_channel { · 62 unmodified lines
204 unsigned int cpb_size;207 unsigned int cpb_size;
205 unsigned int gop_size;208 unsigned int gop_size;
206 209
210 struct allegro_buffer config_blob;
211
212 unsigned int num_ref_idx_l0;
213 unsigned int num_ref_idx_l1;
214
207 struct v4l2_ctrl *mpeg_video_h264_profile;215 struct v4l2_ctrl *mpeg_video_h264_profile;
208 struct v4l2_ctrl *mpeg_video_h264_level;216 struct v4l2_ctrl *mpeg_video_h264_level;
209 struct v4l2_ctrl *mpeg_video_h264_i_frame_qp;217 struct v4l2_ctrl *mpeg_video_h264_i_frame_qp;
@@ -270,6 +278,7 @@ struct fw_info { · 60 unmodified lines
270 unsigned int mailbox_cmd;278 unsigned int mailbox_cmd;
271 unsigned int mailbox_status;279 unsigned int mailbox_status;
272 size_t mailbox_size;280 size_t mailbox_size;
281 enum mcu_msg_version mailbox_version;
273 size_t suballocator_size;282 size_t suballocator_size;
274};283};
275 284
@@ -281,7 +290,17 @@ static const struct fw_info supported_firmware[] = { · 5 unmodified lines
281 .mailbox_cmd = 0x7800,290 .mailbox_cmd = 0x7800,
282 .mailbox_status = 0x7c00,291 .mailbox_status = 0x7c00,
283 .mailbox_size = 0x400 - 0x8,292 .mailbox_size = 0x400 - 0x8,
293 .mailbox_version = MCU_MSG_VERSION_2018_2,
284 .suballocator_size = SZ_16M,294 .suballocator_size = SZ_16M,
295 }, {
296 .id = 14680,
297 .id_codec = 126572,
298 .version = "v2019.2",
299 .mailbox_cmd = 0x7000,
300 .mailbox_status = 0x7800,
301 .mailbox_size = 0x800 - 0x8,
302 .mailbox_version = MCU_MSG_VERSION_2019_2,
303 .suballocator_size = SZ_32M,
285 },304 },
286};305};
287 306
@@ -583,12 +602,20 @@ static void allegro_free_buffer(struct allegro_dev *dev, · 295 unmodified lines
583 * Mailbox interface to send messages to the MCU.602 * Mailbox interface to send messages to the MCU.
584 */603 */
585 604
586static int allegro_mbox_init(struct allegro_dev *dev,605static void allegro_mcu_interrupt(struct allegro_dev *dev);
587 struct allegro_mbox *mbox,606static void allegro_handle_message(struct allegro_dev *dev,
588 unsigned int base, size_t size)607 union mcu_msg_response *msg);
608
609static struct allegro_mbox *allegro_mbox_init(struct allegro_dev *dev,
610 unsigned int base, size_t size)
589{611{
612 struct allegro_mbox *mbox;
613
614 mbox = devm_kmalloc(&dev->plat_dev->dev, sizeof(*mbox), GFP_KERNEL);
590 if (!mbox)615 if (!mbox)
591 return -EINVAL;616 return ERR_PTR(-ENOMEM);
617
618 mbox->dev = dev;
592 619
593 mbox->head = base;620 mbox->head = base;
594 mbox->tail = base + 0x4;621 mbox->tail = base + 0x4;
@@ -599,52 +626,37 @@ static int allegro_mbox_init(struct allegro_dev *dev, · 4 unmodified lines
599 regmap_write(dev->sram, mbox->head, 0);626 regmap_write(dev->sram, mbox->head, 0);
600 regmap_write(dev->sram, mbox->tail, 0);627 regmap_write(dev->sram, mbox->tail, 0);
601 628
602 return 0;629 return mbox;
603}630}
604 631
605static int allegro_mbox_write(struct allegro_dev *dev,632static int allegro_mbox_write(struct allegro_mbox *mbox,
606 struct allegro_mbox *mbox, void *src, size_t size)633 const u32 *src, size_t size)
607{634{
608 struct mcu_msg_header *header = src;635 struct regmap *sram = mbox->dev->sram;
609 unsigned int tail;636 unsigned int tail;
610 size_t size_no_wrap;637 size_t size_no_wrap;
611 int err = 0;638 int err = 0;
639 int stride = regmap_get_reg_stride(sram);
612 640
613 if (!src)641 if (!src)
614 return -EINVAL;642 return -EINVAL;
615 643
616 if (size > mbox->size) {644 if (size > mbox->size)
617 v4l2_err(&dev->v4l2_dev,
618 "message (%zu bytes) too large for mailbox (%zu bytes)\n",
619 size, mbox->size);
620 return -EINVAL;645 return -EINVAL;
621 }
622
623 if (header->length != size - sizeof(*header)) {
624 v4l2_err(&dev->v4l2_dev,
625 "invalid message length: %u bytes (expected %zu bytes)\n",
626 header->length, size - sizeof(*header));
627 return -EINVAL;
628 }
629
630 v4l2_dbg(2, debug, &dev->v4l2_dev,
631 "write command message: type %s, body length %d\n",
632 msg_type_name(header->type), header->length);
633 646
634 mutex_lock(&mbox->lock);647 mutex_lock(&mbox->lock);
635 regmap_read(dev->sram, mbox->tail, &tail);648 regmap_read(sram, mbox->tail, &tail);
636 if (tail > mbox->size) {649 if (tail > mbox->size) {
637 v4l2_err(&dev->v4l2_dev,
638 "invalid tail (0x%x): must be smaller than mailbox size (0x%zx)\n",
639 tail, mbox->size);
640 err = -EIO;650 err = -EIO;
641 goto out;651 goto out;
642 }652 }
643 size_no_wrap = min(size, mbox->size - (size_t)tail);653 size_no_wrap = min(size, mbox->size - (size_t)tail);
644 regmap_bulk_write(dev->sram, mbox->data + tail, src, size_no_wrap / 4);654 regmap_bulk_write(sram, mbox->data + tail,
645 regmap_bulk_write(dev->sram, mbox->data,655 src, size_no_wrap / stride);
646 src + size_no_wrap, (size - size_no_wrap) / 4);656 regmap_bulk_write(sram, mbox->data,
647 regmap_write(dev->sram, mbox->tail, (tail + size) % mbox->size);657 src + (size_no_wrap / sizeof(*src)),
658 (size - size_no_wrap) / stride);
659 regmap_write(sram, mbox->tail, (tail + size) % mbox->size);
648 660
649out:661out:
650 mutex_unlock(&mbox->lock);662 mutex_unlock(&mbox->lock);
@@ -652,40 +664,32 @@ out: · 1 unmodified line
652 return err;664 return err;
653}665}
654 666
655static ssize_t allegro_mbox_read(struct allegro_dev *dev,667static ssize_t allegro_mbox_read(struct allegro_mbox *mbox,
656 struct allegro_mbox *mbox,668 u32 *dst, size_t nbyte)
657 void *dst, size_t nbyte)
658{669{
659 struct mcu_msg_header *header;670 struct {
671 u16 length;
672 u16 type;
673 } __attribute__ ((__packed__)) *header;
674 struct regmap *sram = mbox->dev->sram;
660 unsigned int head;675 unsigned int head;
661 ssize_t size;676 ssize_t size;
662 size_t body_no_wrap;677 size_t body_no_wrap;
678 int stride = regmap_get_reg_stride(sram);
663 679
664 regmap_read(dev->sram, mbox->head, &head);680 regmap_read(sram, mbox->head, &head);
665 if (head > mbox->size) {681 if (head > mbox->size)
666 v4l2_err(&dev->v4l2_dev,
667 "invalid head (0x%x): must be smaller than mailbox size (0x%zx)\n",
668 head, mbox->size);
669 return -EIO;682 return -EIO;
670 }
671 683
672 /* Assume that the header does not wrap. */684 /* Assume that the header does not wrap. */
673 regmap_bulk_read(dev->sram, mbox->data + head,685 regmap_bulk_read(sram, mbox->data + head,
674 dst, sizeof(*header) / 4);686 dst, sizeof(*header) / stride);
675 header = dst;687 header = (void *)dst;
676 size = header->length + sizeof(*header);688 size = header->length + sizeof(*header);
677 if (size > mbox->size || size & 0x3) {689 if (size > mbox->size || size & 0x3)
678 v4l2_err(&dev->v4l2_dev,
679 "invalid message length: %zu bytes (maximum %zu bytes)\n",
680 header->length + sizeof(*header), mbox->size);
681 return -EIO;690 return -EIO;
682 }691 if (size > nbyte)
683 if (size > nbyte) {
684 v4l2_err(&dev->v4l2_dev,
685 "destination buffer too small: %zu bytes (need %zu bytes)\n",
686 nbyte, size);
687 return -EINVAL;692 return -EINVAL;
688 }
689 693
690 /*694 /*
691 * The message might wrap within the mailbox. If the message does not695 * The message might wrap within the mailbox. If the message does not
@@ -698,24 +702,84 @@ static ssize_t allegro_mbox_read(struct allegro_dev *dev, · 6 unmodified lines
698 */702 */
699 body_no_wrap = min((size_t)header->length,703 body_no_wrap = min((size_t)header->length,
700 (size_t)(mbox->size - (head + sizeof(*header))));704 (size_t)(mbox->size - (head + sizeof(*header))));
701 regmap_bulk_read(dev->sram, mbox->data + head + sizeof(*header),705 regmap_bulk_read(sram, mbox->data + head + sizeof(*header),
702 dst + sizeof(*header), body_no_wrap / 4);706 dst + (sizeof(*header) / sizeof(*dst)),
703 regmap_bulk_read(dev->sram, mbox->data,707 body_no_wrap / stride);
704 dst + sizeof(*header) + body_no_wrap,708 regmap_bulk_read(sram, mbox->data,
705 (header->length - body_no_wrap) / 4);709 dst + (sizeof(*header) + body_no_wrap) / sizeof(*dst),
706 710 (header->length - body_no_wrap) / stride);
707 regmap_write(dev->sram, mbox->head, (head + size) % mbox->size);
708 711
709 v4l2_dbg(2, debug, &dev->v4l2_dev,712 regmap_write(sram, mbox->head, (head + size) % mbox->size);
710 "read status message: type %s, body length %d\n",
711 msg_type_name(header->type), header->length);
712 713
713 return size;714 return size;
714}715}
715 716
716static void allegro_mcu_interrupt(struct allegro_dev *dev)717/**
718 * allegro_mbox_send() - Send a message via the mailbox
719 * @mbox: the mailbox which is used to send the message
720 * @msg: the message to send
721 */
722static int allegro_mbox_send(struct allegro_mbox *mbox, void *msg)
717{723{
718 regmap_write(dev->regmap, AL5_MCU_INTERRUPT, BIT(0));724 struct allegro_dev *dev = mbox->dev;
725 ssize_t size;
726 int err;
727 u32 *tmp;
728
729 tmp = kzalloc(mbox->size, GFP_KERNEL);
730 if (!tmp) {
731 err = -ENOMEM;
732 goto out;
733 }
734
735 size = allegro_encode_mail(tmp, msg);
736
737 err = allegro_mbox_write(mbox, tmp, size);
738 kfree(tmp);
739 if (err)
740 goto out;
741
742 allegro_mcu_interrupt(dev);
743
744out:
745 return err;
746}
747
748/**
749 * allegro_mbox_notify() - Notify the mailbox about a new message
750 * @mbox: The allegro_mbox to notify
751 */
752static void allegro_mbox_notify(struct allegro_mbox *mbox)
753{
754 struct allegro_dev *dev = mbox->dev;
755 union mcu_msg_response *msg;
756 ssize_t size;
757 u32 *tmp;
758 int err;
759
760 msg = kmalloc(sizeof(*msg), GFP_KERNEL);
761 if (!msg)
762 return;

439 more lines aren’t shown here.

drivers/staging/media/allegro-dvt/allegro-mail.c+506−0

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

drivers/staging/media/allegro-dvt/allegro-mail.h+69−42

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

drivers/staging/media/hantro/hantro.h+3−10

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

drivers/staging/media/hantro/hantro_drv.c+43−51

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

drivers/staging/media/hantro/hantro_h1_jpeg_enc.c+17−0

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

drivers/staging/media/hantro/hantro_h264.c+2−4

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

drivers/staging/media/hantro/hantro_hw.h+3−2

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

drivers/staging/media/hantro/hantro_v4l2.c+15−15

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

drivers/staging/media/hantro/imx8m_vpu_hw.c+1−1

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

drivers/staging/media/hantro/rk3288_vpu_hw.c+4−4

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

drivers/staging/media/hantro/rk3399_vpu_hw.c+3−4

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

drivers/staging/media/imx/imx-ic-prp.c+2−2

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

drivers/staging/media/imx/imx-ic-prpencvf.c+2−2

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

drivers/staging/media/imx/imx-media-csi.c+2−2

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

drivers/staging/media/imx/imx-media-vdic.c+2−2

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

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

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

drivers/staging/media/rkisp1/rkisp1-capture.c+20−36

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

drivers/staging/media/rkisp1/rkisp1-common.h+15−11

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

drivers/staging/media/rkisp1/rkisp1-dev.c+8−3

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

drivers/staging/media/rkisp1/rkisp1-isp.c+38−37

This diff is large: its 262 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-regs.h+0−1

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

drivers/staging/media/rkisp1/rkisp1-resizer.c+9−9

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

drivers/staging/media/rkisp1/rkisp1-stats.c+17−109

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

drivers/staging/media/rkisp1/uapi/rkisp1-config.h+2−2

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

drivers/staging/media/rkvdec/rkvdec.c+28−1

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

drivers/staging/media/soc_camera/Kconfig+0−51

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

drivers/staging/media/soc_camera/Makefile+0−7

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

drivers/staging/media/soc_camera/TODO+0−4

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

drivers/staging/media/soc_camera/imx074.c+0−492

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

drivers/staging/media/soc_camera/mt9t031.c+0−853

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

drivers/staging/media/soc_camera/soc-camera.rst+0−171

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

drivers/staging/media/soc_camera/soc_camera.c+0−2164

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

drivers/staging/media/soc_camera/soc_mediabus.c+0−529

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

drivers/staging/media/soc_camera/soc_mt9v022.c+0−1008

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

drivers/staging/media/soc_camera/soc_ov5642.c+0−1085

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

drivers/staging/media/soc_camera/soc_ov9740.c+0−992

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

drivers/staging/media/tegra-vde/vde.c+27−18

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

drivers/usb/class/cdc-acm.c+6−0

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

include/linux/platform_data/media/omap1_camera.h+0−32

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

include/linux/property.h+5−0

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

include/media/cec.h+55−2

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

include/media/davinci/vpbe_display.h+1−1

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

include/media/drv-intf/soc_mediabus.h+0−107

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

include/media/dvbdev.h+3−3

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

include/media/media-device.h+1−1

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

include/media/media-devnode.h+1−1

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

include/media/media-entity.h+1−1

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

include/media/soc_camera.h+0−397

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

include/media/tpg/v4l2-tpg.h+2−1

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

include/media/v4l2-mc.h+4−4

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

include/media/v4l2-rect.h+20−0

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

include/media/v4l2-subdev.h+20−19

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

include/media/videobuf2-core.h+40−11

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

include/media/videobuf2-v4l2.h+13−0

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

include/uapi/linux/videodev2.h+15−2

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