History

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

Pull media updates from Mauro Carvalho Chehab: - Removal of some old unused sensor drivers: ad9389b, m5mols, mt9m032, mt9t001, noon010pc30, s5k6aa, sr030pc30 and vs6624 - New i.MX8 image sensor interface driver - Some new RC keymaps - lots of cleanups at atomisp driver to make it support standard features present on other webcam drivers - the cx18 and saa7146 now uses VB2 - lots of cleanups and driver improvements * tag 'media/v6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (460 commits) media: ov5670: Fix probe on ACPI media: nxp: imx8-isi: Remove 300ms sleep after enabling channel media: nxp: imx8-isi: Replace udelay() with fsleep() media: nxp: imx8-isi: Drop partial support for i.MX8QM and i.MX8QXP media: nxp: Add i.MX8 ISI driver media: dt-bindings: media: Add i.MX8 ISI DT bindings media: atomisp: gmin_platform: Add Lenovo Ideapad Miix 310 gmin_vars media: atomisp: gmin_platform: Make DMI quirks take precedence over the _DSM table media: atomisp: Remove struct atomisp_sub_device index field media: atomisp: Drop support for streaming from 2 sensors at once media: atomisp: Remove atomisp_try_fmt() call from atomisp_set_fmt() media: atomisp: Remove unused ATOM_ISP_MAX_WIDTH_TMP and ATOM_ISP_MAX_HEIGHT_TMP media: atomisp: Remove snr_mbus_fmt local var from atomisp_try_fmt() media: atomisp: Remove custom V4L2_CID_FMT_AUTO control media: atomisp: Remove continuous mode related code from atomisp_set_fmt() media: atomisp: Remove duplicate atomisp_[start|stop]_streaming() prototypes media: atomisp: gc0310: Switch over to ACPI powermanagement media: atomisp: gc0310: Use devm_kzalloc() for data struct media: atomisp: gc0310: Add runtime-pm support media: atomisp: gc0310: Delay power-on till streaming is started ...

Linus Torvalds committed 3 years ago

Commit 4ea95692 parents c8cc58e 73b41dc442 files · +15626 −21778Browse files

Unified · Split

442 files
  1. Documentation/admin-guide/media/cec.rst +45 −34
  2. Documentation/admin-guide/media/i2c-cardlist.rst +0 −8
  3. Documentation/devicetree/bindings/media/allwinner,sun4i-a10-ir.yaml +1 −1
  4. Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml +2 −2
  5. Documentation/devicetree/bindings/media/amlogic,axg-ge2d.yaml +2 −2
  6. Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml +2 −2
  7. Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml +2 −2
  8. Documentation/devicetree/bindings/media/amlogic,meson6-ir.yaml +47 −0
  9. Documentation/devicetree/bindings/media/exynos-fimc-lite.txt +0 −16
  10. Documentation/devicetree/bindings/media/exynos4-fimc-is.txt +0 −50
  11. Documentation/devicetree/bindings/media/gpio-ir-receiver.yaml +3 −0
  12. Documentation/devicetree/bindings/media/i2c/chrontel,ch7322.yaml +2 −2
  13. Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml +3 −3
  14. Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml +1 −1
  15. Documentation/devicetree/bindings/media/i2c/ov2685.txt +0 −41
  16. Documentation/devicetree/bindings/media/i2c/ov8856.yaml +1 −1
  17. Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml +1 −1
  18. Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml +101 −0
  19. Documentation/devicetree/bindings/media/i2c/samsung,s5k5baf.yaml +101 −0
  20. Documentation/devicetree/bindings/media/i2c/samsung,s5k6a3.yaml +98 −0
  21. Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml +18 −7
  22. Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml +1 −1
  23. Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml +1 −1
  24. Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml +46 −71
  25. Documentation/devicetree/bindings/media/meson-ir.txt +0 −20
  26. Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml +2 −2
  27. Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml +173 −0
  28. Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml +2 −2
  29. Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml +2 −2
  30. Documentation/devicetree/bindings/media/qcom,msm8916-venus.yaml +29 −57
  31. Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml +2 −2
  32. Documentation/devicetree/bindings/media/qcom,msm8996-venus.yaml +63 −83
  33. Documentation/devicetree/bindings/media/qcom,sc7180-venus.yaml +38 −59
  34. Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml +54 −78
  35. Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml +2 −2
  36. Documentation/devicetree/bindings/media/qcom,sdm660-venus.yaml +58 −86
  37. Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml +2 −2
  38. Documentation/devicetree/bindings/media/qcom,sdm845-venus-v2.yaml +42 −66
  39. Documentation/devicetree/bindings/media/qcom,sdm845-venus.yaml +38 −66
  40. Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml +2 −2
  41. Documentation/devicetree/bindings/media/qcom,sm8250-venus.yaml +49 −73
  42. Documentation/devicetree/bindings/media/qcom,venus-common.yaml +73 −0
  43. Documentation/devicetree/bindings/media/rc.yaml +3 −1
  44. Documentation/devicetree/bindings/media/renesas,csi2.yaml +1 −0
  45. Documentation/devicetree/bindings/media/renesas,fcp.yaml +40 −5
  46. Documentation/devicetree/bindings/media/renesas,isp.yaml +1 −0
  47. Documentation/devicetree/bindings/media/renesas,vin.yaml +1 −0
  48. Documentation/devicetree/bindings/media/renesas,vsp1.yaml +9 −4
  49. Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml +2 −2
  50. Documentation/devicetree/bindings/media/rockchip-isp1.yaml +13 −6
  51. Documentation/devicetree/bindings/media/rockchip-vpu.yaml +2 −2
  52. Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml +170 −0
  53. Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml +152 −0
  54. Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml +220 −0
  55. Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml +63 −0
  56. Documentation/devicetree/bindings/media/samsung,fimc.yaml +279 −0
  57. Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml +165 −0
  58. Documentation/devicetree/bindings/media/samsung-fimc.txt +0 −209
  59. Documentation/devicetree/bindings/media/samsung-mipi-csis.txt +0 −81
  60. Documentation/devicetree/bindings/media/samsung-s5c73m3.txt +0 −97
  61. Documentation/devicetree/bindings/media/samsung-s5k5baf.txt +0 −58
  62. Documentation/devicetree/bindings/media/samsung-s5k6a3.txt +0 −33
  63. Documentation/devicetree/bindings/media/si470x.txt +0 −26
  64. Documentation/devicetree/bindings/media/silabs,si470x.yaml +48 −0
  65. Documentation/devicetree/bindings/media/st,stm32-cec.yaml +0 −53
  66. Documentation/devicetree/bindings/media/ti,cal.yaml +1 −1
  67. Documentation/driver-api/media/drivers/ccs/ccs.rst +22 −0
  68. Documentation/userspace-api/media/v4l/dev-overlay.rst +8 −2
  69. Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +25 −0
  70. Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst +28 −0
  71. Documentation/userspace-api/media/v4l/pixfmt-rgb.rst +42 −0
  72. Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst +15 −0
  73. Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst +94 −0
  74. Documentation/userspace-api/media/v4l/user-func.rst +1 −0
  75. Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +10 −0
  76. Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst +16 −36
  77. Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst +29 −15
  78. Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst +27 −12
  79. Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst +83 −0
  80. MAINTAINERS +17 −31
  81. drivers/media/cec/core/cec-adap.c +5 −2
  82. drivers/media/cec/platform/cec-gpio/cec-gpio.c +2 −3
  83. drivers/media/cec/platform/cros-ec/cros-ec-cec.c +14 −8
  84. drivers/media/cec/platform/meson/ao-cec-g12a.c +2 −4
  85. drivers/media/cec/platform/meson/ao-cec.c +2 −4
  86. drivers/media/cec/platform/s5p/s5p_cec.c +2 −3
  87. drivers/media/cec/platform/seco/seco-cec.c +2 −4
  88. drivers/media/cec/platform/sti/stih-cec.c +2 −4
  89. drivers/media/cec/platform/stm32/stm32-cec.c +2 −4
  90. drivers/media/cec/platform/tegra/tegra_cec.c +2 −4
  91. drivers/media/common/btcx-risc.h +0 −29
  92. drivers/media/common/saa7146/Kconfig +1 −1
  93. drivers/media/common/saa7146/saa7146_core.c +14 −26
  94. drivers/media/common/saa7146/saa7146_fops.c +75 −298
  95. drivers/media/common/saa7146/saa7146_hlp.c +40 −315
  96. drivers/media/common/saa7146/saa7146_vbi.c +118 −169
  97. drivers/media/common/saa7146/saa7146_video.c +199 −760
  98. drivers/media/common/videobuf2/videobuf2-v4l2.c +3 −2
  99. drivers/media/dvb-frontends/drx39xyj/drxj.c +1 −1
  100. drivers/media/dvb-frontends/drxk_hard.c +1 −1
  101. drivers/media/dvb-frontends/rtl2832_sdr.c +2 −4
  102. drivers/media/dvb-frontends/zd1301_demod.c +2 −4
  103. drivers/media/i2c/Kconfig +1 −67
  104. drivers/media/i2c/Makefile +0 −8
  105. drivers/media/i2c/ad9389b.c +0 −1215
  106. drivers/media/i2c/adv748x/adv748x-hdmi.c +15 −6
  107. drivers/media/i2c/adv7604.c +4 −1
  108. drivers/media/i2c/ccs/ccs-core.c +83 −74
  109. drivers/media/i2c/ccs/ccs.h +0 −14
  110. drivers/media/i2c/hi556.c +148 −2
  111. drivers/media/i2c/hi846.c +8 −3
  112. drivers/media/i2c/imx258.c +24 −9
  113. drivers/media/i2c/imx290.c +477 −119
  114. drivers/media/i2c/imx296.c +1 −10
  115. drivers/media/i2c/imx334.c +294 −28
  116. drivers/media/i2c/m5mols/Kconfig +0 −8
  117. drivers/media/i2c/m5mols/Makefile +0 −4
  118. drivers/media/i2c/m5mols/m5mols.h +0 −349
  119. drivers/media/i2c/m5mols/m5mols_capture.c +0 −158
  120. drivers/media/i2c/m5mols/m5mols_controls.c +0 −625
  121. drivers/media/i2c/m5mols/m5mols_core.c +0 −1051
  122. drivers/media/i2c/m5mols/m5mols_reg.h +0 −359
  123. drivers/media/i2c/max9286.c +1 −0
  124. drivers/media/i2c/mt9m032.c +0 −891
  125. drivers/media/i2c/mt9t001.c +0 −992
  126. drivers/media/i2c/noon010pc30.c +0 −821
  127. drivers/media/i2c/ov13b10.c +47 −28
  128. drivers/media/i2c/ov2685.c +77 −3
  129. drivers/media/i2c/ov5647.c +43 −13
  130. drivers/media/i2c/ov5670.c +79 −37
  131. drivers/media/i2c/ov7670.c +3 −8
  132. drivers/media/i2c/ov8856.c +0 −40
  133. drivers/media/i2c/s5k6aa.c +0 −1652
  134. drivers/media/i2c/sr030pc30.c +0 −762
  135. drivers/media/i2c/st-vgxy61.c +11 −12
  136. drivers/media/i2c/tc358746.c +2 −2
  137. drivers/media/i2c/vs6624.c +0 −854
  138. drivers/media/i2c/vs6624_regs.h +0 −325
  139. drivers/media/mc/mc-device.c +1 −2
  140. drivers/media/pci/bt8xx/Kconfig +1 −1
  141. drivers/media/pci/bt8xx/btcx-risc.c +0 −153
  142. drivers/media/pci/bt8xx/btcx-risc.h +0 −9
  143. drivers/media/pci/bt8xx/bttv-cards.c +0 −15
  144. drivers/media/pci/bt8xx/bttv-driver.c +9 −427
  145. drivers/media/pci/bt8xx/bttv-risc.c +0 −131
  146. drivers/media/pci/bt8xx/bttvp.h +1 −27
  147. drivers/media/pci/cobalt/cobalt-v4l2.c +13 −8
  148. drivers/media/pci/cx18/Kconfig +1 −1
  149. drivers/media/pci/cx18/cx18-driver.c +2 −2
  150. drivers/media/pci/cx18/cx18-driver.h +12 −12
  151. drivers/media/pci/cx18/cx18-fileops.c +16 −69
  152. drivers/media/pci/cx18/cx18-fileops.h +2 −1
  153. drivers/media/pci/cx18/cx18-ioctl.c +159 −232
  154. drivers/media/pci/cx18/cx18-mailbox.c +14 −13
  155. drivers/media/pci/cx18/cx18-streams.c +145 −133
  156. drivers/media/pci/cx23885/cx23885-core.c +3 −1
  157. drivers/media/pci/cx23885/cx23885-video.c +7 −6
  158. drivers/media/pci/dm1105/dm1105.c +1 −0
  159. drivers/media/pci/intel/ipu3/cio2-bridge.c +19 −4
  160. drivers/media/pci/intel/ipu3/cio2-bridge.h +2 −1
  161. drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +1 −0
  162. drivers/media/pci/saa7134/saa7134-cards.c +0 −1
  163. drivers/media/pci/saa7134/saa7134-core.c +0 −32
  164. drivers/media/pci/saa7134/saa7134-empress.c +2 −2
  165. drivers/media/pci/saa7134/saa7134-ts.c +1 −0
  166. drivers/media/pci/saa7134/saa7134-vbi.c +1 −0
  167. drivers/media/pci/saa7134/saa7134-video.c +5 −407
  168. drivers/media/pci/saa7134/saa7134.h +0 −13
  169. drivers/media/pci/saa7146/hexium_gemini.c +12 −11
  170. drivers/media/pci/saa7146/hexium_orion.c +13 −11
  171. drivers/media/pci/saa7146/mxb.c +29 −24
  172. drivers/media/pci/ttpci/budget-av.c +3 −2
  173. drivers/media/pci/tw68/tw68-video.c +9 −7
  174. drivers/media/pci/zoran/zoran_device.h +0 −2
  175. drivers/media/platform/allegro-dvt/allegro-core.c +2 −4
  176. drivers/media/platform/amlogic/meson-ge2d/ge2d.c +2 −4
  177. drivers/media/platform/amphion/vdec.c +53 −0
  178. drivers/media/platform/amphion/vpu_codec.h +2 −1
  179. drivers/media/platform/amphion/vpu_core.c +2 −4
  180. drivers/media/platform/amphion/vpu_drv.c +2 −4
  181. drivers/media/platform/amphion/vpu_malone.c +44 −1
  182. drivers/media/platform/amphion/vpu_malone.h +1 −0
  183. drivers/media/platform/aspeed/aspeed-video.c +2 −4
  184. drivers/media/platform/atmel/atmel-isi.c +4 −6
  185. drivers/media/platform/cadence/cdns-csi2rx.c +2 −4
  186. drivers/media/platform/cadence/cdns-csi2tx.c +2 −4
  187. drivers/media/platform/chips-media/coda-common.c +2 −3
  188. drivers/media/platform/intel/pxa_camera.c +4 −6
  189. drivers/media/platform/m2m-deinterlace.c +2 −4
  190. drivers/media/platform/marvell/mcam-core.c +2 −2
  191. drivers/media/platform/marvell/mmp-driver.c +3 −13
  192. drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +84 −56
  193. drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +12 −16
  194. drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +13 −30
  195. drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +8 −30
  196. drivers/media/platform/mediatek/mdp/mtk_mdp_core.c +2 −3
  197. drivers/media/platform/mediatek/mdp3/Makefile +1 −1
  198. drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +453 −0
  199. drivers/media/platform/mediatek/mdp3/mdp_sm_mt8183.h +144 −0
  200. drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h +24 −165
  201. drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h +20 −0
  202. drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +101 −47
  203. drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +346 −193
  204. drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +22 −2
  205. drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +13 −40
  206. drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +16 −2
  207. drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c +19 −17
  208. drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.h +0 −1
  209. drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c +27 −266
  210. drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h +109 −105
  211. drivers/media/platform/mediatek/mdp3/mtk-mdp3-type.h +53 −0
  212. drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c +83 −110
  213. drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.h +7 −22
  214. drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +10 −21
  215. drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +5 −5
  216. drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c +8 −0
  217. drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c +11 −1
  218. drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c +8 −6
  219. drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c +1 −1
  220. drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c +15 −8
  221. drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c +1 −1
  222. drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c +1 −1
  223. drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +82 −13
  224. drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h +12 −0
  225. drivers/media/platform/mediatek/vpu/mtk_vpu.c +2 −4
  226. drivers/media/platform/microchip/microchip-csi2dc.c +2 −4
  227. drivers/media/platform/microchip/microchip-isc-base.c +3 −2
  228. drivers/media/platform/microchip/microchip-sama5d2-isc.c +2 −4
  229. drivers/media/platform/microchip/microchip-sama7g5-isc.c +2 −4
  230. drivers/media/platform/nvidia/tegra-vde/vde.c +2 −4
  231. drivers/media/platform/nxp/Kconfig +2 −0
  232. drivers/media/platform/nxp/Makefile +1 −0
  233. drivers/media/platform/nxp/dw100/dw100.c +3 −7
  234. drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c +15 −4
  235. drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +3 −2
  236. drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +316 −28
  237. drivers/media/platform/nxp/imx-mipi-csis.c +2 −4
  238. drivers/media/platform/nxp/imx-pxp.c +2 −4
  239. drivers/media/platform/nxp/imx7-media-csi.c +19 −14
  240. drivers/media/platform/nxp/imx8-isi/Kconfig +22 −0
  241. drivers/media/platform/nxp/imx8-isi/Makefile +8 −0
  242. drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c +539 −0
  243. drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h +394 −0
  244. drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +529 −0
  245. drivers/media/platform/nxp/imx8-isi/imx8-isi-debug.c +109 −0
  246. drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c +650 −0
  247. drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c +858 −0
  248. drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c +867 −0
  249. drivers/media/platform/nxp/imx8-isi/imx8-isi-regs.h +418 −0
  250. drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c +1512 −0
  251. drivers/media/platform/nxp/mx2_emmaprp.c +2 −4
  252. drivers/media/platform/qcom/camss/camss-csid-gen2.c +34 −20
  253. drivers/media/platform/qcom/camss/camss-csid.c +31 −13
  254. drivers/media/platform/qcom/camss/camss-csid.h +9 −2
  255. drivers/media/platform/qcom/camss/camss-vfe-170.c +2 −2
  256. drivers/media/platform/qcom/camss/camss-vfe-480.c +40 −21
  257. drivers/media/platform/qcom/camss/camss-vfe-gen1.c +2 −2
  258. drivers/media/platform/qcom/camss/camss-vfe.c +1 −0
  259. drivers/media/platform/qcom/camss/camss-video.c +21 −5
  260. drivers/media/platform/qcom/camss/camss.c +3 −5
  261. drivers/media/platform/qcom/venus/core.c +2 −4
  262. drivers/media/platform/qcom/venus/core.h +9 −1
  263. drivers/media/platform/qcom/venus/helpers.c +2 −2
  264. drivers/media/platform/qcom/venus/hfi_cmds.c +23 −0
  265. drivers/media/platform/qcom/venus/hfi_helper.h +18 −0
  266. drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c +2 −2
  267. drivers/media/platform/qcom/venus/vdec.c +20 −9
  268. drivers/media/platform/qcom/venus/venc.c +103 −12
  269. drivers/media/platform/renesas/rcar-fcp.c +2 −4
  270. drivers/media/platform/renesas/rcar-isp.c +3 −8
  271. drivers/media/platform/renesas/rcar-vin/rcar-core.c +2 −40
  272. drivers/media/platform/renesas/rcar-vin/rcar-csi2.c +5 −16
  273. drivers/media/platform/renesas/rcar_drif.c +3 −5
  274. drivers/media/platform/renesas/rcar_fdp1.c +10 −11
  275. drivers/media/platform/renesas/rcar_jpu.c +2 −4
  276. drivers/media/platform/renesas/renesas-ceu.c +4 −6
  277. drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c +2 −4
  278. drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +2 −4
  279. drivers/media/platform/renesas/sh_vou.c +2 −3
  280. drivers/media/platform/renesas/vsp1/vsp1_drm.c +15 −11
  281. drivers/media/platform/renesas/vsp1/vsp1_drv.c +12 −5
  282. drivers/media/platform/renesas/vsp1/vsp1_entity.c +5 −6
  283. drivers/media/platform/renesas/vsp1/vsp1_entity.h +0 −2
  284. drivers/media/platform/renesas/vsp1/vsp1_pipe.h +2 −0
  285. drivers/media/platform/renesas/vsp1/vsp1_regs.h +2 −0
  286. drivers/media/platform/renesas/vsp1/vsp1_video.c +4 −3
  287. drivers/media/platform/rockchip/rga/rga.c +2 −4
  288. drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c +52 −0
  289. drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +2 −4
  290. drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c +7 −7
  291. drivers/media/platform/samsung/exynos-gsc/gsc-core.c +2 −3
  292. drivers/media/platform/samsung/exynos4-is/fimc-capture.c +11 −7
  293. drivers/media/platform/samsung/exynos4-is/fimc-core.c +2 −3
  294. drivers/media/platform/samsung/exynos4-is/fimc-is-errno.c +1 −1
  295. drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h +1 −1
  296. drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.c +2 −4
  297. drivers/media/platform/samsung/exynos4-is/fimc-is.c +2 −4
  298. drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c +7 −3
  299. drivers/media/platform/samsung/exynos4-is/fimc-lite.c +8 −6
  300. drivers/media/platform/samsung/exynos4-is/media-dev.c +9 −9
  301. drivers/media/platform/samsung/exynos4-is/mipi-csis.c +2 −4
  302. drivers/media/platform/samsung/s3c-camif/camif-capture.c +3 −2
  303. drivers/media/platform/samsung/s3c-camif/camif-core.c +5 −6
  304. drivers/media/platform/samsung/s5p-g2d/g2d.c +2 −3
  305. drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c +2 −4
  306. drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c +2 −3
  307. drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c +4 −4
  308. drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c +2 −4
  309. drivers/media/platform/st/sti/delta/delta-v4l2.c +2 −4
  310. drivers/media/platform/st/sti/hva/hva-v4l2.c +2 −4
  311. drivers/media/platform/st/stm32/dma2d/dma2d.c +3 −8
  312. drivers/media/platform/st/stm32/dma2d/dma2d.h +0 −2
  313. drivers/media/platform/st/stm32/stm32-dcmi.c +3 −4
  314. drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +2 −4
  315. drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +2 −4
  316. drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c +2 −4
  317. drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c +2 −4
  318. drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +2 −4
  319. drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +2 −4
  320. drivers/media/platform/ti/am437x/am437x-vpfe.c +21 −20
  321. drivers/media/platform/ti/cal/cal-video.c +20 −17
  322. drivers/media/platform/ti/cal/cal.c +2 −4
  323. drivers/media/platform/ti/davinci/vpif.c +2 −4
  324. drivers/media/platform/ti/davinci/vpif_capture.c +2 −3
  325. drivers/media/platform/ti/davinci/vpif_display.c +2 −4
  326. drivers/media/platform/ti/omap/omap_vout.c +2 −3
  327. drivers/media/platform/ti/omap3isp/isp.c +2 −4
  328. drivers/media/platform/ti/omap3isp/ispccdc.c +3 −2
  329. drivers/media/platform/ti/omap3isp/ispvideo.c +12 −8
  330. drivers/media/platform/ti/vpe/vpe.c +2 −4
  331. drivers/media/platform/verisilicon/hantro_drv.c +41 −15
  332. drivers/media/platform/verisilicon/hantro_postproc.c +1 −1
  333. drivers/media/platform/verisilicon/hantro_v4l2.c +45 −55
  334. drivers/media/platform/verisilicon/hantro_v4l2.h +2 −1
  335. drivers/media/platform/verisilicon/imx8m_vpu_hw.c +2 −0
  336. drivers/media/platform/via/via-camera.c +7 −6
  337. drivers/media/platform/video-mux.c +2 −4
  338. drivers/media/platform/xilinx/xilinx-csi2rxss.c +2 −4
  339. drivers/media/platform/xilinx/xilinx-dma.c +3 −2
  340. drivers/media/platform/xilinx/xilinx-tpg.c +2 −4
  341. drivers/media/platform/xilinx/xilinx-vipp.c +2 −4
  342. drivers/media/platform/xilinx/xilinx-vtc.c +3 −5
  343. drivers/media/radio/radio-si476x.c +2 −4
  344. drivers/media/radio/radio-timb.c +2 −3
  345. drivers/media/radio/radio-wl1273.c +2 −4
  346. drivers/media/radio/si4713/radio-platform-si4713.c +2 −4
  347. drivers/media/rc/gpio-ir-recv.c +4 −4
  348. drivers/media/rc/img-ir/img-ir-core.c +2 −3
  349. drivers/media/rc/ir-hix5hd2.c +2 −3
  350. drivers/media/rc/keymaps/Makefile +2 −0
  351. drivers/media/rc/keymaps/rc-beelink-mxiii.c +57 −0
  352. drivers/media/rc/keymaps/rc-dreambox.c +151 −0
  353. drivers/media/rc/meson-ir-tx.c +2 −4
  354. drivers/media/rc/meson-ir.c +2 −4
  355. drivers/media/rc/mtk-cir.c +2 −4
  356. drivers/media/rc/st_rc.c +2 −3
  357. drivers/media/rc/sunxi-cir.c +2 −4
  358. drivers/media/test-drivers/vicodec/vicodec-core.c +2 −4
  359. drivers/media/test-drivers/vidtv/vidtv_bridge.c +2 −4
  360. drivers/media/test-drivers/vim2m.c +2 −4
  361. drivers/media/test-drivers/vimc/vimc-common.c +4 −4
  362. drivers/media/test-drivers/vimc/vimc-core.c +2 −4
  363. drivers/media/test-drivers/visl/visl-core.c +2 −4
  364. drivers/media/test-drivers/vivid/vivid-core.c +8 −46
  365. drivers/media/test-drivers/vivid/vivid-core.h +0 −19
  366. drivers/media/test-drivers/vivid/vivid-kthread-cap.c +1 −130
  367. drivers/media/test-drivers/vivid/vivid-vid-cap.c +0 −272
  368. drivers/media/test-drivers/vivid/vivid-vid-cap.h +0 −3
  369. drivers/media/test-drivers/vivid/vivid-vid-out.c +0 −74
  370. drivers/media/tuners/it913x.c +2 −4
  371. drivers/media/tuners/mxl5005s.c +8 −4
  372. drivers/media/usb/au0828/au0828-core.c +3 −8
  373. drivers/media/usb/au0828/au0828-dvb.c +2 −2
  374. drivers/media/usb/dvb-usb/cxusb-analog.c +7 −7
  375. drivers/media/usb/dvb-usb/pctv452e.c +2 −0
  376. drivers/media/usb/pvrusb2/Kconfig +1 −1
  377. drivers/media/usb/usbtv/usbtv-core.c +1 −1
  378. drivers/media/v4l2-core/v4l2-async.c +8 −5
  379. drivers/media/v4l2-core/v4l2-common.c +6 −0
  380. drivers/media/v4l2-core/v4l2-compat-ioctl32.c +12 −73
  381. drivers/media/v4l2-core/v4l2-dev.c +3 −2
  382. drivers/media/v4l2-core/v4l2-ioctl.c +34 −52
  383. drivers/media/v4l2-core/v4l2-mc.c +6 −9
  384. drivers/media/v4l2-core/v4l2-subdev.c +166 −34
  385. drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +218 −785
  386. drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +8 −25
  387. drivers/staging/media/atomisp/i2c/gc0310.h +165 −251
  388. drivers/staging/media/atomisp/i2c/ov2680.h +0 −1
  389. drivers/staging/media/atomisp/include/linux/atomisp.h +0 −28
  390. drivers/staging/media/atomisp/include/linux/atomisp_platform.h +5 −6
  391. drivers/staging/media/atomisp/pci/atomisp_cmd.c +142 −936
  392. drivers/staging/media/atomisp/pci/atomisp_cmd.h +0 −9
  393. drivers/staging/media/atomisp/pci/atomisp_compat.h +1 −10
  394. drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +66 −354
  395. drivers/staging/media/atomisp/pci/atomisp_fops.c +5 −114
  396. drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +270 −19
  397. drivers/staging/media/atomisp/pci/atomisp_internal.h +2 −39
  398. drivers/staging/media/atomisp/pci/atomisp_ioctl.c +21 −205
  399. drivers/staging/media/atomisp/pci/atomisp_ioctl.h +0 −6
  400. drivers/staging/media/atomisp/pci/atomisp_subdev.c +39 −150
  401. drivers/staging/media/atomisp/pci/atomisp_subdev.h +0 −22
  402. drivers/staging/media/atomisp/pci/atomisp_v4l2.c +15 −60
  403. drivers/staging/media/av7110/av7110.c +4 −2
  404. drivers/staging/media/av7110/av7110_av.c +2 −2
  405. drivers/staging/media/av7110/av7110_hw.c +2 −1
  406. drivers/staging/media/av7110/av7110_v4l.c +76 −72
  407. drivers/staging/media/deprecated/atmel/atmel-isc-base.c +5 −4
  408. drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c +3 −7
  409. drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c +3 −7
  410. drivers/staging/media/imx/imx-media-capture.c +22 −18
  411. drivers/staging/media/imx/imx-media-csi.c +2 −4
  412. drivers/staging/media/imx/imx-media-dev-common.c +0 −14
  413. drivers/staging/media/imx/imx-media-dev.c +2 −4
  414. drivers/staging/media/imx/imx-media-of.c +2 −3
  415. drivers/staging/media/imx/imx-media-utils.c +4 −72
  416. drivers/staging/media/imx/imx-media.h +0 −13
  417. drivers/staging/media/imx/imx6-mipi-csi2.c +2 −4
  418. drivers/staging/media/imx/imx8mq-mipi-csi2.c +60 −98
  419. drivers/staging/media/meson/vdec/vdec.c +2 −4
  420. drivers/staging/media/omap4iss/iss.c +2 −4
  421. drivers/staging/media/omap4iss/iss_video.c +9 −7
  422. drivers/staging/media/rkvdec/rkvdec.c +4 −3
  423. drivers/staging/media/sunxi/cedrus/cedrus.c +3 −4
  424. drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c +2 −4
  425. drivers/staging/media/tegra-video/vi.c +6 −4
  426. include/media/drv-intf/saa7146_vv.h +10 −55
  427. include/media/dvb_net.h +2 −4
  428. include/media/i2c/ad9389b.h +0 −37
  429. include/media/i2c/m5mols.h +0 −25
  430. include/media/i2c/mt9m032.h +0 −22
  431. include/media/i2c/mt9t001.h +0 −10
  432. include/media/i2c/noon010pc30.h +0 −21
  433. include/media/i2c/s5k6aa.h +0 −48
  434. include/media/i2c/sr030pc30.h +0 −17
  435. include/media/media-device.h +2 −3
  436. include/media/rc-map.h +2 −0
  437. include/media/tveeprom.h +1 −1
  438. include/media/v4l2-ctrls.h +1 −1
  439. include/media/v4l2-mc.h +4 −4
  440. include/media/v4l2-subdev.h +28 −5
  441. include/uapi/linux/v4l2-subdev.h +21 −0
  442. include/uapi/linux/videodev2.h +13 −0
Documentation/admin-guide/media/cec.rst+45−34
@@ -55,6 +55,15 @@ Miscellaneous: · 54 unmodified lines
5555 you can control the CEC line through this driver. This supports error
5656 injection as well.
5757
58+- cec-gpio and Allwinner A10 (or any other driver that uses the CEC pin
59+ framework to drive the CEC pin directly): the CEC pin framework uses
60+ high-resolution timers. These timers are affected by NTP daemons that
61+ speed up or slow down the clock to sync with the official time. The
62+ chronyd server will by default increase or decrease the clock by
63+ 1/12th. This will cause the CEC timings to go out of spec. To fix this,
64+ add a 'maxslewrate 40000' line to chronyd.conf. This limits the clock
65+ frequency change to 1/25th, which keeps the CEC timings within spec.
66+
5867
5968 Utilities
6069 =========
@@ -296,69 +305,71 @@ broadcast messages twice to reduce the chance of them being lost. Specifically · 235 unmodified lines
296305 Making a CEC debugger
297306 =====================
298307
299−By using a Raspberry Pi 2B/3/4 and some cheap components you can make
308+By using a Raspberry Pi 4B and some cheap components you can make
300309 your own low-level CEC debugger.
301310
302−Here is a picture of my setup:
303−
304−https://hverkuil.home.xs4all.nl/rpi3-cec.jpg
305−
306−It's a Raspberry Pi 3 together with a breadboard and some breadboard wires:
307−
308−http://www.dx.com/p/diy-40p-male-to-female-male-to-male-female-to-female-dupont-line-wire-3pcs-356089#.WYLOOXWGN7I
309−
310−Finally on of these HDMI female-female passthrough connectors (full soldering type 1):
311+The critical component is one of these HDMI female-female passthrough connectors
312+(full soldering type 1):
311313
312314 https://elabbay.myshopify.com/collections/camera/products/hdmi-af-af-v1a-hdmi-type-a-female-to-hdmi-type-a-female-pass-through-adapter-breakout-board?variant=45533926147
313315
314−We've tested this and it works up to 4kp30 (297 MHz). The quality is not high
315−enough to pass-through 4kp60 (594 MHz).
316−
317−I also added an RTC and a breakout shield:
318−
319−https://www.amazon.com/Makerfire%C2%AE-Raspberry-Module-DS1307-Battery/dp/B00ZOXWHK4
316+The video quality is variable and certainly not enough to pass-through 4kp60
317+(594 MHz) video. You might be able to support 4kp30, but more likely you will
318+be limited to 1080p60 (148.5 MHz). But for CEC testing that is fine.
320319
321−https://www.dx.com/p/raspberry-pi-gpio-expansion-board-breadboard-easy-multiplexing-board-one-to-three-with-screw-for-raspberry-pi-2-3-b-b-2729992.html#.YGRCG0MzZ7I
320+You need a breadboard and some breadboard wires:
322321
323−These two are not needed but they make life a bit easier.
322+http://www.dx.com/p/diy-40p-male-to-female-male-to-male-female-to-female-dupont-line-wire-3pcs-356089#.WYLOOXWGN7I
324323
325−If you want to monitor the HPD line as well, then you need one of these
326−level shifters:
324+If you want to monitor the HPD and/or 5V lines as well, then you need one of
325+these 5V to 3.3V level shifters:
327326
328327 https://www.adafruit.com/product/757
329328
330329 (This is just where I got these components, there are many other places you
331330 can get similar things).
332331
332+The ground pin of the HDMI connector needs to be connected to a ground
333+pin of the Raspberry Pi, of course.
334+
333335 The CEC pin of the HDMI connector needs to be connected to these pins:
334−CE0/IO8 and CE1/IO7 (pull-up GPIOs). The (optional) HPD pin of the HDMI
335−connector should be connected (via a level shifter to convert the 5V
336−to 3.3V) to these pins: IO17 and IO27. The (optional) 5V pin of the HDMI
337−connector should be connected (via a level shifter) to these pins: IO22
338−and IO24. Monitoring the HPD an 5V lines is not necessary, but it is helpful.
336+GPIO 6 and GPIO 7. The optional HPD pin of the HDMI connector should
337+be connected via the level shifter to these pins: GPIO 23 and GPIO 12.
338+The optional 5V pin of the HDMI connector should be connected via the
339+level shifter to these pins: GPIO 25 and GPIO 22. Monitoring the HPD and
340+5V lines is not necessary, but it is helpful.
339341
340−This kernel patch will hook up the cec-gpio driver correctly to
341−e.g. ``arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts``::
342+This device tree addition in ``arch/arm/boot/dts/bcm2711-rpi-4-b.dts``
343+will hook up the cec-gpio driver correctly::
344+
345+ cec@6 {
346+ compatible = "cec-gpio";
347+ cec-gpios = <&gpio 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
348+ hpd-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
349+ v5-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
350+ };
342351
343352 cec@7 {
344353 compatible = "cec-gpio";
345354 cec-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
346− hpd-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
355+ hpd-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
347356 v5-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
348357 };
349358
350− cec@8 {
351− compatible = "cec-gpio";
352− cec-gpios = <&gpio 8 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
353− hpd-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
354− v5-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
355− };
359+If you haven't hooked up the HPD and/or 5V lines, then just delete those
360+lines.
356361
357362 This dts change will enable two cec GPIO devices: I typically use one to
358363 send/receive CEC commands and the other to monitor. If you monitor using
359364 an unconfigured CEC adapter then it will use GPIO interrupts which makes
360365 monitoring very accurate.
361366
367+If you just want to monitor traffic, then a single instance is sufficient.
368+The minimum configuration is one HDMI female-female passthrough connector
369+and two female-female breadboard wires: one for connecting the HDMI ground
370+pin to a ground pin on the Raspberry Pi, and the other to connect the HDMI
371+CEC pin to GPIO 6 on the Raspberry Pi.
372+
362373 The documentation on how to use the error injection is here: :ref:`cec_pin_error_inj`.
363374
364375 ``cec-ctl --monitor-pin`` will do low-level CEC bus sniffing and analysis.
Documentation/admin-guide/media/i2c-cardlist.rst+0−8
@@ -72,17 +72,13 @@ imx319 Sony IMX319 sensor · 71 unmodified lines
7272 imx334 Sony IMX334 sensor
7373 imx355 Sony IMX355 sensor
7474 imx412 Sony IMX412 sensor
75−m5mols Fujitsu M-5MOLS 8MP sensor
7675 mt9m001 mt9m001
77−mt9m032 MT9M032 camera sensor
7876 mt9m111 mt9m111, mt9m112 and mt9m131
7977 mt9p031 Aptina MT9P031
80−mt9t001 Aptina MT9T001
8178 mt9t112 Aptina MT9T111/MT9T112
8279 mt9v011 Micron mt9v011 sensor
8380 mt9v032 Micron MT9V032 sensor
8481 mt9v111 Aptina MT9V111 sensor
85−noon010pc30 Siliconfile NOON010PC30 sensor
8682 ov13858 OmniVision OV13858 sensor
8783 ov13b10 OmniVision OV13B10 sensor
8884 ov2640 OmniVision OV2640 sensor
@@ -109,9 +105,6 @@ s5c73m3 Samsung S5C73M3 sensor · 20 unmodified lines
109105 s5k4ecgx Samsung S5K4ECGX sensor
110106 s5k5baf Samsung S5K5BAF sensor
111107 s5k6a3 Samsung S5K6A3 sensor
112−s5k6aa Samsung S5K6AAFX sensor
113−sr030pc30 Siliconfile SR030PC30 sensor
114−vs6624 ST VS6624 sensor
115108 ============ ==========================================================
116109
117110 Flash devices
@@ -222,7 +215,6 @@ Video encoders · 104 unmodified lines
222215 ============ ==========================================================
223216 Driver Name
224217 ============ ==========================================================
225−ad9389b Analog Devices AD9389B encoder
226218 adv7170 Analog Devices ADV7170 video encoder
227219 adv7175 Analog Devices ADV7175 video encoder
228220 adv7343 ADV7343 video encoder
Documentation/devicetree/bindings/media/allwinner,sun4i-a10-ir.yaml+1−1
@@ -11,7 +11,7 @@ maintainers: · 10 unmodified lines
1111 - Maxime Ripard <mripard@kernel.org>
1212
1313 allOf:
14− - $ref: "rc.yaml#"
14+ - $ref: rc.yaml#
1515
1616 properties:
1717 compatible:
Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Hantro G2 VPU codec implemented on Allwinner H6 SoC
99
Documentation/devicetree/bindings/media/amlogic,axg-ge2d.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22 # Copyright 2020 BayLibre, SAS
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/amlogic,axg-ge2d.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/amlogic,axg-ge2d.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Amlogic GE2D Acceleration Unit
99
Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22 # Copyright 2019 BayLibre, SAS
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/amlogic,gx-vdec.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/amlogic,gx-vdec.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Amlogic Video Decoder
99
Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Amlogic Meson IR transmitter
99
Documentation/devicetree/bindings/media/amlogic,meson6-ir.yaml+47−0
@@ -0,0 +1,47 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/amlogic,meson6-ir.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Amlogic Meson IR remote control receiver
8+
9+maintainers:
10+ - Neil Armstrong <neil.armstrong@linaro.org>
11+
12+allOf:
13+ - $ref: rc.yaml#
14+
15+properties:
16+ compatible:
17+ oneOf:
18+ - enum:
19+ - amlogic,meson6-ir
20+ - amlogic,meson8b-ir
21+ - amlogic,meson-gxbb-ir
22+ - items:
23+ - const: amlogic,meson-gx-ir
24+ - const: amlogic,meson-gxbb-ir
25+
26+ reg:
27+ maxItems: 1
28+
29+ interrupts:
30+ maxItems: 1
31+
32+required:
33+ - compatible
34+ - reg
35+ - interrupts
36+
37+unevaluatedProperties: false
38+
39+examples:
40+ - |
41+ #include <dt-bindings/interrupt-controller/irq.h>
42+ #include <dt-bindings/interrupt-controller/arm-gic.h>
43+ ir-receiver@c8100480 {
44+ compatible = "amlogic,meson6-ir";
45+ reg = <0xc8100480 0x20>;
46+ interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE_RISING>;
47+ };
Documentation/devicetree/bindings/media/exynos-fimc-lite.txt+0−16
@@ -1,16 +0,0 @@
1−Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE)
2−
3−Required properties:
4−
5−- compatible : should be one of:
6− "samsung,exynos4212-fimc-lite" for Exynos4212/4412 SoCs,
7− "samsung,exynos5250-fimc-lite" for Exynos5250 compatible
8− devices;
9−- reg : physical base address and size of the device memory mapped
10− registers;
11−- interrupts : should contain FIMC-LITE interrupt;
12−- clocks : FIMC LITE gate clock should be specified in this property.
13−- clock-names : should contain "flite" entry.
14−
15−Each FIMC device should have an alias in the aliases node, in the form of
16−fimc-lite<n>, where <n> is an integer specifying the IP block instance.
Documentation/devicetree/bindings/media/exynos4-fimc-is.txt+0−50
@@ -1,50 +0,0 @@
1−Exynos4x12 SoC series Imaging Subsystem (FIMC-IS)
2−
3−The FIMC-IS is a subsystem for processing image signal from an image sensor.
4−The Exynos4x12 SoC series FIMC-IS V1.5 comprises of a dedicated ARM Cortex-A5
5−processor, ISP, DRC and FD IP blocks and peripheral devices such as UART, I2C
6−and SPI bus controllers, PWM and ADC.
7−
8−fimc-is node
9−------------
10−
11−Required properties:
12−- compatible : should be "samsung,exynos4212-fimc-is" for Exynos4212 and
13− Exynos4412 SoCs;
14−- reg : physical base address and length of the registers set;
15−- interrupts : must contain two FIMC-IS interrupts, in order: ISP0, ISP1;
16−- clocks : list of clock specifiers, corresponding to entries in
17− clock-names property;
18−- clock-names : must contain "ppmuispx", "ppmuispx", "lite0", "lite1"
19− "mpll", "sysreg", "isp", "drc", "fd", "mcuisp", "gicisp",
20− "pwm_isp", "mcuctl_isp", "uart", "ispdiv0", "ispdiv1",
21− "mcuispdiv0", "mcuispdiv1", "aclk200", "div_aclk200",
22− "aclk400mcuisp", "div_aclk400mcuisp" entries,
23− matching entries in the clocks property.
24−pmu subnode
25−-----------
26−
27−Required properties:
28− - reg : must contain PMU physical base address and size of the register set.
29−
30−The following are the FIMC-IS peripheral device nodes and can be specified
31−either standalone or as the fimc-is node child nodes.
32−
33−i2c-isp (ISP I2C bus controller) nodes
34−------------------------------------------
35−
36−Required properties:
37−
38−- compatible : should be "samsung,exynos4212-i2c-isp" for Exynos4212 and
39− Exynos4412 SoCs;
40−- reg : physical base address and length of the registers set;
41−- clocks : must contain gate clock specifier for this controller;
42−- clock-names : must contain "i2c_isp" entry.
43−
44−For the above nodes it is required to specify a pinctrl state named "default",
45−according to the pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt.
46−
47−Device tree nodes of the image sensors' controlled directly by the FIMC-IS
48−firmware must be child nodes of their corresponding ISP I2C bus controller node.
49−The data link of these image sensors must be specified using the common video
50−interfaces bindings, defined in video-interfaces.txt.
Documentation/devicetree/bindings/media/gpio-ir-receiver.yaml+3−0
@@ -23,6 +23,9 @@ properties: · 22 unmodified lines
2323 description: autosuspend delay time in milliseconds
2424 $ref: /schemas/types.yaml#/definitions/uint32
2525
26+ wakeup-source:
27+ description: IR receiver can wake-up the system.
28+
2629 required:
2730 - compatible
2831 - gpios
Documentation/devicetree/bindings/media/i2c/chrontel,ch7322.yaml+2−2
@@ -1,8 +1,8 @@
11 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 %YAML 1.2
33 ---
4−$id: "http://devicetree.org/schemas/media/i2c/chrontel,ch7322.yaml#"
5−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/i2c/chrontel,ch7322.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
66
77 title: Chrontel HDMI-CEC Controller
88
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml+3−3
@@ -38,7 +38,7 @@ properties: · 37 unmodified lines
3838 dongwoon,aac-mode:
3939 description:
4040 Indication of AAC mode select.
41− $ref: "/schemas/types.yaml#/definitions/uint32"
41+ $ref: /schemas/types.yaml#/definitions/uint32
4242 enum:
4343 - 1 # AAC2 mode(operation time# 0.48 x Tvib)
4444 - 2 # AAC3 mode(operation time# 0.70 x Tvib)
@@ -50,7 +50,7 @@ properties: · 5 unmodified lines
5050 description:
5151 Number of AAC Timing count that controlled by one 6-bit period of
5252 vibration register AACT[5:0], the unit of which is 100 us.
53− $ref: "/schemas/types.yaml#/definitions/uint32"
53+ $ref: /schemas/types.yaml#/definitions/uint32
5454 default: 0x20
5555 minimum: 0x00
5656 maximum: 0x3f
@@ -59,7 +59,7 @@ properties: · 2 unmodified lines
5959 description:
6060 Indication of VCM internal clock dividing rate select, as one multiple
6161 factor to calculate VCM ring periodic time Tvib.
62− $ref: "/schemas/types.yaml#/definitions/uint32"
62+ $ref: /schemas/types.yaml#/definitions/uint32
6363 enum:
6464 - 0 # Dividing Rate - 2
6565 - 1 # Dividing Rate - 1
Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml+1−1
@@ -86,7 +86,7 @@ properties: · 85 unmodified lines
8686 is 100000 micro volts
8787
8888 maxim,gpio-poc:
89− $ref: '/schemas/types.yaml#/definitions/uint32-array'
89+ $ref: /schemas/types.yaml#/definitions/uint32-array
9090 minItems: 2
9191 maxItems: 2
9292 description: |
Documentation/devicetree/bindings/media/i2c/ov2685.txt+0−41
@@ -1,41 +0,0 @@
1−* Omnivision OV2685 MIPI CSI-2 sensor
2−
3−Required Properties:
4−- compatible: shall be "ovti,ov2685"
5−- clocks: reference to the xvclk input clock
6−- clock-names: shall be "xvclk"
7−- avdd-supply: Analog voltage supply, 2.8 volts
8−- dovdd-supply: Digital I/O voltage supply, 1.8 volts
9−- dvdd-supply: Digital core voltage supply, 1.8 volts
10−- reset-gpios: Low active reset gpio
11−
12−The device node shall contain one 'port' child node with an
13−'endpoint' subnode for its digital output video port,
14−in accordance with the video interface bindings defined in
15−Documentation/devicetree/bindings/media/video-interfaces.txt.
16−The endpoint optional property 'data-lanes' shall be "<1>".
17−
18−Example:
19−&i2c7 {
20− ov2685: camera-sensor@3c {
21− compatible = "ovti,ov2685";
22− reg = <0x3c>;
23− pinctrl-names = "default";
24− pinctrl-0 = <&clk_24m_cam>;
25−
26− clocks = <&cru SCLK_TESTCLKOUT1>;
27− clock-names = "xvclk";
28−
29− avdd-supply = <&pp2800_cam>;
30− dovdd-supply = <&pp1800>;
31− dvdd-supply = <&pp1800>;
32− reset-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
33−
34− port {
35− ucam_out: endpoint {
36− remote-endpoint = <&mipi_in_ucam>;
37− data-lanes = <1>;
38− };
39− };
40− };
41−};
Documentation/devicetree/bindings/media/i2c/ov8856.yaml+1−1
@@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 7 unmodified lines
88 title: Omnivision OV8856 CMOS Sensor
99
1010 maintainers:
11− - Dongchun Zhu <dongchun.zhu@mediatek.com>
11+ - Sakari Ailus <sakari.ailus@linux.intel.com>
1212
1313 description: |-
1414 The Omnivision OV8856 is a high performance, 1/4-inch, 8 megapixel, CMOS
Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml+1−1
@@ -88,7 +88,7 @@ properties: · 87 unmodified lines
8888 properties:
8989 link-frequencies: true
9090 ovti,mipi-clock-voltage:
91− $ref: "/schemas/types.yaml#/definitions/uint32"
91+ $ref: /schemas/types.yaml#/definitions/uint32
9292 description:
9393 Definition of MIPI clock voltage unit. This entry corresponds to
9494 the link speed defined by the 'link-frequencies' property.
Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml+101−0
@@ -0,0 +1,101 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/i2c/ovti,ov2685.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: OmniVision OV2685 Image Sensor
8+
9+maintainers:
10+ - Shunqian Zheng <zhengsq@rock-chips.com>
11+
12+properties:
13+ compatible:
14+ const: ovti,ov2685
15+
16+ reg:
17+ maxItems: 1
18+
19+ clocks:
20+ items:
21+ - description: XVCLK clock
22+
23+ clock-names:
24+ items:
25+ - const: xvclk
26+
27+ dvdd-supply:
28+ description: Digital Domain Power Supply
29+
30+ avdd-supply:
31+ description: Analog Domain Power Supply
32+
33+ dovdd-supply:
34+ description: I/O Domain Power Supply
35+
36+ reset-gpios:
37+ maxItems: 1
38+ description: Reset Pin GPIO Control (active low)
39+
40+ port:
41+ description: MIPI CSI-2 transmitter port
42+ $ref: /schemas/graph.yaml#/$defs/port-base
43+ additionalProperties: false
44+
45+ properties:
46+ endpoint:
47+ $ref: /schemas/media/video-interfaces.yaml#
48+ unevaluatedProperties: false
49+
50+ properties:
51+ data-lanes:
52+ maxItems: 2
53+
54+ required:
55+ - data-lanes
56+
57+required:
58+ - compatible
59+ - reg
60+ - clocks
61+ - clock-names
62+ - dvdd-supply
63+ - avdd-supply
64+ - dovdd-supply
65+ - port
66+
67+additionalProperties: false
68+
69+examples:
70+ - |
71+ #include <dt-bindings/clock/rk3399-cru.h>
72+ #include <dt-bindings/gpio/gpio.h>
73+
74+ i2c {
75+ #address-cells = <1>;
76+ #size-cells = <0>;
77+
78+ ov2685: camera-sensor@3c {
79+ compatible = "ovti,ov2685";
80+ reg = <0x3c>;
81+ pinctrl-names = "default";
82+ pinctrl-0 = <&clk_24m_cam>;
83+
84+ clocks = <&cru SCLK_TESTCLKOUT1>;
85+ clock-names = "xvclk";
86+
87+ avdd-supply = <&pp2800_cam>;
88+ dovdd-supply = <&pp1800>;
89+ dvdd-supply = <&pp1800>;
90+ reset-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
91+
92+ port {
93+ ucam_out: endpoint {
94+ remote-endpoint = <&mipi_in_ucam>;
95+ data-lanes = <1>;
96+ };
97+ };
98+ };
99+ };
100+
101+...
Documentation/devicetree/bindings/media/i2c/samsung,s5k5baf.yaml+101−0
@@ -0,0 +1,101 @@
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/samsung,s5k5baf.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+
12+properties:
13+ compatible:
14+ const: samsung,s5k5baf
15+
16+ reg:
17+ maxItems: 1
18+
19+ clocks:
20+ maxItems: 1
21+
22+ clock-names:
23+ items:
24+ - const: mclk
25+
26+ clock-frequency:
27+ default: 24000000
28+ description: mclk clock frequency
29+
30+ rstn-gpios:
31+ maxItems: 1
32+ description: RSTN pin
33+
34+ stbyn-gpios:
35+ maxItems: 1
36+ description: STDBYN pin
37+
38+ vdda-supply:
39+ description: Analog power supply 2.8V (2.6V to 3.0V)
40+
41+ vddio-supply:
42+ description: I/O power supply 1.8V (1.65V to 1.95V) or 2.8V (2.5V to 3.1V)
43+
44+ vddreg-supply:
45+ description:
46+ Regulator input power supply 1.8V (1.7V to 1.9V) or 2.8V (2.6V to 3.0)
47+
48+ port:
49+ $ref: /schemas/graph.yaml#/$defs/port-base
50+ additionalProperties: false
51+
52+ properties:
53+ endpoint:
54+ $ref: /schemas/media/video-interfaces.yaml#
55+ unevaluatedProperties: false
56+
57+ properties:
58+ data-lanes:
59+ items:
60+ - const: 1
61+
62+required:
63+ - compatible
64+ - clocks
65+ - clock-names
66+ - rstn-gpios
67+ - stbyn-gpios
68+ - vdda-supply
69+ - vddio-supply
70+ - vddreg-supply
71+
72+additionalProperties: false
73+
74+examples:
75+ - |
76+ #include <dt-bindings/gpio/gpio.h>
77+
78+ i2c {
79+ #address-cells = <1>;
80+ #size-cells = <0>;
81+
82+ sensor@2d {
83+ compatible = "samsung,s5k5baf";
84+ reg = <0x2d>;
85+ clocks = <&camera 0>;
86+ clock-names = "mclk";
87+ clock-frequency = <24000000>;
88+ rstn-gpios = <&gpl2 1 GPIO_ACTIVE_LOW>;
89+ stbyn-gpios = <&gpl2 0 GPIO_ACTIVE_LOW>;
90+ vdda-supply = <&cam_io_en_reg>;
91+ vddio-supply = <&vtcam_reg>;
92+ vddreg-supply = <&vt_core_15v_reg>;
93+
94+ port {
95+ endpoint {
96+ remote-endpoint = <&csis1_ep>;
97+ data-lanes = <1>;
98+ };
99+ };
100+ };
101+ };
Documentation/devicetree/bindings/media/i2c/samsung,s5k6a3.yaml+98−0
@@ -0,0 +1,98 @@
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/samsung,s5k6a3.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung S5K6A3(YX) raw image sensor
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+
12+description:
13+ S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data
14+ interfaces and CCI (I2C compatible) control bus.
15+
16+properties:
17+ compatible:
18+ const: samsung,s5k6a3
19+
20+ reg:
21+ maxItems: 1
22+
23+ clocks:
24+ maxItems: 1
25+
26+ clock-names:
27+ items:
28+ - const: extclk
29+
30+ clock-frequency:
31+ default: 24000000
32+ description: extclk clock frequency
33+
34+ gpios:
35+ maxItems: 1
36+ description: GPIO connected to the RESET pin
37+
38+ afvdd-supply:
39+ description: AF (actuator) voltage supply
40+
41+ svdda-supply:
42+ description: Core voltage supply
43+
44+ svddio-supply:
45+ description: I/O voltage supply
46+
47+ port:
48+ $ref: /schemas/graph.yaml#/$defs/port-base
49+ additionalProperties: false
50+
51+ properties:
52+ endpoint:
53+ $ref: /schemas/media/video-interfaces.yaml#
54+ unevaluatedProperties: false
55+
56+ properties:
57+ data-lanes:
58+ items:
59+ - const: 1
60+
61+required:
62+ - compatible
63+ - clocks
64+ - clock-names
65+ - gpios
66+ - afvdd-supply
67+ - svdda-supply
68+ - svddio-supply
69+
70+additionalProperties: false
71+
72+examples:
73+ - |
74+ #include <dt-bindings/gpio/gpio.h>
75+
76+ i2c {
77+ #address-cells = <1>;
78+ #size-cells = <0>;
79+
80+ sensor@10 {
81+ compatible = "samsung,s5k6a3";
82+ reg = <0x10>;
83+ clock-frequency = <24000000>;
84+ clocks = <&camera 1>;
85+ clock-names = "extclk";
86+ gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
87+ afvdd-supply = <&ldo19_reg>;
88+ svdda-supply = <&cam_io_reg>;
89+ svddio-supply = <&ldo19_reg>;
90+
91+ port {
92+ endpoint {
93+ remote-endpoint = <&csis1_ep>;
94+ data-lanes = <1>;
95+ };
96+ };
97+ };
98+ };
Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml+18−7
@@ -12,15 +12,26 @@ maintainers: · 11 unmodified lines
1212
1313 description: |-
1414 The Sony IMX290 is a 1/2.8-Inch CMOS Solid-state image sensor with Square
15− Pixel for Color Cameras. It is programmable through I2C and 4-wire
16− interfaces. The sensor output is available via CMOS logic parallel SDR
17− output, Low voltage LVDS DDR output and CSI-2 serial data output. The CSI-2
18− bus is the default. No bindings have been defined for the other busses.
15+ Pixel, available in either mono or colour variants. It is programmable
16+ through I2C and 4-wire interfaces.
17+
18+ The sensor output is available via CMOS logic parallel SDR output, Low voltage
19+ LVDS DDR output and CSI-2 serial data output. The CSI-2 bus is the default.
20+ No bindings have been defined for the other busses.
21+
22+ imx290lqr is the full model identifier for the colour variant. "sony,imx290"
23+ is treated the same as this as it was the original compatible string.
24+ imx290llr is the mono version of the sensor.
1925
2026 properties:
2127 compatible:
22− enum:
23− - sony,imx290
28+ oneOf:
29+ - enum:
30+ - sony,imx290lqr # Colour
31+ - sony,imx290llr # Monochrome
32+ - sony,imx327lqr # Colour
33+ - const: sony,imx290
34+ deprecated: true
2435
2536 reg:
2637 maxItems: 1
@@ -101,7 +112,7 @@ examples: · 74 unmodified lines
101112 #size-cells = <0>;
102113
103114 imx290: camera-sensor@1a {
104− compatible = "sony,imx290";
115+ compatible = "sony,imx290lqr";
105116 reg = <0x1a>;
106117
107118 pinctrl-names = "default";
Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml+1−1
@@ -82,7 +82,7 @@ examples: · 81 unmodified lines
8282 imx334: endpoint {
8383 remote-endpoint = <&cam>;
8484 data-lanes = <1 2 3 4>;
85− link-frequencies = /bits/ 64 <891000000>;
85+ link-frequencies = /bits/ 64 <891000000 445500000>;
8686 };
8787 };
8888 };
Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml+1−1
@@ -27,7 +27,7 @@ properties: · 26 unmodified lines
2727 maxItems: 1
2828
2929 mediatek,gce-client-reg:
30− $ref: '/schemas/types.yaml#/definitions/phandle-array'
30+ $ref: /schemas/types.yaml#/definitions/phandle-array
3131 items:
3232 items:
3333 - description: phandle of GCE
Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml+46−71
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Mediatek Video Decode Accelerator With Multi Hardware
99
@@ -61,7 +61,10 @@ properties: · 51 unmodified lines
6161 - mediatek,mt8195-vcodec-dec
6262
6363 reg:
64− maxItems: 1
64+ minItems: 1
65+ items:
66+ - description: VDEC_SYS register space
67+ - description: VDEC_RACING_CTRL register space
6568
6669 iommus:
6770 minItems: 1
@@ -76,11 +79,6 @@ properties: · 8 unmodified lines
7679 The node of system control processor (SCP), using
7780 the remoteproc & rpmsg framework.
7881
79− dma-ranges:
80− maxItems: 1
81− description: |
82− Describes the physical address space of IOMMU maps to memory.
83−
8482 "#address-cells":
8583 const: 2
8684
@@ -91,17 +89,19 @@ properties: · 4 unmodified lines
9189
9290 # Required child node:
9391 patternProperties:
94− '^vcodec-lat@[0-9a-f]+$':
92+ '^video-codec@[0-9a-f]+$':
9593 type: object
9694
9795 properties:
9896 compatible:
9997 enum:
98+ - mediatek,mtk-vcodec-core
10099 - mediatek,mtk-vcodec-lat
101100 - mediatek,mtk-vcodec-lat-soc
102101
103102 reg:
104103 maxItems: 1
104+ description: VDEC_MISC register space
105105
106106 interrupts:
107107 maxItems: 1
@@ -114,68 +114,13 @@ patternProperties: · 6 unmodified lines
114114 Refer to bindings/iommu/mediatek,iommu.yaml.
115115
116116 clocks:
117+ minItems: 4
117118 maxItems: 5
118119
119120 clock-names:
120− items:
121− - const: sel
122− - const: soc-vdec
123− - const: soc-lat
124− - const: vdec
125− - const: top
126−
127− assigned-clocks:
128− maxItems: 1
129−
130− assigned-clock-parents:
131− maxItems: 1
132−
133− power-domains:
134− maxItems: 1
135−
136− required:
137− - compatible
138− - reg
139− - iommus
140− - clocks
141− - clock-names
142− - assigned-clocks
143− - assigned-clock-parents
144− - power-domains
145−
146− additionalProperties: false
147−
148− '^vcodec-core@[0-9a-f]+$':
149− type: object
150−
151− properties:
152− compatible:
153− const: mediatek,mtk-vcodec-core
154−
155− reg:
156− maxItems: 1
157−
158− interrupts:
159− maxItems: 1
160−
161− iommus:
162− minItems: 1
163− maxItems: 32
164− description: |
165− List of the hardware port in respective IOMMU block for current Socs.
166− Refer to bindings/iommu/mediatek,iommu.yaml.
167−
168− clocks:
121+ minItems: 4
169122 maxItems: 5
170123
171− clock-names:
172− items:
173− - const: sel
174− - const: soc-vdec
175− - const: soc-lat
176− - const: vdec
177− - const: top
178−
179124 assigned-clocks:
180125 maxItems: 1
181126
@@ -188,7 +133,6 @@ patternProperties: · 6 unmodified lines
188133 required:
189134 - compatible
190135 - reg
191− - interrupts
192136 - iommus
193137 - clocks
194138 - clock-names
@@ -203,7 +147,6 @@ required: · 8 unmodified lines
203147 - reg
204148 - iommus
205149 - mediatek,scp
206− - dma-ranges
207150 - ranges
208151
209152 if:
@@ -211,12 +154,45 @@ if: · 1 unmodified line
211154 compatible:
212155 contains:
213156 enum:
157+ - mediatek,mtk-vcodec-core
214158 - mediatek,mtk-vcodec-lat
215159
216160 then:
217161 required:
218162 - interrupts
219163
164+allOf:
165+ - if:
166+ properties:
167+ compatible:
168+ contains:
169+ enum:
170+ - mediatek,mt8192-vcodec-dec
171+ then:
172+ properties:
173+ clock-names:
174+ items:
175+ - const: sel
176+ - const: soc-vdec
177+ - const: soc-lat
178+ - const: vdec
179+ - const: top
180+
181+ - if:
182+ properties:
183+ compatible:
184+ contains:
185+ enum:
186+ - mediatek,mt8195-vcodec-dec
187+ then:
188+ properties:
189+ clock-names:
190+ items:
191+ - const: sel
192+ - const: vdec
193+ - const: lat
194+ - const: top
195+
220196 additionalProperties: false
221197
222198 examples:
@@ -236,12 +212,11 @@ examples: · 13 unmodified lines
236212 compatible = "mediatek,mt8192-vcodec-dec";
237213 mediatek,scp = <&scp>;
238214 iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
239− dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
240215 #address-cells = <2>;
241216 #size-cells = <2>;
242217 ranges = <0 0 0 0x16000000 0 0x40000>;
243218 reg = <0 0x16000000 0 0x1000>; /* VDEC_SYS */
244− vcodec-lat@10000 {
219+ video-codec@10000 {
245220 compatible = "mediatek,mtk-vcodec-lat";
246221 reg = <0 0x10000 0 0x800>;
247222 interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
@@ -264,7 +239,7 @@ examples: · 16 unmodified lines
264239 power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
265240 };
266241
267− vcodec-core@25000 {
242+ video-codec@25000 {
268243 compatible = "mediatek,mtk-vcodec-core";
269244 reg = <0 0x25000 0 0x1000>;
270245 interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
Documentation/devicetree/bindings/media/meson-ir.txt+0−20
@@ -1,20 +0,0 @@
1−* Amlogic Meson IR remote control receiver
2−
3−Required properties:
4− - compatible : depending on the platform this should be one of:
5− - "amlogic,meson6-ir"
6− - "amlogic,meson8b-ir"
7− - "amlogic,meson-gxbb-ir"
8− - reg : physical base address and length of the device registers
9− - interrupts : a single specifier for the interrupt from the device
10−
11−Optional properties:
12− - linux,rc-map-name: see rc.txt file in the same directory.
13−
14−Example:
15−
16− ir-receiver@c8100480 {
17− compatible= "amlogic,meson6-ir";
18− reg = <0xc8100480 0x20>;
19− interrupts = <0 15 1>;
20− };
Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Hantro G1 VPU codec implemented on Microchip SAMA5D4 SoCs
99
Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml+173−0
@@ -0,0 +1,173 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/nxp,imx8-isi.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: i.MX8 Image Sensing Interface
8+
9+maintainers:
10+ - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11+
12+description: |
13+ The Image Sensing Interface (ISI) combines image processing pipelines with
14+ DMA engines to process and capture frames originating from a variety of
15+ sources. The inputs to the ISI go through Pixel Link interfaces, and their
16+ number and nature is SoC-dependent. They cover both capture interfaces (MIPI
17+ CSI-2 RX, HDMI RX, ...) and display engine outputs for writeback support.
18+
19+properties:
20+ compatible:
21+ enum:
22+ - fsl,imx8mn-isi
23+ - fsl,imx8mp-isi
24+
25+ reg:
26+ maxItems: 1
27+
28+ clocks:
29+ items:
30+ - description: The AXI clock
31+ - description: The APB clock
32+ # TODO: Check if the per-channel ipg_proc_clk clocks need to be specified
33+ # as well, in case some SoCs have the ability to control them separately.
34+ # This may be the case of the i.MX8[DQ]X(P)
35+
36+ clock-names:
37+ items:
38+ - const: axi
39+ - const: apb
40+
41+ fsl,blk-ctrl:
42+ $ref: /schemas/types.yaml#/definitions/phandle
43+ description:
44+ A phandle referencing the block control that contains the CSIS to ISI
45+ gasket.
46+
47+ interrupts:
48+ description: Processing pipeline interrupts, one per pipeline
49+ minItems: 1
50+ maxItems: 2
51+
52+ power-domains:
53+ maxItems: 1
54+
55+ ports:
56+ $ref: /schemas/graph.yaml#/properties/ports
57+ description: |
58+ Ports represent the Pixel Link inputs to the ISI. Their number and
59+ assignment are model-dependent. Each port shall have a single endpoint.
60+
61+required:
62+ - compatible
63+ - reg
64+ - interrupts
65+ - clocks
66+ - clock-names
67+ - fsl,blk-ctrl
68+ - ports
69+
70+allOf:
71+ - if:
72+ properties:
73+ compatible:
74+ contains:
75+ const: fsl,imx8mn-isi
76+ then:
77+ properties:
78+ interrupts:
79+ maxItems: 1
80+ ports:
81+ properties:
82+ port@0:
83+ description: MIPI CSI-2 RX
84+ required:
85+ - port@0
86+
87+ - if:
88+ properties:
89+ compatible:
90+ contains:
91+ const: fsl,imx8mp-isi
92+ then:
93+ properties:
94+ interrupts:
95+ maxItems: 2
96+ ports:
97+ properties:
98+ port@0:
99+ description: MIPI CSI-2 RX 0
100+ port@1:
101+ description: MIPI CSI-2 RX 1
102+ required:
103+ - port@0
104+ - port@1
105+
106+additionalProperties: false
107+
108+examples:
109+ - |
110+ #include <dt-bindings/clock/imx8mn-clock.h>
111+ #include <dt-bindings/interrupt-controller/arm-gic.h>
112+ #include <dt-bindings/interrupt-controller/irq.h>
113+ #include <dt-bindings/power/imx8mn-power.h>
114+
115+ isi@32e20000 {
116+ compatible = "fsl,imx8mn-isi";
117+ reg = <0x32e20000 0x100>;
118+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
119+ clocks = <&clk IMX8MN_CLK_DISP_AXI_ROOT>,
120+ <&clk IMX8MN_CLK_DISP_APB_ROOT>;
121+ clock-names = "axi", "apb";
122+ fsl,blk-ctrl = <&disp_blk_ctrl>;
123+ power-domains = <&disp_blk_ctrl IMX8MN_DISPBLK_PD_ISI>;
124+
125+ ports {
126+ #address-cells = <1>;
127+ #size-cells = <0>;
128+
129+ port@0 {
130+ reg = <0>;
131+ isi_in: endpoint {
132+ remote-endpoint = <&mipi_csi_out>;
133+ };
134+ };
135+ };
136+ };
137+
138+ - |
139+ #include <dt-bindings/clock/imx8mp-clock.h>
140+ #include <dt-bindings/interrupt-controller/arm-gic.h>
141+ #include <dt-bindings/interrupt-controller/irq.h>
142+
143+ isi@32e00000 {
144+ compatible = "fsl,imx8mp-isi";
145+ reg = <0x32e00000 0x4000>;
146+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
147+ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
148+ clocks = <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>,
149+ <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
150+ clock-names = "axi", "apb";
151+ fsl,blk-ctrl = <&media_blk_ctrl>;
152+ power-domains = <&mediamix_pd>;
153+
154+ ports {
155+ #address-cells = <1>;
156+ #size-cells = <0>;
157+
158+ port@0 {
159+ reg = <0>;
160+ isi_in_0: endpoint {
161+ remote-endpoint = <&mipi_csi_0_out>;
162+ };
163+ };
164+
165+ port@1 {
166+ reg = <1>;
167+ isi_in_1: endpoint {
168+ remote-endpoint = <&mipi_csi_1_out>;
169+ };
170+ };
171+ };
172+ };
173+...
Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Hantro G1/G2 VPU codecs implemented on i.MX8M SoCs
99
Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Qualcomm CAMSS ISP
99
Documentation/devicetree/bindings/media/qcom,msm8916-venus.yaml+29−57
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,msm8916-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,msm8916-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm MSM8916 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,msm8916-venus
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 maxItems: 1
2925
@@ -39,9 +35,6 @@ properties: · 9 unmodified lines
3935 iommus:
4036 maxItems: 1
4137
42− memory-region:
43− maxItems: 1
44−
4538 video-decoder:
4639 type: object
4740
@@ -66,57 +59,36 @@ properties: · 18 unmodified lines
6659
6760 additionalProperties: false
6861
69− video-firmware:
70− type: object
71− additionalProperties: false
72−
73− description: |
74− Firmware subnode is needed when the platform does not
75− have TrustZone.
76−
77− properties:
78− iommus:
79− maxItems: 1
80−
81− required:
82− - iommus
83−
8462 required:
8563 - compatible
86− - reg
87− - interrupts
88− - power-domains
89− - clocks
90− - clock-names
9164 - iommus
92− - memory-region
9365 - video-decoder
9466 - video-encoder
9567
96−additionalProperties: false
68+unevaluatedProperties: false
9769
9870 examples:
9971 - |
100− #include <dt-bindings/interrupt-controller/arm-gic.h>
101− #include <dt-bindings/clock/qcom,gcc-msm8916.h>
102−
103− video-codec@1d00000 {
104− compatible = "qcom,msm8916-venus";
105− reg = <0x01d00000 0xff000>;
106− interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
107− clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
108− <&gcc GCC_VENUS0_AHB_CLK>,
109− <&gcc GCC_VENUS0_AXI_CLK>;
110− clock-names = "core", "iface", "bus";
111− power-domains = <&gcc VENUS_GDSC>;
112− iommus = <&apps_iommu 5>;
113− memory-region = <&venus_mem>;
114−
115− video-decoder {
116− compatible = "venus-decoder";
117− };
118−
119− video-encoder {
120− compatible = "venus-encoder";
121− };
72+ #include <dt-bindings/interrupt-controller/arm-gic.h>
73+ #include <dt-bindings/clock/qcom,gcc-msm8916.h>
74+
75+ video-codec@1d00000 {
76+ compatible = "qcom,msm8916-venus";
77+ reg = <0x01d00000 0xff000>;
78+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
79+ clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
80+ <&gcc GCC_VENUS0_AHB_CLK>,
81+ <&gcc GCC_VENUS0_AXI_CLK>;
82+ clock-names = "core", "iface", "bus";
83+ power-domains = <&gcc VENUS_GDSC>;
84+ iommus = <&apps_iommu 5>;
85+ memory-region = <&venus_mem>;
86+
87+ video-decoder {
88+ compatible = "venus-decoder";
89+ };
90+
91+ video-encoder {
92+ compatible = "venus-encoder";
12293 };
94+ };
Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Qualcomm CAMSS ISP
99
Documentation/devicetree/bindings/media/qcom,msm8996-venus.yaml+63−83
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,msm8996-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,msm8996-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm MSM8996 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,msm8996-venus
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 maxItems: 1
2925
@@ -37,12 +33,17 @@ properties: · 7 unmodified lines
3733 - const: bus
3834 - const: mbus
3935
36+ interconnects:
37+ maxItems: 2
38+
39+ interconnect-names:
40+ items:
41+ - const: video-mem
42+ - const: cpu-cfg
43+
4044 iommus:
4145 maxItems: 20
4246
43− memory-region:
44− maxItems: 1
45−
4647 video-decoder:
4748 type: object
4849
@@ -93,83 +94,62 @@ properties: · 44 unmodified lines
9394
9495 additionalProperties: false
9596
96− video-firmware:
97− type: object
98− additionalProperties: false
99−
100− description: |
101− Firmware subnode is needed when the platform does not
102− have TrustZone.
103−
104− properties:
105− iommus:
106− maxItems: 1
107−
108− required:
109− - iommus
110−
11197 required:
11298 - compatible
113− - reg
114− - interrupts
115− - power-domains
116− - clocks
117− - clock-names
11899 - iommus
119− - memory-region
120100 - video-decoder
121101 - video-encoder
122102
123−additionalProperties: false
103+unevaluatedProperties: false
124104
125105 examples:
126106 - |
127− #include <dt-bindings/interrupt-controller/arm-gic.h>
128− #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
129−
130− video-codec@c00000 {
131− compatible = "qcom,msm8996-venus";
132− reg = <0x00c00000 0xff000>;
133− interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
134− clocks = <&mmcc VIDEO_CORE_CLK>,
135− <&mmcc VIDEO_AHB_CLK>,
136− <&mmcc VIDEO_AXI_CLK>,
137− <&mmcc VIDEO_MAXI_CLK>;
138− clock-names = "core", "iface", "bus", "mbus";
139− power-domains = <&mmcc VENUS_GDSC>;
140− iommus = <&venus_smmu 0x00>,
141− <&venus_smmu 0x01>,
142− <&venus_smmu 0x0a>,
143− <&venus_smmu 0x07>,
144− <&venus_smmu 0x0e>,
145− <&venus_smmu 0x0f>,
146− <&venus_smmu 0x08>,
147− <&venus_smmu 0x09>,
148− <&venus_smmu 0x0b>,
149− <&venus_smmu 0x0c>,
150− <&venus_smmu 0x0d>,
151− <&venus_smmu 0x10>,
152− <&venus_smmu 0x11>,
153− <&venus_smmu 0x21>,
154− <&venus_smmu 0x28>,
155− <&venus_smmu 0x29>,
156− <&venus_smmu 0x2b>,
157− <&venus_smmu 0x2c>,
158− <&venus_smmu 0x2d>,
159− <&venus_smmu 0x31>;
160− memory-region = <&venus_mem>;
161−
162− video-decoder {
163− compatible = "venus-decoder";
164− clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
165− clock-names = "core";
166− power-domains = <&mmcc VENUS_CORE0_GDSC>;
167− };
168−
169− video-encoder {
170− compatible = "venus-encoder";
171− clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
172− clock-names = "core";
173− power-domains = <&mmcc VENUS_CORE1_GDSC>;
174− };
107+ #include <dt-bindings/interrupt-controller/arm-gic.h>
108+ #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
109+
110+ video-codec@c00000 {
111+ compatible = "qcom,msm8996-venus";
112+ reg = <0x00c00000 0xff000>;
113+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
114+ clocks = <&mmcc VIDEO_CORE_CLK>,
115+ <&mmcc VIDEO_AHB_CLK>,
116+ <&mmcc VIDEO_AXI_CLK>,
117+ <&mmcc VIDEO_MAXI_CLK>;
118+ clock-names = "core", "iface", "bus", "mbus";
119+ power-domains = <&mmcc VENUS_GDSC>;
120+ iommus = <&venus_smmu 0x00>,
121+ <&venus_smmu 0x01>,
122+ <&venus_smmu 0x0a>,
123+ <&venus_smmu 0x07>,
124+ <&venus_smmu 0x0e>,
125+ <&venus_smmu 0x0f>,
126+ <&venus_smmu 0x08>,
127+ <&venus_smmu 0x09>,
128+ <&venus_smmu 0x0b>,
129+ <&venus_smmu 0x0c>,
130+ <&venus_smmu 0x0d>,
131+ <&venus_smmu 0x10>,
132+ <&venus_smmu 0x11>,
133+ <&venus_smmu 0x21>,
134+ <&venus_smmu 0x28>,
135+ <&venus_smmu 0x29>,
136+ <&venus_smmu 0x2b>,
137+ <&venus_smmu 0x2c>,
138+ <&venus_smmu 0x2d>,
139+ <&venus_smmu 0x31>;
140+ memory-region = <&venus_mem>;
141+
142+ video-decoder {
143+ compatible = "venus-decoder";
144+ clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
145+ clock-names = "core";
146+ power-domains = <&mmcc VENUS_CORE0_GDSC>;
147+ };
148+
149+ video-encoder {
150+ compatible = "venus-encoder";
151+ clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
152+ clock-names = "core";
153+ power-domains = <&mmcc VENUS_CORE1_GDSC>;
175154 };
155+ };
Documentation/devicetree/bindings/media/qcom,sc7180-venus.yaml+38−59
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sc7180-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,sc7180-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm SC7180 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,sc7180-venus
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 minItems: 2
2925 maxItems: 3
@@ -60,6 +56,10 @@ properties: · 30 unmodified lines
6056 - const: video-mem
6157 - const: cpu-cfg
6258
59+ operating-points-v2: true
60+ opp-table:
61+ type: object
62+
6363 video-decoder:
6464 type: object
6565
@@ -84,63 +84,42 @@ properties: · 18 unmodified lines
8484
8585 additionalProperties: false
8686
87− video-firmware:
88− type: object
89− additionalProperties: false
90−
91− description: |
92− Firmware subnode is needed when the platform does not
93− have TrustZone.
94−
95− properties:
96− iommus:
97− maxItems: 1
98−
99− required:
100− - iommus
101−
10287 required:
10388 - compatible
104− - reg
105− - interrupts
106− - power-domains
10789 - power-domain-names
108− - clocks
109− - clock-names
11090 - iommus
111− - memory-region
11291 - video-decoder
11392 - video-encoder
11493
115−additionalProperties: false
94+unevaluatedProperties: false
11695
11796 examples:
11897 - |
119− #include <dt-bindings/interrupt-controller/arm-gic.h>
120− #include <dt-bindings/clock/qcom,videocc-sc7180.h>
121−
122− venus: video-codec@aa00000 {
123− compatible = "qcom,sc7180-venus";
124− reg = <0x0aa00000 0xff000>;
125− interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
126− power-domains = <&videocc VENUS_GDSC>,
127− <&videocc VCODEC0_GDSC>;
128− power-domain-names = "venus", "vcodec0";
129− clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
130− <&videocc VIDEO_CC_VENUS_AHB_CLK>,
131− <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>,
132− <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
133− <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
134− clock-names = "core", "iface", "bus",
135− "vcodec0_core", "vcodec0_bus";
136− iommus = <&apps_smmu 0x0c00 0x60>;
137− memory-region = <&venus_mem>;
138−
139− video-decoder {
140− compatible = "venus-decoder";
141− };
142−
143− video-encoder {
144− compatible = "venus-encoder";
145− };
98+ #include <dt-bindings/interrupt-controller/arm-gic.h>
99+ #include <dt-bindings/clock/qcom,videocc-sc7180.h>
100+
101+ venus: video-codec@aa00000 {
102+ compatible = "qcom,sc7180-venus";
103+ reg = <0x0aa00000 0xff000>;
104+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
105+ power-domains = <&videocc VENUS_GDSC>,
106+ <&videocc VCODEC0_GDSC>;
107+ power-domain-names = "venus", "vcodec0";
108+ clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
109+ <&videocc VIDEO_CC_VENUS_AHB_CLK>,
110+ <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>,
111+ <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
112+ <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
113+ clock-names = "core", "iface", "bus",
114+ "vcodec0_core", "vcodec0_bus";
115+ iommus = <&apps_smmu 0x0c00 0x60>;
116+ memory-region = <&venus_mem>;
117+
118+ video-decoder {
119+ compatible = "venus-decoder";
120+ };
121+
122+ video-encoder {
123+ compatible = "venus-encoder";
146124 };
125+ };
Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml+54−78
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sc7280-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,sc7280-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm SC7280 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus Iris2 IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,sc7280-venus
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 minItems: 2
2925 maxItems: 3
@@ -49,9 +45,6 @@ properties: · 19 unmodified lines
4945 iommus:
5046 maxItems: 2
5147
52− memory-region:
53− maxItems: 1
54−
5548 interconnects:
5649 maxItems: 2
5750
@@ -60,6 +53,10 @@ properties: · 2 unmodified lines
6053 - const: cpu-cfg
6154 - const: video-mem
6255
56+ operating-points-v2: true
57+ opp-table:
58+ type: object
59+
6360 video-decoder:
6461 type: object
6562
@@ -84,79 +81,58 @@ properties: · 18 unmodified lines
8481
8582 additionalProperties: false
8683
87− video-firmware:
88− type: object
89− additionalProperties: false
90−
91− description: |
92− Firmware subnode is needed when the platform does not
93− have TrustZone.
94−
95− properties:
96− iommus:
97− maxItems: 1
98−
99− required:
100− - iommus
101−
10284 required:
10385 - compatible
104− - reg
105− - interrupts
106− - power-domains
10786 - power-domain-names
108− - clocks
109− - clock-names
11087 - iommus
111− - memory-region
11288 - video-decoder
11389 - video-encoder
11490
115−additionalProperties: false
91+unevaluatedProperties: false
11692
11793 examples:
11894 - |
119− #include <dt-bindings/interrupt-controller/arm-gic.h>
120− #include <dt-bindings/clock/qcom,videocc-sc7280.h>
121− #include <dt-bindings/interconnect/qcom,sc7280.h>
122− #include <dt-bindings/power/qcom-rpmpd.h>
123−
124− venus: video-codec@aa00000 {
125− compatible = "qcom,sc7280-venus";
126− reg = <0x0aa00000 0xd0600>;
127− interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
128−
129− clocks = <&videocc VIDEO_CC_MVSC_CORE_CLK>,
130− <&videocc VIDEO_CC_MVSC_CTL_AXI_CLK>,
131− <&videocc VIDEO_CC_VENUS_AHB_CLK>,
132− <&videocc VIDEO_CC_MVS0_CORE_CLK>,
133− <&videocc VIDEO_CC_MVS0_AXI_CLK>;
134− clock-names = "core", "bus", "iface",
135− "vcodec_core", "vcodec_bus";
136−
137− power-domains = <&videocc MVSC_GDSC>,
138− <&videocc MVS0_GDSC>,
139− <&rpmhpd SC7280_CX>;
140− power-domain-names = "venus", "vcodec0", "cx";
141−
142− interconnects = <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_VENUS_CFG 0>,
143− <&mmss_noc MASTER_VIDEO_P0 0 &mc_virt SLAVE_EBI1 0>;
144− interconnect-names = "cpu-cfg", "video-mem";
145−
146− iommus = <&apps_smmu 0x2180 0x20>,
147− <&apps_smmu 0x2184 0x20>;
148−
149− memory-region = <&video_mem>;
150−
151− video-decoder {
152− compatible = "venus-decoder";
153− };
154−
155− video-encoder {
156− compatible = "venus-encoder";
157− };
158−
159− video-firmware {
160− iommus = <&apps_smmu 0x21a2 0x0>;
161− };
95+ #include <dt-bindings/interrupt-controller/arm-gic.h>
96+ #include <dt-bindings/clock/qcom,videocc-sc7280.h>
97+ #include <dt-bindings/interconnect/qcom,sc7280.h>
98+ #include <dt-bindings/power/qcom-rpmpd.h>
99+
100+ venus: video-codec@aa00000 {
101+ compatible = "qcom,sc7280-venus";
102+ reg = <0x0aa00000 0xd0600>;
103+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
104+
105+ clocks = <&videocc VIDEO_CC_MVSC_CORE_CLK>,
106+ <&videocc VIDEO_CC_MVSC_CTL_AXI_CLK>,
107+ <&videocc VIDEO_CC_VENUS_AHB_CLK>,
108+ <&videocc VIDEO_CC_MVS0_CORE_CLK>,
109+ <&videocc VIDEO_CC_MVS0_AXI_CLK>;
110+ clock-names = "core", "bus", "iface",
111+ "vcodec_core", "vcodec_bus";
112+
113+ power-domains = <&videocc MVSC_GDSC>,
114+ <&videocc MVS0_GDSC>,
115+ <&rpmhpd SC7280_CX>;
116+ power-domain-names = "venus", "vcodec0", "cx";
117+
118+ interconnects = <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_VENUS_CFG 0>,
119+ <&mmss_noc MASTER_VIDEO_P0 0 &mc_virt SLAVE_EBI1 0>;
120+ interconnect-names = "cpu-cfg", "video-mem";
121+
122+ iommus = <&apps_smmu 0x2180 0x20>,
123+ <&apps_smmu 0x2184 0x20>;
124+
125+ memory-region = <&video_mem>;
126+
127+ video-decoder {
128+ compatible = "venus-decoder";
129+ };
130+
131+ video-encoder {
132+ compatible = "venus-encoder";
133+ };
134+
135+ video-firmware {
136+ iommus = <&apps_smmu 0x21a2 0x0>;
162137 };
138+ };
Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Qualcomm CAMSS ISP
99
Documentation/devicetree/bindings/media/qcom,sdm660-venus.yaml+58−86
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sdm660-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,sdm660-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm SDM660 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -15,13 +14,13 @@ description: | · 3 unmodified lines
1514 The Venus IP is a video encode and decode accelerator present
1615 on Qualcomm platforms
1716
17+allOf:
18+ - $ref: qcom,venus-common.yaml#
19+
1820 properties:
1921 compatible:
2022 const: qcom,sdm660-venus
2123
22− reg:
23− maxItems: 1
24−
2524 clocks:
2625 maxItems: 4
2726
@@ -40,15 +39,9 @@ properties: · 12 unmodified lines
4039 - const: cpu-cfg
4140 - const: video-mem
4241
43− interrupts:
44− maxItems: 1
45−
4642 iommus:
4743 maxItems: 20
4844
49− memory-region:
50− maxItems: 1
51−
5245 power-domains:
5346 maxItems: 1
5447
@@ -102,86 +95,65 @@ properties: · 47 unmodified lines
10295
10396 additionalProperties: false
10497
105− video-firmware:
106− type: object
107− additionalProperties: false
108−
109− description: |
110− Firmware subnode is needed when the platform does not
111− have TrustZone.
112−
113− properties:
114− iommus:
115− maxItems: 1
116−
117− required:
118− - iommus
119−
12098 required:
12199 - compatible
122− - reg
123− - clocks
124− - clock-names
125− - interrupts
126100 - iommus
127− - memory-region
128− - power-domains
129101 - video-decoder
130102 - video-encoder
131103
132−additionalProperties: false
104+unevaluatedProperties: false
133105
134106 examples:
135107 - |
136− #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
137− #include <dt-bindings/interrupt-controller/arm-gic.h>
138−
139− video-codec@cc00000 {
140− compatible = "qcom,sdm660-venus";
141− reg = <0x0cc00000 0xff000>;
142− clocks = <&mmcc VIDEO_CORE_CLK>,
143− <&mmcc VIDEO_AHB_CLK>,
144− <&mmcc VIDEO_AXI_CLK>,
145− <&mmcc THROTTLE_VIDEO_AXI_CLK>;
146− clock-names = "core", "iface", "bus", "bus_throttle";
147− interconnects = <&gnoc 0 &mnoc 13>,
148− <&mnoc 4 &bimc 5>;
149− interconnect-names = "cpu-cfg", "video-mem";
150− interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
151− iommus = <&mmss_smmu 0x400>,
152− <&mmss_smmu 0x401>,
153− <&mmss_smmu 0x40a>,
154− <&mmss_smmu 0x407>,
155− <&mmss_smmu 0x40e>,
156− <&mmss_smmu 0x40f>,
157− <&mmss_smmu 0x408>,
158− <&mmss_smmu 0x409>,
159− <&mmss_smmu 0x40b>,
160− <&mmss_smmu 0x40c>,
161− <&mmss_smmu 0x40d>,
162− <&mmss_smmu 0x410>,
163− <&mmss_smmu 0x421>,
164− <&mmss_smmu 0x428>,
165− <&mmss_smmu 0x429>,
166− <&mmss_smmu 0x42b>,
167− <&mmss_smmu 0x42c>,
168− <&mmss_smmu 0x42d>,
169− <&mmss_smmu 0x411>,
170− <&mmss_smmu 0x431>;
171− memory-region = <&venus_region>;
172− power-domains = <&mmcc VENUS_GDSC>;
173−
174− video-decoder {
175− compatible = "venus-decoder";
176− clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
177− clock-names = "vcodec0_core";
178− power-domains = <&mmcc VENUS_CORE0_GDSC>;
179− };
180−
181− video-encoder {
182− compatible = "venus-encoder";
183− clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
184− clock-names = "vcodec0_core";
185− power-domains = <&mmcc VENUS_CORE0_GDSC>;
186− };
108+ #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
109+ #include <dt-bindings/interrupt-controller/arm-gic.h>
110+
111+ video-codec@cc00000 {
112+ compatible = "qcom,sdm660-venus";
113+ reg = <0x0cc00000 0xff000>;
114+ clocks = <&mmcc VIDEO_CORE_CLK>,
115+ <&mmcc VIDEO_AHB_CLK>,
116+ <&mmcc VIDEO_AXI_CLK>,
117+ <&mmcc THROTTLE_VIDEO_AXI_CLK>;
118+ clock-names = "core", "iface", "bus", "bus_throttle";
119+ interconnects = <&gnoc 0 &mnoc 13>,
120+ <&mnoc 4 &bimc 5>;
121+ interconnect-names = "cpu-cfg", "video-mem";
122+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
123+ iommus = <&mmss_smmu 0x400>,
124+ <&mmss_smmu 0x401>,
125+ <&mmss_smmu 0x40a>,
126+ <&mmss_smmu 0x407>,
127+ <&mmss_smmu 0x40e>,
128+ <&mmss_smmu 0x40f>,
129+ <&mmss_smmu 0x408>,
130+ <&mmss_smmu 0x409>,
131+ <&mmss_smmu 0x40b>,
132+ <&mmss_smmu 0x40c>,
133+ <&mmss_smmu 0x40d>,
134+ <&mmss_smmu 0x410>,
135+ <&mmss_smmu 0x421>,
136+ <&mmss_smmu 0x428>,
137+ <&mmss_smmu 0x429>,
138+ <&mmss_smmu 0x42b>,
139+ <&mmss_smmu 0x42c>,
140+ <&mmss_smmu 0x42d>,
141+ <&mmss_smmu 0x411>,
142+ <&mmss_smmu 0x431>;
143+ memory-region = <&venus_region>;
144+ power-domains = <&mmcc VENUS_GDSC>;
145+
146+ video-decoder {
147+ compatible = "venus-decoder";
148+ clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
149+ clock-names = "vcodec0_core";
150+ power-domains = <&mmcc VENUS_CORE0_GDSC>;
151+ };
152+
153+ video-encoder {
154+ compatible = "venus-encoder";
155+ clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
156+ clock-names = "vcodec0_core";
157+ power-domains = <&mmcc VENUS_CORE0_GDSC>;
187158 };
159+ };
Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Qualcomm CAMSS ISP
99
Documentation/devicetree/bindings/media/qcom,sdm845-venus-v2.yaml+42−66
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sdm845-venus-v2.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,sdm845-venus-v2.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm SDM845 Venus v2 video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,sdm845-venus-v2
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 minItems: 3
2925 maxItems: 4
@@ -52,8 +48,9 @@ properties: · 22 unmodified lines
5248 iommus:
5349 maxItems: 2
5450
55− memory-region:
56− maxItems: 1
51+ operating-points-v2: true
52+ opp-table:
53+ type: object
5754
5855 video-core0:
5956 type: object
@@ -79,68 +76,47 @@ properties: · 19 unmodified lines
7976
8077 additionalProperties: false
8178
82− video-firmware:
83− type: object
84− additionalProperties: false
85−
86− description: |
87− Firmware subnode is needed when the platform does not
88− have TrustZone.
89−
90− properties:
91− iommus:
92− maxItems: 1
93−
94− required:
95− - iommus
96−
9779 required:
9880 - compatible
99− - reg
100− - interrupts
101− - power-domains
10281 - power-domain-names
103− - clocks
104− - clock-names
10582 - iommus
106− - memory-region
10783 - video-core0
10884 - video-core1
10985
110−additionalProperties: false
86+unevaluatedProperties: false
11187
11288 examples:
11389 - |
114− #include <dt-bindings/interrupt-controller/arm-gic.h>
115− #include <dt-bindings/clock/qcom,videocc-sdm845.h>
116−
117− video-codec@aa00000 {
118− compatible = "qcom,sdm845-venus-v2";
119− reg = <0x0aa00000 0xff000>;
120− interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
121− clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
122− <&videocc VIDEO_CC_VENUS_AHB_CLK>,
123− <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>,
124− <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
125− <&videocc VIDEO_CC_VCODEC0_AXI_CLK>,
126− <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
127− <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
128− clock-names = "core", "iface", "bus",
129− "vcodec0_core", "vcodec0_bus",
130− "vcodec1_core", "vcodec1_bus";
131− power-domains = <&videocc VENUS_GDSC>,
132− <&videocc VCODEC0_GDSC>,
133− <&videocc VCODEC1_GDSC>;
134− power-domain-names = "venus", "vcodec0", "vcodec1";
135− iommus = <&apps_smmu 0x10a0 0x8>,
136− <&apps_smmu 0x10b0 0x0>;
137− memory-region = <&venus_mem>;
138−
139− video-core0 {
140− compatible = "venus-decoder";
141− };
142−
143− video-core1 {
144− compatible = "venus-encoder";
145− };
90+ #include <dt-bindings/interrupt-controller/arm-gic.h>
91+ #include <dt-bindings/clock/qcom,videocc-sdm845.h>
92+
93+ video-codec@aa00000 {
94+ compatible = "qcom,sdm845-venus-v2";
95+ reg = <0x0aa00000 0xff000>;
96+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
97+ clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
98+ <&videocc VIDEO_CC_VENUS_AHB_CLK>,
99+ <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>,
100+ <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
101+ <&videocc VIDEO_CC_VCODEC0_AXI_CLK>,
102+ <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
103+ <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
104+ clock-names = "core", "iface", "bus",
105+ "vcodec0_core", "vcodec0_bus",
106+ "vcodec1_core", "vcodec1_bus";
107+ power-domains = <&videocc VENUS_GDSC>,
108+ <&videocc VCODEC0_GDSC>,
109+ <&videocc VCODEC1_GDSC>;
110+ power-domain-names = "venus", "vcodec0", "vcodec1";
111+ iommus = <&apps_smmu 0x10a0 0x8>,
112+ <&apps_smmu 0x10b0 0x0>;
113+ memory-region = <&venus_mem>;
114+
115+ video-core0 {
116+ compatible = "venus-decoder";
117+ };
118+
119+ video-core1 {
120+ compatible = "venus-encoder";
146121 };
122+ };
Documentation/devicetree/bindings/media/qcom,sdm845-venus.yaml+38−66
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sdm845-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,sdm845-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm SDM845 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,sdm845-venus
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 maxItems: 1
2925
@@ -39,9 +35,6 @@ properties: · 9 unmodified lines
3935 iommus:
4036 maxItems: 2
4137
42− memory-region:
43− maxItems: 1
44−
4538 video-core0:
4639 type: object
4740
@@ -94,66 +87,45 @@ properties: · 46 unmodified lines
9487
9588 additionalProperties: false
9689
97− video-firmware:
98− type: object
99− additionalProperties: false
100−
101− description: |
102− Firmware subnode is needed when the platform does not
103− have TrustZone.
104−
105− properties:
106− iommus:
107− maxItems: 1
108−
109− required:
110− - iommus
111−
11290 required:
11391 - compatible
114− - reg
115− - interrupts
116− - power-domains
117− - clocks
118− - clock-names
11992 - iommus
120− - memory-region
12193 - video-core0
12294 - video-core1
12395
124−additionalProperties: false
96+unevaluatedProperties: false
12597
12698 examples:
12799 - |
128− #include <dt-bindings/interrupt-controller/arm-gic.h>
129− #include <dt-bindings/clock/qcom,videocc-sdm845.h>
130−
131− video-codec@aa00000 {
132− compatible = "qcom,sdm845-venus";
133− reg = <0x0aa00000 0xff000>;
134− interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
135− clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
136− <&videocc VIDEO_CC_VENUS_AHB_CLK>,
137− <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>;
138− clock-names = "core", "iface", "bus";
139− power-domains = <&videocc VENUS_GDSC>;
140− iommus = <&apps_smmu 0x10a0 0x8>,
141− <&apps_smmu 0x10b0 0x0>;
142− memory-region = <&venus_mem>;
143−
144− video-core0 {
145− compatible = "venus-decoder";
146− clocks = <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
147− <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
148− clock-names = "core", "bus";
149− power-domains = <&videocc VCODEC0_GDSC>;
150− };
151−
152− video-core1 {
153− compatible = "venus-encoder";
154− clocks = <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
155− <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
156− clock-names = "core", "bus";
157− power-domains = <&videocc VCODEC1_GDSC>;
158− };
100+ #include <dt-bindings/interrupt-controller/arm-gic.h>
101+ #include <dt-bindings/clock/qcom,videocc-sdm845.h>
102+
103+ video-codec@aa00000 {
104+ compatible = "qcom,sdm845-venus";
105+ reg = <0x0aa00000 0xff000>;
106+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
107+ clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
108+ <&videocc VIDEO_CC_VENUS_AHB_CLK>,
109+ <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>;
110+ clock-names = "core", "iface", "bus";
111+ power-domains = <&videocc VENUS_GDSC>;
112+ iommus = <&apps_smmu 0x10a0 0x8>,
113+ <&apps_smmu 0x10b0 0x0>;
114+ memory-region = <&venus_mem>;
115+
116+ video-core0 {
117+ compatible = "venus-decoder";
118+ clocks = <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
119+ <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
120+ clock-names = "core", "bus";
121+ power-domains = <&videocc VCODEC0_GDSC>;
122+ };
123+
124+ video-core1 {
125+ compatible = "venus-encoder";
126+ clocks = <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
127+ <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
128+ clock-names = "core", "bus";
129+ power-domains = <&videocc VCODEC1_GDSC>;
159130 };
131+ };
Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Qualcomm CAMSS ISP
99
Documentation/devicetree/bindings/media/qcom,sm8250-venus.yaml+49−73
@@ -1,11 +1,10 @@
11 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2−
32 %YAML 1.2
43 ---
5−$id: "http://devicetree.org/schemas/media/qcom,sm8250-venus.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
4+$id: http://devicetree.org/schemas/media/qcom,sm8250-venus.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
76
8−title: Qualcomm Venus video encode and decode accelerators
7+title: Qualcomm SM8250 Venus video encode and decode accelerators
98
109 maintainers:
1110 - Stanimir Varbanov <stanimir.varbanov@linaro.org>
@@ -14,16 +13,13 @@ description: | · 2 unmodified lines
1413 The Venus IP is a video encode and decode accelerator present
1514 on Qualcomm platforms
1615
16+allOf:
17+ - $ref: qcom,venus-common.yaml#
18+
1719 properties:
1820 compatible:
1921 const: qcom,sm8250-venus
2022
21− reg:
22− maxItems: 1
23−
24− interrupts:
25− maxItems: 1
26−
2723 power-domains:
2824 minItems: 2
2925 maxItems: 3
@@ -47,9 +43,6 @@ properties: · 17 unmodified lines
4743 iommus:
4844 maxItems: 1
4945
50− memory-region:
51− maxItems: 1
52−
5346 interconnects:
5447 maxItems: 2
5548
@@ -58,6 +51,10 @@ properties: · 2 unmodified lines
5851 - const: cpu-cfg
5952 - const: video-mem
6053
54+ operating-points-v2: true
55+ opp-table:
56+ type: object
57+
6158 resets:
6259 maxItems: 2
6360
@@ -90,78 +87,57 @@ properties: · 26 unmodified lines
9087
9188 additionalProperties: false
9289
93− video-firmware:
94− type: object
95− additionalProperties: false
96−
97− description: |
98− Firmware subnode is needed when the platform does not
99− have TrustZone.
100−
101− properties:
102− iommus:
103− maxItems: 1
104−
105− required:
106− - iommus
107−
10890 required:
10991 - compatible
110− - reg
111− - interrupts
112− - power-domains
11392 - power-domain-names
114− - clocks
115− - clock-names
11693 - interconnects
11794 - interconnect-names
11895 - iommus
119− - memory-region
12096 - resets
12197 - reset-names
12298 - video-decoder
12399 - video-encoder
124100
125−additionalProperties: false
101+unevaluatedProperties: false
126102
127103 examples:
128104 - |
129− #include <dt-bindings/interrupt-controller/arm-gic.h>
130− #include <dt-bindings/clock/qcom,videocc-sm8250.h>
131− #include <dt-bindings/interconnect/qcom,sm8250.h>
132− #include <dt-bindings/clock/qcom,gcc-sm8250.h>
133− #include <dt-bindings/power/qcom-rpmpd.h>
134−
135− venus: video-codec@aa00000 {
136− compatible = "qcom,sm8250-venus";
137− reg = <0x0aa00000 0xff000>;
138− interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
139− power-domains = <&videocc MVS0C_GDSC>,
140− <&videocc MVS0_GDSC>,
141− <&rpmhpd SM8250_MX>;
142− power-domain-names = "venus", "vcodec0", "mx";
143−
144− clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
145− <&videocc VIDEO_CC_MVS0C_CLK>,
146− <&videocc VIDEO_CC_MVS0_CLK>;
147− clock-names = "iface", "core", "vcodec0_core";
148−
149− interconnects = <&gem_noc MASTER_AMPSS_M0 &config_noc SLAVE_VENUS_CFG>,
150− <&mmss_noc MASTER_VIDEO_P0 &mc_virt SLAVE_EBI_CH0>;
151− interconnect-names = "cpu-cfg", "video-mem";
152−
153− iommus = <&apps_smmu 0x2100 0x0400>;
154− memory-region = <&video_mem>;
155−
156− resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>,
157− <&videocc VIDEO_CC_MVS0C_CLK_ARES>;
158− reset-names = "bus", "core";
159−
160− video-decoder {
161− compatible = "venus-decoder";
162− };
163−
164− video-encoder {
165− compatible = "venus-encoder";
166− };
105+ #include <dt-bindings/interrupt-controller/arm-gic.h>
106+ #include <dt-bindings/clock/qcom,videocc-sm8250.h>
107+ #include <dt-bindings/interconnect/qcom,sm8250.h>
108+ #include <dt-bindings/clock/qcom,gcc-sm8250.h>
109+ #include <dt-bindings/power/qcom-rpmpd.h>
110+
111+ venus: video-codec@aa00000 {
112+ compatible = "qcom,sm8250-venus";
113+ reg = <0x0aa00000 0xff000>;
114+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
115+ power-domains = <&videocc MVS0C_GDSC>,
116+ <&videocc MVS0_GDSC>,
117+ <&rpmhpd SM8250_MX>;
118+ power-domain-names = "venus", "vcodec0", "mx";
119+
120+ clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
121+ <&videocc VIDEO_CC_MVS0C_CLK>,
122+ <&videocc VIDEO_CC_MVS0_CLK>;
123+ clock-names = "iface", "core", "vcodec0_core";
124+
125+ interconnects = <&gem_noc MASTER_AMPSS_M0 &config_noc SLAVE_VENUS_CFG>,
126+ <&mmss_noc MASTER_VIDEO_P0 &mc_virt SLAVE_EBI_CH0>;
127+ interconnect-names = "cpu-cfg", "video-mem";
128+
129+ iommus = <&apps_smmu 0x2100 0x0400>;
130+ memory-region = <&video_mem>;
131+
132+ resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>,
133+ <&videocc VIDEO_CC_MVS0C_CLK_ARES>;
134+ reset-names = "bus", "core";
135+
136+ video-decoder {
137+ compatible = "venus-decoder";
138+ };
139+
140+ video-encoder {
141+ compatible = "venus-encoder";
167142 };
143+ };
Documentation/devicetree/bindings/media/qcom,venus-common.yaml+73−0
@@ -0,0 +1,73 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/qcom,venus-common.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Qualcomm SoC Venus Video Encode and Decode Accelerators Common Properties
8+
9+maintainers:
10+ - Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
11+ - Vikash Garodia <quic_vgarodia@quicinc.com>
12+
13+description: |
14+ The Venus IP is a video encode and decode accelerator present
15+ on Qualcomm platforms
16+
17+properties:
18+ reg:
19+ maxItems: 1
20+
21+ clocks:
22+ minItems: 3
23+ maxItems: 7
24+
25+ clock-names:
26+ minItems: 3
27+ maxItems: 7
28+
29+ firmware-name:
30+ maxItems: 1
31+
32+ interrupts:
33+ maxItems: 1
34+
35+ iommus:
36+ minItems: 1
37+ maxItems: 20
38+
39+ memory-region:
40+ maxItems: 1
41+
42+ power-domains:
43+ minItems: 1
44+ maxItems: 4
45+
46+ power-domain-names:
47+ minItems: 1
48+ maxItems: 4
49+
50+ video-firmware:
51+ type: object
52+ additionalProperties: false
53+
54+ description: |
55+ Firmware subnode is needed when the platform does not
56+ have TrustZone.
57+
58+ properties:
59+ iommus:
60+ maxItems: 1
61+
62+ required:
63+ - iommus
64+
65+required:
66+ - reg
67+ - clocks
68+ - clock-names
69+ - interrupts
70+ - memory-region
71+ - power-domains
72+
73+additionalProperties: true
Documentation/devicetree/bindings/media/rc.yaml+3−1
@@ -18,7 +18,7 @@ properties: · 17 unmodified lines
1818 description:
1919 Specifies the scancode/key mapping table defined in-kernel for
2020 the remote controller.
21− $ref: '/schemas/types.yaml#/definitions/string'
21+ $ref: /schemas/types.yaml#/definitions/string
2222 enum:
2323 - rc-adstech-dvb-t-pci
2424 - rc-alink-dtu-m
@@ -39,6 +39,7 @@ properties: · 14 unmodified lines
3939 - rc-avertv-303
4040 - rc-azurewave-ad-tu700
4141 - rc-beelink-gs1
42+ - rc-beelink-mxiii
4243 - rc-behold
4344 - rc-behold-columbus
4445 - rc-budget-ci-old
@@ -55,6 +56,7 @@ properties: · 10 unmodified lines
5556 - rc-dm1105-nec
5657 - rc-dntv-live-dvb-t
5758 - rc-dntv-live-dvbt-pro
59+ - rc-dreambox
5860 - rc-dtt200u
5961 - rc-dvbsky
6062 - rc-dvico-mce
Documentation/devicetree/bindings/media/renesas,csi2.yaml+1−0
@@ -31,6 +31,7 @@ properties: · 30 unmodified lines
3131 - renesas,r8a77980-csi2 # R-Car V3H
3232 - renesas,r8a77990-csi2 # R-Car E3
3333 - renesas,r8a779a0-csi2 # R-Car V3U
34+ - renesas,r8a779g0-csi2 # R-Car V4H
3435
3536 reg:
3637 maxItems: 1
Documentation/devicetree/bindings/media/renesas,fcp.yaml+40−5
@@ -21,15 +21,22 @@ description: | · 20 unmodified lines
2121
2222 properties:
2323 compatible:
24− enum:
25− - renesas,fcpv # FCP for VSP
26− - renesas,fcpf # FCP for FDP
24+ oneOf:
25+ - enum:
26+ - renesas,fcpv # FCP for VSP
27+ - renesas,fcpf # FCP for FDP
28+ - items:
29+ - enum:
30+ - renesas,r9a07g044-fcpvd # RZ/G2{L,LC}
31+ - renesas,r9a07g054-fcpvd # RZ/V2L
32+ - const: renesas,fcpv # Generic FCP for VSP fallback
2733
2834 reg:
2935 maxItems: 1
3036
31− clocks:
32− maxItems: 1
37+ clocks: true
38+
39+ clock-names: true
3340
3441 iommus:
3542 maxItems: 1
@@ -49,6 +56,34 @@ required: · 13 unmodified lines
4956
5057 additionalProperties: false
5158
59+allOf:
60+ - if:
61+ properties:
62+ compatible:
63+ contains:
64+ enum:
65+ - renesas,r9a07g044-fcpvd
66+ - renesas,r9a07g054-fcpvd
67+ then:
68+ properties:
69+ clocks:
70+ items:
71+ - description: Main clock
72+ - description: Register access clock
73+ - description: Video clock
74+ clock-names:
75+ items:
76+ - const: aclk
77+ - const: pclk
78+ - const: vclk
79+ required:
80+ - clock-names
81+ else:
82+ properties:
83+ clocks:
84+ maxItems: 1
85+ clock-names: false
86+
5287 examples:
5388 # R8A7795 (R-Car H3) FCP for VSP-D1
5489 - |
Documentation/devicetree/bindings/media/renesas,isp.yaml+1−0
@@ -21,6 +21,7 @@ properties: · 20 unmodified lines
2121 items:
2222 - enum:
2323 - renesas,r8a779a0-isp # V3U
24+ - renesas,r8a779g0-isp # V4H
2425 reg:
2526 maxItems: 1
2627
Documentation/devicetree/bindings/media/renesas,vin.yaml+1−0
@@ -53,6 +53,7 @@ properties: · 52 unmodified lines
5353 - renesas,vin-r8a77990 # R-Car E3
5454 - renesas,vin-r8a77995 # R-Car D3
5555 - renesas,vin-r8a779a0 # R-Car V3U
56+ - renesas,vin-r8a779g0 # R-Car V4H
5657
5758 reg:
5859 maxItems: 1
Documentation/devicetree/bindings/media/renesas,vsp1.yaml+9−4
@@ -16,10 +16,15 @@ description: · 15 unmodified lines
1616
1717 properties:
1818 compatible:
19− enum:
20− - renesas,r9a07g044-vsp2 # RZ/G2L
21− - renesas,vsp1 # R-Car Gen2 and RZ/G1
22− - renesas,vsp2 # R-Car Gen3 and RZ/G2
19+ oneOf:
20+ - enum:
21+ - renesas,r9a07g044-vsp2 # RZ/G2L
22+ - renesas,vsp1 # R-Car Gen2 and RZ/G1
23+ - renesas,vsp2 # R-Car Gen3 and RZ/G2
24+ - items:
25+ - enum:
26+ - renesas,r9a07g054-vsp2 # RZ/V2L
27+ - const: renesas,r9a07g044-vsp2 # RZ/G2L fallback
2328
2429 reg:
2530 maxItems: 1
Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/rockchip,rk3568-vepu.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/rockchip,rk3568-vepu.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Hantro G1 VPU encoders implemented on Rockchip SoCs
99
Documentation/devicetree/bindings/media/rockchip-isp1.yaml+13−6
@@ -212,12 +212,19 @@ examples: · 211 unmodified lines
212212 compatible = "ovti,ov2685";
213213 reg = <0x3c>;
214214
215− port {
216− ucam_out: endpoint {
217− remote-endpoint = <&mipi_in_ucam>;
218− data-lanes = <1>;
219− };
220− };
215+ clocks = <&cru SCLK_TESTCLKOUT1>;
216+ clock-names = "xvclk";
217+
218+ avdd-supply = <&pp2800_cam>;
219+ dovdd-supply = <&pp1800>;
220+ dvdd-supply = <&pp1800>;
221+
222+ port {
223+ ucam_out: endpoint {
224+ remote-endpoint = <&mipi_in_ucam>;
225+ data-lanes = <1>;
226+ };
227+ };
221228 };
222229 };
223230 };
Documentation/devicetree/bindings/media/rockchip-vpu.yaml+2−2
@@ -2,8 +2,8 @@ · 1 unmodified line
22
33 %YAML 1.2
44 ---
5−$id: "http://devicetree.org/schemas/media/rockchip-vpu.yaml#"
6−$schema: "http://devicetree.org/meta-schemas/core.yaml#"
5+$id: http://devicetree.org/schemas/media/rockchip-vpu.yaml#
6+$schema: http://devicetree.org/meta-schemas/core.yaml#
77
88 title: Hantro G1 VPU codecs implemented on Rockchip SoCs
99
Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml+170−0
@@ -0,0 +1,170 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/samsung,exynos4210-csis.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung S5P/Exynos SoC series MIPI CSI-2 receiver (MIPI CSIS)
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
12+
13+properties:
14+ compatible:
15+ enum:
16+ - samsung,s5pv210-csis
17+ - samsung,exynos4210-csis
18+ - samsung,exynos4212-csis
19+ - samsung,exynos5250-csis
20+
21+ reg:
22+ maxItems: 1
23+
24+ '#address-cells':
25+ const: 1
26+
27+ '#size-cells':
28+ const: 0
29+
30+ bus-width:
31+ $ref: /schemas/types.yaml#/definitions/uint32
32+ enum: [2, 4]
33+ description:
34+ Number of data lines supported.
35+
36+ clocks:
37+ maxItems: 2
38+
39+ clock-names:
40+ items:
41+ - const: csis
42+ - const: sclk_csis
43+
44+ clock-frequency:
45+ default: 166000000
46+ description:
47+ The IP's main (system bus) clock frequency in Hz.
48+
49+ interrupts:
50+ maxItems: 1
51+
52+ phys:
53+ maxItems: 1
54+
55+ phy-names:
56+ items:
57+ - const: csis
58+
59+ power-domains:
60+ maxItems: 1
61+
62+ vddio-supply:
63+ description: MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V).
64+
65+ vddcore-supply:
66+ description: MIPI CSIS Core voltage supply (e.g. 1.1V).
67+
68+patternProperties:
69+ "^port@[34]$":
70+ $ref: /schemas/graph.yaml#/$defs/port-base
71+ additionalProperties: false
72+ description:
73+ Camera input port.
74+
75+ properties:
76+ reg:
77+ enum: [3, 4]
78+
79+ endpoint:
80+ $ref: video-interfaces.yaml#
81+ unevaluatedProperties: false
82+
83+ properties:
84+ data-lanes:
85+ minItems: 1
86+ maxItems: 4
87+
88+ samsung,csis-hs-settle:
89+ $ref: /schemas/types.yaml#/definitions/uint32
90+ description: Differential receiver (HS-RX) settle time.
91+
92+ samsung,csis-wclk:
93+ type: boolean
94+ description:
95+ CSI-2 wrapper clock selection. If this property is present external clock
96+ from CMU will be used, or the bus clock if it's not specified.
97+
98+ required:
99+ - data-lanes
100+
101+ required:
102+ - reg
103+
104+required:
105+ - compatible
106+ - reg
107+ - bus-width
108+ - clocks
109+ - clock-names
110+ - interrupts
111+ - vddio-supply
112+ - vddcore-supply
113+
114+anyOf:
115+ - required:
116+ - port@3
117+ - required:
118+ - port@4
119+
120+allOf:
121+ - if:
122+ required:
123+ - samsung,isp-wb
124+ then:
125+ required:
126+ - samsung,sysreg
127+
128+additionalProperties: false
129+
130+examples:
131+ - |
132+ #include <dt-bindings/clock/exynos4.h>
133+ #include <dt-bindings/interrupt-controller/arm-gic.h>
134+
135+ csis@11890000 {
136+ compatible = "samsung,exynos4210-csis";
137+ reg = <0x11890000 0x4000>;
138+ clocks = <&clock CLK_CSIS1>,
139+ <&clock CLK_SCLK_CSIS1>;
140+ clock-names = "csis", "sclk_csis";
141+ assigned-clocks = <&clock CLK_MOUT_CSIS1>,
142+ <&clock CLK_SCLK_CSIS1>;
143+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
144+ assigned-clock-rates = <0>, <176000000>;
145+
146+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
147+
148+ bus-width = <2>;
149+ power-domains = <&pd_cam>;
150+ phys = <&mipi_phy 2>;
151+ phy-names = "csis";
152+
153+ vddcore-supply = <&ldo8_reg>;
154+ vddio-supply = <&ldo10_reg>;
155+
156+ #address-cells = <1>;
157+ #size-cells = <0>;
158+
159+ /* Camera D (4) MIPI CSI-2 (CSIS1) */
160+ port@4 {
161+ reg = <4>;
162+
163+ endpoint {
164+ remote-endpoint = <&is_s5k6a3_ep>;
165+ data-lanes = <1>;
166+ samsung,csis-hs-settle = <18>;
167+ samsung,csis-wclk;
168+ };
169+ };
170+ };
Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml+152−0
@@ -0,0 +1,152 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/samsung,exynos4210-fimc.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung S5P/Exynos SoC Fully Integrated Mobile Camera
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
12+
13+description:
14+ Each FIMC device should have an alias in the aliases node, in the form of
15+ fimc<n>, where <n> is an integer specifying the IP block instance.
16+
17+properties:
18+ compatible:
19+ enum:
20+ - samsung,exynos4210-fimc
21+ - samsung,exynos4212-fimc
22+ - samsung,s5pv210-fimc
23+
24+ reg:
25+ maxItems: 1
26+
27+ clocks:
28+ maxItems: 2
29+
30+ clock-names:
31+ items:
32+ - const: fimc
33+ - const: sclk_fimc
34+
35+ clock-frequency:
36+ description:
37+ Maximum FIMC local clock (LCLK) frequency.
38+
39+ interrupts:
40+ maxItems: 1
41+
42+ iommus:
43+ maxItems: 1
44+
45+ power-domains:
46+ maxItems: 1
47+
48+ samsung,cam-if:
49+ type: boolean
50+ description:
51+ The FIMC IP block includes the camera input interface.
52+
53+ samsung,isp-wb:
54+ type: boolean
55+ description: |
56+ The FIMC IP block has the ISP writeback input.
57+
58+ samsung,lcd-wb:
59+ type: boolean
60+ description: |
61+ The FIMC IP block has the LCD writeback input.
62+
63+ samsung,mainscaler-ext:
64+ type: boolean
65+ description:
66+ FIMC IP supports extended image size and has CIEXTEN register.
67+
68+ samsung,min-pix-alignment:
69+ $ref: /schemas/types.yaml#/definitions/uint32-array
70+ items:
71+ - description: Minimum supported image height alignment.
72+ - description: Horizontal image offset.
73+ description:
74+ The values are in pixels and default is <2 1>.
75+
76+ samsung,min-pix-sizes:
77+ $ref: /schemas/types.yaml#/definitions/uint32-array
78+ maxItems: 2
79+ description: |
80+ An array specyfing minimum image size in pixels at the FIMC input and
81+ output DMA, in the first and second cell respectively. Default value
82+ is <16 16>.
83+
84+ samsung,pix-limits:
85+ $ref: /schemas/types.yaml#/definitions/uint32-array
86+ maxItems: 4
87+ description: |
88+ An array of maximum supported image sizes in pixels, for details refer to
89+ Table 2-1 in the S5PV210 SoC User Manual. The meaning of each cell is as
90+ follows:
91+ 0 - scaler input horizontal size
92+ 1 - input horizontal size for the scaler bypassed
93+ 2 - REAL_WIDTH without input rotation
94+ 3 - REAL_HEIGHT with input rotation
95+
96+ samsung,rotators:
97+ $ref: /schemas/types.yaml#/definitions/uint32
98+ default: 0x11
99+ description: |
100+ A bitmask specifying whether this IP has the input and the output
101+ rotator. Bits 4 and 0 correspond to input and output rotator
102+ respectively. If a rotator is present its corresponding bit should be
103+ set.
104+
105+ samsung,sysreg:
106+ $ref: /schemas/types.yaml#/definitions/phandle
107+ description:
108+ System Registers (SYSREG) node.
109+
110+required:
111+ - compatible
112+ - reg
113+ - clocks
114+ - clock-names
115+ - samsung,pix-limits
116+
117+allOf:
118+ - if:
119+ required:
120+ - samsung,isp-wb
121+ then:
122+ required:
123+ - samsung,sysreg
124+
125+additionalProperties: false
126+
127+examples:
128+ - |
129+ #include <dt-bindings/clock/exynos4.h>
130+ #include <dt-bindings/interrupt-controller/arm-gic.h>
131+
132+ fimc@11800000 {
133+ compatible = "samsung,exynos4212-fimc";
134+ reg = <0x11800000 0x1000>;
135+ clocks = <&clock CLK_FIMC0>,
136+ <&clock CLK_SCLK_FIMC0>;
137+ clock-names = "fimc", "sclk_fimc";
138+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
139+ iommus = <&sysmmu_fimc0>;
140+ power-domains = <&pd_cam>;
141+ samsung,sysreg = <&sys_reg>;
142+
143+ samsung,pix-limits = <4224 8192 1920 4224>;
144+ samsung,mainscaler-ext;
145+ samsung,isp-wb;
146+ samsung,cam-if;
147+
148+ assigned-clocks = <&clock CLK_MOUT_FIMC0>,
149+ <&clock CLK_SCLK_FIMC0>;
150+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
151+ assigned-clock-rates = <0>, <176000000>;
152+ };
Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml+220−0
@@ -0,0 +1,220 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/samsung,exynos4212-fimc-is.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung Exynos4212/4412 SoC Imaging Subsystem (FIMC-IS)
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
12+
13+description:
14+ The FIMC-IS is a subsystem for processing image signal from an image sensor.
15+ The Exynos4x12 SoC series FIMC-IS V1.5 comprises of a dedicated ARM Cortex-A5
16+ processor, ISP, DRC and FD IP blocks and peripheral devices such as UART, I2C
17+ and SPI bus controllers, PWM and ADC.
18+
19+properties:
20+ compatible:
21+ enum:
22+ - samsung,exynos4212-fimc-is
23+
24+ reg:
25+ maxItems: 1
26+
27+ ranges: true
28+
29+ '#address-cells':
30+ const: 1
31+
32+ '#size-cells':
33+ const: 1
34+
35+ clocks:
36+ maxItems: 21
37+
38+ clock-names:
39+ items:
40+ - const: lite0
41+ - const: lite1
42+ - const: ppmuispx
43+ - const: ppmuispmx
44+ - const: isp
45+ - const: drc
46+ - const: fd
47+ - const: mcuisp
48+ - const: gicisp
49+ - const: mcuctl_isp
50+ - const: pwm_isp
51+ - const: ispdiv0
52+ - const: ispdiv1
53+ - const: mcuispdiv0
54+ - const: mcuispdiv1
55+ - const: mpll
56+ - const: aclk200
57+ - const: aclk400mcuisp
58+ - const: div_aclk200
59+ - const: div_aclk400mcuisp
60+ - const: uart
61+
62+ interrupts:
63+ maxItems: 2
64+
65+ iommus:
66+ maxItems: 4
67+
68+ iommu-names:
69+ items:
70+ - const: isp
71+ - const: drc
72+ - const: fd
73+ - const: mcuctl
74+
75+ power-domains:
76+ maxItems: 1
77+
78+patternProperties:
79+ "^pmu@[0-9a-f]+$":
80+ type: object
81+ additionalProperties: false
82+ description:
83+ Node representing the SoC's Power Management Unit (duplicated with the
84+ correct PMU node in the SoC).
85+
86+ properties:
87+ reg:
88+ maxItems: 1
89+
90+ required:
91+ - reg
92+
93+ "^i2c-isp@[0-9a-f]+$":
94+ type: object
95+ $ref: /schemas/i2c/i2c-controller.yaml#
96+ unevaluatedProperties: false
97+ description:
98+ ISP I2C bus controller
99+
100+ properties:
101+ compatible:
102+ const: samsung,exynos4212-i2c-isp
103+
104+ reg:
105+ maxItems: 1
106+
107+
108+ clocks:
109+ maxItems: 1
110+
111+ clock-names:
112+ items:
113+ - const: i2c_isp
114+
115+ pinctrl-0: true
116+ pinctrl-names:
117+ items:
118+ - const: default
119+
120+ required:
121+ - compatible
122+ - reg
123+ - clocks
124+ - clock-names
125+
126+required:
127+ - compatible
128+ - reg
129+ - '#address-cells'
130+ - clocks
131+ - clock-names
132+ - interrupts
133+ - ranges
134+ - '#size-cells'
135+
136+additionalProperties: false
137+
138+examples:
139+ - |
140+ #include <dt-bindings/clock/exynos4.h>
141+ #include <dt-bindings/gpio/gpio.h>
142+ #include <dt-bindings/interrupt-controller/arm-gic.h>
143+
144+ fimc-is@12000000 {
145+ compatible = "samsung,exynos4212-fimc-is";
146+ reg = <0x12000000 0x260000>;
147+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
148+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
149+ clocks = <&isp_clock CLK_ISP_FIMC_LITE0>,
150+ <&isp_clock CLK_ISP_FIMC_LITE1>,
151+ <&isp_clock CLK_ISP_PPMUISPX>,
152+ <&isp_clock CLK_ISP_PPMUISPMX>,
153+ <&isp_clock CLK_ISP_FIMC_ISP>,
154+ <&isp_clock CLK_ISP_FIMC_DRC>,
155+ <&isp_clock CLK_ISP_FIMC_FD>,
156+ <&isp_clock CLK_ISP_MCUISP>,
157+ <&isp_clock CLK_ISP_GICISP>,
158+ <&isp_clock CLK_ISP_MCUCTL_ISP>,
159+ <&isp_clock CLK_ISP_PWM_ISP>,
160+ <&isp_clock CLK_ISP_DIV_ISP0>,
161+ <&isp_clock CLK_ISP_DIV_ISP1>,
162+ <&isp_clock CLK_ISP_DIV_MCUISP0>,
163+ <&isp_clock CLK_ISP_DIV_MCUISP1>,
164+ <&clock CLK_MOUT_MPLL_USER_T>,
165+ <&clock CLK_ACLK200>,
166+ <&clock CLK_ACLK400_MCUISP>,
167+ <&clock CLK_DIV_ACLK200>,
168+ <&clock CLK_DIV_ACLK400_MCUISP>,
169+ <&clock CLK_UART_ISP_SCLK>;
170+ clock-names = "lite0", "lite1", "ppmuispx",
171+ "ppmuispmx", "isp",
172+ "drc", "fd", "mcuisp",
173+ "gicisp", "mcuctl_isp", "pwm_isp",
174+ "ispdiv0", "ispdiv1", "mcuispdiv0",
175+ "mcuispdiv1", "mpll", "aclk200",
176+ "aclk400mcuisp", "div_aclk200",
177+ "div_aclk400mcuisp", "uart";
178+ iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
179+ <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
180+ iommu-names = "isp", "drc", "fd", "mcuctl";
181+ power-domains = <&pd_isp>;
182+
183+ #address-cells = <1>;
184+ #size-cells = <1>;
185+ ranges;
186+
187+ pmu@10020000 {
188+ reg = <0x10020000 0x3000>;
189+ };
190+
191+ i2c-isp@12140000 {
192+ compatible = "samsung,exynos4212-i2c-isp";
193+ reg = <0x12140000 0x100>;
194+ clocks = <&isp_clock CLK_ISP_I2C1_ISP>;
195+ clock-names = "i2c_isp";
196+ pinctrl-0 = <&fimc_is_i2c1>;
197+ pinctrl-names = "default";
198+ #address-cells = <1>;
199+ #size-cells = <0>;
200+
201+ image-sensor@10 {
202+ compatible = "samsung,s5k6a3";
203+ reg = <0x10>;
204+ svdda-supply = <&cam_io_reg>;
205+ svddio-supply = <&ldo19_reg>;
206+ afvdd-supply = <&ldo19_reg>;
207+ clock-frequency = <24000000>;
208+ clocks = <&camera 1>;
209+ clock-names = "extclk";
210+ gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
211+
212+ port {
213+ endpoint {
214+ remote-endpoint = <&csis1_ep>;
215+ data-lanes = <1>;
216+ };
217+ };
218+ };
219+ };
220+ };
Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml+63−0
@@ -0,0 +1,63 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/samsung,exynos4212-fimc-lite.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung Exynos SoC series camera host interface (FIMC-LITE)
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
12+
13+description:
14+ Each FIMC device should have an alias in the aliases node, in the form of
15+ fimc-lite<n>, where <n> is an integer specifying the IP block instance.
16+
17+properties:
18+ compatible:
19+ enum:
20+ - samsung,exynos4212-fimc-lite
21+ - samsung,exynos5250-fimc-lite
22+
23+ reg:
24+ maxItems: 1
25+
26+ clocks:
27+ maxItems: 1
28+
29+ clock-names:
30+ items:
31+ - const: flite
32+
33+ interrupts:
34+ maxItems: 1
35+
36+ iommus:
37+ maxItems: 1
38+
39+ power-domains:
40+ maxItems: 1
41+
42+required:
43+ - compatible
44+ - reg
45+ - clocks
46+ - clock-names
47+ - interrupts
48+
49+additionalProperties: false
50+
51+examples:
52+ - |
53+ #include <dt-bindings/clock/exynos4.h>
54+ #include <dt-bindings/interrupt-controller/arm-gic.h>
55+ fimc-lite@12390000 {
56+ compatible = "samsung,exynos4212-fimc-lite";
57+ reg = <0x12390000 0x1000>;
58+ clocks = <&isp_clock CLK_ISP_FIMC_LITE0>;
59+ clock-names = "flite";
60+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
61+ power-domains = <&pd_isp>;
62+ iommus = <&sysmmu_fimc_lite0>;
63+ };
Documentation/devicetree/bindings/media/samsung,fimc.yaml+279−0
@@ -0,0 +1,279 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/samsung,fimc.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung S5P/Exynos SoC Camera Subsystem (FIMC)
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
12+
13+description: |
14+ The S5P/Exynos SoC Camera subsystem comprises of multiple sub-devices
15+ represented by separate device tree nodes. Currently this includes: Fully
16+ Integrated Mobile Camera (FIMC, in the S5P SoCs series known as CAMIF), MIPI
17+ CSIS, FIMC-LITE and FIMC-IS (ISP).
18+
19+properties:
20+ compatible:
21+ const: samsung,fimc
22+
23+ ranges: true
24+
25+ '#address-cells':
26+ const: 1
27+
28+ '#size-cells':
29+ const: 1
30+
31+ '#clock-cells':
32+ const: 1
33+ description: |
34+ The clock specifier cell stores an index of a clock: 0, 1 for
35+ CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
36+
37+ clocks:
38+ minItems: 2
39+ maxItems: 4
40+
41+ clock-names:
42+ minItems: 2
43+ items:
44+ - const: sclk_cam0
45+ - const: sclk_cam1
46+ - const: pxl_async0
47+ - const: pxl_async1
48+
49+ clock-output-names:
50+ maxItems: 2
51+
52+ parallel-ports:
53+ $ref: /schemas/graph.yaml#/properties/ports
54+ description:
55+ Active parallel video input ports.
56+
57+ patternProperties:
58+ "^port@[01]$":
59+ $ref: /schemas/graph.yaml#/$defs/port-base
60+ description:
61+ Camera A and camera B inputs.
62+
63+ properties:
64+ endpoint:
65+ $ref: /schemas/media/video-interfaces.yaml#
66+ unevaluatedProperties: false
67+
68+ pinctrl-names:
69+ minItems: 1
70+ items:
71+ - const: default
72+ - const: idle
73+ - const: active_a
74+ - const: active_b
75+
76+patternProperties:
77+ "^csis@[0-9a-f]+$":
78+ type: object
79+ $ref: samsung,exynos4210-csis.yaml#
80+ description: MIPI CSI-2 receiver.
81+
82+ "^fimc@[0-9a-f]+$":
83+ type: object
84+ $ref: samsung,exynos4210-fimc.yaml#
85+ description: Fully Integrated Mobile Camera.
86+
87+ "^fimc-is@[0-9a-f]+$":
88+ type: object
89+ $ref: samsung,exynos4212-fimc-is.yaml#
90+ description: Imaging Subsystem (FIMC-IS).
91+
92+ "^fimc-lite@[0-9a-f]+$":
93+ type: object
94+ $ref: samsung,exynos4212-fimc-lite.yaml#
95+ description: Camera host interface (FIMC-LITE).
96+
97+required:
98+ - compatible
99+ - '#address-cells'
100+ - '#clock-cells'
101+ - clocks
102+ - clock-names
103+ - clock-output-names
104+ - ranges
105+ - '#size-cells'
106+
107+additionalProperties: false
108+
109+examples:
110+ - |
111+ #include <dt-bindings/clock/exynos4.h>
112+ #include <dt-bindings/gpio/gpio.h>
113+ #include <dt-bindings/interrupt-controller/arm-gic.h>
114+
115+ camera@11800000 {
116+ compatible = "samsung,fimc";
117+ #clock-cells = <1>;
118+ #address-cells = <1>;
119+ #size-cells = <1>;
120+ ranges = <0x0 0x0 0x18000000>;
121+
122+ clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>,
123+ <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>;
124+ clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1";
125+ clock-output-names = "cam_a_clkout", "cam_b_clkout";
126+
127+ assigned-clocks = <&clock CLK_MOUT_CAM0>,
128+ <&clock CLK_MOUT_CAM1>;
129+ assigned-clock-parents = <&clock CLK_XUSBXTI>,
130+ <&clock CLK_XUSBXTI>;
131+
132+ pinctrl-0 = <&cam_port_a_clk_active &cam_port_b_clk_active>;
133+ pinctrl-names = "default";
134+
135+ fimc@11800000 {
136+ compatible = "samsung,exynos4212-fimc";
137+ reg = <0x11800000 0x1000>;
138+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
139+ clocks = <&clock CLK_FIMC0>,
140+ <&clock CLK_SCLK_FIMC0>;
141+ clock-names = "fimc", "sclk_fimc";
142+ power-domains = <&pd_cam>;
143+ samsung,sysreg = <&sys_reg>;
144+ iommus = <&sysmmu_fimc0>;
145+
146+ samsung,pix-limits = <4224 8192 1920 4224>;
147+ samsung,mainscaler-ext;
148+ samsung,isp-wb;
149+ samsung,cam-if;
150+ };
151+
152+ /* ... FIMC 1-3 */
153+
154+ csis@11880000 {
155+ compatible = "samsung,exynos4210-csis";
156+ reg = <0x11880000 0x4000>;
157+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
158+ clocks = <&clock CLK_CSIS0>,
159+ <&clock CLK_SCLK_CSIS0>;
160+ clock-names = "csis", "sclk_csis";
161+ assigned-clocks = <&clock CLK_MOUT_CSIS0>,
162+ <&clock CLK_SCLK_CSIS0>;
163+ assigned-clock-parents = <&clock CLK_MOUT_MPLL_USER_T>;
164+ assigned-clock-rates = <0>, <176000000>;
165+
166+ bus-width = <4>;
167+ power-domains = <&pd_cam>;
168+ phys = <&mipi_phy 0>;
169+ phy-names = "csis";
170+ #address-cells = <1>;
171+ #size-cells = <0>;
172+
173+ vddcore-supply = <&ldo8_reg>;
174+ vddio-supply = <&ldo10_reg>;
175+
176+ /* Camera C (3) MIPI CSI-2 (CSIS0) */
177+ port@3 {
178+ reg = <3>;
179+ endpoint {
180+ remote-endpoint = <&s5c73m3_ep>;
181+ data-lanes = <1 2 3 4>;
182+ samsung,csis-hs-settle = <12>;
183+ };
184+ };
185+ };
186+
187+ /* ... CSIS 1 */
188+
189+ fimc-lite@12390000 {
190+ compatible = "samsung,exynos4212-fimc-lite";
191+ reg = <0x12390000 0x1000>;
192+ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
193+ power-domains = <&pd_isp>;
194+ clocks = <&isp_clock CLK_ISP_FIMC_LITE0>;
195+ clock-names = "flite";
196+ iommus = <&sysmmu_fimc_lite0>;
197+ };
198+
199+ /* ... FIMC-LITE 1 */
200+
201+ fimc-is@12000000 {
202+ compatible = "samsung,exynos4212-fimc-is";
203+ reg = <0x12000000 0x260000>;
204+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
205+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
206+ clocks = <&isp_clock CLK_ISP_FIMC_LITE0>,
207+ <&isp_clock CLK_ISP_FIMC_LITE1>,
208+ <&isp_clock CLK_ISP_PPMUISPX>,
209+ <&isp_clock CLK_ISP_PPMUISPMX>,
210+ <&isp_clock CLK_ISP_FIMC_ISP>,
211+ <&isp_clock CLK_ISP_FIMC_DRC>,
212+ <&isp_clock CLK_ISP_FIMC_FD>,
213+ <&isp_clock CLK_ISP_MCUISP>,
214+ <&isp_clock CLK_ISP_GICISP>,
215+ <&isp_clock CLK_ISP_MCUCTL_ISP>,
216+ <&isp_clock CLK_ISP_PWM_ISP>,
217+ <&isp_clock CLK_ISP_DIV_ISP0>,
218+ <&isp_clock CLK_ISP_DIV_ISP1>,
219+ <&isp_clock CLK_ISP_DIV_MCUISP0>,
220+ <&isp_clock CLK_ISP_DIV_MCUISP1>,
221+ <&clock CLK_MOUT_MPLL_USER_T>,
222+ <&clock CLK_ACLK200>,
223+ <&clock CLK_ACLK400_MCUISP>,
224+ <&clock CLK_DIV_ACLK200>,
225+ <&clock CLK_DIV_ACLK400_MCUISP>,
226+ <&clock CLK_UART_ISP_SCLK>;
227+ clock-names = "lite0", "lite1", "ppmuispx",
228+ "ppmuispmx", "isp",
229+ "drc", "fd", "mcuisp",
230+ "gicisp", "mcuctl_isp", "pwm_isp",
231+ "ispdiv0", "ispdiv1", "mcuispdiv0",
232+ "mcuispdiv1", "mpll", "aclk200",
233+ "aclk400mcuisp", "div_aclk200",
234+ "div_aclk400mcuisp", "uart";
235+ iommus = <&sysmmu_fimc_isp>, <&sysmmu_fimc_drc>,
236+ <&sysmmu_fimc_fd>, <&sysmmu_fimc_mcuctl>;
237+ iommu-names = "isp", "drc", "fd", "mcuctl";
238+ power-domains = <&pd_isp>;
239+
240+ #address-cells = <1>;
241+ #size-cells = <1>;
242+ ranges;
243+
244+ pmu@10020000 {
245+ reg = <0x10020000 0x3000>;
246+ };
247+
248+ i2c-isp@12140000 {
249+ compatible = "samsung,exynos4212-i2c-isp";
250+ reg = <0x12140000 0x100>;
251+ clocks = <&isp_clock CLK_ISP_I2C1_ISP>;
252+ clock-names = "i2c_isp";
253+ pinctrl-0 = <&fimc_is_i2c1>;
254+ pinctrl-names = "default";
255+ #address-cells = <1>;
256+ #size-cells = <0>;
257+
258+ image-sensor@10 {
259+ compatible = "samsung,s5k6a3";
260+ reg = <0x10>;
261+ svdda-supply = <&cam_io_reg>;
262+ svddio-supply = <&ldo19_reg>;
263+ afvdd-supply = <&ldo19_reg>;
264+ clock-frequency = <24000000>;
265+ /* CAM_B_CLKOUT */
266+ clocks = <&camera 1>;
267+ clock-names = "extclk";
268+ gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
269+
270+ port {
271+ endpoint {
272+ remote-endpoint = <&csis1_ep>;
273+ data-lanes = <1>;
274+ };
275+ };
276+ };
277+ };
278+ };
279+ };
Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml+165−0
@@ -0,0 +1,165 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/samsung,s5c73m3.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung S5C73M3 8Mp camera ISP
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
12+
13+description:
14+ The S5C73M3 camera ISP supports MIPI CSI-2 and parallel (ITU-R BT.656)
15+ video data busses. The I2C bus is the main control bus and additionally the
16+ SPI bus is used, mostly for transferring the firmware to and from the
17+ device. Two slave device nodes corresponding to these control bus
18+ interfaces are required and should be placed under respective bus
19+ controller nodes.
20+
21+properties:
22+ compatible:
23+ const: samsung,s5c73m3
24+
25+ reg:
26+ maxItems: 1
27+
28+ clocks:
29+ maxItems: 1
30+
31+ clock-names:
32+ items:
33+ - const: cis_extclk
34+
35+ clock-frequency:
36+ default: 24000000
37+ description: cis_extclk clock frequency.
38+
39+ standby-gpios:
40+ maxItems: 1
41+ description: STANDBY pin.
42+
43+ vdda-supply:
44+ description: Analog power supply (1.2V).
45+
46+ vdd-af-supply:
47+ description: lens power supply (2.8V).
48+
49+ vddio-cis-supply:
50+ description: CIS I/O power supply (1.2V to 1.8V).
51+
52+ vddio-host-supply:
53+ description: Host I/O power supply (1.8V to 2.8V).
54+
55+ vdd-int-supply:
56+ description: Digital power supply (1.2V).
57+
58+ vdd-reg-supply:
59+ description: Regulator input power supply (2.8V).
60+
61+ xshutdown-gpios:
62+ maxItems: 1
63+ description: XSHUTDOWN pin.
64+
65+ port:
66+ $ref: /schemas/graph.yaml#/$defs/port-base
67+ additionalProperties: false
68+
69+ properties:
70+ endpoint:
71+ $ref: /schemas/media/video-interfaces.yaml#
72+ unevaluatedProperties: false
73+
74+ properties:
75+ data-lanes:
76+ items:
77+ - const: 1
78+ - const: 2
79+ - const: 3
80+ - const: 4
81+
82+required:
83+ - compatible
84+ - reg
85+
86+allOf:
87+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
88+ - if:
89+ required:
90+ - spi-max-frequency
91+ then:
92+ properties:
93+ # The SPI node is simplified firmware-transfer interface only
94+ clocks: false
95+ clock-names: false
96+ standby-gpios: false
97+ vdda-supply: false
98+ vdd-af-supply: false
99+ vddio-cis-supply: false
100+ vddio-host-supply: false
101+ vdd-int-supply: false
102+ vdd-reg-supply: false
103+ xshutdown-gpios: false
104+ port: false
105+ else:
106+ required:
107+ - clocks
108+ - clock-names
109+ - standby-gpios
110+ - vdda-supply
111+ - vdd-af-supply
112+ - vddio-cis-supply
113+ - vddio-host-supply
114+ - vdd-int-supply
115+ - vdd-reg-supply
116+ - xshutdown-gpios
117+ - port
118+
119+unevaluatedProperties: false
120+
121+examples:
122+ - |
123+ #include <dt-bindings/gpio/gpio.h>
124+
125+ i2c {
126+ #address-cells = <1>;
127+ #size-cells = <0>;
128+
129+ image-sensor@3c {
130+ compatible = "samsung,s5c73m3";
131+ reg = <0x3c>;
132+ clock-frequency = <24000000>;
133+ clocks = <&camera 0>;
134+ clock-names = "cis_extclk";
135+ standby-gpios = <&gpm0 6 GPIO_ACTIVE_LOW>;
136+ vdda-supply = <&cam_vdda_reg>;
137+ vdd-af-supply = <&cam_af_reg>;
138+ vddio-cis-supply = <&ldo9_reg>;
139+ vddio-host-supply = <&ldo18_reg>;
140+ vdd-int-supply = <&buck9_reg>;
141+ vdd-reg-supply = <&cam_io_reg>;
142+ xshutdown-gpios = <&gpf1 3 GPIO_ACTIVE_LOW>; /* ISP_RESET */
143+
144+ port {
145+ s5c73m3_ep: endpoint {
146+ remote-endpoint = <&csis0_ep>;
147+ data-lanes = <1 2 3 4>;
148+ };
149+ };
150+ };
151+ };
152+
153+ spi {
154+ #address-cells = <1>;
155+ #size-cells = <0>;
156+
157+ image-sensor@0 {
158+ compatible = "samsung,s5c73m3";
159+ reg = <0>;
160+ spi-max-frequency = <50000000>;
161+ controller-data {
162+ samsung,spi-feedback-delay = <2>;
163+ };
164+ };
165+ };
Documentation/devicetree/bindings/media/samsung-fimc.txt+0−209
@@ -1,209 +0,0 @@
1−Samsung S5P/Exynos SoC Camera Subsystem (FIMC)
2−----------------------------------------------
3−
4−The S5P/Exynos SoC Camera subsystem comprises of multiple sub-devices
5−represented by separate device tree nodes. Currently this includes: FIMC (in
6−the S5P SoCs series known as CAMIF), MIPI CSIS, FIMC-LITE and FIMC-IS (ISP).
7−
8−The sub-subdevices are defined as child nodes of the common 'camera' node which
9−also includes common properties of the whole subsystem not really specific to
10−any single sub-device, like common camera port pins or the CAMCLK clock outputs
11−for external image sensors attached to an SoC.
12−
13−Common 'camera' node
14−--------------------
15−
16−Required properties:
17−
18−- compatible: must be "samsung,fimc", "simple-bus"
19−- clocks: list of clock specifiers, corresponding to entries in
20− the clock-names property;
21−- clock-names : must contain "sclk_cam0", "sclk_cam1", "pxl_async0",
22− "pxl_async1" entries, matching entries in the clocks property.
23−
24−- #clock-cells: from the common clock bindings (../clock/clock-bindings.txt),
25− must be 1. A clock provider is associated with the 'camera' node and it should
26− be referenced by external sensors that use clocks provided by the SoC on
27− CAM_*_CLKOUT pins. The clock specifier cell stores an index of a clock.
28− The indices are 0, 1 for CAM_A_CLKOUT, CAM_B_CLKOUT clocks respectively.
29−
30−- clock-output-names: from the common clock bindings, should contain names of
31− clocks registered by the camera subsystem corresponding to CAM_A_CLKOUT,
32− CAM_B_CLKOUT output clocks respectively.
33−
34−The pinctrl bindings defined in ../pinctrl/pinctrl-bindings.txt must be used
35−to define a required pinctrl state named "default" and optional pinctrl states:
36−"idle", "active-a", active-b". These optional states can be used to switch the
37−camera port pinmux at runtime. The "idle" state should configure both the camera
38−ports A and B into high impedance state, especially the CAMCLK clock output
39−should be inactive. For the "active-a" state the camera port A must be activated
40−and the port B deactivated and for the state "active-b" it should be the other
41−way around.
42−
43−The 'camera' node must include at least one 'fimc' child node.
44−
45−
46−'fimc' device nodes
47−-------------------
48−
49−Required properties:
50−
51−- compatible: "samsung,s5pv210-fimc" for S5PV210, "samsung,exynos4210-fimc"
52− for Exynos4210 and "samsung,exynos4212-fimc" for Exynos4x12 SoCs;
53−- reg: physical base address and length of the registers set for the device;
54−- interrupts: should contain FIMC interrupt;
55−- clocks: list of clock specifiers, must contain an entry for each required
56− entry in clock-names;
57−- clock-names: must contain "fimc", "sclk_fimc" entries.
58−- samsung,pix-limits: an array of maximum supported image sizes in pixels, for
59− details refer to Table 2-1 in the S5PV210 SoC User Manual; The meaning of
60− each cell is as follows:
61− 0 - scaler input horizontal size,
62− 1 - input horizontal size for the scaler bypassed,
63− 2 - REAL_WIDTH without input rotation,
64− 3 - REAL_HEIGHT with input rotation,
65−- samsung,sysreg: a phandle to the SYSREG node.
66−
67−Each FIMC device should have an alias in the aliases node, in the form of
68−fimc<n>, where <n> is an integer specifying the IP block instance.
69−
70−Optional properties:
71−
72−- clock-frequency: maximum FIMC local clock (LCLK) frequency;
73−- samsung,min-pix-sizes: an array specyfing minimum image size in pixels at
74− the FIMC input and output DMA, in the first and second cell respectively.
75− Default value when this property is not present is <16 16>;
76−- samsung,min-pix-alignment: minimum supported image height alignment (first
77− cell) and the horizontal image offset (second cell). The values are in pixels
78− and default to <2 1> when this property is not present;
79−- samsung,mainscaler-ext: a boolean property indicating whether the FIMC IP
80− supports extended image size and has CIEXTEN register;
81−- samsung,rotators: a bitmask specifying whether this IP has the input and
82− the output rotator. Bits 4 and 0 correspond to input and output rotator
83− respectively. If a rotator is present its corresponding bit should be set.
84− Default value when this property is not specified is 0x11.
85−- samsung,cam-if: a bolean property indicating whether the IP block includes
86− the camera input interface.
87−- samsung,isp-wb: this property must be present if the IP block has the ISP
88− writeback input.
89−- samsung,lcd-wb: this property must be present if the IP block has the LCD
90− writeback input.
91−
92−
93−'parallel-ports' node
94−---------------------
95−
96−This node should contain child 'port' nodes specifying active parallel video
97−input ports. It includes camera A and camera B inputs. 'reg' property in the
98−port nodes specifies data input - 1, 2 indicates input A, B respectively.
99−
100−Optional properties
101−
102−- samsung,camclk-out (deprecated) : specifies clock output for remote sensor,
103− 0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT;
104−
105−Image sensor nodes
106−------------------
107−
108−The sensor device nodes should be added to their control bus controller (e.g.
109−I2C0) nodes and linked to a port node in the csis or the parallel-ports node,
110−using the common video interfaces bindings, defined in video-interfaces.txt.
111−
112−Example:
113−
114− aliases {
115− fimc0 = &fimc_0;
116− };
117−
118− /* Parallel bus IF sensor */
119− i2c_0: i2c@13860000 {
120− s5k6aa: sensor@3c {
121− compatible = "samsung,s5k6aafx";
122− reg = <0x3c>;
123− vddio-supply = <...>;
124−
125− clock-frequency = <24000000>;
126− clocks = <&camera 1>;
127− clock-names = "mclk";
128−
129− port {
130− s5k6aa_ep: endpoint {
131− remote-endpoint = <&fimc0_ep>;
132− bus-width = <8>;
133− hsync-active = <0>;
134− vsync-active = <1>;
135− pclk-sample = <1>;
136− };
137− };
138− };
139−
140− /* MIPI CSI-2 bus IF sensor */
141− s5c73m3: sensor@1a {
142− compatible = "samsung,s5c73m3";
143− reg = <0x1a>;
144− vddio-supply = <...>;
145−
146− clock-frequency = <24000000>;
147− clocks = <&camera 0>;
148− clock-names = "mclk";
149−
150− port {
151− s5c73m3_1: endpoint {
152− data-lanes = <1 2 3 4>;
153− remote-endpoint = <&csis0_ep>;
154− };
155− };
156− };
157− };
158−
159− camera {
160− compatible = "samsung,fimc", "simple-bus";
161− clocks = <&clock 132>, <&clock 133>, <&clock 351>,
162− <&clock 352>;
163− clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
164− "pxl_async1";
165− #clock-cells = <1>;
166− clock-output-names = "cam_a_clkout", "cam_b_clkout";
167− pinctrl-names = "default";
168− pinctrl-0 = <&cam_port_a_clk_active>;
169− #address-cells = <1>;
170− #size-cells = <1>;
171−
172− /* parallel camera ports */
173− parallel-ports {
174− /* camera A input */
175− port@1 {
176− reg = <1>;
177− fimc0_ep: endpoint {
178− remote-endpoint = <&s5k6aa_ep>;
179− bus-width = <8>;
180− hsync-active = <0>;
181− vsync-active = <1>;
182− pclk-sample = <1>;
183− };
184− };
185− };
186−
187− fimc_0: fimc@11800000 {
188− compatible = "samsung,exynos4210-fimc";
189− reg = <0x11800000 0x1000>;
190− interrupts = <0 85 0>;
191− };
192−
193− csis_0: csis@11880000 {
194− compatible = "samsung,exynos4210-csis";
195− reg = <0x11880000 0x1000>;
196− interrupts = <0 78 0>;
197− /* camera C input */
198− port@3 {
199− reg = <3>;
200− csis0_ep: endpoint {
201− remote-endpoint = <&s5c73m3_ep>;
202− data-lanes = <1 2 3 4>;
203− samsung,csis-hs-settle = <12>;
204− };
205− };
206− };
207− };
208−
209−The MIPI-CSIS device binding is defined in samsung-mipi-csis.txt.
Documentation/devicetree/bindings/media/samsung-mipi-csis.txt+0−81
@@ -1,81 +0,0 @@
1−Samsung S5P/Exynos SoC series MIPI CSI-2 receiver (MIPI CSIS)
2−-------------------------------------------------------------
3−
4−Required properties:
5−
6−- compatible : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
7− "samsung,exynos4210-csis" for Exynos4210 (S5PC210),
8− "samsung,exynos4212-csis" for Exynos4212/Exynos4412,
9− "samsung,exynos5250-csis" for Exynos5250;
10−- reg : offset and length of the register set for the device;
11−- interrupts : should contain MIPI CSIS interrupt; the format of the
12− interrupt specifier depends on the interrupt controller;
13−- bus-width : maximum number of data lanes supported (SoC specific);
14−- vddio-supply : MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V);
15−- vddcore-supply : MIPI CSIS Core voltage supply (e.g. 1.1V);
16−- clocks : list of clock specifiers, corresponding to entries in
17− clock-names property;
18−- clock-names : must contain "csis", "sclk_csis" entries, matching entries
19− in the clocks property.
20−
21−Optional properties:
22−
23−- clock-frequency : The IP's main (system bus) clock frequency in Hz, default
24− value when this property is not specified is 166 MHz;
25−- samsung,csis-wclk : CSI-2 wrapper clock selection. If this property is present
26− external clock from CMU will be used, or the bus clock if
27− if it's not specified.
28−
29−The device node should contain one 'port' child node with one child 'endpoint'
30−node, according to the bindings defined in Documentation/devicetree/bindings/
31−media/video-interfaces.txt. The following are properties specific to those nodes.
32−
33−port node
34−---------
35−
36−- reg : (required) must be 3 for camera C input (CSIS0) or 4 for
37− camera D input (CSIS1);
38−
39−endpoint node
40−-------------
41−
42−- data-lanes : (required) an array specifying active physical MIPI-CSI2
43− data input lanes and their mapping to logical lanes; the
44− array's content is unused, only its length is meaningful;
45−
46−- samsung,csis-hs-settle : (optional) differential receiver (HS-RX) settle time;
47−
48−
49−Example:
50−
51− reg0: regulator@0 {
52− };
53−
54− reg1: regulator@1 {
55− };
56−
57−/* SoC properties */
58−
59− csis_0: csis@11880000 {
60− compatible = "samsung,exynos4210-csis";
61− reg = <0x11880000 0x1000>;
62− interrupts = <0 78 0>;
63− #address-cells = <1>;
64− #size-cells = <0>;
65− };
66−
67−/* Board properties */
68−
69− csis_0: csis@11880000 {
70− clock-frequency = <166000000>;
71− vddio-supply = <&reg0>;
72− vddcore-supply = <&reg1>;
73− port {
74− reg = <3>; /* 3 - CSIS0, 4 - CSIS1 */
75− csis0_ep: endpoint {
76− remote-endpoint = <...>;
77− data-lanes = <1>, <2>;
78− samsung,csis-hs-settle = <12>;
79− };
80− };
81− };
Documentation/devicetree/bindings/media/samsung-s5c73m3.txt+0−97
@@ -1,97 +0,0 @@
1−Samsung S5C73M3 8Mp camera ISP
2−------------------------------
3−
4−The S5C73M3 camera ISP supports MIPI CSI-2 and parallel (ITU-R BT.656) video
5−data busses. The I2C bus is the main control bus and additionally the SPI bus
6−is used, mostly for transferring the firmware to and from the device. Two
7−slave device nodes corresponding to these control bus interfaces are required
8−and should be placed under respective bus controller nodes.
9−
10−I2C slave device node
11−---------------------
12−
13−Required properties:
14−
15−- compatible : "samsung,s5c73m3";
16−- reg : I2C slave address of the sensor;
17−- vdd-int-supply : digital power supply (1.2V);
18−- vdda-supply : analog power supply (1.2V);
19−- vdd-reg-supply : regulator input power supply (2.8V);
20−- vddio-host-supply : host I/O power supply (1.8V to 2.8V);
21−- vddio-cis-supply : CIS I/O power supply (1.2V to 1.8V);
22−- vdd-af-supply : lens power supply (2.8V);
23−- xshutdown-gpios : specifier of GPIO connected to the XSHUTDOWN pin;
24−- standby-gpios : specifier of GPIO connected to the STANDBY pin;
25−- clocks : should contain list of phandle and clock specifier pairs
26− according to common clock bindings for the clocks described
27− in the clock-names property;
28−- clock-names : should contain "cis_extclk" entry for the CIS_EXTCLK clock;
29−
30−Optional properties:
31−
32−- clock-frequency : the frequency at which the "cis_extclk" clock should be
33− configured to operate, in Hz; if this property is not
34− specified default 24 MHz value will be used.
35−
36−The common video interfaces bindings (see video-interfaces.txt) should be used
37−to specify link from the S5C73M3 to an external image data receiver. The S5C73M3
38−device node should contain one 'port' child node with an 'endpoint' subnode for
39−this purpose. The data link from a raw image sensor to the S5C73M3 can be
40−similarly specified, but it is optional since the S5C73M3 ISP and a raw image
41−sensor are usually inseparable and form a hybrid module.
42−
43−Following properties are valid for the endpoint node(s):
44−
45−endpoint subnode
46−----------------
47−
48−- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
49− video-interfaces.txt. This sensor doesn't support data lane remapping
50− and physical lane indexes in subsequent elements of the array should
51− be only consecutive ascending values.
52−
53−SPI device node
54−---------------
55−
56−Required properties:
57−
58−- compatible : "samsung,s5c73m3";
59−
60−For more details see description of the SPI busses bindings
61−(../spi/spi-bus.txt) and bindings of a specific bus controller.
62−
63−Example:
64−
65−i2c@138a000000 {
66− ...
67− s5c73m3@3c {
68− compatible = "samsung,s5c73m3";
69− reg = <0x3c>;
70− vdd-int-supply = <&buck9_reg>;
71− vdda-supply = <&ldo17_reg>;
72− vdd-reg-supply = <&cam_io_reg>;
73− vddio-host-supply = <&ldo18_reg>;
74− vddio-cis-supply = <&ldo9_reg>;
75− vdd-af-supply = <&cam_af_reg>;
76− clock-frequency = <24000000>;
77− clocks = <&clk 0>;
78− clock-names = "cis_extclk";
79− xshutdown-gpios = <&gpf1 3 1>;
80− standby-gpios = <&gpm0 1 1>;
81− port {
82− s5c73m3_ep: endpoint {
83− remote-endpoint = <&csis0_ep>;
84− data-lanes = <1 2 3 4>;
85− };
86− };
87− };
88−};
89−
90−spi@1392000 {
91− ...
92− s5c73m3_spi: s5c73m3@0 {
93− compatible = "samsung,s5c73m3";
94− reg = <0>;
95− ...
96− };
97−};
Documentation/devicetree/bindings/media/samsung-s5k5baf.txt+0−58
@@ -1,58 +0,0 @@
1−Samsung S5K5BAF UXGA 1/5" 2M CMOS Image Sensor with embedded SoC ISP
2−--------------------------------------------------------------------
3−
4−Required properties:
5−
6−- compatible : "samsung,s5k5baf";
7−- reg : I2C slave address of the sensor;
8−- vdda-supply : analog power supply 2.8V (2.6V to 3.0V);
9−- vddreg-supply : regulator input power supply 1.8V (1.7V to 1.9V)
10− or 2.8V (2.6V to 3.0);
11−- vddio-supply : I/O power supply 1.8V (1.65V to 1.95V)
12− or 2.8V (2.5V to 3.1V);
13−- stbyn-gpios : GPIO connected to STDBYN pin;
14−- rstn-gpios : GPIO connected to RSTN pin;
15−- clocks : list of phandle and clock specifier pairs
16− according to common clock bindings for the
17− clocks described in clock-names;
18−- clock-names : should include "mclk" for the sensor's master clock;
19−
20−Optional properties:
21−
22−- clock-frequency : the frequency at which the "mclk" clock should be
23− configured to operate, in Hz; if this property is not
24− specified default 24 MHz value will be used.
25−
26−The device node should contain one 'port' child node with one child 'endpoint'
27−node, according to the bindings defined in Documentation/devicetree/bindings/
28−media/video-interfaces.txt. The following are properties specific to those
29−nodes.
30−
31−endpoint node
32−-------------
33−
34−- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
35− video-interfaces.txt. If present it should be <1> - the device
36− supports only one data lane without re-mapping.
37−
38−Example:
39−
40−s5k5bafx@2d {
41− compatible = "samsung,s5k5baf";
42− reg = <0x2d>;
43− vdda-supply = <&cam_io_en_reg>;
44− vddreg-supply = <&vt_core_15v_reg>;
45− vddio-supply = <&vtcam_reg>;
46− stbyn-gpios = <&gpl2 0 1>;
47− rstn-gpios = <&gpl2 1 1>;
48− clock-names = "mclk";
49− clocks = <&clock_cam 0>;
50− clock-frequency = <24000000>;
51−
52− port {
53− s5k5bafx_ep: endpoint {
54− remote-endpoint = <&csis1_ep>;
55− data-lanes = <1>;
56− };
57− };
58−};
Documentation/devicetree/bindings/media/samsung-s5k6a3.txt+0−33
@@ -1,33 +0,0 @@
1−Samsung S5K6A3(YX) raw image sensor
2−---------------------------------
3−
4−S5K6A3(YX) is a raw image sensor with MIPI CSI-2 and CCP2 image data interfaces
5−and CCI (I2C compatible) control bus.
6−
7−Required properties:
8−
9−- compatible : "samsung,s5k6a3";
10−- reg : I2C slave address of the sensor;
11−- svdda-supply : core voltage supply;
12−- svddio-supply : I/O voltage supply;
13−- afvdd-supply : AF (actuator) voltage supply;
14−- gpios : specifier of a GPIO connected to the RESET pin;
15−- clocks : should contain list of phandle and clock specifier pairs
16− according to common clock bindings for the clocks described
17− in the clock-names property;
18−- clock-names : should contain "extclk" entry for the sensor's EXTCLK clock;
19−
20−Optional properties:
21−
22−- clock-frequency : the frequency at which the "extclk" clock should be
23− configured to operate, in Hz; if this property is not
24− specified default 24 MHz value will be used.
25−
26−The common video interfaces bindings (see video-interfaces.txt) should be
27−used to specify link to the image data receiver. The S5K6A3(YX) device
28−node should contain one 'port' child node with an 'endpoint' subnode.
29−
30−Following properties are valid for the endpoint node:
31−
32−- data-lanes : (optional) specifies MIPI CSI-2 data lanes as covered in
33− video-interfaces.txt. The sensor supports only one data lane.
Documentation/devicetree/bindings/media/si470x.txt+0−26
@@ -1,26 +0,0 @@
1−* Silicon Labs FM Radio receiver
2−
3−The Silicon Labs Si470x is family of FM radio receivers with receive power scan
4−supporting 76-108 MHz, programmable through an I2C interface.
5−Some of them includes an RDS encoder.
6−
7−Required Properties:
8−- compatible: Should contain "silabs,si470x"
9−- reg: the I2C address of the device
10−
11−Optional Properties:
12−- interrupts : The interrupt number
13−- reset-gpios: GPIO specifier for the chips reset line
14−
15−Example:
16−
17−&i2c2 {
18− si470x@63 {
19− compatible = "silabs,si470x";
20− reg = <0x63>;
21−
22− interrupt-parent = <&gpj2>;
23− interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
24− reset-gpios = <&gpj2 5 GPIO_ACTIVE_HIGH>;
25− };
26−};
Documentation/devicetree/bindings/media/silabs,si470x.yaml+48−0
@@ -0,0 +1,48 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/silabs,si470x.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Silicon Labs Si470x FM Radio Receiver
8+
9+maintainers:
10+ - Hans Verkuil <hverkuil@xs4all.nl>
11+ - Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
12+
13+properties:
14+ compatible:
15+ const: silabs,si470x
16+
17+ reg:
18+ maxItems: 1
19+
20+ interrupts:
21+ maxItems: 1
22+
23+ reset-gpios:
24+ maxItems: 1
25+
26+required:
27+ - compatible
28+ - reg
29+
30+additionalProperties: false
31+
32+examples:
33+ - |
34+ #include <dt-bindings/gpio/gpio.h>
35+ #include <dt-bindings/interrupt-controller/irq.h>
36+
37+ i2c {
38+ #address-cells = <1>;
39+ #size-cells = <0>;
40+
41+ fmradio@10 {
42+ compatible = "silabs,si470x";
43+ reg = <0x10>;
44+ interrupt-parent = <&gpj2>;
45+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
46+ reset-gpios = <&gpj2 5 GPIO_ACTIVE_HIGH>;
47+ };
48+ };
Documentation/devicetree/bindings/media/st,stm32-cec.yaml+0−53
@@ -1,53 +0,0 @@
1−# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2−%YAML 1.2
3−---
4−$id: http://devicetree.org/schemas/media/st,stm32-cec.yaml#
5−$schema: http://devicetree.org/meta-schemas/core.yaml#
6−
7−title: STMicroelectronics STM32 CEC
8−
9−maintainers:
10− - Yannick Fertre <yannick.fertre@foss.st.com>
11−
12−properties:
13− compatible:
14− const: st,stm32-cec
15−
16− reg:
17− maxItems: 1
18−
19− interrupts:
20− maxItems: 1
21−
22− clocks:
23− items:
24− - description: Module Clock
25− - description: Bus Clock
26−
27− clock-names:
28− items:
29− - const: cec
30− - const: hdmi-cec
31−
32−required:
33− - compatible
34− - reg
35− - interrupts
36− - clocks
37− - clock-names
38−
39−additionalProperties: false
40−
41−examples:
42− - |
43− #include <dt-bindings/interrupt-controller/arm-gic.h>
44− #include <dt-bindings/clock/stm32mp1-clks.h>
45− cec: cec@40006c00 {
46− compatible = "st,stm32-cec";
47− reg = <0x40006c00 0x400>;
48− interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
49− clocks = <&rcc CEC_K>, <&clk_lse>;
50− clock-names = "cec", "hdmi-cec";
51− };
52−
53−...
Documentation/devicetree/bindings/media/ti,cal.yaml+1−1
@@ -47,7 +47,7 @@ properties: · 46 unmodified lines
4747 maxItems: 1
4848
4949 ti,camerrx-control:
50− $ref: "/schemas/types.yaml#/definitions/phandle-array"
50+ $ref: /schemas/types.yaml#/definitions/phandle-array
5151 items:
5252 - items:
5353 - description: phandle to device control module
Documentation/driver-api/media/drivers/ccs/ccs.rst+22−0
@@ -56,6 +56,28 @@ analogue data is never read from the pixel matrix that are outside the · 55 unmodified lines
5656 configured selection rectangle that designates crop. The difference has an
5757 effect in device timing and likely also in power consumption.
5858
59+CCS static data
60+---------------
61+
62+The MIPI CCS driver supports CCS static data for all compliant devices,
63+including not just those compliant with CCS 1.1 but also CCS 1.0 and SMIA(++).
64+For CCS the file names are formed as
65+
66+ ccs/ccs-sensor-vvvv-mmmm-rrrr.fw (sensor) and
67+ ccs/ccs-module-vvvv-mmmm-rrrr.fw (module).
68+
69+For SMIA++ compliant devices the corresponding file names are
70+
71+ ccs/smiapp-sensor-vv-mmmm-rr.fw (sensor) and
72+ ccs/smiapp-module-vv-mmmm-rrrr.fw (module).
73+
74+For SMIA (non-++) compliant devices the static data file name is
75+
76+ ccs/smia-sensor-vv-mmmm-rr.fw (sensor).
77+
78+vvvv or vv denotes MIPI and SMIA manufacturer IDs respectively, mmmm model ID
79+and rrrr or rr revision number.
80+
5981 Register definition generator
6082 -----------------------------
6183
Documentation/userspace-api/media/v4l/dev-overlay.rst+8−2
@@ -67,6 +67,7 @@ ioctls must be supported by all video overlay devices. · 66 unmodified lines
6767 Setup
6868 =====
6969
70+*Note: support for this has been removed.*
7071 Before overlay can commence applications must program the driver with
7172 frame buffer parameters, namely the address and size of the frame buffer
7273 and the image format, for example RGB 5:6:5. The
@@ -92,11 +93,13 @@ A driver may support any (or none) of five clipping/blending methods: · 19 unmodified lines
9293 1. Chroma-keying displays the overlaid image only where pixels in the
9394 primary graphics surface assume a certain color.
9495
95−2. A bitmap can be specified where each bit corresponds to a pixel in
96+2. *Note: support for this has been removed.*
97+ A bitmap can be specified where each bit corresponds to a pixel in
9698 the overlaid image. When the bit is set, the corresponding video
9799 pixel is displayed, otherwise a pixel of the graphics surface.
98100
99−3. A list of clipping rectangles can be specified. In these regions *no*
101+3. *Note: support for this has been removed.*
102+ A list of clipping rectangles can be specified. In these regions *no*
100103 video is displayed, so the graphics surface can be seen here.
101104
102105 4. The framebuffer has an alpha channel that can be used to clip or
@@ -185,6 +188,7 @@ struct v4l2_window · 82 unmodified lines
185188 be 0xRRGGBB on a little endian, 0xBBGGRR on a big endian host.
186189
187190 ``struct v4l2_clip * clips``
191+ *Note: support for this has been removed.*
188192 When chroma-keying has *not* been negotiated and
189193 :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` indicated this capability,
190194 applications can set this field to point to an array of clipping
@@ -201,6 +205,7 @@ struct v4l2_window · 10 unmodified lines
201205 are undefined.
202206
203207 ``__u32 clipcount``
208+ *Note: support for this has been removed.*
204209 When the application set the ``clips`` field, this field must
205210 contain the number of clipping rectangles in the list. When clip
206211 lists are not supported the driver ignores this field, its contents
@@ -208,6 +213,7 @@ struct v4l2_window · 1 unmodified line
208213 supported but no clipping is desired this field must be set to zero.
209214
210215 ``void * bitmap``
216+ *Note: support for this has been removed.*
211217 When chroma-keying has *not* been negotiated and
212218 :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` indicated this capability,
213219 applications can set this field to point to a clipping bit mask.
Documentation/userspace-api/media/v4l/pixfmt-compressed.rst+25−0
@@ -88,6 +88,11 @@ Compressed Formats · 87 unmodified lines
8888 - ``V4L2_PIX_FMT_H263``
8989 - 'H263'
9090 - H263 video elementary stream.
91+ * .. _V4L2-PIX-FMT-SPK:
92+
93+ - ``V4L2_PIX_FMT_SPK``
94+ - 'SPK0'
95+ - Sorenson Spark is an implementation of H.263 for use in Flash Video and Adobe Flash files
9196 * .. _V4L2-PIX-FMT-MPEG1:
9297
9398 - ``V4L2_PIX_FMT_MPEG1``
@@ -232,6 +237,26 @@ Compressed Formats · 138 unmodified lines
232237 Metadata associated with the frame to decode is required to be passed
233238 through the ``V4L2_CID_STATELESS_FWHT_PARAMS`` control.
234239 See the :ref:`associated Codec Control ID <codec-stateless-fwht>`.
240+ * .. _V4L2-PIX-FMT-RV30:
241+
242+ - ``V4L2_PIX_FMT_RV30``
243+ - 'RV30'
244+ - RealVideo, or also spelled as Real Video, is a suite of
245+ proprietary video compression formats developed by
246+ RealNetworks - the specific format changes with the version.
247+ RealVideo codecs are identified by four-character codes.
248+ RV30 corresponds to RealVideo 8, suspected to be based
249+ largely on an early draft of H.264
250+ * .. _V4L2-PIX-FMT-RV40:
251+
252+ - ``V4L2_PIX_FMT_RV40``
253+ - 'RV40'
254+ - RV40 represents RealVideo 9 and RealVideo 10.
255+ RealVideo 9, suspected to be based on H.264.
256+ RealVideo 10, aka RV9 EHQ, This refers to an improved encoder
257+ for the RV9 format that is fully backwards compatible with
258+ RV9 players - the format and decoder did not change, only
259+ the encoder did. As a result, it uses the same FourCC.
235260
236261 .. raw:: latex
237262
Documentation/userspace-api/media/v4l/pixfmt-packed-yuv.rst+28−0
@@ -257,6 +257,34 @@ the second byte and Y'\ :sub:`7-0` in the third byte. · 256 unmodified lines
257257 - The padding bits contain undefined values that must be ignored by all
258258 applications and drivers.
259259
260+The next table lists the packed YUV 4:4:4 formats with 12 bits per component.
261+Expand the bits per component to 16 bits, data in the high bits, zeros in the low bits,
262+arranged in little endian order, storing 1 pixel in 6 bytes.
263+
264+.. flat-table:: Packed YUV 4:4:4 Image Formats (12bpc)
265+ :header-rows: 1
266+ :stub-columns: 0
267+
268+ * - Identifier
269+ - Code
270+ - Byte 1-0
271+ - Byte 3-2
272+ - Byte 5-4
273+ - Byte 7-6
274+ - Byte 9-8
275+ - Byte 11-10
276+
277+ * .. _V4L2-PIX-FMT-YUV48-12:
278+
279+ - ``V4L2_PIX_FMT_YUV48_12``
280+ - 'Y312'
281+
282+ - Y'\ :sub:`0`
283+ - Cb\ :sub:`0`
284+ - Cr\ :sub:`0`
285+ - Y'\ :sub:`1`
286+ - Cb\ :sub:`1`
287+ - Cr\ :sub:`1`
260288
261289 4:2:2 Subsampling
262290 =================
Documentation/userspace-api/media/v4l/pixfmt-rgb.rst+42−0
@@ -953,6 +953,48 @@ number of bits for each component. · 952 unmodified lines
953953
954954 \endgroup
955955
956+12 Bits Per Component
957+==============================
958+
959+These formats store an RGB triplet in six or eight bytes, with 12 bits per component.
960+Expand the bits per component to 16 bits, data in the high bits, zeros in the low bits,
961+arranged in little endian order.
962+
963+.. raw:: latex
964+
965+ \small
966+
967+.. flat-table:: RGB Formats With 12 Bits Per Component
968+ :header-rows: 1
969+
970+ * - Identifier
971+ - Code
972+ - Byte 1-0
973+ - Byte 3-2
974+ - Byte 5-4
975+ - Byte 7-6
976+ * .. _V4L2-PIX-FMT-BGR48-12:
977+
978+ - ``V4L2_PIX_FMT_BGR48_12``
979+ - 'B312'
980+
981+ - B\ :sub:`15-4`
982+ - G\ :sub:`15-4`
983+ - R\ :sub:`15-4`
984+ -
985+ * .. _V4L2-PIX-FMT-ABGR64-12:
986+
987+ - ``V4L2_PIX_FMT_ABGR64_12``
988+ - 'B412'
989+
990+ - B\ :sub:`15-4`
991+ - G\ :sub:`15-4`
992+ - R\ :sub:`15-4`
993+ - A\ :sub:`15-4`
994+
995+.. raw:: latex
996+
997+ \normalsize
956998
957999 Deprecated RGB Formats
9581000 ======================
Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst+15−0
@@ -103,6 +103,17 @@ are often referred to as greyscale formats. · 102 unmodified lines
103103 - ...
104104 - ...
105105
106+ * .. _V4L2-PIX-FMT-Y012:
107+
108+ - ``V4L2_PIX_FMT_Y012``
109+ - 'Y012'
110+
111+ - Y'\ :sub:`0`\ [3:0] `0000`
112+ - Y'\ :sub:`0`\ [11:4]
113+ - ...
114+ - ...
115+ - ...
116+
106117 * .. _V4L2-PIX-FMT-Y14:
107118
108119 - ``V4L2_PIX_FMT_Y14``
@@ -146,3 +157,7 @@ are often referred to as greyscale formats. · 37 unmodified lines
146157 than 16 bits. For example, 10 bits per pixel uses values in the range 0 to
147158 1023. For the IPU3_Y10 format 25 pixels are packed into 32 bytes, which
148159 leaves the 6 most significant bits of the last byte padded with 0.
160+
161+ For Y012 and Y12 formats, Y012 places its data in the 12 high bits, with
162+ padding zeros in the 4 low bits, in contrast to the Y12 format, which has
163+ its padding located in the most significant bits of the 16 bit word.
Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst+94−0
@@ -123,6 +123,20 @@ All components are stored with the same number of bits per component. · 122 unmodified lines
123123 - Cb, Cr
124124 - Yes
125125 - 4x4 tiles
126+ * - V4L2_PIX_FMT_P012
127+ - 'P012'
128+ - 12
129+ - 4:2:0
130+ - Cb, Cr
131+ - Yes
132+ - Linear
133+ * - V4L2_PIX_FMT_P012M
134+ - 'PM12'
135+ - 12
136+ - 4:2:0
137+ - Cb, Cr
138+ - No
139+ - Linear
126140 * - V4L2_PIX_FMT_NV16
127141 - 'NV16'
128142 - 8
@@ -586,6 +600,86 @@ Data in the 10 high bits, zeros in the 6 low bits, arranged in little endian ord · 457 unmodified lines
586600 - Cb\ :sub:`11`
587601 - Cr\ :sub:`11`
588602
603+.. _V4L2-PIX-FMT-P012:
604+.. _V4L2-PIX-FMT-P012M:
605+
606+P012 and P012M
607+--------------
608+
609+P012 is like NV12 with 12 bits per component, expanded to 16 bits.
610+Data in the 12 high bits, zeros in the 4 low bits, arranged in little endian order.
611+
612+.. flat-table:: Sample 4x4 P012 Image
613+ :header-rows: 0
614+ :stub-columns: 0
615+
616+ * - start + 0:
617+ - Y'\ :sub:`00`
618+ - Y'\ :sub:`01`
619+ - Y'\ :sub:`02`
620+ - Y'\ :sub:`03`
621+ * - start + 8:
622+ - Y'\ :sub:`10`
623+ - Y'\ :sub:`11`
624+ - Y'\ :sub:`12`
625+ - Y'\ :sub:`13`
626+ * - start + 16:
627+ - Y'\ :sub:`20`
628+ - Y'\ :sub:`21`
629+ - Y'\ :sub:`22`
630+ - Y'\ :sub:`23`
631+ * - start + 24:
632+ - Y'\ :sub:`30`
633+ - Y'\ :sub:`31`
634+ - Y'\ :sub:`32`
635+ - Y'\ :sub:`33`
636+ * - start + 32:
637+ - Cb\ :sub:`00`
638+ - Cr\ :sub:`00`
639+ - Cb\ :sub:`01`
640+ - Cr\ :sub:`01`
641+ * - start + 40:
642+ - Cb\ :sub:`10`
643+ - Cr\ :sub:`10`
644+ - Cb\ :sub:`11`
645+ - Cr\ :sub:`11`
646+
647+.. flat-table:: Sample 4x4 P012M Image
648+ :header-rows: 0
649+ :stub-columns: 0
650+
651+ * - start0 + 0:
652+ - Y'\ :sub:`00`
653+ - Y'\ :sub:`01`
654+ - Y'\ :sub:`02`
655+ - Y'\ :sub:`03`
656+ * - start0 + 8:
657+ - Y'\ :sub:`10`
658+ - Y'\ :sub:`11`
659+ - Y'\ :sub:`12`
660+ - Y'\ :sub:`13`
661+ * - start0 + 16:
662+ - Y'\ :sub:`20`
663+ - Y'\ :sub:`21`
664+ - Y'\ :sub:`22`
665+ - Y'\ :sub:`23`
666+ * - start0 + 24:
667+ - Y'\ :sub:`30`
668+ - Y'\ :sub:`31`
669+ - Y'\ :sub:`32`
670+ - Y'\ :sub:`33`
671+ * -
672+ * - start1 + 0:
673+ - Cb\ :sub:`00`
674+ - Cr\ :sub:`00`
675+ - Cb\ :sub:`01`
676+ - Cr\ :sub:`01`
677+ * - start1 + 8:
678+ - Cb\ :sub:`10`
679+ - Cr\ :sub:`10`
680+ - Cb\ :sub:`11`
681+ - Cr\ :sub:`11`
682+
589683
590684 Fully Planar YUV Formats
591685 ========================
Documentation/userspace-api/media/v4l/user-func.rst+1−0
@@ -72,6 +72,7 @@ Function Reference · 71 unmodified lines
7272 vidioc-subdev-g-frame-interval
7373 vidioc-subdev-g-routing
7474 vidioc-subdev-g-selection
75+ vidioc-subdev-g-client-cap
7576 vidioc-subdev-querycap
7677 vidioc-subscribe-event
7778 func-mmap
Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst+10−0
@@ -185,6 +185,16 @@ still cause this situation. · 184 unmodified lines
185185 - ``p_u32``
186186 - A pointer to a matrix control of unsigned 32-bit values. Valid if
187187 this control is of type ``V4L2_CTRL_TYPE_U32``.
188+ * - __u32 *
189+ - ``p_s32``
190+ - A pointer to a matrix control of signed 32-bit values. Valid if
191+ this control is of type ``V4L2_CTRL_TYPE_INTEGER`` and
192+ ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set.
193+ * - __u32 *
194+ - ``p_s64``
195+ - A pointer to a matrix control of signed 64-bit values. Valid if
196+ this control is of type ``V4L2_CTRL_TYPE_INTEGER64`` and
197+ ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set.
188198 * - struct :c:type:`v4l2_area` *
189199 - ``p_area``
190200 - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is
Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst+16−36
@@ -49,6 +49,9 @@ of a graphics card. A non-destructive overlay blends video images into a · 48 unmodified lines
4949 VGA signal or graphics into a video signal. *Video Output Overlays* are
5050 always non-destructive.
5151
52+Destructive overlay support has been removed: with modern GPUs and CPUs
53+this is no longer needed, and it was always a very dangerous feature.
54+
5255 To get the current parameters applications call the :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
5356 ioctl with a pointer to a struct :c:type:`v4l2_framebuffer`
5457 structure. The driver fills all fields of the structure or returns an
@@ -63,18 +66,12 @@ this structure, the driver prepares for the overlay and returns the · 8 unmodified lines
6366 framebuffer parameters as :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>` does, or it returns an error
6467 code.
6568
66−To set the parameters for a *non-destructive Video Overlay*,
69+To set the parameters for a *Video Capture Overlay*
6770 applications must initialize the ``flags`` field, the ``fmt``
6871 substructure, and call :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>`. Again the driver prepares for
6972 the overlay and returns the framebuffer parameters as :ref:`VIDIOC_G_FBUF <VIDIOC_G_FBUF>`
7073 does, or it returns an error code.
7174
72−For a *destructive Video Overlay* applications must additionally provide
73−a ``base`` address. Setting up a DMA to a random memory location can
74−jeopardize the system security, its stability or even damage the
75−hardware, therefore only the superuser can set the parameters for a
76−destructive video overlay.
77−
7875 .. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{6.6cm}|
7976
8077 .. c:type:: v4l2_framebuffer
@@ -100,17 +97,14 @@ destructive video overlay. · 19 unmodified lines
10097 - ``base``
10198 -
10299 - Physical base address of the framebuffer, that is the address of
103− the pixel in the top left corner of the framebuffer. [#f1]_
104− * -
105− -
106− -
107− - This field is irrelevant to *non-destructive Video Overlays*. For
108− *destructive Video Overlays* applications must provide a base
109− address. The driver may accept only base addresses which are a
110− multiple of two, four or eight bytes. For *Video Output Overlays*
111− the driver must return a valid base address, so applications can
100+ the pixel in the top left corner of the framebuffer.
101+ For :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` this field is no longer supported
102+ and the kernel will always set this to NULL.
103+ For *Video Output Overlays*
104+ the driver will return a valid base address, so applications can
112105 find the corresponding Linux framebuffer device (see
113− :ref:`osd`).
106+ :ref:`osd`). For *Video Capture Overlays* this field will always be
107+ NULL.
114108 * - struct
115109 - ``fmt``
116110 -
@@ -136,8 +130,7 @@ destructive video overlay. · 19 unmodified lines
136130 * -
137131 -
138132 -
139− - For *destructive Video Overlays* applications must initialize this
140− field. For *Video Output Overlays* the driver must return a valid
133+ - For *Video Output Overlays* the driver must return a valid
141134 format.
142135 * -
143136 -
@@ -165,13 +158,6 @@ destructive video overlay. · 21 unmodified lines
165158
166159 This field is irrelevant to *non-destructive Video Overlays*.
167160
168− For *destructive Video Overlays* both applications and drivers can
169− set this field to request padding bytes at the end of each line.
170− Drivers however may ignore the requested value, returning
171− ``width`` times bytes-per-pixel or a larger value required by the
172− hardware. That implies applications can just set this field to
173− zero to get a reasonable default.
174−
175161 For *Video Output Overlays* the driver must return a valid value.
176162
177163 Video hardware may access padding bytes, therefore they must
@@ -190,9 +176,8 @@ destructive video overlay. · 12 unmodified lines
190176 * -
191177 - __u32
192178 - ``sizeimage``
193− - This field is irrelevant to *non-destructive Video Overlays*. For
194− *destructive Video Overlays* applications must initialize this
195− field. For *Video Output Overlays* the driver must return a valid
179+ - This field is irrelevant to *non-destructive Video Overlays*.
180+ For *Video Output Overlays* the driver must return a valid
196181 format.
197182
198183 Together with ``base`` it defines the framebuffer memory
@@ -232,9 +217,11 @@ destructive video overlay. · 33 unmodified lines
232217 * - ``V4L2_FBUF_CAP_LIST_CLIPPING``
233218 - 0x0004
234219 - The device supports clipping using a list of clip rectangles.
220+ Note that this is no longer supported.
235221 * - ``V4L2_FBUF_CAP_BITMAP_CLIPPING``
236222 - 0x0008
237223 - The device supports clipping using a bit mask.
224+ Note that this is no longer supported.
238225 * - ``V4L2_FBUF_CAP_LOCAL_ALPHA``
239226 - 0x0010
240227 - The device supports clipping/blending using the alpha channel of
@@ -342,10 +329,3 @@ EPERM · 101 unmodified lines
342329
343330 EINVAL
344331 The :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` parameters are unsuitable.
345−
346−.. [#f1]
347− A physical base address may not suit all platforms. GK notes in
348− theory we should pass something like PCI device + memory region +
349− offset instead. If you encounter problems please discuss on the
350− linux-media mailing list:
351− `https://linuxtv.org/lists.php <https://linuxtv.org/lists.php>`__.
Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst+29−15
@@ -31,18 +31,30 @@ Arguments · 30 unmodified lines
3131 Description
3232 ===========
3333
34−This ioctl allows applications to enumerate all frame sizes supported by
35−a sub-device on the given pad for the given media bus format. Supported
36−formats can be retrieved with the
34+This ioctl allows applications to access the enumeration of frame sizes
35+supported by a sub-device on the specified pad
36+for the specified media bus format.
37+Supported formats can be retrieved with the
3738 :ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE`
3839 ioctl.
3940
40−To enumerate frame sizes applications initialize the ``pad``, ``which``
41−, ``code`` and ``index`` fields of the struct
42−:c:type:`v4l2_subdev_mbus_code_enum` and
43−call the :ref:`VIDIOC_SUBDEV_ENUM_FRAME_SIZE` ioctl with a pointer to the
44−structure. Drivers fill the minimum and maximum frame sizes or return an
45−EINVAL error code if one of the input parameters is invalid.
41+The enumerations are defined by the driver, and indexed using the ``index`` field
42+of the struct :c:type:`v4l2_subdev_frame_size_enum`.
43+Each pair of ``pad`` and ``code`` correspond to a separate enumeration.
44+Each enumeration starts with the ``index`` of 0, and
45+the lowest invalid index marks the end of the enumeration.
46+
47+Therefore, to enumerate frame sizes allowed on the specified pad
48+and using the specified mbus format, initialize the
49+``pad``, ``which``, and ``code`` fields to desired values,
50+and set ``index`` to 0.
51+Then call the :ref:`VIDIOC_SUBDEV_ENUM_FRAME_SIZE` ioctl with a pointer to the
52+structure.
53+
54+A successful call will return with minimum and maximum frame sizes filled in.
55+Repeat with increasing ``index`` until ``EINVAL`` is received.
56+``EINVAL`` means that either no more entries are available in the enumeration,
57+or that an input parameter was invalid.
4658
4759 Sub-devices that only support discrete frame sizes (such as most
4860 sensors) will return one or more frame sizes with identical minimum and
@@ -72,26 +84,28 @@ information about try formats. · 23 unmodified lines
7284
7385 * - __u32
7486 - ``index``
75− - Number of the format in the enumeration, set by the application.
87+ - Index of the frame size in the enumeration belonging to the given pad
88+ and format. Filled in by the application.
7689 * - __u32
7790 - ``pad``
7891 - Pad number as reported by the media controller API.
92+ Filled in by the application.
7993 * - __u32
8094 - ``code``
8195 - The media bus format code, as defined in
82− :ref:`v4l2-mbus-format`.
96+ :ref:`v4l2-mbus-format`. Filled in by the application.
8397 * - __u32
8498 - ``min_width``
85− - Minimum frame width, in pixels.
99+ - Minimum frame width, in pixels. Filled in by the driver.
86100 * - __u32
87101 - ``max_width``
88− - Maximum frame width, in pixels.
102+ - Maximum frame width, in pixels. Filled in by the driver.
89103 * - __u32
90104 - ``min_height``
91− - Minimum frame height, in pixels.
105+ - Minimum frame height, in pixels. Filled in by the driver.
92106 * - __u32
93107 - ``max_height``
94− - Maximum frame height, in pixels.
108+ - Maximum frame height, in pixels. Filled in by the driver.
95109 * - __u32
96110 - ``which``
97111 - Frame sizes to be enumerated, from enum
Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst+27−12
@@ -31,15 +31,28 @@ Arguments · 30 unmodified lines
3131 Description
3232 ===========
3333
34−To enumerate media bus formats available at a given sub-device pad
35−applications initialize the ``pad``, ``which`` and ``index`` fields of
36−struct
37−:c:type:`v4l2_subdev_mbus_code_enum` and
38−call the :ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE` ioctl with a pointer to this
39−structure. Drivers fill the rest of the structure or return an ``EINVAL``
40−error code if either the ``pad`` or ``index`` are invalid. All media bus
41−formats are enumerable by beginning at index zero and incrementing by
42−one until ``EINVAL`` is returned.
34+This call is used by the application to access the enumeration
35+of media bus formats for the selected pad.
36+
37+The enumerations are defined by the driver, and indexed using the ``index`` field
38+of struct :c:type:`v4l2_subdev_mbus_code_enum`.
39+Each enumeration starts with the ``index`` of 0, and
40+the lowest invalid index marks the end of enumeration.
41+
42+Therefore, to enumerate media bus formats available at a given sub-device pad,
43+initialize the ``pad``, and ``which`` fields to desired values,
44+and set ``index`` to 0.
45+Then call the :ref:`VIDIOC_SUBDEV_ENUM_MBUS_CODE` ioctl
46+with a pointer to this structure.
47+
48+A successful call will return with the ``code`` field filled in
49+with a mbus code value.
50+Repeat with increasing ``index`` until ``EINVAL`` is received.
51+``EINVAL`` means that either ``pad`` is invalid,
52+or that there are no more codes available at this pad.
53+
54+The driver must not return the same value of ``code`` for different indices
55+at the same pad.
4356
4457 Available media bus formats may depend on the current 'try' formats at
4558 other pads of the sub-device, as well as on the current active links.
@@ -57,14 +70,16 @@ information about the try formats. · 11 unmodified lines
5770
5871 * - __u32
5972 - ``pad``
60− - Pad number as reported by the media controller API.
73+ - Pad number as reported by the media controller API. Filled in by the
74+ application.
6175 * - __u32
6276 - ``index``
63− - Number of the format in the enumeration, set by the application.
77+ - Index of the mbus code in the enumeration belonging to the given pad.
78+ Filled in by the application.
6479 * - __u32
6580 - ``code``
6681 - The media bus format code, as defined in
67− :ref:`v4l2-mbus-format`.
82+ :ref:`v4l2-mbus-format`. Filled in by the driver.
6883 * - __u32
6984 - ``which``
7085 - Media bus format codes to be enumerated, from enum
Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst+83−0
@@ -0,0 +1,83 @@
1+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
2+.. c:namespace:: V4L
3+
4+.. _VIDIOC_SUBDEV_G_CLIENT_CAP:
5+
6+************************************************************
7+ioctl VIDIOC_SUBDEV_G_CLIENT_CAP, VIDIOC_SUBDEV_S_CLIENT_CAP
8+************************************************************
9+
10+Name
11+====
12+
13+VIDIOC_SUBDEV_G_CLIENT_CAP - VIDIOC_SUBDEV_S_CLIENT_CAP - Get or set client
14+capabilities.
15+
16+Synopsis
17+========
18+
19+.. c:macro:: VIDIOC_SUBDEV_G_CLIENT_CAP
20+
21+``int ioctl(int fd, VIDIOC_SUBDEV_G_CLIENT_CAP, struct v4l2_subdev_client_capability *argp)``
22+
23+.. c:macro:: VIDIOC_SUBDEV_S_CLIENT_CAP
24+
25+``int ioctl(int fd, VIDIOC_SUBDEV_S_CLIENT_CAP, struct v4l2_subdev_client_capability *argp)``
26+
27+Arguments
28+=========
29+
30+``fd``
31+ File descriptor returned by :ref:`open() <func-open>`.
32+
33+``argp``
34+ Pointer to struct :c:type:`v4l2_subdev_client_capability`.
35+
36+Description
37+===========
38+
39+These ioctls are used to get and set the client (the application using the
40+subdevice ioctls) capabilities. The client capabilities are stored in the file
41+handle of the opened subdev device node, and the client must set the
42+capabilities for each opened subdev separately.
43+
44+By default no client capabilities are set when a subdev device node is opened.
45+
46+The purpose of the client capabilities are to inform the kernel of the behavior
47+of the client, mainly related to maintaining compatibility with different
48+kernel and userspace versions.
49+
50+The ``VIDIOC_SUBDEV_G_CLIENT_CAP`` ioctl returns the current client capabilities
51+associated with the file handle ``fd``.
52+
53+The ``VIDIOC_SUBDEV_S_CLIENT_CAP`` ioctl sets client capabilities for the file
54+handle ``fd``. The new capabilities fully replace the current capabilities, the
55+ioctl can therefore also be used to remove capabilities that have previously
56+been set.
57+
58+``VIDIOC_SUBDEV_S_CLIENT_CAP`` modifies the struct
59+:c:type:`v4l2_subdev_client_capability` to reflect the capabilities that have
60+been accepted. A common case for the kernel not accepting a capability is that
61+the kernel is older than the headers the userspace uses, and thus the capability
62+is unknown to the kernel.
63+
64+.. flat-table:: Client Capabilities
65+ :header-rows: 1
66+
67+ * - Capability
68+ - Description
69+ * - ``V4L2_SUBDEV_CLIENT_CAP_STREAMS``
70+ - The client is aware of streams. Setting this flag enables the use
71+ of 'stream' fields (referring to the stream number) with various
72+ ioctls. If this is not set (which is the default), the 'stream' fields
73+ will be forced to 0 by the kernel.
74+
75+Return Value
76+============
77+
78+On success 0 is returned, on error -1 and the ``errno`` variable is set
79+appropriately. The generic error codes are described at the
80+:ref:`Generic Error Codes <gen-errors>` chapter.
81+
82+ENOIOCTLCMD
83+ The kernel does not support this ioctl.
MAINTAINERS+17−31
@@ -1227,12 +1227,6 @@ F: Documentation/devicetree/bindings/iio/addac/adi,ad74413r.yaml · 1226 unmodified lines
12271227 F: drivers/iio/addac/ad74413r.c
12281228 F: include/dt-bindings/iio/addac/adi,ad74413r.h
12291229
1230−ANALOG DEVICES INC AD9389B DRIVER
1231−M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
1232−L: linux-media@vger.kernel.org
1233−S: Maintained
1234−F: drivers/media/i2c/ad9389b*
1235−
12361230 ANALOG DEVICES INC ADA4250 DRIVER
12371231 M: Antoniu Miclaus <antoniu.miclaus@analog.com>
12381232 L: linux-iio@vger.kernel.org
@@ -8441,14 +8435,6 @@ L: platform-driver-x86@vger.kernel.org · 7202 unmodified lines
84418435 S: Maintained
84428436 F: drivers/platform/x86/fujitsu-laptop.c
84438437
8444−FUJITSU M-5MO LS CAMERA ISP DRIVER
8445−M: Kyungmin Park <kyungmin.park@samsung.com>
8446−M: Heungjun Kim <riverful.kim@samsung.com>
8447−L: linux-media@vger.kernel.org
8448−S: Maintained
8449−F: drivers/media/i2c/m5mols/
8450−F: include/media/i2c/m5mols.h
8451−
84528438 FUJITSU TABLET EXTRAS
84538439 M: Robert Gerlach <khnz@gmx.de>
84548440 L: platform-driver-x86@vger.kernel.org
@@ -14206,14 +14192,6 @@ L: linux-mtd@lists.infradead.org · 5751 unmodified lines
1420614192 S: Maintained
1420714193 F: drivers/mtd/devices/docg3*
1420814194
14209−MT9M032 APTINA SENSOR DRIVER
14210−M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
14211−L: linux-media@vger.kernel.org
14212−S: Maintained
14213−T: git git://linuxtv.org/media_tree.git
14214−F: drivers/media/i2c/mt9m032.c
14215−F: include/media/i2c/mt9m032.h
14216−
1421714195 MT9P031 APTINA CAMERA SENSOR
1421814196 M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
1421914197 L: linux-media@vger.kernel.org
@@ -14223,14 +14201,6 @@ F: Documentation/devicetree/bindings/media/i2c/aptina,mt9p031.yaml · 3 unmodified lines
1422314201 F: drivers/media/i2c/mt9p031.c
1422414202 F: include/media/i2c/mt9p031.h
1422514203
14226−MT9T001 APTINA CAMERA SENSOR
14227−M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
14228−L: linux-media@vger.kernel.org
14229−S: Maintained
14230−T: git git://linuxtv.org/media_tree.git
14231−F: drivers/media/i2c/mt9t001.c
14232−F: include/media/i2c/mt9t001.h
14233−
1423414204 MT9T112 APTINA CAMERA SENSOR
1423514205 M: Jacopo Mondi <jacopo@jmondi.org>
1423614206 L: linux-media@vger.kernel.org
@@ -14983,6 +14953,13 @@ F: Documentation/devicetree/bindings/clock/imx* · 746 unmodified lines
1498314953 F: drivers/clk/imx/
1498414954 F: include/dt-bindings/clock/imx*
1498514955
14956+NXP i.MX 8M ISI DRIVER
14957+M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
14958+L: linux-media@vger.kernel.org
14959+S: Maintained
14960+F: Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
14961+F: drivers/media/platform/nxp/imx8-isi/
14962+
1498614963 NXP i.MX 8MQ DCSS DRIVER
1498714964 M: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
1498814965 R: Lucas Stach <l.stach@pengutronix.de>
@@ -15410,6 +15387,7 @@ M: Shunqian Zheng <zhengsq@rock-chips.com> · 421 unmodified lines
1541015387 L: linux-media@vger.kernel.org
1541115388 S: Maintained
1541215389 T: git git://linuxtv.org/media_tree.git
15390+F: Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml
1541315391 F: drivers/media/i2c/ov2685.c
1541415392
1541515393 OMNIVISION OV2740 SENSOR DRIVER
@@ -15501,7 +15479,7 @@ F: Documentation/devicetree/bindings/media/i2c/ov7740.txt · 85 unmodified lines
1550115479 F: drivers/media/i2c/ov7740.c
1550215480
1550315481 OMNIVISION OV8856 SENSOR DRIVER
15504−M: Dongchun Zhu <dongchun.zhu@mediatek.com>
15482+M: Sakari Ailus <sakari.ailus@linux.intel.com>
1550515483 L: linux-media@vger.kernel.org
1550615484 S: Maintained
1550715485 T: git git://linuxtv.org/media_tree.git
@@ -17260,6 +17238,7 @@ F: drivers/net/wwan/qcom_bam_dmux.c · 1752 unmodified lines
1726017238 QUALCOMM CAMERA SUBSYSTEM DRIVER
1726117239 M: Robert Foss <rfoss@kernel.org>
1726217240 M: Todor Tomov <todor.too@gmail.com>
17241+M: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
1726317242 L: linux-media@vger.kernel.org
1726417243 S: Maintained
1726517244 F: Documentation/admin-guide/media/qcom_camss.rst
@@ -18536,6 +18515,7 @@ M: Sylwester Nawrocki <s.nawrocki@samsung.com> · 1270 unmodified lines
1853618515 M: Andrzej Hajda <andrzej.hajda@intel.com>
1853718516 L: linux-media@vger.kernel.org
1853818517 S: Supported
18518+F: Documentation/devicetree/bindings/media/samsung,s5c73m3.yaml
1853918519 F: drivers/media/i2c/s5c73m3/*
1854018520
1854118521 SAMSUNG S5K5BAF CAMERA DRIVER
@@ -18560,6 +18540,11 @@ M: Sylwester Nawrocki <s.nawrocki@samsung.com> · 18 unmodified lines
1856018540 L: linux-media@vger.kernel.org
1856118541 S: Supported
1856218542 Q: https://patchwork.linuxtv.org/project/linux-media/list/
18543+F: Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml
18544+F: Documentation/devicetree/bindings/media/samsung,exynos4210-fimc.yaml
18545+F: Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-is.yaml
18546+F: Documentation/devicetree/bindings/media/samsung,exynos4212-fimc-lite.yaml
18547+F: Documentation/devicetree/bindings/media/samsung,fimc.yaml
1856318548 F: drivers/media/platform/samsung/exynos4-is/
1856418549
1856518550 SAMSUNG SOC CLOCK DRIVERS
@@ -19038,6 +19023,7 @@ L: linux-media@vger.kernel.org · 472 unmodified lines
1903819023 S: Odd Fixes
1903919024 W: https://linuxtv.org
1904019025 T: git git://linuxtv.org/media_tree.git
19026+F: Documentation/devicetree/bindings/media/silabs,si470x.yaml
1904119027 F: drivers/media/radio/si470x/radio-si470x-i2c.c
1904219028
1904319029 SI470X FM RADIO RECEIVER USB DRIVER
drivers/media/cec/core/cec-adap.c+5−2
@@ -1052,6 +1052,7 @@ void cec_received_msg_ts(struct cec_adapter *adap, · 1051 unmodified lines
10521052 u8 cmd = msg->msg[1];
10531053 bool is_reply = false;
10541054 bool valid_la = true;
1055+ bool monitor_valid_la = true;
10551056 u8 min_len = 0;
10561057
10571058 if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE))
@@ -1093,8 +1094,10 @@ void cec_received_msg_ts(struct cec_adapter *adap, · 35 unmodified lines
10931094 adap->last_initiator = 0xff;
10941095
10951096 /* Check if this message was for us (directed or broadcast). */
1096− if (!cec_msg_is_broadcast(msg))
1097+ if (!cec_msg_is_broadcast(msg)) {
10971098 valid_la = cec_has_log_addr(adap, msg_dest);
1099+ monitor_valid_la = valid_la;
1100+ }
10981101
10991102 /*
11001103 * Check if the length is not too short or if the message is a
@@ -1227,7 +1230,7 @@ void cec_received_msg_ts(struct cec_adapter *adap, · 126 unmodified lines
12271230 mutex_unlock(&adap->lock);
12281231
12291232 /* Pass the message on to any monitoring filehandles */
1230− cec_queue_msg_monitor(adap, msg, valid_la);
1233+ cec_queue_msg_monitor(adap, msg, monitor_valid_la);
12311234
12321235 /* We're done if it is not for us or a poll message */
12331236 if (!valid_la || msg->len <= 1)
drivers/media/cec/platform/cec-gpio/cec-gpio.c+2−3
@@ -269,13 +269,12 @@ del_adap: · 268 unmodified lines
269269 return ret;
270270 }
271271
272−static int cec_gpio_remove(struct platform_device *pdev)
272+static void cec_gpio_remove(struct platform_device *pdev)
273273 {
274274 struct cec_gpio *cec = platform_get_drvdata(pdev);
275275
276276 cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
277277 cec_unregister_adapter(cec->adap);
278− return 0;
279278 }
280279
281280 static const struct of_device_id cec_gpio_match[] = {
@@ -288,7 +287,7 @@ MODULE_DEVICE_TABLE(of, cec_gpio_match); · 6 unmodified lines
288287
289288 static struct platform_driver cec_gpio_pdrv = {
290289 .probe = cec_gpio_probe,
291− .remove = cec_gpio_remove,
290+ .remove_new = cec_gpio_remove,
292291 .driver = {
293292 .name = "cec-gpio",
294293 .of_match_table = cec_gpio_match,
drivers/media/cec/platform/cros-ec/cros-ec-cec.c+14−8
@@ -225,6 +225,12 @@ static const struct cec_dmi_match cec_dmi_match_table[] = { · 224 unmodified lines
225225 { "Google", "Kinox", "0000:00:02.0", "Port B" },
226226 /* Google Kuldax */
227227 { "Google", "Kuldax", "0000:00:02.0", "Port B" },
228+ /* Google Aurash */
229+ { "Google", "Aurash", "0000:00:02.0", "Port B" },
230+ /* Google Gladios */
231+ { "Google", "Gladios", "0000:00:02.0", "Port B" },
232+ /* Google Lisbon */
233+ { "Google", "Lisbon", "0000:00:02.0", "Port B" },
228234 };
229235
230236 static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
@@ -326,31 +332,31 @@ out_probe_adapter: · 95 unmodified lines
326332 return ret;
327333 }
328334
329−static int cros_ec_cec_remove(struct platform_device *pdev)
335+static void cros_ec_cec_remove(struct platform_device *pdev)
330336 {
331337 struct cros_ec_cec *cros_ec_cec = platform_get_drvdata(pdev);
332338 struct device *dev = &pdev->dev;
333339 int ret;
334340
341+ /*
342+ * blocking_notifier_chain_unregister() only fails if the notifier isn't
343+ * in the list. We know it was added to it by .probe(), so there should
344+ * be no need for error checking. Be cautious and still check.
345+ */
335346 ret = blocking_notifier_chain_unregister(
336347 &cros_ec_cec->cros_ec->event_notifier,
337348 &cros_ec_cec->notifier);
338−
339− if (ret) {
349+ if (ret)
340350 dev_err(dev, "failed to unregister notifier\n");
341− return ret;
342− }
343351
344352 cec_notifier_cec_adap_unregister(cros_ec_cec->notify,
345353 cros_ec_cec->adap);
346354 cec_unregister_adapter(cros_ec_cec->adap);
347−
348− return 0;
349355 }
350356
351357 static struct platform_driver cros_ec_cec_driver = {
352358 .probe = cros_ec_cec_probe,
353− .remove = cros_ec_cec_remove,
359+ .remove_new = cros_ec_cec_remove,
354360 .driver = {
355361 .name = DRV_NAME,
356362 .pm = &cros_ec_cec_pm_ops,
drivers/media/cec/platform/meson/ao-cec-g12a.c+2−4
@@ -744,7 +744,7 @@ out_probe_adapter: · 743 unmodified lines
744744 return ret;
745745 }
746746
747−static int meson_ao_cec_g12a_remove(struct platform_device *pdev)
747+static void meson_ao_cec_g12a_remove(struct platform_device *pdev)
748748 {
749749 struct meson_ao_cec_g12a_device *ao_cec = platform_get_drvdata(pdev);
750750
@@ -753,8 +753,6 @@ static int meson_ao_cec_g12a_remove(struct platform_device *pdev) · 2 unmodified lines
753753 cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
754754
755755 cec_unregister_adapter(ao_cec->adap);
756−
757− return 0;
758756 }
759757
760758 static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = {
@@ -780,7 +778,7 @@ MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match); · 19 unmodified lines
780778
781779 static struct platform_driver meson_ao_cec_g12a_driver = {
782780 .probe = meson_ao_cec_g12a_probe,
783− .remove = meson_ao_cec_g12a_remove,
781+ .remove_new = meson_ao_cec_g12a_remove,
784782 .driver = {
785783 .name = "meson-ao-cec-g12a",
786784 .of_match_table = of_match_ptr(meson_ao_cec_g12a_of_match),
drivers/media/cec/platform/meson/ao-cec.c+2−4
@@ -696,7 +696,7 @@ out_probe_adapter: · 695 unmodified lines
696696 return ret;
697697 }
698698
699−static int meson_ao_cec_remove(struct platform_device *pdev)
699+static void meson_ao_cec_remove(struct platform_device *pdev)
700700 {
701701 struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev);
702702
@@ -704,8 +704,6 @@ static int meson_ao_cec_remove(struct platform_device *pdev) · 1 unmodified line
704704
705705 cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
706706 cec_unregister_adapter(ao_cec->adap);
707−
708− return 0;
709707 }
710708
711709 static const struct of_device_id meson_ao_cec_of_match[] = {
@@ -716,7 +714,7 @@ MODULE_DEVICE_TABLE(of, meson_ao_cec_of_match); · 4 unmodified lines
716714
717715 static struct platform_driver meson_ao_cec_driver = {
718716 .probe = meson_ao_cec_probe,
719− .remove = meson_ao_cec_remove,
717+ .remove_new = meson_ao_cec_remove,
720718 .driver = {
721719 .name = "meson-ao-cec",
722720 .of_match_table = of_match_ptr(meson_ao_cec_of_match),
drivers/media/cec/platform/s5p/s5p_cec.c+2−3
@@ -249,14 +249,13 @@ err_delete_adapter: · 248 unmodified lines
249249 return ret;
250250 }
251251
252−static int s5p_cec_remove(struct platform_device *pdev)
252+static void s5p_cec_remove(struct platform_device *pdev)
253253 {
254254 struct s5p_cec_dev *cec = platform_get_drvdata(pdev);
255255
256256 cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
257257 cec_unregister_adapter(cec->adap);
258258 pm_runtime_disable(&pdev->dev);
259− return 0;
260259 }
261260
262261 static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev)
@@ -295,7 +294,7 @@ MODULE_DEVICE_TABLE(of, s5p_cec_match); · 32 unmodified lines
295294
296295 static struct platform_driver s5p_cec_pdrv = {
297296 .probe = s5p_cec_probe,
298− .remove = s5p_cec_remove,
297+ .remove_new = s5p_cec_remove,
299298 .driver = {
300299 .name = CEC_NAME,
301300 .of_match_table = s5p_cec_match,
drivers/media/cec/platform/seco/seco-cec.c+2−4
@@ -668,7 +668,7 @@ err: · 667 unmodified lines
668668 return ret;
669669 }
670670
671−static int secocec_remove(struct platform_device *pdev)
671+static void secocec_remove(struct platform_device *pdev)
672672 {
673673 struct secocec_data *secocec = platform_get_drvdata(pdev);
674674 u16 val;
@@ -686,8 +686,6 @@ static int secocec_remove(struct platform_device *pdev) · 11 unmodified lines
686686 release_region(BRA_SMB_BASE_ADDR, 7);
687687
688688 dev_dbg(&pdev->dev, "CEC device removed\n");
689−
690− return 0;
691689 }
692690
693691 #ifdef CONFIG_PM_SLEEP
@@ -780,7 +778,7 @@ static struct platform_driver secocec_driver = { · 86 unmodified lines
780778 .pm = SECOCEC_PM_OPS,
781779 },
782780 .probe = secocec_probe,
783− .remove = secocec_remove,
781+ .remove_new = secocec_remove,
784782 };
785783
786784 module_platform_driver(secocec_driver);
drivers/media/cec/platform/sti/stih-cec.c+2−4
@@ -364,14 +364,12 @@ err_delete_adapter: · 363 unmodified lines
364364 return ret;
365365 }
366366
367−static int stih_cec_remove(struct platform_device *pdev)
367+static void stih_cec_remove(struct platform_device *pdev)
368368 {
369369 struct stih_cec *cec = platform_get_drvdata(pdev);
370370
371371 cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
372372 cec_unregister_adapter(cec->adap);
373−
374− return 0;
375373 }
376374
377375 static const struct of_device_id stih_cec_match[] = {
@@ -384,7 +382,7 @@ MODULE_DEVICE_TABLE(of, stih_cec_match); · 6 unmodified lines
384382
385383 static struct platform_driver stih_cec_pdrv = {
386384 .probe = stih_cec_probe,
387− .remove = stih_cec_remove,
385+ .remove_new = stih_cec_remove,
388386 .driver = {
389387 .name = CEC_NAME,
390388 .of_match_table = stih_cec_match,
drivers/media/cec/platform/stm32/stm32-cec.c+2−4
@@ -344,7 +344,7 @@ err_unprepare_cec_clk: · 343 unmodified lines
344344 return ret;
345345 }
346346
347−static int stm32_cec_remove(struct platform_device *pdev)
347+static void stm32_cec_remove(struct platform_device *pdev)
348348 {
349349 struct stm32_cec *cec = platform_get_drvdata(pdev);
350350
@@ -352,8 +352,6 @@ static int stm32_cec_remove(struct platform_device *pdev) · 1 unmodified line
352352 clk_unprepare(cec->clk_hdmi_cec);
353353
354354 cec_unregister_adapter(cec->adap);
355−
356− return 0;
357355 }
358356
359357 static const struct of_device_id stm32_cec_of_match[] = {
@@ -364,7 +362,7 @@ MODULE_DEVICE_TABLE(of, stm32_cec_of_match); · 4 unmodified lines
364362
365363 static struct platform_driver stm32_cec_driver = {
366364 .probe = stm32_cec_probe,
367− .remove = stm32_cec_remove,
365+ .remove_new = stm32_cec_remove,
368366 .driver = {
369367 .name = CEC_NAME,
370368 .of_match_table = stm32_cec_of_match,
drivers/media/cec/platform/tegra/tegra_cec.c+2−4
@@ -421,7 +421,7 @@ err_clk: · 420 unmodified lines
421421 return ret;
422422 }
423423
424−static int tegra_cec_remove(struct platform_device *pdev)
424+static void tegra_cec_remove(struct platform_device *pdev)
425425 {
426426 struct tegra_cec *cec = platform_get_drvdata(pdev);
427427
@@ -429,8 +429,6 @@ static int tegra_cec_remove(struct platform_device *pdev) · 1 unmodified line
429429
430430 cec_notifier_cec_adap_unregister(cec->notifier, cec->adap);
431431 cec_unregister_adapter(cec->adap);
432−
433− return 0;
434432 }
435433
436434 #ifdef CONFIG_PM
@@ -467,7 +465,7 @@ static struct platform_driver tegra_cec_driver = { · 30 unmodified lines
467465 .of_match_table = of_match_ptr(tegra_cec_of_match),
468466 },
469467 .probe = tegra_cec_probe,
470− .remove = tegra_cec_remove,
468+ .remove_new = tegra_cec_remove,
471469
472470 #ifdef CONFIG_PM
473471 .suspend = tegra_cec_suspend,
drivers/media/common/btcx-risc.h+0−29
@@ -1,29 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−/*
3− */
4−struct btcx_riscmem {
5− unsigned int size;
6− __le32 *cpu;
7− __le32 *jmp;
8− dma_addr_t dma;
9−};
10−
11−struct btcx_skiplist {
12− int start;
13− int end;
14−};
15−
16−int btcx_riscmem_alloc(struct pci_dev *pci,
17− struct btcx_riscmem *risc,
18− unsigned int size);
19−void btcx_riscmem_free(struct pci_dev *pci,
20− struct btcx_riscmem *risc);
21−
22−int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
23− struct v4l2_clip *clips, unsigned int n);
24−int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
25− unsigned int n, int mask);
26−void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
27−void btcx_calc_skips(int line, int width, int *maxy,
28− struct btcx_skiplist *skips, unsigned int *nskips,
29− const struct v4l2_clip *clips, unsigned int nclips);
drivers/media/common/saa7146/Kconfig+1−1
@@ -6,5 +6,5 @@ config VIDEO_SAA7146 · 5 unmodified lines
66 config VIDEO_SAA7146_VV
77 tristate
88 depends on VIDEO_DEV
9− select VIDEOBUF_DMA_SG
9+ select VIDEOBUF2_DMA_SG
1010 select VIDEO_SAA7146
drivers/media/common/saa7146/saa7146_core.c+14−26
@@ -37,7 +37,8 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data) · 36 unmodified lines
3737 {
3838 u32 value = 0;
3939
40− BUG_ON(port > 3);
40+ if (WARN_ON(port > 3))
41+ return;
4142
4243 value = saa7146_read(dev, GPIO_CTRL);
4344 value &= ~(0xff << (8*port));
@@ -148,7 +149,8 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) · 104 unmodified lines
148149 pg = vmalloc_to_page(virt);
149150 if (NULL == pg)
150151 goto err;
151− BUG_ON(PageHighMem(pg));
152+ if (WARN_ON(PageHighMem(pg)))
153+ return NULL;
152154 sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
153155 }
154156 return sglist;
@@ -233,46 +235,32 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) · 78 unmodified lines
233235 }
234236
235237 int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
236− struct scatterlist *list, int sglen )
238+ struct scatterlist *list, int sglen)
237239 {
240+ struct sg_dma_page_iter dma_iter;
238241 __le32 *ptr, fill;
239242 int nr_pages = 0;
240− int i,p;
243+ int i;
241244
242− BUG_ON(0 == sglen);
243− BUG_ON(list->offset > PAGE_SIZE);
245+ if (WARN_ON(!sglen) ||
246+ WARN_ON(list->offset > PAGE_SIZE))
247+ return -EIO;
244248
245249 /* if we have a user buffer, the first page may not be
246250 aligned to a page boundary. */
247251 pt->offset = list->offset;
248252
249253 ptr = pt->cpu;
250− for (i = 0; i < sglen; i++, list++) {
251−/*
252− pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n",
253− i, sg_dma_address(list), sg_dma_len(list),
254− list->offset);
255−*/
256− for (p = 0; p * 4096 < sg_dma_len(list); p++, ptr++) {
257− *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096);
258− nr_pages++;
259− }
254+ for_each_sg_dma_page(list, &dma_iter, sglen, 0) {
255+ *ptr++ = cpu_to_le32(sg_page_iter_dma_address(&dma_iter));
256+ nr_pages++;
260257 }
261258
262259
263260 /* safety; fill the page table up with the last valid page */
264261 fill = *(ptr-1);
265− for(i=nr_pages;i<1024;i++) {
262+ for (i = nr_pages; i < 1024; i++)
266263 *ptr++ = fill;
267− }
268−
269−/*
270− ptr = pt->cpu;
271− pr_debug("offset: %d\n", pt->offset);
272− for(i=0;i<5;i++) {
273− pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]);
274− }
275−*/
276264 return 0;
277265 }
278266
drivers/media/common/saa7146/saa7146_fops.c+75−298
@@ -7,12 +7,11 @@ · 6 unmodified lines
77 /****************************************************************************/
88 /* resource management functions, shamelessly stolen from saa7134 driver */
99
10−int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
10+int saa7146_res_get(struct saa7146_dev *dev, unsigned int bit)
1111 {
12− struct saa7146_dev *dev = fh->dev;
1312 struct saa7146_vv *vv = dev->vv_data;
1413
15− if (fh->resources & bit) {
14+ if (vv->resources & bit) {
1615 DEB_D("already allocated! want: 0x%02x, cur:0x%02x\n",
1716 bit, vv->resources);
1817 /* have it already allocated */
@@ -27,41 +26,22 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit) · 8 unmodified lines
2726 return 0;
2827 }
2928 /* it's free, grab it */
30− fh->resources |= bit;
3129 vv->resources |= bit;
3230 DEB_D("res: get 0x%02x, cur:0x%02x\n", bit, vv->resources);
3331 return 1;
3432 }
3533
36−void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
34+void saa7146_res_free(struct saa7146_dev *dev, unsigned int bits)
3735 {
38− struct saa7146_dev *dev = fh->dev;
3936 struct saa7146_vv *vv = dev->vv_data;
4037
41− BUG_ON((fh->resources & bits) != bits);
38+ WARN_ON((vv->resources & bits) != bits);
4239
43− fh->resources &= ~bits;
4440 vv->resources &= ~bits;
4541 DEB_D("res: put 0x%02x, cur:0x%02x\n", bits, vv->resources);
4642 }
4743
4844
49−/********************************************************************************/
50−/* common dma functions */
51−
52−void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
53− struct saa7146_buf *buf)
54−{
55− struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
56− DEB_EE("dev:%p, buf:%p\n", dev, buf);
57−
58− videobuf_waiton(q, &buf->vb, 0, 0);
59− videobuf_dma_unmap(q->dev, dma);
60− videobuf_dma_free(dma);
61− buf->vb.state = VIDEOBUF_NEEDS_INIT;
62−}
63−
64−
6545 /********************************************************************************/
6646 /* common buffer functions */
6747
@@ -72,15 +52,15 @@ int saa7146_buffer_queue(struct saa7146_dev *dev, · 4 unmodified lines
7252 assert_spin_locked(&dev->slock);
7353 DEB_EE("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf);
7454
75− BUG_ON(!q);
55+ if (WARN_ON(!q))
56+ return -EIO;
7657
7758 if (NULL == q->curr) {
7859 q->curr = buf;
7960 DEB_D("immediately activating buffer %p\n", buf);
8061 buf->activate(dev,buf,NULL);
8162 } else {
82− list_add_tail(&buf->vb.queue,&q->queue);
83− buf->vb.state = VIDEOBUF_QUEUED;
63+ list_add_tail(&buf->list, &q->queue);
8464 DEB_D("adding buffer %p to queue. (active buffer present)\n",
8565 buf);
8666 }
@@ -91,21 +71,31 @@ void saa7146_buffer_finish(struct saa7146_dev *dev, · 4 unmodified lines
9171 struct saa7146_dmaqueue *q,
9272 int state)
9373 {
74+ struct saa7146_vv *vv = dev->vv_data;
75+ struct saa7146_buf *buf = q->curr;
76+
9477 assert_spin_locked(&dev->slock);
9578 DEB_EE("dev:%p, dmaq:%p, state:%d\n", dev, q, state);
9679 DEB_EE("q->curr:%p\n", q->curr);
9780
9881 /* finish current buffer */
99− if (NULL == q->curr) {
82+ if (!buf) {
10083 DEB_D("aiii. no current buffer\n");
10184 return;
10285 }
10386
104− q->curr->vb.state = state;
105− q->curr->vb.ts = ktime_get_ns();
106− wake_up(&q->curr->vb.done);
107−
10887 q->curr = NULL;
88+ buf->vb.vb2_buf.timestamp = ktime_get_ns();
89+ if (vv->video_fmt.field == V4L2_FIELD_ALTERNATE)
90+ buf->vb.field = vv->last_field;
91+ else if (vv->video_fmt.field == V4L2_FIELD_ANY)
92+ buf->vb.field = (vv->video_fmt.height > vv->standard->v_max_out / 2)
93+ ? V4L2_FIELD_INTERLACED
94+ : V4L2_FIELD_BOTTOM;
95+ else
96+ buf->vb.field = vv->video_fmt.field;
97+ buf->vb.sequence = vv->seqnr++;
98+ vb2_buffer_done(&buf->vb.vb2_buf, state);
10999 }
110100
111101 void saa7146_buffer_next(struct saa7146_dev *dev,
@@ -113,17 +103,18 @@ void saa7146_buffer_next(struct saa7146_dev *dev, · 1 unmodified line
113103 {
114104 struct saa7146_buf *buf,*next = NULL;
115105
116− BUG_ON(!q);
106+ if (WARN_ON(!q))
107+ return;
117108
118109 DEB_INT("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi);
119110
120111 assert_spin_locked(&dev->slock);
121112 if (!list_empty(&q->queue)) {
122113 /* activate next one from queue */
123− buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
124− list_del(&buf->vb.queue);
114+ buf = list_entry(q->queue.next, struct saa7146_buf, list);
115+ list_del(&buf->list);
125116 if (!list_empty(&q->queue))
126− next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
117+ next = list_entry(q->queue.next, struct saa7146_buf, list);
127118 q->curr = buf;
128119 DEB_INT("next buffer: buf:%p, prev:%p, next:%p\n",
129120 buf, q->queue.prev, q->queue.next);
@@ -171,7 +162,7 @@ void saa7146_buffer_timeout(struct timer_list *t) · 41 unmodified lines
171162 spin_lock_irqsave(&dev->slock,flags);
172163 if (q->curr) {
173164 DEB_D("timeout on %p\n", q->curr);
174− saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR);
165+ saa7146_buffer_finish(dev, q, VB2_BUF_STATE_ERROR);
175166 }
176167
177168 /* we don't restart the transfer here like other drivers do. when
@@ -180,256 +171,39 @@ void saa7146_buffer_timeout(struct timer_list *t) · 2 unmodified lines
180171 we mess up our capture logic. if a timeout occurs on another buffer,
181172 then something is seriously broken before, so no need to buffer the
182173 next capture IMHO... */
183−/*
184− saa7146_buffer_next(dev,q);
185−*/
174+
175+ saa7146_buffer_next(dev, q, 0);
176+
186177 spin_unlock_irqrestore(&dev->slock,flags);
187178 }
188179
189180 /********************************************************************************/
190181 /* file operations */
191182
192−static int fops_open(struct file *file)
183+static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
193184 {
194185 struct video_device *vdev = video_devdata(file);
195186 struct saa7146_dev *dev = video_drvdata(file);
196− struct saa7146_fh *fh = NULL;
197− int result = 0;
198−
199− DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
200−
201− if (mutex_lock_interruptible(vdev->lock))
202− return -ERESTARTSYS;
203−
204− DEB_D("using: %p\n", dev);
205−
206− /* check if an extension is registered */
207− if( NULL == dev->ext ) {
208− DEB_S("no extension registered for this device\n");
209− result = -ENODEV;
210− goto out;
211− }
212−
213− /* allocate per open data */
214− fh = kzalloc(sizeof(*fh),GFP_KERNEL);
215− if (NULL == fh) {
216− DEB_S("cannot allocate memory for per open data\n");
217− result = -ENOMEM;
218− goto out;
219− }
220−
221− v4l2_fh_init(&fh->fh, vdev);
222−
223− file->private_data = &fh->fh;
224− fh->dev = dev;
225−
226− if (vdev->vfl_type == VFL_TYPE_VBI) {
227− DEB_S("initializing vbi...\n");
228− if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
229− result = saa7146_vbi_uops.open(dev,file);
230− if (dev->ext_vv_data->vbi_fops.open)
231− dev->ext_vv_data->vbi_fops.open(file);
232− } else {
233− DEB_S("initializing video...\n");
234− result = saa7146_video_uops.open(dev,file);
235− }
236−
237− if (0 != result) {
238− goto out;
239− }
240−
241− if( 0 == try_module_get(dev->ext->module)) {
242− result = -EINVAL;
243− goto out;
244− }
245−
246− result = 0;
247− v4l2_fh_add(&fh->fh);
248−out:
249− if (fh && result != 0) {
250− kfree(fh);
251− file->private_data = NULL;
252− }
253− mutex_unlock(vdev->lock);
254− return result;
255−}
256−
257−static int fops_release(struct file *file)
258−{
259− struct video_device *vdev = video_devdata(file);
260− struct saa7146_fh *fh = file->private_data;
261− struct saa7146_dev *dev = fh->dev;
262−
263− DEB_EE("file:%p\n", file);
264−
265− mutex_lock(vdev->lock);
266−
267− if (vdev->vfl_type == VFL_TYPE_VBI) {
268− if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
269− saa7146_vbi_uops.release(dev,file);
270− if (dev->ext_vv_data->vbi_fops.release)
271− dev->ext_vv_data->vbi_fops.release(file);
272− } else {
273− saa7146_video_uops.release(dev,file);
274− }
275−
276− v4l2_fh_del(&fh->fh);
277− v4l2_fh_exit(&fh->fh);
278− module_put(dev->ext->module);
279− file->private_data = NULL;
280− kfree(fh);
281−
282− mutex_unlock(vdev->lock);
283−
284− return 0;
285−}
286−
287−static int fops_mmap(struct file *file, struct vm_area_struct * vma)
288−{
289− struct video_device *vdev = video_devdata(file);
290− struct saa7146_fh *fh = file->private_data;
291− struct videobuf_queue *q;
292− int res;
293−
294− switch (vdev->vfl_type) {
295− case VFL_TYPE_VIDEO: {
296− DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",
297− file, vma);
298− q = &fh->video_q;
299− break;
300− }
301− case VFL_TYPE_VBI: {
302− DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",
303− file, vma);
304− if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
305− return -ENODEV;
306− q = &fh->vbi_q;
307− break;
308− }
309− default:
310− BUG();
311− }
187+ int ret;
312188
189+ if (vdev->vfl_type != VFL_TYPE_VBI || !dev->ext_vv_data->vbi_fops.write)
190+ return -EINVAL;
313191 if (mutex_lock_interruptible(vdev->lock))
314192 return -ERESTARTSYS;
315− res = videobuf_mmap_mapper(q, vma);
193+ ret = dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
316194 mutex_unlock(vdev->lock);
317− return res;
318−}
319−
320−static __poll_t __fops_poll(struct file *file, struct poll_table_struct *wait)
321−{
322− struct video_device *vdev = video_devdata(file);
323− struct saa7146_fh *fh = file->private_data;
324− struct videobuf_buffer *buf = NULL;
325− struct videobuf_queue *q;
326− __poll_t res = v4l2_ctrl_poll(file, wait);
327−
328− DEB_EE("file:%p, poll:%p\n", file, wait);
329−
330− if (vdev->vfl_type == VFL_TYPE_VBI) {
331− if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
332− return res | EPOLLOUT | EPOLLWRNORM;
333− if( 0 == fh->vbi_q.streaming )
334− return res | videobuf_poll_stream(file, &fh->vbi_q, wait);
335− q = &fh->vbi_q;
336− } else {
337− DEB_D("using video queue\n");
338− q = &fh->video_q;
339− }
340−
341− if (!list_empty(&q->stream))
342− buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
343−
344− if (!buf) {
345− DEB_D("buf == NULL!\n");
346− return res | EPOLLERR;
347− }
348−
349− poll_wait(file, &buf->done, wait);
350− if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) {
351− DEB_D("poll succeeded!\n");
352− return res | EPOLLIN | EPOLLRDNORM;
353− }
354−
355− DEB_D("nothing to poll for, buf->state:%d\n", buf->state);
356− return res;
357−}
358−
359−static __poll_t fops_poll(struct file *file, struct poll_table_struct *wait)
360−{
361− struct video_device *vdev = video_devdata(file);
362− __poll_t res;
363−
364− mutex_lock(vdev->lock);
365− res = __fops_poll(file, wait);
366− mutex_unlock(vdev->lock);
367− return res;
368−}
369−
370−static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
371−{
372− struct video_device *vdev = video_devdata(file);
373− struct saa7146_fh *fh = file->private_data;
374− int ret;
375−
376− switch (vdev->vfl_type) {
377− case VFL_TYPE_VIDEO:
378−/*
379− DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun",
380− file, data, (unsigned long)count);
381−*/
382− return saa7146_video_uops.read(file,data,count,ppos);
383− case VFL_TYPE_VBI:
384−/*
385− DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
386− file, data, (unsigned long)count);
387−*/
388− if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) {
389− if (mutex_lock_interruptible(vdev->lock))
390− return -ERESTARTSYS;
391− ret = saa7146_vbi_uops.read(file, data, count, ppos);
392− mutex_unlock(vdev->lock);
393− return ret;
394− }
395− return -EINVAL;
396− default:
397− BUG();
398− }
399−}
400−
401−static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
402−{
403− struct video_device *vdev = video_devdata(file);
404− struct saa7146_fh *fh = file->private_data;
405− int ret;
406−
407− switch (vdev->vfl_type) {
408− case VFL_TYPE_VIDEO:
409− return -EINVAL;
410− case VFL_TYPE_VBI:
411− if (fh->dev->ext_vv_data->vbi_fops.write) {
412− if (mutex_lock_interruptible(vdev->lock))
413− return -ERESTARTSYS;
414− ret = fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
415− mutex_unlock(vdev->lock);
416− return ret;
417− }
418− return -EINVAL;
419− default:
420− BUG();
421− }
195+ return ret;
422196 }
423197
424198 static const struct v4l2_file_operations video_fops =
425199 {
426200 .owner = THIS_MODULE,
427− .open = fops_open,
428− .release = fops_release,
429− .read = fops_read,
201+ .open = v4l2_fh_open,
202+ .release = vb2_fop_release,
203+ .read = vb2_fop_read,
430204 .write = fops_write,
431− .poll = fops_poll,
432− .mmap = fops_mmap,
205+ .poll = vb2_fop_poll,
206+ .mmap = vb2_fop_mmap,
433207 .unlocked_ioctl = video_ioctl2,
434208 };
435209
@@ -516,33 +290,15 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) · 80 unmodified lines
516290 configuration data) */
517291 dev->ext_vv_data = ext_vv;
518292
519− vv->d_clipping.cpu_addr =
520− dma_alloc_coherent(&dev->pci->dev, SAA7146_CLIPPING_MEM,
521− &vv->d_clipping.dma_handle, GFP_KERNEL);
522− if( NULL == vv->d_clipping.cpu_addr ) {
523− ERR("out of memory. aborting.\n");
524− kfree(vv);
525− v4l2_ctrl_handler_free(hdl);
526− v4l2_device_unregister(&dev->v4l2_dev);
527− return -ENOMEM;
528− }
529−
530293 saa7146_video_uops.init(dev,vv);
531294 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
532295 saa7146_vbi_uops.init(dev,vv);
533296
534− vv->ov_fb.fmt.width = vv->standard->h_max_out;
535− vv->ov_fb.fmt.height = vv->standard->v_max_out;
536− vv->ov_fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
537− vv->ov_fb.fmt.bytesperline = 2 * vv->ov_fb.fmt.width;
538− vv->ov_fb.fmt.sizeimage = vv->ov_fb.fmt.bytesperline * vv->ov_fb.fmt.height;
539− vv->ov_fb.fmt.colorspace = V4L2_COLORSPACE_SRGB;
540−
541297 fmt = &vv->video_fmt;
542298 fmt->width = 384;
543299 fmt->height = 288;
544300 fmt->pixelformat = V4L2_PIX_FMT_BGR24;
545− fmt->field = V4L2_FIELD_ANY;
301+ fmt->field = V4L2_FIELD_INTERLACED;
546302 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
547303 fmt->bytesperline = 3 * fmt->width;
548304 fmt->sizeimage = fmt->bytesperline * fmt->height;
@@ -561,8 +317,6 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) · 12 unmodified lines
561317
562318 timer_setup(&vv->vbi_read_timeout, NULL, 0);
563319
564− vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING;
565− vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY;
566320 dev->vv_data = vv;
567321 dev->vv_callback = &vv_callback;
568322
@@ -577,8 +331,6 @@ int saa7146_vv_release(struct saa7146_dev* dev) · 8 unmodified lines
577331 DEB_EE("dev:%p\n", dev);
578332
579333 v4l2_device_unregister(&dev->v4l2_dev);
580− dma_free_coherent(&dev->pci->dev, SAA7146_CLIPPING_MEM,
581− vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
582334 v4l2_ctrl_handler_free(&dev->ctrl_handler);
583335 kfree(vv);
584336 dev->vv_data = NULL;
@@ -591,16 +343,20 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release); · 6 unmodified lines
591343 int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
592344 char *name, int type)
593345 {
346+ struct vb2_queue *q;
594347 int err;
595348 int i;
596349
597350 DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);
598351
599352 vfd->fops = &video_fops;
600− if (type == VFL_TYPE_VIDEO)
353+ if (type == VFL_TYPE_VIDEO) {
601354 vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
602− else
355+ q = &dev->vv_data->video_dmaq.q;
356+ } else {
603357 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
358+ q = &dev->vv_data->vbi_dmaq.q;
359+ }
604360 vfd->release = video_device_release_empty;
605361 vfd->lock = &dev->v4l2_lock;
606362 vfd->v4l2_dev = &dev->v4l2_dev;
@@ -608,15 +364,36 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev, · 1 unmodified line
608364 for (i = 0; i < dev->ext_vv_data->num_stds; i++)
609365 vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
610366 strscpy(vfd->name, name, sizeof(vfd->name));
611− vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
367+ vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE |
612368 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
613369 vfd->device_caps |= dev->ext_vv_data->capabilities;
614− if (type == VFL_TYPE_VIDEO)
370+ if (type == VFL_TYPE_VIDEO) {
615371 vfd->device_caps &=
616372 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
617− else
618− vfd->device_caps &=
619− ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
373+ } else if (vfd->device_caps & V4L2_CAP_SLICED_VBI_OUTPUT) {
374+ vfd->vfl_dir = VFL_DIR_TX;
375+ vfd->device_caps &= ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
376+ V4L2_CAP_AUDIO | V4L2_CAP_TUNER);
377+ } else {
378+ vfd->device_caps &= ~V4L2_CAP_VIDEO_CAPTURE;
379+ }
380+
381+ q->type = type == VFL_TYPE_VIDEO ? V4L2_BUF_TYPE_VIDEO_CAPTURE : V4L2_BUF_TYPE_VBI_CAPTURE;
382+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
383+ q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
384+ q->ops = type == VFL_TYPE_VIDEO ? &video_qops : &vbi_qops;
385+ q->mem_ops = &vb2_dma_sg_memops;
386+ q->drv_priv = dev;
387+ q->gfp_flags = __GFP_DMA32;
388+ q->buf_struct_size = sizeof(struct saa7146_buf);
389+ q->lock = &dev->v4l2_lock;
390+ q->min_buffers_needed = 2;
391+ q->dev = &dev->pci->dev;
392+ err = vb2_queue_init(q);
393+ if (err)
394+ return err;
395+ vfd->queue = q;
396+
620397 video_set_drvdata(vfd, dev);
621398
622399 err = video_register_device(vfd, type, -1);
drivers/media/common/saa7146/saa7146_hlp.c+40−315
@@ -306,221 +306,6 @@ static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field · 305 unmodified lines
306306 }
307307
308308 /* simple bubble-sort algorithm with duplicate elimination */
309−static int sort_and_eliminate(u32* values, int* count)
310−{
311− int low = 0, high = 0, top = 0;
312− int cur = 0, next = 0;
313−
314− /* sanity checks */
315− if( (0 > *count) || (NULL == values) ) {
316− return -EINVAL;
317− }
318−
319− /* bubble sort the first @count items of the array @values */
320− for( top = *count; top > 0; top--) {
321− for( low = 0, high = 1; high < top; low++, high++) {
322− if( values[low] > values[high] )
323− swap(values[low], values[high]);
324− }
325− }
326−
327− /* remove duplicate items */
328− for( cur = 0, next = 1; next < *count; next++) {
329− if( values[cur] != values[next])
330− values[++cur] = values[next];
331− }
332−
333− *count = cur + 1;
334−
335− return 0;
336−}
337−
338−static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh,
339− struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field)
340−{
341− struct saa7146_vv *vv = dev->vv_data;
342− __le32 *clipping = vv->d_clipping.cpu_addr;
343−
344− int width = vv->ov.win.w.width;
345− int height = vv->ov.win.w.height;
346− int clipcount = vv->ov.nclips;
347−
348− u32 line_list[32];
349− u32 pixel_list[32];
350− int numdwords = 0;
351−
352− int i = 0, j = 0;
353− int cnt_line = 0, cnt_pixel = 0;
354−
355− int x[32], y[32], w[32], h[32];
356−
357− /* clear out memory */
358− memset(&line_list[0], 0x00, sizeof(u32)*32);
359− memset(&pixel_list[0], 0x00, sizeof(u32)*32);
360− memset(clipping, 0x00, SAA7146_CLIPPING_MEM);
361−
362− /* fill the line and pixel-lists */
363− for(i = 0; i < clipcount; i++) {
364− int l = 0, r = 0, t = 0, b = 0;
365−
366− x[i] = vv->ov.clips[i].c.left;
367− y[i] = vv->ov.clips[i].c.top;
368− w[i] = vv->ov.clips[i].c.width;
369− h[i] = vv->ov.clips[i].c.height;
370−
371− if( w[i] < 0) {
372− x[i] += w[i]; w[i] = -w[i];
373− }
374− if( h[i] < 0) {
375− y[i] += h[i]; h[i] = -h[i];
376− }
377− if( x[i] < 0) {
378− w[i] += x[i]; x[i] = 0;
379− }
380− if( y[i] < 0) {
381− h[i] += y[i]; y[i] = 0;
382− }
383− if( 0 != vv->vflip ) {
384− y[i] = height - y[i] - h[i];
385− }
386−
387− l = x[i];
388− r = x[i]+w[i];
389− t = y[i];
390− b = y[i]+h[i];
391−
392− /* insert left/right coordinates */
393− pixel_list[ 2*i ] = min_t(int, l, width);
394− pixel_list[(2*i)+1] = min_t(int, r, width);
395− /* insert top/bottom coordinates */
396− line_list[ 2*i ] = min_t(int, t, height);
397− line_list[(2*i)+1] = min_t(int, b, height);
398− }
399−
400− /* sort and eliminate lists */
401− cnt_line = cnt_pixel = 2*clipcount;
402− sort_and_eliminate( &pixel_list[0], &cnt_pixel );
403− sort_and_eliminate( &line_list[0], &cnt_line );
404−
405− /* calculate the number of used u32s */
406− numdwords = max_t(int, (cnt_line+1), (cnt_pixel+1))*2;
407− numdwords = max_t(int, 4, numdwords);
408− numdwords = min_t(int, 64, numdwords);
409−
410− /* fill up cliptable */
411− for(i = 0; i < cnt_pixel; i++) {
412− clipping[2*i] |= cpu_to_le32(pixel_list[i] << 16);
413− }
414− for(i = 0; i < cnt_line; i++) {
415− clipping[(2*i)+1] |= cpu_to_le32(line_list[i] << 16);
416− }
417−
418− /* fill up cliptable with the display infos */
419− for(j = 0; j < clipcount; j++) {
420−
421− for(i = 0; i < cnt_pixel; i++) {
422−
423− if( x[j] < 0)
424− x[j] = 0;
425−
426− if( pixel_list[i] < (x[j] + w[j])) {
427−
428− if ( pixel_list[i] >= x[j] ) {
429− clipping[2*i] |= cpu_to_le32(1 << j);
430− }
431− }
432− }
433− for(i = 0; i < cnt_line; i++) {
434−
435− if( y[j] < 0)
436− y[j] = 0;
437−
438− if( line_list[i] < (y[j] + h[j]) ) {
439−
440− if( line_list[i] >= y[j] ) {
441− clipping[(2*i)+1] |= cpu_to_le32(1 << j);
442− }
443− }
444− }
445− }
446−
447− /* adjust arbitration control register */
448− *arbtr_ctrl &= 0xffff00ff;
449− *arbtr_ctrl |= 0x00001c00;
450−
451− vdma2->base_even = vv->d_clipping.dma_handle;
452− vdma2->base_odd = vv->d_clipping.dma_handle;
453− vdma2->prot_addr = vv->d_clipping.dma_handle+((sizeof(u32))*(numdwords));
454− vdma2->base_page = 0x04;
455− vdma2->pitch = 0x00;
456− vdma2->num_line_byte = (0 << 16 | (sizeof(u32))*(numdwords-1) );
457−
458− /* set clipping-mode. this depends on the field(s) used */
459− *clip_format &= 0xfffffff7;
460− if (V4L2_FIELD_HAS_BOTH(field)) {
461− *clip_format |= 0x00000008;
462− } else {
463− *clip_format |= 0x00000000;
464− }
465−}
466−
467−/* disable clipping */
468−static void saa7146_disable_clipping(struct saa7146_dev *dev)
469−{
470− u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
471−
472− /* mask out relevant bits (=lower word)*/
473− clip_format &= MASK_W1;
474−
475− /* upload clipping-registers*/
476− saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format);
477− saa7146_write(dev, MC2, (MASK_05 | MASK_21));
478−
479− /* disable video dma2 */
480− saa7146_write(dev, MC1, MASK_21);
481−}
482−
483−static void saa7146_set_clipping_rect(struct saa7146_fh *fh)
484−{
485− struct saa7146_dev *dev = fh->dev;
486− struct saa7146_vv *vv = dev->vv_data;
487− enum v4l2_field field = vv->ov.win.field;
488− struct saa7146_video_dma vdma2;
489− u32 clip_format;
490− u32 arbtr_ctrl;
491−
492− /* check clipcount, disable clipping if clipcount == 0*/
493− if (vv->ov.nclips == 0) {
494− saa7146_disable_clipping(dev);
495− return;
496− }
497−
498− clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
499− arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
500−
501− calculate_clipping_registers_rect(dev, fh, &vdma2, &clip_format, &arbtr_ctrl, field);
502−
503− /* set clipping format */
504− clip_format &= 0xffff0008;
505− clip_format |= (SAA7146_CLIPPING_RECT << 4);
506−
507− /* prepare video dma2 */
508− saa7146_write(dev, BASE_EVEN2, vdma2.base_even);
509− saa7146_write(dev, BASE_ODD2, vdma2.base_odd);
510− saa7146_write(dev, PROT_ADDR2, vdma2.prot_addr);
511− saa7146_write(dev, BASE_PAGE2, vdma2.base_page);
512− saa7146_write(dev, PITCH2, vdma2.pitch);
513− saa7146_write(dev, NUM_LINE_BYTE2, vdma2.num_line_byte);
514−
515− /* prepare the rest */
516− saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format);
517− saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
518−
519− /* upload clip_control-register, clipping-registers, enable video dma2 */
520− saa7146_write(dev, MC2, (MASK_05 | MASK_21 | MASK_03 | MASK_19));
521− saa7146_write(dev, MC1, (MASK_05 | MASK_21));
522−}
523−
524309 static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field)
525310 {
526311 struct saa7146_vv *vv = dev->vv_data;
@@ -556,62 +341,6 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e · 29 unmodified lines
556341 saa7146_write(dev, MC2, (MASK_05 | MASK_06 | MASK_21 | MASK_22) );
557342 }
558343
559−/* calculate the new memory offsets for a desired position */
560−static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
561−{
562− struct saa7146_vv *vv = dev->vv_data;
563− struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
564−
565− int b_depth = vv->ov_fmt->depth;
566− int b_bpl = vv->ov_fb.fmt.bytesperline;
567− /* The unsigned long cast is to remove a 64-bit compile warning since
568− it looks like a 64-bit address is cast to a 32-bit value, even
569− though the base pointer is really a 32-bit physical address that
570− goes into a 32-bit DMA register.
571− FIXME: might not work on some 64-bit platforms, but see the FIXME
572− in struct v4l2_framebuffer (videodev2.h) for that.
573− */
574− u32 base = (u32)(unsigned long)vv->ov_fb.base;
575−
576− struct saa7146_video_dma vdma1;
577−
578− /* calculate memory offsets for picture, look if we shall top-down-flip */
579− vdma1.pitch = 2*b_bpl;
580− if ( 0 == vv->vflip ) {
581− vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
582− vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2);
583− vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2));
584− }
585− else {
586− vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
587− vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2);
588− vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2));
589− }
590−
591− if (V4L2_FIELD_HAS_BOTH(field)) {
592− } else if (field == V4L2_FIELD_ALTERNATE) {
593− /* fixme */
594− vdma1.base_odd = vdma1.prot_addr;
595− vdma1.pitch /= 2;
596− } else if (field == V4L2_FIELD_TOP) {
597− vdma1.base_odd = vdma1.prot_addr;
598− vdma1.pitch /= 2;
599− } else if (field == V4L2_FIELD_BOTTOM) {
600− vdma1.base_odd = vdma1.base_even;
601− vdma1.base_even = vdma1.prot_addr;
602− vdma1.pitch /= 2;
603− }
604−
605− if ( 0 != vv->vflip ) {
606− vdma1.pitch *= -1;
607− }
608−
609− vdma1.base_page = sfmt->swap;
610− vdma1.num_line_byte = (vv->standard->v_field<<16)+vv->standard->h_pixels;
611−
612− saa7146_write_out_dma(dev, 1, &vdma1);
613−}
614−
615344 static void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette)
616345 {
617346 u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
@@ -645,30 +374,6 @@ void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sy · 27 unmodified lines
645374 }
646375 EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
647376
648−int saa7146_enable_overlay(struct saa7146_fh *fh)
649−{
650− struct saa7146_dev *dev = fh->dev;
651− struct saa7146_vv *vv = dev->vv_data;
652−
653− saa7146_set_window(dev, vv->ov.win.w.width, vv->ov.win.w.height, vv->ov.win.field);
654− saa7146_set_position(dev, vv->ov.win.w.left, vv->ov.win.w.top, vv->ov.win.w.height, vv->ov.win.field, vv->ov_fmt->pixelformat);
655− saa7146_set_output_format(dev, vv->ov_fmt->trans);
656− saa7146_set_clipping_rect(fh);
657−
658− /* enable video dma1 */
659− saa7146_write(dev, MC1, (MASK_06 | MASK_22));
660− return 0;
661−}
662−
663−void saa7146_disable_overlay(struct saa7146_fh *fh)
664−{
665− struct saa7146_dev *dev = fh->dev;
666−
667− /* disable clipping + video dma1 */
668− saa7146_disable_clipping(dev);
669− saa7146_write(dev, MC1, MASK_22);
670−}
671−
672377 void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma)
673378 {
674379 int where = 0;
@@ -702,14 +407,14 @@ void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_vi · 27 unmodified lines
702407 static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf)
703408 {
704409 struct saa7146_vv *vv = dev->vv_data;
410+ struct v4l2_pix_format *pix = &vv->video_fmt;
705411 struct saa7146_video_dma vdma1;
412+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pix->pixelformat);
706413
707− struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
708−
709− int width = buf->fmt->width;
710− int height = buf->fmt->height;
711− int bytesperline = buf->fmt->bytesperline;
712− enum v4l2_field field = buf->fmt->field;
414+ int width = pix->width;
415+ int height = pix->height;
416+ int bytesperline = pix->bytesperline;
417+ enum v4l2_field field = pix->field;
713418
714419 int depth = sfmt->depth;
715420
@@ -764,8 +469,9 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71 · 48 unmodified lines
764469
765470 static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3)
766471 {
767− int height = buf->fmt->height;
768− int width = buf->fmt->width;
472+ struct v4l2_pix_format *pix = &vv->video_fmt;
473+ int height = pix->height;
474+ int width = pix->width;
769475
770476 vdma2->pitch = width;
771477 vdma3->pitch = width;
@@ -795,8 +501,9 @@ static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struc · 23 unmodified lines
795501
796502 static int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3)
797503 {
798− int height = buf->fmt->height;
799− int width = buf->fmt->width;
504+ struct v4l2_pix_format *pix = &vv->video_fmt;
505+ int height = pix->height;
506+ int width = pix->width;
800507
801508 vdma2->pitch = width/2;
802509 vdma3->pitch = width/2;
@@ -825,19 +532,20 @@ static int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struc · 22 unmodified lines
825532 static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf)
826533 {
827534 struct saa7146_vv *vv = dev->vv_data;
535+ struct v4l2_pix_format *pix = &vv->video_fmt;
828536 struct saa7146_video_dma vdma1;
829537 struct saa7146_video_dma vdma2;
830538 struct saa7146_video_dma vdma3;
539+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pix->pixelformat);
831540
832− struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
541+ int width = pix->width;
542+ int height = pix->height;
543+ enum v4l2_field field = pix->field;
833544
834− int width = buf->fmt->width;
835− int height = buf->fmt->height;
836− enum v4l2_field field = buf->fmt->field;
837−
838− BUG_ON(0 == buf->pt[0].dma);
839− BUG_ON(0 == buf->pt[1].dma);
840− BUG_ON(0 == buf->pt[2].dma);
545+ if (WARN_ON(!buf->pt[0].dma) ||
546+ WARN_ON(!buf->pt[1].dma) ||
547+ WARN_ON(!buf->pt[2].dma))
548+ return -1;
841549
842550 DEB_CAP("[size=%dx%d,fields=%s]\n",
843551 width, height, v4l2_field_names[field]);
@@ -994,10 +702,27 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar) · 150 unmodified lines
994702 WRITE_RPS0(CMD_STOP);
995703 }
996704
705+/* disable clipping */
706+static void saa7146_disable_clipping(struct saa7146_dev *dev)
707+{
708+ u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
709+
710+ /* mask out relevant bits (=lower word)*/
711+ clip_format &= MASK_W1;
712+
713+ /* upload clipping-registers*/
714+ saa7146_write(dev, CLIP_FORMAT_CTRL, clip_format);
715+ saa7146_write(dev, MC2, (MASK_05 | MASK_21));
716+
717+ /* disable video dma2 */
718+ saa7146_write(dev, MC1, MASK_21);
719+}
720+
997721 void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
998722 {
999− struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1000723 struct saa7146_vv *vv = dev->vv_data;
724+ struct v4l2_pix_format *pix = &vv->video_fmt;
725+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pix->pixelformat);
1001726 u32 vdma1_prot_addr;
1002727
1003728 DEB_CAP("buf:%p, next:%p\n", buf, next);
@@ -1009,7 +734,7 @@ void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struc · 5 unmodified lines
1009734 saa7146_write(dev, MC2, MASK_27 );
1010735 }
1011736
1012− saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field);
737+ saa7146_set_window(dev, pix->width, pix->height, pix->field);
1013738 saa7146_set_output_format(dev, sfmt->trans);
1014739 saa7146_disable_clipping(dev);
1015740
drivers/media/common/saa7146/saa7146_vbi.c+118−169
@@ -207,7 +207,6 @@ static int buffer_activate(struct saa7146_dev *dev, · 206 unmodified lines
207207 struct saa7146_buf *next)
208208 {
209209 struct saa7146_vv *vv = dev->vv_data;
210− buf->vb.state = VIDEOBUF_ACTIVE;
211210
212211 DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
213212 saa7146_set_vbi_capture(dev,buf,next);
@@ -216,114 +215,101 @@ static int buffer_activate(struct saa7146_dev *dev, · 2 unmodified lines
216215 return 0;
217216 }
218217
219−static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
220−{
221− struct file *file = q->priv_data;
222− struct saa7146_fh *fh = file->private_data;
223− struct saa7146_dev *dev = fh->dev;
224− struct saa7146_buf *buf = (struct saa7146_buf *)vb;
218+/* ------------------------------------------------------------------ */
225219
226− int err = 0;
227− int lines, llength, size;
220+static int queue_setup(struct vb2_queue *q,
221+ unsigned int *num_buffers, unsigned int *num_planes,
222+ unsigned int sizes[], struct device *alloc_devs[])
223+{
224+ unsigned int size = 16 * 2 * vbi_pixel_to_capture;
228225
229− lines = 16 * 2 ; /* 2 fields */
230− llength = vbi_pixel_to_capture;
231− size = lines * llength;
226+ if (*num_planes)
227+ return sizes[0] < size ? -EINVAL : 0;
228+ *num_planes = 1;
229+ sizes[0] = size;
232230
233− DEB_VBI("vb:%p\n", vb);
231+ return 0;
232+}
234233
235− if (0 != buf->vb.baddr && buf->vb.bsize < size) {
236− DEB_VBI("size mismatch\n");
237− return -EINVAL;
238− }
234+static void buf_queue(struct vb2_buffer *vb)
235+{
236+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
237+ struct vb2_queue *vq = vb->vb2_queue;
238+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
239+ struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb);
240+ unsigned long flags;
239241
240− if (buf->vb.size != size)
241− saa7146_dma_free(dev,q,buf);
242+ spin_lock_irqsave(&dev->slock, flags);
242243
243− if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
244− struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
244+ saa7146_buffer_queue(dev, &dev->vv_data->vbi_dmaq, buf);
245+ spin_unlock_irqrestore(&dev->slock, flags);
246+}
245247
246− buf->vb.width = llength;
247− buf->vb.height = lines;
248− buf->vb.size = size;
249− buf->vb.field = field; // FIXME: check this
248+static int buf_init(struct vb2_buffer *vb)
249+{
250+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
251+ struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb);
252+ struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0);
253+ struct scatterlist *list = sgt->sgl;
254+ int length = sgt->nents;
255+ struct vb2_queue *vq = vb->vb2_queue;
256+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
257+ int ret;
250258
251− saa7146_pgtable_free(dev->pci, &buf->pt[2]);
252− saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
253−
254− err = videobuf_iolock(q,&buf->vb, NULL);
255− if (err)
256− goto oops;
257− err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
258− dma->sglist, dma->sglen);
259− if (0 != err)
260− return err;
261− }
262− buf->vb.state = VIDEOBUF_PREPARED;
263259 buf->activate = buffer_activate;
264260
265− return 0;
266−
267− oops:
268− DEB_VBI("error out\n");
269− saa7146_dma_free(dev,q,buf);
261+ saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
270262
271− return err;
263+ ret = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
264+ list, length);
265+ if (ret)
266+ saa7146_pgtable_free(dev->pci, &buf->pt[2]);
267+ return ret;
272268 }
273269
274−static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
270+static int buf_prepare(struct vb2_buffer *vb)
275271 {
276− int llength,lines;
277−
278− lines = 16 * 2 ; /* 2 fields */
279− llength = vbi_pixel_to_capture;
280−
281− *size = lines * llength;
282− *count = 2;
283−
284− DEB_VBI("count:%d, size:%d\n", *count, *size);
272+ unsigned int size = 16 * 2 * vbi_pixel_to_capture;
285273
274+ if (vb2_plane_size(vb, 0) < size)
275+ return -EINVAL;
276+ vb2_set_plane_payload(vb, 0, size);
286277 return 0;
287278 }
288279
289−static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
280+static void buf_cleanup(struct vb2_buffer *vb)
290281 {
291− struct file *file = q->priv_data;
292− struct saa7146_fh *fh = file->private_data;
293− struct saa7146_dev *dev = fh->dev;
294− struct saa7146_vv *vv = dev->vv_data;
295− struct saa7146_buf *buf = (struct saa7146_buf *)vb;
282+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
283+ struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb);
284+ struct vb2_queue *vq = vb->vb2_queue;
285+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
296286
297− DEB_VBI("vb:%p\n", vb);
298− saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
287+ saa7146_pgtable_free(dev->pci, &buf->pt[2]);
299288 }
300289
301−static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
290+static void return_buffers(struct vb2_queue *q, int state)
302291 {
303− struct file *file = q->priv_data;
304− struct saa7146_fh *fh = file->private_data;
305− struct saa7146_dev *dev = fh->dev;
306− struct saa7146_buf *buf = (struct saa7146_buf *)vb;
307−
308− DEB_VBI("vb:%p\n", vb);
309− saa7146_dma_free(dev,q,buf);
292+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
293+ struct saa7146_dmaqueue *dq = &dev->vv_data->vbi_dmaq;
294+ struct saa7146_buf *buf;
295+
296+ if (dq->curr) {
297+ buf = dq->curr;
298+ dq->curr = NULL;
299+ vb2_buffer_done(&buf->vb.vb2_buf, state);
300+ }
301+ while (!list_empty(&dq->queue)) {
302+ buf = list_entry(dq->queue.next, struct saa7146_buf, list);
303+ list_del(&buf->list);
304+ vb2_buffer_done(&buf->vb.vb2_buf, state);
305+ }
310306 }
311307
312−static const struct videobuf_queue_ops vbi_qops = {
313− .buf_setup = buffer_setup,
314− .buf_prepare = buffer_prepare,
315− .buf_queue = buffer_queue,
316− .buf_release = buffer_release,
317−};
318−
319−/* ------------------------------------------------------------------ */
320−
321−static void vbi_stop(struct saa7146_fh *fh, struct file *file)
308+static void vbi_stop(struct saa7146_dev *dev)
322309 {
323− struct saa7146_dev *dev = fh->dev;
324310 struct saa7146_vv *vv = dev->vv_data;
325311 unsigned long flags;
326− DEB_VBI("dev:%p, fh:%p\n", dev, fh);
312+ DEB_VBI("dev:%p\n", dev);
327313
328314 spin_lock_irqsave(&dev->slock,flags);
329315
@@ -336,13 +322,6 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file) · 6 unmodified lines
336322 /* shut down dma 3 transfers */
337323 saa7146_write(dev, MC1, MASK_20);
338324
339− if (vv->vbi_dmaq.curr)
340− saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
341−
342− videobuf_queue_cancel(&fh->vbi_q);
343−
344− vv->vbi_streaming = NULL;
345−
346325 del_timer(&vv->vbi_dmaq.timeout);
347326 del_timer(&vv->vbi_read_timeout);
348327
@@ -352,38 +331,22 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file) · 3 unmodified lines
352331 static void vbi_read_timeout(struct timer_list *t)
353332 {
354333 struct saa7146_vv *vv = from_timer(vv, t, vbi_read_timeout);
355− struct file *file = vv->vbi_read_timeout_file;
356− struct saa7146_fh *fh = file->private_data;
357− struct saa7146_dev *dev = fh->dev;
358−
359− DEB_VBI("dev:%p, fh:%p\n", dev, fh);
334+ struct saa7146_dev *dev = vv->vbi_dmaq.dev;
360335
361− vbi_stop(fh, file);
362−}
363−
364−static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
365−{
366336 DEB_VBI("dev:%p\n", dev);
367337
368− INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
369−
370− timer_setup(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout, 0);
371− vv->vbi_dmaq.dev = dev;
372−
373− init_waitqueue_head(&vv->vbi_wq);
338+ vbi_stop(dev);
374339 }
375340
376−static int vbi_open(struct saa7146_dev *dev, struct file *file)
341+static int vbi_begin(struct saa7146_dev *dev)
377342 {
378− struct saa7146_fh *fh = file->private_data;
379− struct saa7146_vv *vv = fh->dev->vv_data;
380−
343+ struct saa7146_vv *vv = dev->vv_data;
381344 u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
382345 int ret = 0;
383346
384− DEB_VBI("dev:%p, fh:%p\n", dev, fh);
347+ DEB_VBI("dev:%p\n", dev);
385348
386− ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
349+ ret = saa7146_res_get(dev, RESOURCE_DMA3_BRS);
387350 if (0 == ret) {
388351 DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n");
389352 return -EBUSY;
@@ -395,15 +358,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) · 5 unmodified lines
395358 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
396359 saa7146_write(dev, MC2, (MASK_04|MASK_20));
397360
398− videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
399− &dev->pci->dev, &dev->slock,
400− V4L2_BUF_TYPE_VBI_CAPTURE,
401− V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
402− sizeof(struct saa7146_buf),
403− file, &dev->v4l2_lock);
404−
405361 vv->vbi_read_timeout.function = vbi_read_timeout;
406− vv->vbi_read_timeout_file = file;
407362
408363 /* initialize the brs */
409364 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
@@ -422,16 +377,52 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) · 12 unmodified lines
422377 return 0;
423378 }
424379
425−static void vbi_close(struct saa7146_dev *dev, struct file *file)
380+static int start_streaming(struct vb2_queue *q, unsigned int count)
426381 {
427− struct saa7146_fh *fh = file->private_data;
428− struct saa7146_vv *vv = dev->vv_data;
429− DEB_VBI("dev:%p, fh:%p\n", dev, fh);
382+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
383+ int ret;
384+
385+ if (!vb2_is_streaming(&dev->vv_data->vbi_dmaq.q))
386+ dev->vv_data->seqnr = 0;
387+ ret = vbi_begin(dev);
388+ if (ret)
389+ return_buffers(q, VB2_BUF_STATE_QUEUED);
390+ return ret;
391+}
430392
431− if( fh == vv->vbi_streaming ) {
432− vbi_stop(fh, file);
433− }
434− saa7146_res_free(fh, RESOURCE_DMA3_BRS);
393+static void stop_streaming(struct vb2_queue *q)
394+{
395+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
396+
397+ vbi_stop(dev);
398+ return_buffers(q, VB2_BUF_STATE_ERROR);
399+ saa7146_res_free(dev, RESOURCE_DMA3_BRS);
400+}
401+
402+const struct vb2_ops vbi_qops = {
403+ .queue_setup = queue_setup,
404+ .buf_queue = buf_queue,
405+ .buf_init = buf_init,
406+ .buf_prepare = buf_prepare,
407+ .buf_cleanup = buf_cleanup,
408+ .start_streaming = start_streaming,
409+ .stop_streaming = stop_streaming,
410+ .wait_prepare = vb2_ops_wait_prepare,
411+ .wait_finish = vb2_ops_wait_finish,
412+};
413+
414+/* ------------------------------------------------------------------ */
415+
416+static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
417+{
418+ DEB_VBI("dev:%p\n", dev);
419+
420+ INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
421+
422+ timer_setup(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout, 0);
423+ vv->vbi_dmaq.dev = dev;
424+
425+ init_waitqueue_head(&vv->vbi_wq);
435426 }
436427
437428 static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
@@ -441,10 +432,7 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) · 3 unmodified lines
441432
442433 if (vv->vbi_dmaq.curr) {
443434 DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
444− /* this must be += 2, one count for each field */
445− vv->vbi_fieldcount+=2;
446− vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
447− saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
435+ saa7146_buffer_finish(dev, &vv->vbi_dmaq, VB2_BUF_STATE_DONE);
448436 } else {
449437 DEB_VBI("dev:%p\n", dev);
450438 }
@@ -453,46 +441,7 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) · 2 unmodified lines
453441 spin_unlock(&dev->slock);
454442 }
455443
456−static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
457−{
458− struct saa7146_fh *fh = file->private_data;
459− struct saa7146_dev *dev = fh->dev;
460− struct saa7146_vv *vv = dev->vv_data;
461− ssize_t ret = 0;
462−
463− DEB_VBI("dev:%p, fh:%p\n", dev, fh);
464−
465− if( NULL == vv->vbi_streaming ) {
466− // fixme: check if dma3 is available
467− // fixme: activate vbi engine here if necessary. (really?)
468− vv->vbi_streaming = fh;
469− }
470−
471− if( fh != vv->vbi_streaming ) {
472− DEB_VBI("open %p is already using vbi capture\n",
473− vv->vbi_streaming);
474− return -EBUSY;
475− }
476−
477− mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
478− ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
479− file->f_flags & O_NONBLOCK);
480−/*
481− printk("BASE_ODD3: 0x%08x\n", saa7146_read(dev, BASE_ODD3));
482− printk("BASE_EVEN3: 0x%08x\n", saa7146_read(dev, BASE_EVEN3));
483− printk("PROT_ADDR3: 0x%08x\n", saa7146_read(dev, PROT_ADDR3));
484− printk("PITCH3: 0x%08x\n", saa7146_read(dev, PITCH3));
485− printk("BASE_PAGE3: 0x%08x\n", saa7146_read(dev, BASE_PAGE3));
486− printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
487− printk("BRS_CTRL: 0x%08x\n", saa7146_read(dev, BRS_CTRL));
488−*/
489− return ret;
490−}
491−
492444 const struct saa7146_use_ops saa7146_vbi_uops = {
493445 .init = vbi_init,
494− .open = vbi_open,
495− .release = vbi_close,
496446 .irq_done = vbi_irq_done,
497− .read = vbi_read,
498447 };
drivers/media/common/saa7146/saa7146_video.c+199−760
@@ -6,17 +6,6 @@ · 5 unmodified lines
66 #include <linux/module.h>
77 #include <linux/kernel.h>
88
9−static int max_memory = 32;
10−
11−module_param(max_memory, int, 0644);
12−MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)");
13−
14−#define IS_CAPTURE_ACTIVE(fh) \
15− (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh))
16−
17−#define IS_OVERLAY_ACTIVE(fh) \
18− (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh))
19−
209 /* format descriptions for capture and preview */
2110 static struct saa7146_format formats[] = {
2211 {
@@ -54,7 +43,7 @@ static struct saa7146_format formats[] = { · 31 unmodified lines
5443 .pixelformat = V4L2_PIX_FMT_YUV422P,
5544 .trans = YUV422_DECOMPOSED,
5645 .depth = 16,
57− .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
46+ .flags = FORMAT_IS_PLANAR,
5847 }, {
5948 .pixelformat = V4L2_PIX_FMT_YVU420,
6049 .trans = YUV420_DECOMPOSED,
@@ -91,115 +80,18 @@ struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fou · 30 unmodified lines
9180 return NULL;
9281 }
9382
94−static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
95−
96−int saa7146_start_preview(struct saa7146_fh *fh)
97−{
98− struct saa7146_dev *dev = fh->dev;
99− struct saa7146_vv *vv = dev->vv_data;
100− struct v4l2_format fmt;
101− int ret = 0, err = 0;
102−
103− DEB_EE("dev:%p, fh:%p\n", dev, fh);
104−
105− /* check if we have overlay information */
106− if (vv->ov.fh == NULL) {
107− DEB_D("no overlay data available. try S_FMT first.\n");
108− return -EAGAIN;
109− }
110−
111− /* check if streaming capture is running */
112− if (IS_CAPTURE_ACTIVE(fh) != 0) {
113− DEB_D("streaming capture is active\n");
114− return -EBUSY;
115− }
116−
117− /* check if overlay is running */
118− if (IS_OVERLAY_ACTIVE(fh) != 0) {
119− if (vv->video_fh == fh) {
120− DEB_D("overlay is already active\n");
121− return 0;
122− }
123− DEB_D("overlay is already active in another open\n");
124− return -EBUSY;
125− }
126−
127− if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
128− DEB_D("cannot get necessary overlay resources\n");
129− return -EBUSY;
130− }
131−
132− fmt.fmt.win = vv->ov.win;
133− err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
134− if (0 != err) {
135− saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
136− return -EBUSY;
137− }
138− vv->ov.win = fmt.fmt.win;
139−
140− DEB_D("%dx%d+%d+%d 0x%08x field=%s\n",
141− vv->ov.win.w.width, vv->ov.win.w.height,
142− vv->ov.win.w.left, vv->ov.win.w.top,
143− vv->ov_fmt->pixelformat, v4l2_field_names[vv->ov.win.field]);
144−
145− if (0 != (ret = saa7146_enable_overlay(fh))) {
146− DEB_D("enabling overlay failed: %d\n", ret);
147− saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
148− return ret;
149− }
150−
151− vv->video_status = STATUS_OVERLAY;
152− vv->video_fh = fh;
153−
154− return 0;
155−}
156−EXPORT_SYMBOL_GPL(saa7146_start_preview);
157−
158−int saa7146_stop_preview(struct saa7146_fh *fh)
159−{
160− struct saa7146_dev *dev = fh->dev;
161− struct saa7146_vv *vv = dev->vv_data;
162−
163− DEB_EE("dev:%p, fh:%p\n", dev, fh);
164−
165− /* check if streaming capture is running */
166− if (IS_CAPTURE_ACTIVE(fh) != 0) {
167− DEB_D("streaming capture is active\n");
168− return -EBUSY;
169− }
170−
171− /* check if overlay is running at all */
172− if ((vv->video_status & STATUS_OVERLAY) == 0) {
173− DEB_D("no active overlay\n");
174− return 0;
175− }
176−
177− if (vv->video_fh != fh) {
178− DEB_D("overlay is active, but in another open\n");
179− return -EBUSY;
180− }
181−
182− vv->video_status = 0;
183− vv->video_fh = NULL;
184−
185− saa7146_disable_overlay(fh);
186−
187− saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
188−
189− return 0;
190−}
191−EXPORT_SYMBOL_GPL(saa7146_stop_preview);
192−
19383 /********************************************************************************/
19484 /* common pagetable functions */
19585
19686 static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
19787 {
88+ struct saa7146_vv *vv = dev->vv_data;
19889 struct pci_dev *pci = dev->pci;
199− struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
200− struct scatterlist *list = dma->sglist;
201− int length = dma->sglen;
202− struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
90+ struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0);
91+ struct scatterlist *list = sgt->sgl;
92+ int length = sgt->nents;
93+ struct v4l2_pix_format *pix = &vv->video_fmt;
94+ struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pix->pixelformat);
20395
20496 DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev, buf, length);
20597
@@ -207,31 +99,32 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu · 1 unmodified line
20799 struct saa7146_pgtable *pt1 = &buf->pt[0];
208100 struct saa7146_pgtable *pt2 = &buf->pt[1];
209101 struct saa7146_pgtable *pt3 = &buf->pt[2];
102+ struct sg_dma_page_iter dma_iter;
210103 __le32 *ptr1, *ptr2, *ptr3;
211104 __le32 fill;
212105
213− int size = buf->fmt->width*buf->fmt->height;
214− int i,p,m1,m2,m3,o1,o2;
106+ int size = pix->width * pix->height;
107+ int i, m1, m2, m3, o1, o2;
215108
216109 switch( sfmt->depth ) {
217110 case 12: {
218111 /* create some offsets inside the page table */
219− m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
220− m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1;
221− m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
222− o1 = size%PAGE_SIZE;
223− o2 = (size+(size/4))%PAGE_SIZE;
112+ m1 = ((size + PAGE_SIZE) / PAGE_SIZE) - 1;
113+ m2 = ((size + (size / 4) + PAGE_SIZE) / PAGE_SIZE) - 1;
114+ m3 = ((size + (size / 2) + PAGE_SIZE) / PAGE_SIZE) - 1;
115+ o1 = size % PAGE_SIZE;
116+ o2 = (size + (size / 4)) % PAGE_SIZE;
224117 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",
225118 size, m1, m2, m3, o1, o2);
226119 break;
227120 }
228121 case 16: {
229122 /* create some offsets inside the page table */
230− m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
231− m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
232− m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
233− o1 = size%PAGE_SIZE;
234− o2 = (size+(size/2))%PAGE_SIZE;
123+ m1 = ((size + PAGE_SIZE) / PAGE_SIZE) - 1;
124+ m2 = ((size + (size / 2) + PAGE_SIZE) / PAGE_SIZE) - 1;
125+ m3 = ((2 * size + PAGE_SIZE) / PAGE_SIZE) - 1;
126+ o1 = size % PAGE_SIZE;
127+ o2 = (size + (size / 2)) % PAGE_SIZE;
235128 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",
236129 size, m1, m2, m3, o1, o2);
237130 break;
@@ -245,64 +138,37 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu · 7 unmodified lines
245138 ptr2 = pt2->cpu;
246139 ptr3 = pt3->cpu;
247140
248− /* walk all pages, copy all page addresses to ptr1 */
249− for (i = 0; i < length; i++, list++) {
250− for (p = 0; p * 4096 < sg_dma_len(list); p++, ptr1++)
251− *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset);
252− }
253−/*
254− ptr1 = pt1->cpu;
255− for(j=0;j<40;j++) {
256− printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
257− }
258−*/
141+ for_each_sg_dma_page(list, &dma_iter, length, 0)
142+ *ptr1++ = cpu_to_le32(sg_page_iter_dma_address(&dma_iter) - list->offset);
259143
260144 /* if we have a user buffer, the first page may not be
261145 aligned to a page boundary. */
262− pt1->offset = dma->sglist->offset;
263− pt2->offset = pt1->offset+o1;
264− pt3->offset = pt1->offset+o2;
146+ pt1->offset = sgt->sgl->offset;
147+ pt2->offset = pt1->offset + o1;
148+ pt3->offset = pt1->offset + o2;
265149
266150 /* create video-dma2 page table */
267151 ptr1 = pt1->cpu;
268− for(i = m1; i <= m2 ; i++, ptr2++) {
152+ for (i = m1; i <= m2; i++, ptr2++)
269153 *ptr2 = ptr1[i];
270− }
271− fill = *(ptr2-1);
272− for(;i<1024;i++,ptr2++) {
154+ fill = *(ptr2 - 1);
155+ for (; i < 1024; i++, ptr2++)
273156 *ptr2 = fill;
274− }
275157 /* create video-dma3 page table */
276158 ptr1 = pt1->cpu;
277− for(i = m2; i <= m3; i++,ptr3++) {
159+ for (i = m2; i <= m3; i++, ptr3++)
278160 *ptr3 = ptr1[i];
279− }
280− fill = *(ptr3-1);
281− for(;i<1024;i++,ptr3++) {
161+ fill = *(ptr3 - 1);
162+ for (; i < 1024; i++, ptr3++)
282163 *ptr3 = fill;
283− }
284164 /* finally: finish up video-dma1 page table */
285− ptr1 = pt1->cpu+m1;
165+ ptr1 = pt1->cpu + m1;
286166 fill = pt1->cpu[m1];
287− for(i=m1;i<1024;i++,ptr1++) {
167+ for (i = m1; i < 1024; i++, ptr1++)
288168 *ptr1 = fill;
289− }
290−/*
291− ptr1 = pt1->cpu;
292− ptr2 = pt2->cpu;
293− ptr3 = pt3->cpu;
294− for(j=0;j<40;j++) {
295− printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
296− }
297− for(j=0;j<40;j++) {
298− printk("ptr2 %d: 0x%08x\n",j,ptr2[j]);
299− }
300− for(j=0;j<40;j++) {
301− printk("ptr3 %d: 0x%08x\n",j,ptr3[j]);
302− }
303−*/
304169 } else {
305170 struct saa7146_pgtable *pt = &buf->pt[0];
171+
306172 return saa7146_pgtable_build_single(pci, pt, list, length);
307173 }
308174
@@ -313,34 +179,14 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu · 4 unmodified lines
313179 /********************************************************************************/
314180 /* file operations */
315181
316−static int video_begin(struct saa7146_fh *fh)
182+static int video_begin(struct saa7146_dev *dev)
317183 {
318− struct saa7146_dev *dev = fh->dev;
319184 struct saa7146_vv *vv = dev->vv_data;
320185 struct saa7146_format *fmt = NULL;
321186 unsigned int resource;
322− int ret = 0, err = 0;
323−
324− DEB_EE("dev:%p, fh:%p\n", dev, fh);
325−
326− if ((vv->video_status & STATUS_CAPTURE) != 0) {
327− if (vv->video_fh == fh) {
328− DEB_S("already capturing\n");
329− return 0;
330− }
331− DEB_S("already capturing in another open\n");
332− return -EBUSY;
333− }
187+ int ret = 0;
334188
335− if ((vv->video_status & STATUS_OVERLAY) != 0) {
336− DEB_S("warning: suspending overlay video for streaming capture\n");
337− vv->ov_suspend = vv->video_fh;
338− err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
339− if (0 != err) {
340− DEB_D("suspending video failed. aborting\n");
341− return err;
342− }
343− }
189+ DEB_EE("dev:%p\n", dev);
344190
345191 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
346192 /* we need to have a valid format set here */
@@ -353,13 +199,9 @@ static int video_begin(struct saa7146_fh *fh) · 6 unmodified lines
353199 resource = RESOURCE_DMA1_HPS;
354200 }
355201
356− ret = saa7146_res_get(fh, resource);
202+ ret = saa7146_res_get(dev, resource);
357203 if (0 == ret) {
358204 DEB_S("cannot get capture resource %d\n", resource);
359− if (vv->ov_suspend != NULL) {
360− saa7146_start_preview(vv->ov_suspend);
361− vv->ov_suspend = NULL;
362− }
363205 return -EBUSY;
364206 }
365207
@@ -369,37 +211,22 @@ static int video_begin(struct saa7146_fh *fh) · 3 unmodified lines
369211 /* enable rps0 irqs */
370212 SAA7146_IER_ENABLE(dev, MASK_27);
371213
372− vv->video_fh = fh;
373− vv->video_status = STATUS_CAPTURE;
374−
375214 return 0;
376215 }
377216
378−static int video_end(struct saa7146_fh *fh, struct file *file)
217+static void video_end(struct saa7146_dev *dev)
379218 {
380− struct saa7146_dev *dev = fh->dev;
381219 struct saa7146_vv *vv = dev->vv_data;
382− struct saa7146_dmaqueue *q = &vv->video_dmaq;
383220 struct saa7146_format *fmt = NULL;
384221 unsigned long flags;
385222 unsigned int resource;
386223 u32 dmas = 0;
387− DEB_EE("dev:%p, fh:%p\n", dev, fh);
388−
389− if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
390− DEB_S("not capturing\n");
391− return 0;
392− }
393−
394− if (vv->video_fh != fh) {
395− DEB_S("capturing, but in another open\n");
396− return -EBUSY;
397− }
224+ DEB_EE("dev:%p\n", dev);
398225
399226 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
400227 /* we need to have a valid format set here */
401228 if (!fmt)
402− return -EINVAL;
229+ return;
403230
404231 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
405232 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
@@ -419,88 +246,24 @@ static int video_end(struct saa7146_fh *fh, struct file *file) · 13 unmodified lines
419246 /* shut down all used video dma transfers */
420247 saa7146_write(dev, MC1, dmas);
421248
422− if (q->curr)
423− saa7146_buffer_finish(dev, q, VIDEOBUF_DONE);
424−
425249 spin_unlock_irqrestore(&dev->slock, flags);
426250
427− vv->video_fh = NULL;
428− vv->video_status = 0;
429−
430− saa7146_res_free(fh, resource);
431−
432− if (vv->ov_suspend != NULL) {
433− saa7146_start_preview(vv->ov_suspend);
434− vv->ov_suspend = NULL;
435− }
436−
437− return 0;
251+ saa7146_res_free(dev, resource);
438252 }
439253
440254 static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
441255 {
442− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
256+ struct saa7146_dev *dev = video_drvdata(file);
443257
444258 strscpy((char *)cap->driver, "saa7146 v4l2", sizeof(cap->driver));
445259 strscpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
446− cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
260+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
447261 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
448262 V4L2_CAP_DEVICE_CAPS;
449263 cap->capabilities |= dev->ext_vv_data->capabilities;
450264 return 0;
451265 }
452266
453−static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
454−{
455− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
456− struct saa7146_vv *vv = dev->vv_data;
457−
458− *fb = vv->ov_fb;
459− fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
460− fb->flags = V4L2_FBUF_FLAG_PRIMARY;
461− return 0;
462−}
463−
464−static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
465−{
466− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
467− struct saa7146_vv *vv = dev->vv_data;
468− struct saa7146_format *fmt;
469−
470− DEB_EE("VIDIOC_S_FBUF\n");
471−
472− if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
473− return -EPERM;
474−
475− /* check args */
476− fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
477− if (NULL == fmt)
478− return -EINVAL;
479−
480− /* planar formats are not allowed for overlay video, clipping and video dma would clash */
481− if (fmt->flags & FORMAT_IS_PLANAR)
482− DEB_S("planar pixelformat '%4.4s' not allowed for overlay\n",
483− (char *)&fmt->pixelformat);
484−
485− /* check if overlay is running */
486− if (IS_OVERLAY_ACTIVE(fh) != 0) {
487− if (vv->video_fh != fh) {
488− DEB_D("refusing to change framebuffer information while overlay is active in another open\n");
489− return -EBUSY;
490− }
491− }
492−
493− /* ok, accept it */
494− vv->ov_fb = *fb;
495− vv->ov_fmt = fmt;
496−
497− if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
498− vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
499− DEB_D("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline);
500− }
501− return 0;
502−}
503−
504267 static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
505268 {
506269 if (f->index >= ARRAY_SIZE(formats))
@@ -543,13 +306,13 @@ int saa7146_s_ctrl(struct v4l2_ctrl *ctrl) · 36 unmodified lines
543306
544307 case V4L2_CID_HFLIP:
545308 /* fixme: we can support changing VFLIP and HFLIP here... */
546− if ((vv->video_status & STATUS_CAPTURE))
309+ if (vb2_is_busy(&vv->video_dmaq.q))
547310 return -EBUSY;
548311 vv->hflip = ctrl->val;
549312 break;
550313
551314 case V4L2_CID_VFLIP:
552− if ((vv->video_status & STATUS_CAPTURE))
315+ if (vb2_is_busy(&vv->video_dmaq.q))
553316 return -EBUSY;
554317 vv->vflip = ctrl->val;
555318 break;
@@ -557,20 +320,13 @@ int saa7146_s_ctrl(struct v4l2_ctrl *ctrl) · 1 unmodified line
557320 default:
558321 return -EINVAL;
559322 }
560−
561− if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
562− struct saa7146_fh *fh = vv->video_fh;
563−
564− saa7146_stop_preview(fh);
565− saa7146_start_preview(fh);
566− }
567323 return 0;
568324 }
569325
570326 static int vidioc_g_parm(struct file *file, void *fh,
571327 struct v4l2_streamparm *parm)
572328 {
573− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
329+ struct saa7146_dev *dev = video_drvdata(file);
574330 struct saa7146_vv *vv = dev->vv_data;
575331
576332 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -583,25 +339,16 @@ static int vidioc_g_parm(struct file *file, void *fh, · 6 unmodified lines
583339
584340 static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
585341 {
586− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
342+ struct saa7146_dev *dev = video_drvdata(file);
587343 struct saa7146_vv *vv = dev->vv_data;
588344
589345 f->fmt.pix = vv->video_fmt;
590346 return 0;
591347 }
592348
593−static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
594−{
595− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
596− struct saa7146_vv *vv = dev->vv_data;
597−
598− f->fmt.win = vv->ov.win;
599− return 0;
600−}
601−
602349 static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
603350 {
604− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
351+ struct saa7146_dev *dev = video_drvdata(file);
605352 struct saa7146_vv *vv = dev->vv_data;
606353
607354 f->fmt.vbi = vv->vbi_fmt;
@@ -610,7 +357,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format · 2 unmodified lines
610357
611358 static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
612359 {
613− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
360+ struct saa7146_dev *dev = video_drvdata(file);
614361 struct saa7146_vv *vv = dev->vv_data;
615362 struct saa7146_format *fmt;
616363 enum v4l2_field field;
@@ -634,24 +381,21 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma · 17 unmodified lines
634381 }
635382 switch (field) {
636383 case V4L2_FIELD_ALTERNATE:
637− vv->last_field = V4L2_FIELD_TOP;
638− maxh = maxh / 2;
639− break;
640384 case V4L2_FIELD_TOP:
641385 case V4L2_FIELD_BOTTOM:
642− vv->last_field = V4L2_FIELD_INTERLACED;
643386 maxh = maxh / 2;
644387 break;
645− case V4L2_FIELD_INTERLACED:
646− vv->last_field = V4L2_FIELD_INTERLACED;
647− break;
648388 default:
649− DEB_D("no known field mode '%d'\n", field);
650− return -EINVAL;
389+ field = V4L2_FIELD_INTERLACED;
390+ break;
651391 }
652392
653393 f->fmt.pix.field = field;
654394 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
395+ if (f->fmt.pix.width < 48)
396+ f->fmt.pix.width = 48;
397+ if (f->fmt.pix.height < 32)
398+ f->fmt.pix.height = 32;
655399 if (f->fmt.pix.width > maxw)
656400 f->fmt.pix.width = maxw;
657401 if (f->fmt.pix.height > maxh)
@@ -673,169 +417,65 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma · 15 unmodified lines
673417 return 0;
674418 }
675419
676−
677−static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
420+static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
678421 {
679− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
680− struct saa7146_vv *vv = dev->vv_data;
681− struct v4l2_window *win = &f->fmt.win;
682− enum v4l2_field field;
683− int maxw, maxh;
684−
685− DEB_EE("dev:%p\n", dev);
686−
687− if (NULL == vv->ov_fb.base) {
688− DEB_D("no fb base set\n");
689− return -EINVAL;
690− }
691− if (NULL == vv->ov_fmt) {
692− DEB_D("no fb fmt set\n");
693− return -EINVAL;
694− }
695− if (win->w.width < 48 || win->w.height < 32) {
696− DEB_D("min width/height. (%d,%d)\n",
697− win->w.width, win->w.height);
698− return -EINVAL;
699− }
700− if (win->clipcount > 16) {
701− DEB_D("clipcount too big\n");
702− return -EINVAL;
703− }
704−
705− field = win->field;
706− maxw = vv->standard->h_max_out;
707− maxh = vv->standard->v_max_out;
708−
709− if (V4L2_FIELD_ANY == field) {
710− field = (win->w.height > maxh / 2)
711− ? V4L2_FIELD_INTERLACED
712− : V4L2_FIELD_TOP;
713− }
714− switch (field) {
715− case V4L2_FIELD_TOP:
716− case V4L2_FIELD_BOTTOM:
717− case V4L2_FIELD_ALTERNATE:
718− maxh = maxh / 2;
719− break;
720− case V4L2_FIELD_INTERLACED:
721− break;
722− default:
723− DEB_D("no known field mode '%d'\n", field);
724− return -EINVAL;
725− }
726−
727− win->field = field;
728− if (win->w.width > maxw)
729− win->w.width = maxw;
730− if (win->w.height > maxh)
731− win->w.height = maxh;
732−
733− return 0;
734−}
735−
736−static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
737−{
738− struct saa7146_fh *fh = __fh;
739− struct saa7146_dev *dev = fh->dev;
422+ struct saa7146_dev *dev = video_drvdata(file);
740423 struct saa7146_vv *vv = dev->vv_data;
741424 int err;
742425
743− DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh);
744− if (IS_CAPTURE_ACTIVE(fh) != 0) {
426+ DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p\n", dev);
427+ if (vb2_is_busy(&vv->video_dmaq.q)) {
745428 DEB_EE("streaming capture is active\n");
746429 return -EBUSY;
747430 }
748431 err = vidioc_try_fmt_vid_cap(file, fh, f);
749432 if (0 != err)
750433 return err;
434+ switch (f->fmt.pix.field) {
435+ case V4L2_FIELD_ALTERNATE:
436+ vv->last_field = V4L2_FIELD_TOP;
437+ break;
438+ default:
439+ vv->last_field = V4L2_FIELD_INTERLACED;
440+ break;
441+ }
751442 vv->video_fmt = f->fmt.pix;
752443 DEB_EE("set to pixelformat '%4.4s'\n",
753444 (char *)&vv->video_fmt.pixelformat);
754445 return 0;
755446 }
756447
757−static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
758−{
759− struct saa7146_fh *fh = __fh;
760− struct saa7146_dev *dev = fh->dev;
761− struct saa7146_vv *vv = dev->vv_data;
762− int err;
763−
764− DEB_EE("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh);
765− err = vidioc_try_fmt_vid_overlay(file, fh, f);
766− if (0 != err)
767− return err;
768− vv->ov.win = f->fmt.win;
769− vv->ov.nclips = f->fmt.win.clipcount;
770− if (vv->ov.nclips > 16)
771− vv->ov.nclips = 16;
772− memcpy(vv->ov.clips, f->fmt.win.clips,
773− sizeof(struct v4l2_clip) * vv->ov.nclips);
774−
775− /* vv->ov.fh is used to indicate that we have valid overlay information, too */
776− vv->ov.fh = fh;
777−
778− /* check if our current overlay is active */
779− if (IS_OVERLAY_ACTIVE(fh) != 0) {
780− saa7146_stop_preview(fh);
781− saa7146_start_preview(fh);
782− }
783− return 0;
784−}
785−
786448 static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
787449 {
788− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
450+ struct saa7146_dev *dev = video_drvdata(file);
789451 struct saa7146_vv *vv = dev->vv_data;
790452
791453 *norm = vv->standard->id;
792454 return 0;
793455 }
794456
795− /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
796− PAL / NTSC / SECAM. if your hardware does not (or does more)
797− -- override this function in your extension */
798−/*
799− case VIDIOC_ENUMSTD:
800− {
801− struct v4l2_standard *e = arg;
802− if (e->index < 0 )
803− return -EINVAL;
804− if( e->index < dev->ext_vv_data->num_stds ) {
805− DEB_EE("VIDIOC_ENUMSTD: index:%d\n", e->index);
806− v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
807− return 0;
808− }
809− return -EINVAL;
810− }
811− */
812−
813457 static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
814458 {
815− struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
459+ struct saa7146_dev *dev = video_drvdata(file);
816460 struct saa7146_vv *vv = dev->vv_data;
817461 int found = 0;
818− int err, i;
462+ int i;
819463
820464 DEB_EE("VIDIOC_S_STD\n");
821465
822− if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
466+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
467+ if (id & dev->ext_vv_data->stds[i].id)
468+ break;
469+
470+ if (i != dev->ext_vv_data->num_stds &&
471+ vv->standard == &dev->ext_vv_data->stds[i])
472+ return 0;
473+
474+ if (vb2_is_busy(&vv->video_dmaq.q) || vb2_is_busy(&vv->vbi_dmaq.q)) {
823475 DEB_D("cannot change video standard while streaming capture is active\n");
824476 return -EBUSY;
825477 }
826478
827− if ((vv->video_status & STATUS_OVERLAY) != 0) {
828− vv->ov_suspend = vv->video_fh;
829− err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
830− if (0 != err) {
831− DEB_D("suspending video failed. aborting\n");
832− return err;
833− }
834− }
835−
836− for (i = 0; i < dev->ext_vv_data->num_stds; i++)
837− if (id & dev->ext_vv_data->stds[i].id)
838− break;
839479 if (i != dev->ext_vv_data->num_stds) {
840480 vv->standard = &dev->ext_vv_data->stds[i];
841481 if (NULL != dev->ext_vv_data->std_callback)
@@ -843,11 +483,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id) · 1 unmodified line
843483 found = 1;
844484 }
845485
846− if (vv->ov_suspend != NULL) {
847− saa7146_start_preview(vv->ov_suspend);
848− vv->ov_suspend = NULL;
849− }
850−
851486 if (!found) {
852487 DEB_EE("VIDIOC_S_STD: standard not found\n");
853488 return -EINVAL;
@@ -857,138 +492,22 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id) · 3 unmodified lines
857492 return 0;
858493 }
859494
860−static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
861−{
862− int err;
863−
864− DEB_D("VIDIOC_OVERLAY on:%d\n", on);
865− if (on)
866− err = saa7146_start_preview(fh);
867− else
868− err = saa7146_stop_preview(fh);
869− return err;
870−}
871−
872−static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
873−{
874− struct saa7146_fh *fh = __fh;
875−
876− if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
877− return videobuf_reqbufs(&fh->video_q, b);
878− if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
879− return videobuf_reqbufs(&fh->vbi_q, b);
880− return -EINVAL;
881−}
882−
883−static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
884−{
885− struct saa7146_fh *fh = __fh;
886−
887− if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
888− return videobuf_querybuf(&fh->video_q, buf);
889− if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
890− return videobuf_querybuf(&fh->vbi_q, buf);
891− return -EINVAL;
892−}
893−
894−static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
895−{
896− struct saa7146_fh *fh = __fh;
897−
898− if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
899− return videobuf_qbuf(&fh->video_q, buf);
900− if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
901− return videobuf_qbuf(&fh->vbi_q, buf);
902− return -EINVAL;
903−}
904−
905−static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
906−{
907− struct saa7146_fh *fh = __fh;
908−
909− if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
910− return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
911− if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
912− return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
913− return -EINVAL;
914−}
915−
916−static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
917−{
918− struct saa7146_fh *fh = __fh;
919− int err;
920−
921− DEB_D("VIDIOC_STREAMON, type:%d\n", type);
922−
923− err = video_begin(fh);
924− if (err)
925− return err;
926− if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
927− return videobuf_streamon(&fh->video_q);
928− if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
929− return videobuf_streamon(&fh->vbi_q);
930− return -EINVAL;
931−}
932−
933−static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
934−{
935− struct saa7146_fh *fh = __fh;
936− struct saa7146_dev *dev = fh->dev;
937− struct saa7146_vv *vv = dev->vv_data;
938− int err;
939−
940− DEB_D("VIDIOC_STREAMOFF, type:%d\n", type);
941−
942− /* ugly: we need to copy some checks from video_end(),
943− because videobuf_streamoff() relies on the capture running.
944− check and fix this */
945− if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
946− DEB_S("not capturing\n");
947− return 0;
948− }
949−
950− if (vv->video_fh != fh) {
951− DEB_S("capturing, but in another open\n");
952− return -EBUSY;
953− }
954−
955− err = -EINVAL;
956− if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
957− err = videobuf_streamoff(&fh->video_q);
958− else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
959− err = videobuf_streamoff(&fh->vbi_q);
960− if (0 != err) {
961− DEB_D("warning: videobuf_streamoff() failed\n");
962− video_end(fh, file);
963− } else {
964− err = video_end(fh, file);
965− }
966− return err;
967−}
968−
969495 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
970496 .vidioc_querycap = vidioc_querycap,
971497 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
972− .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
973498 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
974499 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
975500 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
976− .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
977− .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
978− .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
979−
980− .vidioc_overlay = vidioc_overlay,
981− .vidioc_g_fbuf = vidioc_g_fbuf,
982− .vidioc_s_fbuf = vidioc_s_fbuf,
983− .vidioc_reqbufs = vidioc_reqbufs,
984− .vidioc_querybuf = vidioc_querybuf,
985− .vidioc_qbuf = vidioc_qbuf,
986− .vidioc_dqbuf = vidioc_dqbuf,
987501 .vidioc_g_std = vidioc_g_std,
988502 .vidioc_s_std = vidioc_s_std,
989− .vidioc_streamon = vidioc_streamon,
990− .vidioc_streamoff = vidioc_streamoff,
991503 .vidioc_g_parm = vidioc_g_parm,
504+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
505+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
506+ .vidioc_querybuf = vb2_ioctl_querybuf,
507+ .vidioc_qbuf = vb2_ioctl_qbuf,
508+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
509+ .vidioc_streamon = vb2_ioctl_streamon,
510+ .vidioc_streamoff = vb2_ioctl_streamoff,
992511 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
993512 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
994513 };
@@ -996,16 +515,18 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { · 1 unmodified line
996515 const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
997516 .vidioc_querycap = vidioc_querycap,
998517 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
999−
1000− .vidioc_reqbufs = vidioc_reqbufs,
1001− .vidioc_querybuf = vidioc_querybuf,
1002− .vidioc_qbuf = vidioc_qbuf,
1003− .vidioc_dqbuf = vidioc_dqbuf,
518+ .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
519+ .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1004520 .vidioc_g_std = vidioc_g_std,
1005521 .vidioc_s_std = vidioc_s_std,
1006− .vidioc_streamon = vidioc_streamon,
1007− .vidioc_streamoff = vidioc_streamoff,
1008522 .vidioc_g_parm = vidioc_g_parm,
523+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
524+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
525+ .vidioc_querybuf = vb2_ioctl_querybuf,
526+ .vidioc_qbuf = vb2_ioctl_qbuf,
527+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
528+ .vidioc_streamon = vb2_ioctl_streamon,
529+ .vidioc_streamoff = vb2_ioctl_streamoff,
1009530 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1010531 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1011532 };
@@ -1019,7 +540,6 @@ static int buffer_activate (struct saa7146_dev *dev, · 7 unmodified lines
1019540 {
1020541 struct saa7146_vv *vv = dev->vv_data;
1021542
1022− buf->vb.state = VIDEOBUF_ACTIVE;
1023543 saa7146_set_capture(dev,buf,next);
1024544
1025545 mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
@@ -1033,140 +553,136 @@ static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf * · 7 unmodified lines
1033553 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1034554 }
1035555
1036−static int buffer_prepare(struct videobuf_queue *q,
1037− struct videobuf_buffer *vb, enum v4l2_field field)
556+static int queue_setup(struct vb2_queue *q,
557+ unsigned int *num_buffers, unsigned int *num_planes,
558+ unsigned int sizes[], struct device *alloc_devs[])
1038559 {
1039− struct file *file = q->priv_data;
1040− struct saa7146_fh *fh = file->private_data;
1041− struct saa7146_dev *dev = fh->dev;
1042− struct saa7146_vv *vv = dev->vv_data;
1043− struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1044− int size,err = 0;
1045−
1046− DEB_CAP("vbuf:%p\n", vb);
1047−
1048− /* sanity checks */
1049− if (vv->video_fmt.width < 48 ||
1050− vv->video_fmt.height < 32 ||
1051− vv->video_fmt.width > vv->standard->h_max_out ||
1052− vv->video_fmt.height > vv->standard->v_max_out) {
1053− DEB_D("w (%d) / h (%d) out of bounds\n",
1054− vv->video_fmt.width, vv->video_fmt.height);
1055− return -EINVAL;
1056− }
560+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
561+ unsigned int size = dev->vv_data->video_fmt.sizeimage;
1057562
1058− size = vv->video_fmt.sizeimage;
1059− if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1060− DEB_D("size mismatch\n");
1061− return -EINVAL;
1062− }
563+ if (*num_planes)
564+ return sizes[0] < size ? -EINVAL : 0;
565+ *num_planes = 1;
566+ sizes[0] = size;
1063567
1064− DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1065− vv->video_fmt.width, vv->video_fmt.height,
1066− size, v4l2_field_names[vv->video_fmt.field]);
1067− if (buf->vb.width != vv->video_fmt.width ||
1068− buf->vb.bytesperline != vv->video_fmt.bytesperline ||
1069− buf->vb.height != vv->video_fmt.height ||
1070− buf->vb.size != size ||
1071− buf->vb.field != field ||
1072− buf->vb.field != vv->video_fmt.field ||
1073− buf->fmt != &vv->video_fmt) {
1074− saa7146_dma_free(dev,q,buf);
1075− }
568+ return 0;
569+}
1076570
1077− if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
1078− struct saa7146_format *sfmt;
571+static void buf_queue(struct vb2_buffer *vb)
572+{
573+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
574+ struct vb2_queue *vq = vb->vb2_queue;
575+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
576+ struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb);
577+ unsigned long flags;
1079578
1080− buf->vb.bytesperline = vv->video_fmt.bytesperline;
1081− buf->vb.width = vv->video_fmt.width;
1082− buf->vb.height = vv->video_fmt.height;
1083− buf->vb.size = size;
1084− buf->vb.field = field;
1085− buf->fmt = &vv->video_fmt;
1086− buf->vb.field = vv->video_fmt.field;
579+ spin_lock_irqsave(&dev->slock, flags);
1087580
1088− sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
581+ saa7146_buffer_queue(dev, &dev->vv_data->video_dmaq, buf);
582+ spin_unlock_irqrestore(&dev->slock, flags);
583+}
1089584
1090− release_all_pagetables(dev, buf);
1091− if( 0 != IS_PLANAR(sfmt->trans)) {
1092− saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1093− saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1094− saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1095− } else {
1096− saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1097− }
585+static int buf_init(struct vb2_buffer *vb)
586+{
587+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
588+ struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb);
589+ struct vb2_queue *vq = vb->vb2_queue;
590+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
591+ struct saa7146_vv *vv = dev->vv_data;
592+ struct saa7146_format *sfmt;
593+ int ret;
1098594
1099− err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
1100− if (err)
1101− goto oops;
1102− err = saa7146_pgtable_build(dev,buf);
1103− if (err)
1104− goto oops;
1105− }
1106− buf->vb.state = VIDEOBUF_PREPARED;
1107595 buf->activate = buffer_activate;
596+ sfmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
1108597
1109− return 0;
1110−
1111− oops:
1112− DEB_D("error out\n");
1113− saa7146_dma_free(dev,q,buf);
598+ if (IS_PLANAR(sfmt->trans)) {
599+ saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
600+ saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
601+ saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
602+ } else {
603+ saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
604+ }
1114605
1115− return err;
606+ ret = saa7146_pgtable_build(dev, buf);
607+ if (ret)
608+ release_all_pagetables(dev, buf);
609+ return ret;
1116610 }
1117611
1118−static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
612+static int buf_prepare(struct vb2_buffer *vb)
1119613 {
1120− struct file *file = q->priv_data;
1121− struct saa7146_fh *fh = file->private_data;
1122− struct saa7146_vv *vv = fh->dev->vv_data;
1123−
1124− if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1125− *count = MAX_SAA7146_CAPTURE_BUFFERS;
1126−
1127− *size = vv->video_fmt.sizeimage;
614+ struct vb2_queue *vq = vb->vb2_queue;
615+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
616+ struct saa7146_vv *vv = dev->vv_data;
617+ unsigned int size = vv->video_fmt.sizeimage;
1128618
1129− /* check if we exceed the "max_memory" parameter */
1130− if( (*count * *size) > (max_memory*1048576) ) {
1131− *count = (max_memory*1048576) / *size;
1132− }
619+ if (vb2_plane_size(vb, 0) < size)
620+ return -EINVAL;
621+ vb2_set_plane_payload(vb, 0, size);
622+ return 0;
623+}
1133624
1134− DEB_CAP("%d buffers, %d bytes each\n", *count, *size);
625+static void buf_cleanup(struct vb2_buffer *vb)
626+{
627+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
628+ struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb);
629+ struct vb2_queue *vq = vb->vb2_queue;
630+ struct saa7146_dev *dev = vb2_get_drv_priv(vq);
1135631
1136− return 0;
632+ release_all_pagetables(dev, buf);
1137633 }
1138634
1139−static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
635+static void return_buffers(struct vb2_queue *q, int state)
1140636 {
1141− struct file *file = q->priv_data;
1142− struct saa7146_fh *fh = file->private_data;
1143− struct saa7146_dev *dev = fh->dev;
1144− struct saa7146_vv *vv = dev->vv_data;
1145− struct saa7146_buf *buf = (struct saa7146_buf *)vb;
637+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
638+ struct saa7146_dmaqueue *dq = &dev->vv_data->video_dmaq;
639+ struct saa7146_buf *buf;
1146640
1147− DEB_CAP("vbuf:%p\n", vb);
1148− saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf);
641+ if (dq->curr) {
642+ buf = dq->curr;
643+ dq->curr = NULL;
644+ vb2_buffer_done(&buf->vb.vb2_buf, state);
645+ }
646+ while (!list_empty(&dq->queue)) {
647+ buf = list_entry(dq->queue.next, struct saa7146_buf, list);
648+ list_del(&buf->list);
649+ vb2_buffer_done(&buf->vb.vb2_buf, state);
650+ }
1149651 }
1150652
1151−static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
653+static int start_streaming(struct vb2_queue *q, unsigned int count)
1152654 {
1153− struct file *file = q->priv_data;
1154− struct saa7146_fh *fh = file->private_data;
1155− struct saa7146_dev *dev = fh->dev;
1156− struct saa7146_buf *buf = (struct saa7146_buf *)vb;
655+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
656+ int ret;
1157657
1158− DEB_CAP("vbuf:%p\n", vb);
658+ if (!vb2_is_streaming(&dev->vv_data->video_dmaq.q))
659+ dev->vv_data->seqnr = 0;
660+ ret = video_begin(dev);
661+ if (ret)
662+ return_buffers(q, VB2_BUF_STATE_QUEUED);
663+ return ret;
664+}
1159665
1160− saa7146_dma_free(dev,q,buf);
666+static void stop_streaming(struct vb2_queue *q)
667+{
668+ struct saa7146_dev *dev = vb2_get_drv_priv(q);
669+ struct saa7146_dmaqueue *dq = &dev->vv_data->video_dmaq;
1161670
1162− release_all_pagetables(dev, buf);
671+ del_timer(&dq->timeout);
672+ video_end(dev);
673+ return_buffers(q, VB2_BUF_STATE_ERROR);
1163674 }
1164675
1165−static const struct videobuf_queue_ops video_qops = {
1166− .buf_setup = buffer_setup,
1167− .buf_prepare = buffer_prepare,
1168− .buf_queue = buffer_queue,
1169− .buf_release = buffer_release,
676+const struct vb2_ops video_qops = {
677+ .queue_setup = queue_setup,
678+ .buf_queue = buf_queue,
679+ .buf_init = buf_init,
680+ .buf_prepare = buf_prepare,
681+ .buf_cleanup = buf_cleanup,
682+ .start_streaming = start_streaming,
683+ .stop_streaming = stop_streaming,
684+ .wait_prepare = vb2_ops_wait_prepare,
685+ .wait_finish = vb2_ops_wait_finish,
1170686 };
1171687
1172688 /********************************************************************************/
@@ -1187,38 +703,6 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) · 14 unmodified lines
1187703 vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
1188704 }
1189705
1190−
1191−static int video_open(struct saa7146_dev *dev, struct file *file)
1192−{
1193− struct saa7146_fh *fh = file->private_data;
1194−
1195− videobuf_queue_sg_init(&fh->video_q, &video_qops,
1196− &dev->pci->dev, &dev->slock,
1197− V4L2_BUF_TYPE_VIDEO_CAPTURE,
1198− V4L2_FIELD_INTERLACED,
1199− sizeof(struct saa7146_buf),
1200− file, &dev->v4l2_lock);
1201−
1202− return 0;
1203−}
1204−
1205−
1206−static void video_close(struct saa7146_dev *dev, struct file *file)
1207−{
1208− struct saa7146_fh *fh = file->private_data;
1209− struct saa7146_vv *vv = dev->vv_data;
1210− struct videobuf_queue *q = &fh->video_q;
1211−
1212− if (IS_CAPTURE_ACTIVE(fh) != 0)
1213− video_end(fh, file);
1214− else if (IS_OVERLAY_ACTIVE(fh) != 0)
1215− saa7146_stop_preview(fh);
1216−
1217− videobuf_stop(q);
1218− /* hmm, why is this function declared void? */
1219−}
1220−
1221−
1222706 static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1223707 {
1224708 struct saa7146_vv *vv = dev->vv_data;
@@ -1228,59 +712,14 @@ static void video_irq_done(struct saa7146_dev *dev, unsigned long st) · 3 unmodified lines
1228712 DEB_CAP("called\n");
1229713
1230714 /* only finish the buffer if we have one... */
1231− if( NULL != q->curr ) {
1232− saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
1233− }
715+ if (q->curr)
716+ saa7146_buffer_finish(dev, q, VB2_BUF_STATE_DONE);
1234717 saa7146_buffer_next(dev,q,0);
1235718
1236719 spin_unlock(&dev->slock);
1237720 }
1238721
1239−static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1240−{
1241− struct saa7146_fh *fh = file->private_data;
1242− struct saa7146_dev *dev = fh->dev;
1243− struct saa7146_vv *vv = dev->vv_data;
1244− ssize_t ret = 0;
1245−
1246− DEB_EE("called\n");
1247−
1248− if ((vv->video_status & STATUS_CAPTURE) != 0) {
1249− /* fixme: should we allow read() captures while streaming capture? */
1250− if (vv->video_fh == fh) {
1251− DEB_S("already capturing\n");
1252− return -EBUSY;
1253− }
1254− DEB_S("already capturing in another open\n");
1255− return -EBUSY;
1256− }
1257−
1258− ret = video_begin(fh);
1259− if( 0 != ret) {
1260− goto out;
1261− }
1262−
1263− ret = videobuf_read_one(&fh->video_q , data, count, ppos,
1264− file->f_flags & O_NONBLOCK);
1265− if (ret != 0) {
1266− video_end(fh, file);
1267− } else {
1268− ret = video_end(fh, file);
1269− }
1270−out:
1271− /* restart overlay if it was active before */
1272− if (vv->ov_suspend != NULL) {
1273− saa7146_start_preview(vv->ov_suspend);
1274− vv->ov_suspend = NULL;
1275− }
1276−
1277− return ret;
1278−}
1279−
1280722 const struct saa7146_use_ops saa7146_video_uops = {
1281723 .init = video_init,
1282− .open = video_open,
1283− .release = video_close,
1284724 .irq_done = video_irq_done,
1285− .read = video_read,
1286725 };
drivers/media/common/videobuf2/videobuf2-v4l2.c+3−2
@@ -1171,10 +1171,11 @@ ssize_t vb2_fop_read(struct file *file, char __user *buf, · 1170 unmodified lines
11711171 return -ERESTARTSYS;
11721172 if (vb2_queue_is_busy(vdev->queue, file))
11731173 goto exit;
1174+ vdev->queue->owner = file->private_data;
11741175 err = vb2_read(vdev->queue, buf, count, ppos,
11751176 file->f_flags & O_NONBLOCK);
1176− if (vdev->queue->fileio)
1177− vdev->queue->owner = file->private_data;
1177+ if (!vdev->queue->fileio)
1178+ vdev->queue->owner = NULL;
11781179 exit:
11791180 if (lock)
11801181 mutex_unlock(lock);
drivers/media/dvb-frontends/drx39xyj/drxj.c+1−1
@@ -11070,7 +11070,7 @@ ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode) · 11069 unmodified lines
1107011070 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
1107111071 break;
1107211072 default:
11073− /* Unknow sleep mode */
11073+ /* Unknown sleep mode */
1107411074 return -EINVAL;
1107511075 }
1107611076
drivers/media/dvb-frontends/drxk_hard.c+1−1
@@ -1585,7 +1585,7 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) · 1584 unmodified lines
15851585 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
15861586 break;
15871587 default:
1588− /* Unknow sleep mode */
1588+ /* Unknown sleep mode */
15891589 return -EINVAL;
15901590 }
15911591
drivers/media/dvb-frontends/rtl2832_sdr.c+2−4
@@ -1463,7 +1463,7 @@ err: · 1462 unmodified lines
14631463 return ret;
14641464 }
14651465
1466−static int rtl2832_sdr_remove(struct platform_device *pdev)
1466+static void rtl2832_sdr_remove(struct platform_device *pdev)
14671467 {
14681468 struct rtl2832_sdr_dev *dev = platform_get_drvdata(pdev);
14691469
@@ -1479,8 +1479,6 @@ static int rtl2832_sdr_remove(struct platform_device *pdev) · 9 unmodified lines
14791479 mutex_unlock(&dev->vb_queue_lock);
14801480 v4l2_device_put(&dev->v4l2_dev);
14811481 module_put(pdev->dev.parent->driver->owner);
1482−
1483− return 0;
14841482 }
14851483
14861484 static struct platform_driver rtl2832_sdr_driver = {
@@ -1488,7 +1486,7 @@ static struct platform_driver rtl2832_sdr_driver = { · 1 unmodified line
14881486 .name = "rtl2832_sdr",
14891487 },
14901488 .probe = rtl2832_sdr_probe,
1491− .remove = rtl2832_sdr_remove,
1489+ .remove_new = rtl2832_sdr_remove,
14921490 };
14931491 module_platform_driver(rtl2832_sdr_driver);
14941492
drivers/media/dvb-frontends/zd1301_demod.c+2−4
@@ -515,7 +515,7 @@ err: · 514 unmodified lines
515515 return ret;
516516 }
517517
518−static int zd1301_demod_remove(struct platform_device *pdev)
518+static void zd1301_demod_remove(struct platform_device *pdev)
519519 {
520520 struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
521521
@@ -523,8 +523,6 @@ static int zd1301_demod_remove(struct platform_device *pdev) · 1 unmodified line
523523
524524 i2c_del_adapter(&dev->adapter);
525525 kfree(dev);
526−
527− return 0;
528526 }
529527
530528 static struct platform_driver zd1301_demod_driver = {
@@ -533,7 +531,7 @@ static struct platform_driver zd1301_demod_driver = { · 2 unmodified lines
533531 .suppress_bind_attrs = true,
534532 },
535533 .probe = zd1301_demod_probe,
536− .remove = zd1301_demod_remove,
534+ .remove_new = zd1301_demod_remove,
537535 };
538536 module_platform_driver(zd1301_demod_driver);
539537
drivers/media/i2c/Kconfig+1−67
@@ -267,16 +267,6 @@ config VIDEO_MT9M001 · 266 unmodified lines
267267 This driver supports MT9M001 cameras from Micron, monochrome
268268 and colour models.
269269
270−config VIDEO_MT9M032
271− tristate "MT9M032 camera sensor support"
272− depends on I2C && VIDEO_DEV
273− select MEDIA_CONTROLLER
274− select VIDEO_V4L2_SUBDEV_API
275− select VIDEO_APTINA_PLL
276− help
277− This driver supports MT9M032 camera sensors from Aptina, monochrome
278− models only.
279−
280270 config VIDEO_MT9M111
281271 tristate "mt9m111, mt9m112 and mt9m131 support"
282272 depends on I2C && VIDEO_DEV
@@ -296,15 +286,6 @@ config VIDEO_MT9P031 · 13 unmodified lines
296286 This is a Video4Linux2 sensor driver for the Aptina
297287 (Micron) mt9p031 5 Mpixel camera.
298288
299−config VIDEO_MT9T001
300− tristate "Aptina MT9T001 support"
301− depends on I2C && VIDEO_DEV
302− select MEDIA_CONTROLLER
303− select VIDEO_V4L2_SUBDEV_API
304− help
305− This is a Video4Linux2 sensor driver for the Aptina
306− (Micron) mt0t001 3 Mpixel camera.
307−
308289 config VIDEO_MT9T112
309290 tristate "Aptina MT9T111/MT9T112 support"
310291 depends on I2C && VIDEO_DEV
@@ -344,14 +325,6 @@ config VIDEO_MT9V111 · 33 unmodified lines
344325 To compile this driver as a module, choose M here: the
345326 module will be called mt9v111.
346327
347−config VIDEO_NOON010PC30
348− tristate "Siliconfile NOON010PC30 sensor support"
349− depends on I2C && VIDEO_DEV
350− select MEDIA_CONTROLLER
351− select VIDEO_V4L2_SUBDEV_API
352− help
353− This driver supports NOON010PC30 CIF camera from Siliconfile
354−
355328 config VIDEO_OG01A1B
356329 tristate "OmniVision OG01A1B sensor support"
357330 depends on I2C && VIDEO_DEV
@@ -462,6 +435,7 @@ config VIDEO_OV2685 · 104 unmodified lines
462435 tristate "OmniVision OV2685 sensor support"
463436 depends on VIDEO_DEV && I2C
464437 select MEDIA_CONTROLLER
438+ select VIDEO_V4L2_SUBDEV_API
465439 select V4L2_FWNODE
466440 help
467441 This is a Video4Linux2 sensor driver for the OmniVision
@@ -810,21 +784,6 @@ config VIDEO_S5K6A3 · 342 unmodified lines
810784 This is a V4L2 sensor driver for Samsung S5K6A3 raw
811785 camera sensor.
812786
813−config VIDEO_S5K6AA
814− tristate "Samsung S5K6AAFX sensor support"
815− depends on I2C && VIDEO_DEV
816− select MEDIA_CONTROLLER
817− select VIDEO_V4L2_SUBDEV_API
818− help
819− This is a V4L2 sensor driver for Samsung S5K6AA(FX) 1.3M
820− camera sensor with an embedded SoC image signal processor.
821−
822−config VIDEO_SR030PC30
823− tristate "Siliconfile SR030PC30 sensor support"
824− depends on I2C && VIDEO_DEV
825− help
826− This driver supports SR030PC30 VGA camera from Siliconfile
827−
828787 config VIDEO_ST_VGXY61
829788 tristate "ST VGXY61 sensor support"
830789 depends on OF && GPIOLIB && VIDEO_DEV && I2C
@@ -835,19 +794,8 @@ config VIDEO_ST_VGXY61 · 4 unmodified lines
835794 This is a Video4Linux2 sensor driver for the ST VGXY61
836795 camera sensor.
837796
838−config VIDEO_VS6624
839− tristate "ST VS6624 sensor support"
840− depends on VIDEO_DEV && I2C
841− help
842− This is a Video4Linux2 sensor driver for the ST VS6624
843− camera.
844−
845− To compile this driver as a module, choose M here: the
846− module will be called vs6624.
847−
848797 source "drivers/media/i2c/ccs/Kconfig"
849798 source "drivers/media/i2c/et8ek8/Kconfig"
850−source "drivers/media/i2c/m5mols/Kconfig"
851799
852800 endmenu
853801
@@ -1453,20 +1401,6 @@ endmenu · 599 unmodified lines
14531401 menu "Video encoders"
14541402 visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
14551403
1456−config VIDEO_AD9389B
1457− tristate "Analog Devices AD9389B encoder"
1458− depends on VIDEO_DEV && I2C
1459− select MEDIA_CONTROLLER
1460− select VIDEO_V4L2_SUBDEV_API
1461−
1462− help
1463− Support for the Analog Devices AD9389B video encoder.
1464−
1465− This is a Analog Devices HDMI transmitter.
1466−
1467− To compile this driver as a module, choose M here: the
1468− module will be called ad9389b.
1469−
14701404 config VIDEO_ADV7170
14711405 tristate "Analog Devices ADV7170 video encoder"
14721406 depends on VIDEO_DEV && I2C
drivers/media/i2c/Makefile+0−8
@@ -4,7 +4,6 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o · 3 unmodified lines
44
55 obj-$(CONFIG_SDR_MAX2175) += max2175.o
66 obj-$(CONFIG_VIDEO_AD5820) += ad5820.o
7−obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
87 obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
98 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
109 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
@@ -56,21 +55,17 @@ obj-$(CONFIG_VIDEO_KS0127) += ks0127.o · 45 unmodified lines
5655 obj-$(CONFIG_VIDEO_LM3560) += lm3560.o
5756 obj-$(CONFIG_VIDEO_LM3646) += lm3646.o
5857 obj-$(CONFIG_VIDEO_M52790) += m52790.o
59−obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
6058 obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
6159 obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
6260 obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
6361 obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
6462 obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o
65−obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
6663 obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o
6764 obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
68−obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
6965 obj-$(CONFIG_VIDEO_MT9T112) += mt9t112.o
7066 obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
7167 obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
7268 obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o
73−obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
7469 obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o
7570 obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
7671 obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o
@@ -110,7 +105,6 @@ obj-$(CONFIG_VIDEO_RJ54N1) += rj54n1cb0c.o · 33 unmodified lines
110105 obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
111106 obj-$(CONFIG_VIDEO_S5K5BAF) += s5k5baf.o
112107 obj-$(CONFIG_VIDEO_S5K6A3) += s5k6a3.o
113−obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
114108 obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
115109 obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
116110 obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
@@ -119,7 +113,6 @@ obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o · 2 unmodified lines
119113 obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
120114 obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
121115 obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
122−obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
123116 obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
124117 obj-$(CONFIG_VIDEO_ST_VGXY61) += st-vgxy61.o
125118 obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
@@ -145,6 +138,5 @@ obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o · 19 unmodified lines
145138 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
146139 obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
147140 obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
148−obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
149141 obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
150142 obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
drivers/media/i2c/ad9389b.c+0−1215
@@ -1,1215 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/*
3− * Analog Devices AD9389B/AD9889B video encoder driver
4− *
5− * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6− */
7−
8−/*
9− * References (c = chapter, p = page):
10− * REF_01 - Analog Devices, Programming Guide, AD9889B/AD9389B,
11− * HDMI Transitter, Rev. A, October 2010
12− */
13−
14−#include <linux/kernel.h>
15−#include <linux/module.h>
16−#include <linux/slab.h>
17−#include <linux/i2c.h>
18−#include <linux/delay.h>
19−#include <linux/videodev2.h>
20−#include <linux/workqueue.h>
21−#include <linux/v4l2-dv-timings.h>
22−#include <media/v4l2-device.h>
23−#include <media/v4l2-common.h>
24−#include <media/v4l2-dv-timings.h>
25−#include <media/v4l2-ctrls.h>
26−#include <media/i2c/ad9389b.h>
27−
28−static int debug;
29−module_param(debug, int, 0644);
30−MODULE_PARM_DESC(debug, "debug level (0-2)");
31−
32−MODULE_DESCRIPTION("Analog Devices AD9389B/AD9889B video encoder driver");
33−MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
34−MODULE_AUTHOR("Martin Bugge <marbugge@cisco.com>");
35−MODULE_LICENSE("GPL");
36−
37−#define MASK_AD9389B_EDID_RDY_INT 0x04
38−#define MASK_AD9389B_MSEN_INT 0x40
39−#define MASK_AD9389B_HPD_INT 0x80
40−
41−#define MASK_AD9389B_HPD_DETECT 0x40
42−#define MASK_AD9389B_MSEN_DETECT 0x20
43−#define MASK_AD9389B_EDID_RDY 0x10
44−
45−#define EDID_MAX_RETRIES (8)
46−#define EDID_DELAY 250
47−#define EDID_MAX_SEGM 8
48−
49−/*
50−**********************************************************************
51−*
52−* Arrays with configuration parameters for the AD9389B
53−*
54−**********************************************************************
55−*/
56−
57−struct ad9389b_state_edid {
58− /* total number of blocks */
59− u32 blocks;
60− /* Number of segments read */
61− u32 segments;
62− u8 data[EDID_MAX_SEGM * 256];
63− /* Number of EDID read retries left */
64− unsigned read_retries;
65−};
66−
67−struct ad9389b_state {
68− struct ad9389b_platform_data pdata;
69− struct v4l2_subdev sd;
70− struct media_pad pad;
71− struct v4l2_ctrl_handler hdl;
72− int chip_revision;
73− /* Is the ad9389b powered on? */
74− bool power_on;
75− /* Did we receive hotplug and rx-sense signals? */
76− bool have_monitor;
77− /* timings from s_dv_timings */
78− struct v4l2_dv_timings dv_timings;
79− /* controls */
80− struct v4l2_ctrl *hdmi_mode_ctrl;
81− struct v4l2_ctrl *hotplug_ctrl;
82− struct v4l2_ctrl *rx_sense_ctrl;
83− struct v4l2_ctrl *have_edid0_ctrl;
84− struct v4l2_ctrl *rgb_quantization_range_ctrl;
85− struct i2c_client *edid_i2c_client;
86− struct ad9389b_state_edid edid;
87− /* Running counter of the number of detected EDIDs (for debugging) */
88− unsigned edid_detect_counter;
89− struct delayed_work edid_handler; /* work entry */
90−};
91−
92−static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd);
93−static bool ad9389b_check_edid_status(struct v4l2_subdev *sd);
94−static void ad9389b_setup(struct v4l2_subdev *sd);
95−static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq);
96−static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
97−
98−static inline struct ad9389b_state *get_ad9389b_state(struct v4l2_subdev *sd)
99−{
100− return container_of(sd, struct ad9389b_state, sd);
101−}
102−
103−static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
104−{
105− return &container_of(ctrl->handler, struct ad9389b_state, hdl)->sd;
106−}
107−
108−/* ------------------------ I2C ----------------------------------------------- */
109−
110−static int ad9389b_rd(struct v4l2_subdev *sd, u8 reg)
111−{
112− struct i2c_client *client = v4l2_get_subdevdata(sd);
113−
114− return i2c_smbus_read_byte_data(client, reg);
115−}
116−
117−static int ad9389b_wr(struct v4l2_subdev *sd, u8 reg, u8 val)
118−{
119− struct i2c_client *client = v4l2_get_subdevdata(sd);
120− int ret;
121− int i;
122−
123− for (i = 0; i < 3; i++) {
124− ret = i2c_smbus_write_byte_data(client, reg, val);
125− if (ret == 0)
126− return 0;
127− }
128− v4l2_err(sd, "%s: failed reg 0x%x, val 0x%x\n", __func__, reg, val);
129− return ret;
130−}
131−
132−/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
133− and then the value-mask (to be OR-ed). */
134−static inline void ad9389b_wr_and_or(struct v4l2_subdev *sd, u8 reg,
135− u8 clr_mask, u8 val_mask)
136−{
137− ad9389b_wr(sd, reg, (ad9389b_rd(sd, reg) & clr_mask) | val_mask);
138−}
139−
140−static void ad9389b_edid_rd(struct v4l2_subdev *sd, u16 len, u8 *buf)
141−{
142− struct ad9389b_state *state = get_ad9389b_state(sd);
143− int i;
144−
145− v4l2_dbg(1, debug, sd, "%s:\n", __func__);
146−
147− for (i = 0; i < len; i++)
148− buf[i] = i2c_smbus_read_byte_data(state->edid_i2c_client, i);
149−}
150−
151−static inline bool ad9389b_have_hotplug(struct v4l2_subdev *sd)
152−{
153− return ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT;
154−}
155−
156−static inline bool ad9389b_have_rx_sense(struct v4l2_subdev *sd)
157−{
158− return ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT;
159−}
160−
161−static void ad9389b_csc_conversion_mode(struct v4l2_subdev *sd, u8 mode)
162−{
163− ad9389b_wr_and_or(sd, 0x17, 0xe7, (mode & 0x3)<<3);
164− ad9389b_wr_and_or(sd, 0x18, 0x9f, (mode & 0x3)<<5);
165−}
166−
167−static void ad9389b_csc_coeff(struct v4l2_subdev *sd,
168− u16 A1, u16 A2, u16 A3, u16 A4,
169− u16 B1, u16 B2, u16 B3, u16 B4,
170− u16 C1, u16 C2, u16 C3, u16 C4)
171−{
172− /* A */
173− ad9389b_wr_and_or(sd, 0x18, 0xe0, A1>>8);
174− ad9389b_wr(sd, 0x19, A1);
175− ad9389b_wr_and_or(sd, 0x1A, 0xe0, A2>>8);
176− ad9389b_wr(sd, 0x1B, A2);
177− ad9389b_wr_and_or(sd, 0x1c, 0xe0, A3>>8);
178− ad9389b_wr(sd, 0x1d, A3);
179− ad9389b_wr_and_or(sd, 0x1e, 0xe0, A4>>8);
180− ad9389b_wr(sd, 0x1f, A4);
181−
182− /* B */
183− ad9389b_wr_and_or(sd, 0x20, 0xe0, B1>>8);
184− ad9389b_wr(sd, 0x21, B1);
185− ad9389b_wr_and_or(sd, 0x22, 0xe0, B2>>8);
186− ad9389b_wr(sd, 0x23, B2);
187− ad9389b_wr_and_or(sd, 0x24, 0xe0, B3>>8);
188− ad9389b_wr(sd, 0x25, B3);
189− ad9389b_wr_and_or(sd, 0x26, 0xe0, B4>>8);
190− ad9389b_wr(sd, 0x27, B4);
191−
192− /* C */
193− ad9389b_wr_and_or(sd, 0x28, 0xe0, C1>>8);
194− ad9389b_wr(sd, 0x29, C1);
195− ad9389b_wr_and_or(sd, 0x2A, 0xe0, C2>>8);
196− ad9389b_wr(sd, 0x2B, C2);
197− ad9389b_wr_and_or(sd, 0x2C, 0xe0, C3>>8);
198− ad9389b_wr(sd, 0x2D, C3);
199− ad9389b_wr_and_or(sd, 0x2E, 0xe0, C4>>8);
200− ad9389b_wr(sd, 0x2F, C4);
201−}
202−
203−static void ad9389b_csc_rgb_full2limit(struct v4l2_subdev *sd, bool enable)
204−{
205− if (enable) {
206− u8 csc_mode = 0;
207−
208− ad9389b_csc_conversion_mode(sd, csc_mode);
209− ad9389b_csc_coeff(sd,
210− 4096-564, 0, 0, 256,
211− 0, 4096-564, 0, 256,
212− 0, 0, 4096-564, 256);
213− /* enable CSC */
214− ad9389b_wr_and_or(sd, 0x3b, 0xfe, 0x1);
215− /* AVI infoframe: Limited range RGB (16-235) */
216− ad9389b_wr_and_or(sd, 0xcd, 0xf9, 0x02);
217− } else {
218− /* disable CSC */
219− ad9389b_wr_and_or(sd, 0x3b, 0xfe, 0x0);
220− /* AVI infoframe: Full range RGB (0-255) */
221− ad9389b_wr_and_or(sd, 0xcd, 0xf9, 0x04);
222− }
223−}
224−
225−static void ad9389b_set_IT_content_AVI_InfoFrame(struct v4l2_subdev *sd)
226−{
227− struct ad9389b_state *state = get_ad9389b_state(sd);
228−
229− if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) {
230− /* CE format, not IT */
231− ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x00);
232− } else {
233− /* IT format */
234− ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x40);
235− }
236−}
237−
238−static int ad9389b_set_rgb_quantization_mode(struct v4l2_subdev *sd, struct v4l2_ctrl *ctrl)
239−{
240− struct ad9389b_state *state = get_ad9389b_state(sd);
241−
242− switch (ctrl->val) {
243− case V4L2_DV_RGB_RANGE_AUTO:
244− /* automatic */
245− if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) {
246− /* CE format, RGB limited range (16-235) */
247− ad9389b_csc_rgb_full2limit(sd, true);
248− } else {
249− /* not CE format, RGB full range (0-255) */
250− ad9389b_csc_rgb_full2limit(sd, false);
251− }
252− break;
253− case V4L2_DV_RGB_RANGE_LIMITED:
254− /* RGB limited range (16-235) */
255− ad9389b_csc_rgb_full2limit(sd, true);
256− break;
257− case V4L2_DV_RGB_RANGE_FULL:
258− /* RGB full range (0-255) */
259− ad9389b_csc_rgb_full2limit(sd, false);
260− break;
261− default:
262− return -EINVAL;
263− }
264− return 0;
265−}
266−
267−static void ad9389b_set_manual_pll_gear(struct v4l2_subdev *sd, u32 pixelclock)
268−{
269− u8 gear;
270−
271− /* Workaround for TMDS PLL problem
272− * The TMDS PLL in AD9389b change gear when the chip is heated above a
273− * certain temperature. The output is disabled when the PLL change gear
274− * so the monitor has to lock on the signal again. A workaround for
275− * this is to use the manual PLL gears. This is a solution from Analog
276− * Devices that is not documented in the datasheets.
277− * 0x98 [7] = enable manual gearing. 0x98 [6:4] = gear
278− *
279− * The pixel frequency ranges are based on readout of the gear the
280− * automatic gearing selects for different pixel clocks
281− * (read from 0x9e [3:1]).
282− */
283−
284− if (pixelclock > 140000000)
285− gear = 0xc0; /* 4th gear */
286− else if (pixelclock > 117000000)
287− gear = 0xb0; /* 3rd gear */
288− else if (pixelclock > 87000000)
289− gear = 0xa0; /* 2nd gear */
290− else if (pixelclock > 60000000)
291− gear = 0x90; /* 1st gear */
292− else
293− gear = 0x80; /* 0th gear */
294−
295− ad9389b_wr_and_or(sd, 0x98, 0x0f, gear);
296−}
297−
298−/* ------------------------------ CTRL OPS ------------------------------ */
299−
300−static int ad9389b_s_ctrl(struct v4l2_ctrl *ctrl)
301−{
302− struct v4l2_subdev *sd = to_sd(ctrl);
303− struct ad9389b_state *state = get_ad9389b_state(sd);
304−
305− v4l2_dbg(1, debug, sd,
306− "%s: ctrl id: %d, ctrl->val %d\n", __func__, ctrl->id, ctrl->val);
307−
308− if (state->hdmi_mode_ctrl == ctrl) {
309− /* Set HDMI or DVI-D */
310− ad9389b_wr_and_or(sd, 0xaf, 0xfd,
311− ctrl->val == V4L2_DV_TX_MODE_HDMI ? 0x02 : 0x00);
312− return 0;
313− }
314− if (state->rgb_quantization_range_ctrl == ctrl)
315− return ad9389b_set_rgb_quantization_mode(sd, ctrl);
316− return -EINVAL;
317−}
318−
319−static const struct v4l2_ctrl_ops ad9389b_ctrl_ops = {
320− .s_ctrl = ad9389b_s_ctrl,
321−};
322−
323−/* ---------------------------- CORE OPS ------------------------------------------- */
324−
325−#ifdef CONFIG_VIDEO_ADV_DEBUG
326−static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
327−{
328− reg->val = ad9389b_rd(sd, reg->reg & 0xff);
329− reg->size = 1;
330− return 0;
331−}
332−
333−static int ad9389b_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
334−{
335− ad9389b_wr(sd, reg->reg & 0xff, reg->val & 0xff);
336− return 0;
337−}
338−#endif
339−
340−static int ad9389b_log_status(struct v4l2_subdev *sd)
341−{
342− struct ad9389b_state *state = get_ad9389b_state(sd);
343− struct ad9389b_state_edid *edid = &state->edid;
344−
345− static const char * const states[] = {
346− "in reset",
347− "reading EDID",
348− "idle",
349− "initializing HDCP",
350− "HDCP enabled",
351− "initializing HDCP repeater",
352− "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"
353− };
354− static const char * const errors[] = {
355− "no error",
356− "bad receiver BKSV",
357− "Ri mismatch",
358− "Pj mismatch",
359− "i2c error",
360− "timed out",
361− "max repeater cascade exceeded",
362− "hash check failed",
363− "too many devices",
364− "9", "A", "B", "C", "D", "E", "F"
365− };
366−
367− u8 manual_gear;
368−
369− v4l2_info(sd, "chip revision %d\n", state->chip_revision);
370− v4l2_info(sd, "power %s\n", state->power_on ? "on" : "off");
371− v4l2_info(sd, "%s hotplug, %s Rx Sense, %s EDID (%d block(s))\n",
372− (ad9389b_rd(sd, 0x42) & MASK_AD9389B_HPD_DETECT) ?
373− "detected" : "no",
374− (ad9389b_rd(sd, 0x42) & MASK_AD9389B_MSEN_DETECT) ?
375− "detected" : "no",
376− edid->segments ? "found" : "no", edid->blocks);
377− v4l2_info(sd, "%s output %s\n",
378− (ad9389b_rd(sd, 0xaf) & 0x02) ?
379− "HDMI" : "DVI-D",
380− (ad9389b_rd(sd, 0xa1) & 0x3c) ?
381− "disabled" : "enabled");
382− v4l2_info(sd, "ad9389b: %s\n", (ad9389b_rd(sd, 0xb8) & 0x40) ?
383− "encrypted" : "no encryption");
384− v4l2_info(sd, "state: %s, error: %s, detect count: %u, msk/irq: %02x/%02x\n",
385− states[ad9389b_rd(sd, 0xc8) & 0xf],
386− errors[ad9389b_rd(sd, 0xc8) >> 4],
387− state->edid_detect_counter,
388− ad9389b_rd(sd, 0x94), ad9389b_rd(sd, 0x96));
389− manual_gear = ad9389b_rd(sd, 0x98) & 0x80;
390− v4l2_info(sd, "ad9389b: RGB quantization: %s range\n",
391− ad9389b_rd(sd, 0x3b) & 0x01 ? "limited" : "full");
392− v4l2_info(sd, "ad9389b: %s gear %d\n",
393− manual_gear ? "manual" : "automatic",
394− manual_gear ? ((ad9389b_rd(sd, 0x98) & 0x70) >> 4) :
395− ((ad9389b_rd(sd, 0x9e) & 0x0e) >> 1));
396− if (ad9389b_rd(sd, 0xaf) & 0x02) {
397− /* HDMI only */
398− u8 manual_cts = ad9389b_rd(sd, 0x0a) & 0x80;
399− u32 N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
400− ad9389b_rd(sd, 0x02) << 8 |
401− ad9389b_rd(sd, 0x03);
402− u8 vic_detect = ad9389b_rd(sd, 0x3e) >> 2;
403− u8 vic_sent = ad9389b_rd(sd, 0x3d) & 0x3f;
404− u32 CTS;
405−
406− if (manual_cts)
407− CTS = (ad9389b_rd(sd, 0x07) & 0xf) << 16 |
408− ad9389b_rd(sd, 0x08) << 8 |
409− ad9389b_rd(sd, 0x09);
410− else
411− CTS = (ad9389b_rd(sd, 0x04) & 0xf) << 16 |
412− ad9389b_rd(sd, 0x05) << 8 |
413− ad9389b_rd(sd, 0x06);
414− N = (ad9389b_rd(sd, 0x01) & 0xf) << 16 |
415− ad9389b_rd(sd, 0x02) << 8 |
416− ad9389b_rd(sd, 0x03);
417−
418− v4l2_info(sd, "ad9389b: CTS %s mode: N %d, CTS %d\n",
419− manual_cts ? "manual" : "automatic", N, CTS);
420−
421− v4l2_info(sd, "ad9389b: VIC: detected %d, sent %d\n",
422− vic_detect, vic_sent);
423− }
424− if (state->dv_timings.type == V4L2_DV_BT_656_1120)
425− v4l2_print_dv_timings(sd->name, "timings: ",
426− &state->dv_timings, false);
427− else
428− v4l2_info(sd, "no timings set\n");
429− return 0;
430−}
431−
432−/* Power up/down ad9389b */
433−static int ad9389b_s_power(struct v4l2_subdev *sd, int on)
434−{
435− struct ad9389b_state *state = get_ad9389b_state(sd);
436− struct ad9389b_platform_data *pdata = &state->pdata;
437− const int retries = 20;
438− int i;
439−
440− v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");
441−
442− state->power_on = on;
443−
444− if (!on) {
445− /* Power down */
446− ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x40);
447− return true;
448− }
449−
450− /* Power up */
451− /* The ad9389b does not always come up immediately.
452− Retry multiple times. */
453− for (i = 0; i < retries; i++) {
454− ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x0);
455− if ((ad9389b_rd(sd, 0x41) & 0x40) == 0)
456− break;
457− ad9389b_wr_and_or(sd, 0x41, 0xbf, 0x40);
458− msleep(10);
459− }
460− if (i == retries) {
461− v4l2_dbg(1, debug, sd, "failed to powerup the ad9389b\n");
462− ad9389b_s_power(sd, 0);
463− return false;
464− }
465− if (i > 1)
466− v4l2_dbg(1, debug, sd,
467− "needed %d retries to powerup the ad9389b\n", i);
468−
469− /* Select chip: AD9389B */
470− ad9389b_wr_and_or(sd, 0xba, 0xef, 0x10);
471−
472− /* Reserved registers that must be set according to REF_01 p. 11*/
473− ad9389b_wr_and_or(sd, 0x98, 0xf0, 0x07);
474− ad9389b_wr(sd, 0x9c, 0x38);
475− ad9389b_wr_and_or(sd, 0x9d, 0xfc, 0x01);
476−
477− /* Differential output drive strength */
478− if (pdata->diff_data_drive_strength > 0)
479− ad9389b_wr(sd, 0xa2, pdata->diff_data_drive_strength);
480− else
481− ad9389b_wr(sd, 0xa2, 0x87);
482−
483− if (pdata->diff_clk_drive_strength > 0)
484− ad9389b_wr(sd, 0xa3, pdata->diff_clk_drive_strength);
485− else
486− ad9389b_wr(sd, 0xa3, 0x87);
487−
488− ad9389b_wr(sd, 0x0a, 0x01);
489− ad9389b_wr(sd, 0xbb, 0xff);
490−
491− /* Set number of attempts to read the EDID */
492− ad9389b_wr(sd, 0xc9, 0xf);
493− return true;
494−}
495−
496−/* Enable interrupts */
497−static void ad9389b_set_isr(struct v4l2_subdev *sd, bool enable)
498−{
499− u8 irqs = MASK_AD9389B_HPD_INT | MASK_AD9389B_MSEN_INT;
500− u8 irqs_rd;
501− int retries = 100;
502−
503− /* The datasheet says that the EDID ready interrupt should be
504− disabled if there is no hotplug. */
505− if (!enable)
506− irqs = 0;
507− else if (ad9389b_have_hotplug(sd))
508− irqs |= MASK_AD9389B_EDID_RDY_INT;
509−
510− /*
511− * This i2c write can fail (approx. 1 in 1000 writes). But it
512− * is essential that this register is correct, so retry it
513− * multiple times.
514− *
515− * Note that the i2c write does not report an error, but the readback
516− * clearly shows the wrong value.
517− */
518− do {
519− ad9389b_wr(sd, 0x94, irqs);
520− irqs_rd = ad9389b_rd(sd, 0x94);
521− } while (retries-- && irqs_rd != irqs);
522−
523− if (irqs_rd != irqs)
524− v4l2_err(sd, "Could not set interrupts: hw failure?\n");
525−}
526−
527−/* Interrupt handler */
528−static int ad9389b_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
529−{
530− u8 irq_status;
531−
532− /* disable interrupts to prevent a race condition */
533− ad9389b_set_isr(sd, false);
534− irq_status = ad9389b_rd(sd, 0x96);
535− /* clear detected interrupts */
536− ad9389b_wr(sd, 0x96, irq_status);
537− /* enable interrupts */
538− ad9389b_set_isr(sd, true);
539−
540− v4l2_dbg(1, debug, sd, "%s: irq_status 0x%x\n", __func__, irq_status);
541−
542− if (irq_status & (MASK_AD9389B_HPD_INT))
543− ad9389b_check_monitor_present_status(sd);
544− if (irq_status & MASK_AD9389B_EDID_RDY_INT)
545− ad9389b_check_edid_status(sd);
546−
547− *handled = true;
548− return 0;
549−}
550−
551−static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
552− .log_status = ad9389b_log_status,
553−#ifdef CONFIG_VIDEO_ADV_DEBUG
554− .g_register = ad9389b_g_register,
555− .s_register = ad9389b_s_register,
556−#endif
557− .s_power = ad9389b_s_power,
558− .interrupt_service_routine = ad9389b_isr,
559−};
560−
561−/* ------------------------------ VIDEO OPS ------------------------------ */
562−
563−/* Enable/disable ad9389b output */
564−static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable)
565−{
566− v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
567−
568− ad9389b_wr_and_or(sd, 0xa1, ~0x3c, (enable ? 0 : 0x3c));
569− if (enable) {
570− ad9389b_check_monitor_present_status(sd);
571− } else {
572− ad9389b_s_power(sd, 0);
573− }
574− return 0;
575−}
576−
577−static const struct v4l2_dv_timings_cap ad9389b_timings_cap = {
578− .type = V4L2_DV_BT_656_1120,
579− /* keep this initialization for compatibility with GCC < 4.4.6 */
580− .reserved = { 0 },
581− V4L2_INIT_BT_TIMINGS(640, 1920, 350, 1200, 25000000, 170000000,
582− V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
583− V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
584− V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING |
585− V4L2_DV_BT_CAP_CUSTOM)
586−};
587−
588−static int ad9389b_s_dv_timings(struct v4l2_subdev *sd,
589− struct v4l2_dv_timings *timings)
590−{
591− struct ad9389b_state *state = get_ad9389b_state(sd);
592−
593− v4l2_dbg(1, debug, sd, "%s:\n", __func__);
594−
595− /* quick sanity check */
596− if (!v4l2_valid_dv_timings(timings, &ad9389b_timings_cap, NULL, NULL))
597− return -EINVAL;
598−
599− /* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
600− if the format is one of the CEA or DMT timings. */
601− v4l2_find_dv_timings_cap(timings, &ad9389b_timings_cap, 0, NULL, NULL);
602−
603− timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
604−
605− /* save timings */
606− state->dv_timings = *timings;
607−
608− /* update quantization range based on new dv_timings */
609− ad9389b_set_rgb_quantization_mode(sd, state->rgb_quantization_range_ctrl);
610−
611− /* update PLL gear based on new dv_timings */
612− if (state->pdata.tmds_pll_gear == AD9389B_TMDS_PLL_GEAR_SEMI_AUTOMATIC)
613− ad9389b_set_manual_pll_gear(sd, (u32)timings->bt.pixelclock);
614−
615− /* update AVI infoframe */
616− ad9389b_set_IT_content_AVI_InfoFrame(sd);
617−
618− return 0;
619−}
620−
621−static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
622− struct v4l2_dv_timings *timings)
623−{
624− struct ad9389b_state *state = get_ad9389b_state(sd);
625−
626− v4l2_dbg(1, debug, sd, "%s:\n", __func__);
627−
628− if (!timings)
629− return -EINVAL;
630−
631− *timings = state->dv_timings;
632−
633− return 0;
634−}
635−
636−static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
637− struct v4l2_enum_dv_timings *timings)
638−{
639− if (timings->pad != 0)
640− return -EINVAL;
641−
642− return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
643− NULL, NULL);
644−}
645−
646−static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
647− struct v4l2_dv_timings_cap *cap)
648−{
649− if (cap->pad != 0)
650− return -EINVAL;
651−
652− *cap = ad9389b_timings_cap;
653− return 0;
654−}
655−
656−static const struct v4l2_subdev_video_ops ad9389b_video_ops = {
657− .s_stream = ad9389b_s_stream,
658− .s_dv_timings = ad9389b_s_dv_timings,
659− .g_dv_timings = ad9389b_g_dv_timings,
660−};
661−
662−/* ------------------------------ PAD OPS ------------------------------ */
663−
664−static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
665−{
666− struct ad9389b_state *state = get_ad9389b_state(sd);
667−
668− if (edid->pad != 0)
669− return -EINVAL;
670− if (edid->blocks == 0 || edid->blocks > 256)
671− return -EINVAL;
672− if (!state->edid.segments) {
673− v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
674− return -ENODATA;
675− }
676− if (edid->start_block >= state->edid.segments * 2)
677− return -E2BIG;
678− if (edid->blocks + edid->start_block >= state->edid.segments * 2)
679− edid->blocks = state->edid.segments * 2 - edid->start_block;
680− memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
681− 128 * edid->blocks);
682− return 0;
683−}
684−
685−static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
686− .get_edid = ad9389b_get_edid,
687− .enum_dv_timings = ad9389b_enum_dv_timings,
688− .dv_timings_cap = ad9389b_dv_timings_cap,
689−};
690−
691−/* ------------------------------ AUDIO OPS ------------------------------ */
692−
693−static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable)
694−{
695− v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
696−
697− if (enable)
698− ad9389b_wr_and_or(sd, 0x45, 0x3f, 0x80);
699− else
700− ad9389b_wr_and_or(sd, 0x45, 0x3f, 0x40);
701−
702− return 0;
703−}
704−
705−static int ad9389b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
706−{
707− u32 N;
708−
709− switch (freq) {
710− case 32000: N = 4096; break;
711− case 44100: N = 6272; break;
712− case 48000: N = 6144; break;
713− case 88200: N = 12544; break;
714− case 96000: N = 12288; break;
715− case 176400: N = 25088; break;
716− case 192000: N = 24576; break;
717− default:
718− return -EINVAL;
719− }
720−
721− /* Set N (used with CTS to regenerate the audio clock) */
722− ad9389b_wr(sd, 0x01, (N >> 16) & 0xf);
723− ad9389b_wr(sd, 0x02, (N >> 8) & 0xff);
724− ad9389b_wr(sd, 0x03, N & 0xff);
725−
726− return 0;
727−}
728−
729−static int ad9389b_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
730−{
731− u32 i2s_sf;
732−
733− switch (freq) {
734− case 32000: i2s_sf = 0x30; break;
735− case 44100: i2s_sf = 0x00; break;
736− case 48000: i2s_sf = 0x20; break;
737− case 88200: i2s_sf = 0x80; break;
738− case 96000: i2s_sf = 0xa0; break;
739− case 176400: i2s_sf = 0xc0; break;
740− case 192000: i2s_sf = 0xe0; break;
741− default:
742− return -EINVAL;
743− }
744−
745− /* Set sampling frequency for I2S audio to 48 kHz */
746− ad9389b_wr_and_or(sd, 0x15, 0xf, i2s_sf);
747−
748− return 0;
749−}
750−
751−static int ad9389b_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, u32 config)
752−{
753− /* TODO based on input/output/config */
754− /* TODO See datasheet "Programmers guide" p. 39-40 */
755−
756− /* Only 2 channels in use for application */
757− ad9389b_wr_and_or(sd, 0x50, 0x1f, 0x20);
758− /* Speaker mapping */
759− ad9389b_wr(sd, 0x51, 0x00);
760−
761− /* TODO Where should this be placed? */
762− /* 16 bit audio word length */
763− ad9389b_wr_and_or(sd, 0x14, 0xf0, 0x02);
764−
765− return 0;
766−}
767−
768−static const struct v4l2_subdev_audio_ops ad9389b_audio_ops = {
769− .s_stream = ad9389b_s_audio_stream,
770− .s_clock_freq = ad9389b_s_clock_freq,
771− .s_i2s_clock_freq = ad9389b_s_i2s_clock_freq,
772− .s_routing = ad9389b_s_routing,
773−};
774−
775−/* --------------------- SUBDEV OPS --------------------------------------- */
776−
777−static const struct v4l2_subdev_ops ad9389b_ops = {
778− .core = &ad9389b_core_ops,
779− .video = &ad9389b_video_ops,
780− .audio = &ad9389b_audio_ops,
781− .pad = &ad9389b_pad_ops,
782−};
783−
784−/* ----------------------------------------------------------------------- */
785−static void ad9389b_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd,
786− int segment, u8 *buf)
787−{
788− int i, j;
789−
790− if (debug < lvl)
791− return;
792−
793− v4l2_dbg(lvl, debug, sd, "edid segment %d\n", segment);
794− for (i = 0; i < 256; i += 16) {
795− u8 b[128];
796− u8 *bp = b;
797−
798− if (i == 128)
799− v4l2_dbg(lvl, debug, sd, "\n");
800− for (j = i; j < i + 16; j++) {
801− sprintf(bp, "0x%02x, ", buf[j]);
802− bp += 6;
803− }
804− bp[0] = '\0';
805− v4l2_dbg(lvl, debug, sd, "%s\n", b);
806− }
807−}
808−
809−static void ad9389b_edid_handler(struct work_struct *work)
810−{
811− struct delayed_work *dwork = to_delayed_work(work);
812− struct ad9389b_state *state =
813− container_of(dwork, struct ad9389b_state, edid_handler);
814− struct v4l2_subdev *sd = &state->sd;
815− struct ad9389b_edid_detect ed;
816−
817− v4l2_dbg(1, debug, sd, "%s:\n", __func__);
818−
819− if (ad9389b_check_edid_status(sd)) {
820− /* Return if we received the EDID. */
821− return;
822− }
823−
824− if (ad9389b_have_hotplug(sd)) {
825− /* We must retry reading the EDID several times, it is possible
826− * that initially the EDID couldn't be read due to i2c errors
827− * (DVI connectors are particularly prone to this problem). */
828− if (state->edid.read_retries) {
829− state->edid.read_retries--;
830− v4l2_dbg(1, debug, sd, "%s: edid read failed\n", __func__);
831− ad9389b_s_power(sd, false);
832− ad9389b_s_power(sd, true);
833− schedule_delayed_work(&state->edid_handler, EDID_DELAY);
834− return;
835− }
836− }
837−
838− /* We failed to read the EDID, so send an event for this. */
839− ed.present = false;
840− ed.segment = ad9389b_rd(sd, 0xc4);
841− v4l2_subdev_notify(sd, AD9389B_EDID_DETECT, (void *)&ed);
842− v4l2_dbg(1, debug, sd, "%s: no edid found\n", __func__);
843−}
844−
845−static void ad9389b_audio_setup(struct v4l2_subdev *sd)
846−{
847− v4l2_dbg(1, debug, sd, "%s\n", __func__);
848−
849− ad9389b_s_i2s_clock_freq(sd, 48000);
850− ad9389b_s_clock_freq(sd, 48000);
851− ad9389b_s_routing(sd, 0, 0, 0);
852−}
853−
854−/* Initial setup of AD9389b */
855−
856−/* Configure hdmi transmitter. */
857−static void ad9389b_setup(struct v4l2_subdev *sd)
858−{
859− struct ad9389b_state *state = get_ad9389b_state(sd);
860−
861− v4l2_dbg(1, debug, sd, "%s\n", __func__);
862−
863− /* Input format: RGB 4:4:4 */
864− ad9389b_wr_and_or(sd, 0x15, 0xf1, 0x0);
865− /* Output format: RGB 4:4:4 */
866− ad9389b_wr_and_or(sd, 0x16, 0x3f, 0x0);
867− /* 1st order interpolation 4:2:2 -> 4:4:4 up conversion,
868− Aspect ratio: 16:9 */
869− ad9389b_wr_and_or(sd, 0x17, 0xf9, 0x06);
870− /* Output format: RGB 4:4:4, Active Format Information is valid. */
871− ad9389b_wr_and_or(sd, 0x45, 0xc7, 0x08);
872− /* Underscanned */
873− ad9389b_wr_and_or(sd, 0x46, 0x3f, 0x80);
874− /* Setup video format */
875− ad9389b_wr(sd, 0x3c, 0x0);
876− /* Active format aspect ratio: same as picure. */
877− ad9389b_wr(sd, 0x47, 0x80);
878− /* No encryption */
879− ad9389b_wr_and_or(sd, 0xaf, 0xef, 0x0);
880− /* Positive clk edge capture for input video clock */
881− ad9389b_wr_and_or(sd, 0xba, 0x1f, 0x60);
882−
883− ad9389b_audio_setup(sd);
884−
885− v4l2_ctrl_handler_setup(&state->hdl);
886−
887− ad9389b_set_IT_content_AVI_InfoFrame(sd);
888−}
889−
890−static void ad9389b_notify_monitor_detect(struct v4l2_subdev *sd)
891−{
892− struct ad9389b_monitor_detect mdt;
893− struct ad9389b_state *state = get_ad9389b_state(sd);
894−
895− mdt.present = state->have_monitor;
896− v4l2_subdev_notify(sd, AD9389B_MONITOR_DETECT, (void *)&mdt);
897−}
898−
899−static void ad9389b_update_monitor_present_status(struct v4l2_subdev *sd)
900−{
901− struct ad9389b_state *state = get_ad9389b_state(sd);
902− /* read hotplug and rx-sense state */
903− u8 status = ad9389b_rd(sd, 0x42);
904−
905− v4l2_dbg(1, debug, sd, "%s: status: 0x%x%s%s\n",
906− __func__,
907− status,
908− status & MASK_AD9389B_HPD_DETECT ? ", hotplug" : "",
909− status & MASK_AD9389B_MSEN_DETECT ? ", rx-sense" : "");
910−
911− if (status & MASK_AD9389B_HPD_DETECT) {
912− v4l2_dbg(1, debug, sd, "%s: hotplug detected\n", __func__);
913− state->have_monitor = true;
914− if (!ad9389b_s_power(sd, true)) {
915− v4l2_dbg(1, debug, sd,
916− "%s: monitor detected, powerup failed\n", __func__);
917− return;
918− }
919− ad9389b_setup(sd);
920− ad9389b_notify_monitor_detect(sd);
921− state->edid.read_retries = EDID_MAX_RETRIES;
922− schedule_delayed_work(&state->edid_handler, EDID_DELAY);
923− } else if (!(status & MASK_AD9389B_HPD_DETECT)) {
924− v4l2_dbg(1, debug, sd, "%s: hotplug not detected\n", __func__);
925− state->have_monitor = false;
926− ad9389b_notify_monitor_detect(sd);
927− ad9389b_s_power(sd, false);
928− memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
929− }
930−
931− /* update read only ctrls */
932− v4l2_ctrl_s_ctrl(state->hotplug_ctrl, ad9389b_have_hotplug(sd) ? 0x1 : 0x0);
933− v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, ad9389b_have_rx_sense(sd) ? 0x1 : 0x0);
934− v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
935−
936− /* update with setting from ctrls */
937− ad9389b_s_ctrl(state->rgb_quantization_range_ctrl);
938− ad9389b_s_ctrl(state->hdmi_mode_ctrl);
939−}
940−
941−static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
942−{
943− struct ad9389b_state *state = get_ad9389b_state(sd);
944− int retry = 0;
945−
946− ad9389b_update_monitor_present_status(sd);
947−
948− /*
949− * Rapid toggling of the hotplug may leave the chip powered off,
950− * even if we think it is on. In that case reset and power up again.
951− */
952− while (state->power_on && (ad9389b_rd(sd, 0x41) & 0x40)) {
953− if (++retry > 5) {
954− v4l2_err(sd, "retried %d times, give up\n", retry);
955− return;
956− }
957− v4l2_dbg(1, debug, sd, "%s: reset and re-check status (%d)\n", __func__, retry);
958− ad9389b_notify_monitor_detect(sd);
959− cancel_delayed_work_sync(&state->edid_handler);
960− memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
961− ad9389b_s_power(sd, false);
962− ad9389b_update_monitor_present_status(sd);
963− }
964−}
965−
966−static bool edid_block_verify_crc(u8 *edid_block)
967−{
968− u8 sum = 0;
969− int i;
970−
971− for (i = 0; i < 128; i++)
972− sum += edid_block[i];
973− return sum == 0;
974−}
975−
976−static bool edid_verify_crc(struct v4l2_subdev *sd, u32 segment)
977−{
978− struct ad9389b_state *state = get_ad9389b_state(sd);
979− u32 blocks = state->edid.blocks;
980− u8 *data = state->edid.data;
981−
982− if (edid_block_verify_crc(&data[segment * 256])) {
983− if ((segment + 1) * 2 <= blocks)
984− return edid_block_verify_crc(&data[segment * 256 + 128]);
985− return true;
986− }
987− return false;
988−}
989−
990−static bool edid_verify_header(struct v4l2_subdev *sd, u32 segment)
991−{
992− static const u8 hdmi_header[] = {
993− 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
994− };
995− struct ad9389b_state *state = get_ad9389b_state(sd);
996− u8 *data = state->edid.data;
997− int i;
998−
999− if (segment)
1000− return true;
1001−
1002− for (i = 0; i < ARRAY_SIZE(hdmi_header); i++)
1003− if (data[i] != hdmi_header[i])
1004− return false;
1005−
1006− return true;
1007−}
1008−
1009−static bool ad9389b_check_edid_status(struct v4l2_subdev *sd)
1010−{
1011− struct ad9389b_state *state = get_ad9389b_state(sd);
1012− struct ad9389b_edid_detect ed;
1013− int segment;
1014− u8 edidRdy = ad9389b_rd(sd, 0xc5);
1015−
1016− v4l2_dbg(1, debug, sd, "%s: edid ready (retries: %d)\n",
1017− __func__, EDID_MAX_RETRIES - state->edid.read_retries);
1018−
1019− if (!(edidRdy & MASK_AD9389B_EDID_RDY))
1020− return false;
1021−
1022− segment = ad9389b_rd(sd, 0xc4);
1023− if (segment >= EDID_MAX_SEGM) {
1024− v4l2_err(sd, "edid segment number too big\n");
1025− return false;
1026− }
1027− v4l2_dbg(1, debug, sd, "%s: got segment %d\n", __func__, segment);
1028− ad9389b_edid_rd(sd, 256, &state->edid.data[segment * 256]);
1029− ad9389b_dbg_dump_edid(2, debug, sd, segment,
1030− &state->edid.data[segment * 256]);
1031− if (segment == 0) {
1032− state->edid.blocks = state->edid.data[0x7e] + 1;
1033− v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n",
1034− __func__, state->edid.blocks);
1035− }
1036− if (!edid_verify_crc(sd, segment) ||
1037− !edid_verify_header(sd, segment)) {
1038− /* edid crc error, force reread of edid segment */
1039− v4l2_err(sd, "%s: edid crc or header error\n", __func__);
1040− ad9389b_s_power(sd, false);
1041− ad9389b_s_power(sd, true);
1042− return false;
1043− }
1044− /* one more segment read ok */
1045− state->edid.segments = segment + 1;
1046− if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
1047− /* Request next EDID segment */
1048− v4l2_dbg(1, debug, sd, "%s: request segment %d\n",
1049− __func__, state->edid.segments);
1050− ad9389b_wr(sd, 0xc9, 0xf);
1051− ad9389b_wr(sd, 0xc4, state->edid.segments);
1052− state->edid.read_retries = EDID_MAX_RETRIES;
1053− schedule_delayed_work(&state->edid_handler, EDID_DELAY);
1054− return false;
1055− }
1056−
1057− /* report when we have all segments but report only for segment 0 */
1058− ed.present = true;
1059− ed.segment = 0;
1060− v4l2_subdev_notify(sd, AD9389B_EDID_DETECT, (void *)&ed);
1061− state->edid_detect_counter++;
1062− v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
1063− return ed.present;
1064−}
1065−
1066−/* ----------------------------------------------------------------------- */
1067−
1068−static void ad9389b_init_setup(struct v4l2_subdev *sd)
1069−{
1070− struct ad9389b_state *state = get_ad9389b_state(sd);
1071− struct ad9389b_state_edid *edid = &state->edid;
1072−
1073− v4l2_dbg(1, debug, sd, "%s\n", __func__);
1074−
1075− /* clear all interrupts */
1076− ad9389b_wr(sd, 0x96, 0xff);
1077−
1078− memset(edid, 0, sizeof(struct ad9389b_state_edid));
1079− state->have_monitor = false;
1080− ad9389b_set_isr(sd, false);
1081−}
1082−
1083−static int ad9389b_probe(struct i2c_client *client)
1084−{
1085− const struct v4l2_dv_timings dv1080p60 = V4L2_DV_BT_CEA_1920X1080P60;
1086− struct ad9389b_state *state;
1087− struct ad9389b_platform_data *pdata = client->dev.platform_data;
1088− struct v4l2_ctrl_handler *hdl;
1089− struct v4l2_subdev *sd;
1090− int err = -EIO;
1091−
1092− /* Check if the adapter supports the needed features */
1093− if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1094− return -EIO;
1095−
1096− v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
1097− client->addr << 1);
1098−
1099− state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
1100− if (!state)
1101− return -ENOMEM;
1102−
1103− /* Platform data */
1104− if (pdata == NULL) {
1105− v4l_err(client, "No platform data!\n");
1106− return -ENODEV;
1107− }
1108− memcpy(&state->pdata, pdata, sizeof(state->pdata));
1109−
1110− sd = &state->sd;
1111− v4l2_i2c_subdev_init(sd, client, &ad9389b_ops);
1112− sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1113−
1114− hdl = &state->hdl;
1115− v4l2_ctrl_handler_init(hdl, 5);
1116−
1117− state->hdmi_mode_ctrl = v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
1118− V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1119− 0, V4L2_DV_TX_MODE_DVI_D);
1120− state->hotplug_ctrl = v4l2_ctrl_new_std(hdl, NULL,
1121− V4L2_CID_DV_TX_HOTPLUG, 0, 1, 0, 0);
1122− state->rx_sense_ctrl = v4l2_ctrl_new_std(hdl, NULL,
1123− V4L2_CID_DV_TX_RXSENSE, 0, 1, 0, 0);
1124− state->have_edid0_ctrl = v4l2_ctrl_new_std(hdl, NULL,
1125− V4L2_CID_DV_TX_EDID_PRESENT, 0, 1, 0, 0);
1126− state->rgb_quantization_range_ctrl =
1127− v4l2_ctrl_new_std_menu(hdl, &ad9389b_ctrl_ops,
1128− V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1129− 0, V4L2_DV_RGB_RANGE_AUTO);
1130− sd->ctrl_handler = hdl;
1131− if (hdl->error) {
1132− err = hdl->error;
1133−
1134− goto err_hdl;
1135− }
1136− state->pad.flags = MEDIA_PAD_FL_SINK;
1137− sd->entity.function = MEDIA_ENT_F_DV_ENCODER;
1138− err = media_entity_pads_init(&sd->entity, 1, &state->pad);
1139− if (err)
1140− goto err_hdl;
1141−
1142− state->chip_revision = ad9389b_rd(sd, 0x0);
1143− if (state->chip_revision != 2) {
1144− v4l2_err(sd, "chip_revision %d != 2\n", state->chip_revision);
1145− err = -EIO;
1146− goto err_entity;
1147− }
1148− v4l2_dbg(1, debug, sd, "reg 0x41 0x%x, chip version (reg 0x00) 0x%x\n",
1149− ad9389b_rd(sd, 0x41), state->chip_revision);
1150−
1151− state->edid_i2c_client = i2c_new_dummy_device(client->adapter, (0x7e >> 1));
1152− if (IS_ERR(state->edid_i2c_client)) {
1153− v4l2_err(sd, "failed to register edid i2c client\n");
1154− err = PTR_ERR(state->edid_i2c_client);
1155− goto err_entity;
1156− }
1157−
1158− INIT_DELAYED_WORK(&state->edid_handler, ad9389b_edid_handler);
1159− state->dv_timings = dv1080p60;
1160−
1161− ad9389b_init_setup(sd);
1162− ad9389b_set_isr(sd, true);
1163−
1164− v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
1165− client->addr << 1, client->adapter->name);
1166− return 0;
1167−
1168−err_entity:
1169− media_entity_cleanup(&sd->entity);
1170−err_hdl:
1171− v4l2_ctrl_handler_free(&state->hdl);
1172− return err;
1173−}
1174−
1175−/* ----------------------------------------------------------------------- */
1176−
1177−static void ad9389b_remove(struct i2c_client *client)
1178−{
1179− struct v4l2_subdev *sd = i2c_get_clientdata(client);
1180− struct ad9389b_state *state = get_ad9389b_state(sd);
1181−
1182− state->chip_revision = -1;
1183−
1184− v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
1185− client->addr << 1, client->adapter->name);
1186−
1187− ad9389b_s_stream(sd, false);
1188− ad9389b_s_audio_stream(sd, false);
1189− ad9389b_init_setup(sd);
1190− cancel_delayed_work_sync(&state->edid_handler);
1191− i2c_unregister_device(state->edid_i2c_client);
1192− v4l2_device_unregister_subdev(sd);
1193− media_entity_cleanup(&sd->entity);
1194− v4l2_ctrl_handler_free(sd->ctrl_handler);
1195−}
1196−
1197−/* ----------------------------------------------------------------------- */
1198−
1199−static const struct i2c_device_id ad9389b_id[] = {
1200− { "ad9389b", 0 },
1201− { "ad9889b", 0 },
1202− { }
1203−};
1204−MODULE_DEVICE_TABLE(i2c, ad9389b_id);
1205−
1206−static struct i2c_driver ad9389b_driver = {
1207− .driver = {
1208− .name = "ad9389b",
1209− },
1210− .probe_new = ad9389b_probe,
1211− .remove = ad9389b_remove,
1212− .id_table = ad9389b_id,
1213−};
1214−
1215−module_i2c_driver(ad9389b_driver);
drivers/media/i2c/adv748x/adv748x-hdmi.c+15−6
@@ -176,9 +176,9 @@ static int adv748x_hdmi_set_video_timings(struct adv748x_state *state, · 175 unmodified lines
176176 unsigned int i;
177177
178178 for (i = 0; i < ARRAY_SIZE(adv748x_hdmi_video_standards); i++) {
179− if (!v4l2_match_dv_timings(timings, &stds[i].timings, 250000,
180− false))
181− continue;
179+ if (v4l2_match_dv_timings(timings, &stds[i].timings, 250000,
180+ false))
181+ break;
182182 }
183183
184184 if (i >= ARRAY_SIZE(adv748x_hdmi_video_standards))
@@ -283,6 +283,16 @@ static int adv748x_hdmi_query_dv_timings(struct v4l2_subdev *sd, · 98 unmodified lines
283283
284284 memset(timings, 0, sizeof(struct v4l2_dv_timings));
285285
286+ /*
287+ * If the pattern generator is enabled the device shall not be queried
288+ * for timings. Instead the timings programmed shall be reported as they
289+ * are the ones being used to generate the pattern.
290+ */
291+ if (cp_read(state, ADV748X_CP_PAT_GEN) & ADV748X_CP_PAT_GEN_EN) {
292+ *timings = hdmi->timings;
293+ return 0;
294+ }
295+
286296 if (!adv748x_hdmi_has_signal(state))
287297 return -ENOLINK;
288298
@@ -721,11 +731,10 @@ static int adv748x_hdmi_init_controls(struct adv748x_hdmi *hdmi) · 432 unmodified lines
721731 int adv748x_hdmi_init(struct adv748x_hdmi *hdmi)
722732 {
723733 struct adv748x_state *state = adv748x_hdmi_to_state(hdmi);
724− static const struct v4l2_dv_timings cea1280x720 =
725− V4L2_DV_BT_CEA_1280X720P30;
734+ struct v4l2_dv_timings cea1280x720 = V4L2_DV_BT_CEA_1280X720P30;
726735 int ret;
727736
728− hdmi->timings = cea1280x720;
737+ adv748x_hdmi_s_dv_timings(&hdmi->sd, &cea1280x720);
729738
730739 /* Initialise a default 16:9 aspect ratio */
731740 hdmi->aspect_ratio.numerator = 16;
drivers/media/i2c/adv7604.c+4−1
@@ -1805,6 +1805,9 @@ static void select_input(struct v4l2_subdev *sd) · 1804 unmodified lines
18051805 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n",
18061806 __func__, state->selected_input);
18071807 }
1808+
1809+ /* Enable video adjustment (contrast, saturation, brightness and hue) */
1810+ cp_write_clr_set(sd, 0x3e, 0x80, 0x80);
18081811 }
18091812
18101813 static int adv76xx_s_routing(struct v4l2_subdev *sd,
@@ -3545,7 +3548,7 @@ static int adv76xx_probe(struct i2c_client *client) · 1734 unmodified lines
35453548 v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops,
35463549 V4L2_CID_SATURATION, 0, 255, 1, 128);
35473550 v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops,
3548− V4L2_CID_HUE, 0, 128, 1, 0);
3551+ V4L2_CID_HUE, 0, 255, 1, 0);
35493552 ctrl = v4l2_ctrl_new_std_menu(hdl, &adv76xx_ctrl_ops,
35503553 V4L2_CID_DV_RX_IT_CONTENT_TYPE, V4L2_DV_IT_CONTENT_TYPE_NO_ITC,
35513554 0, V4L2_DV_IT_CONTENT_TYPE_NO_ITC);
drivers/media/i2c/ccs/ccs-core.c+83−74
@@ -569,8 +569,6 @@ static u32 ccs_pixel_order(struct ccs_sensor *sensor) · 568 unmodified lines
569569 flip |= CCS_IMAGE_ORIENTATION_VERTICAL_FLIP;
570570 }
571571
572− flip ^= sensor->hvflip_inv_mask;
573−
574572 dev_dbg(&client->dev, "flip %u\n", flip);
575573 return sensor->default_pixel_order ^ flip;
576574 }
@@ -632,8 +630,6 @@ static int ccs_set_ctrl(struct v4l2_ctrl *ctrl) · 55 unmodified lines
632630 if (sensor->vflip->val)
633631 orient |= CCS_IMAGE_ORIENTATION_VERTICAL_FLIP;
634632
635− orient ^= sensor->hvflip_inv_mask;
636−
637633 ccs_update_mbus_formats(sensor);
638634
639635 break;
@@ -800,14 +796,24 @@ static const struct v4l2_ctrl_ops ccs_ctrl_ops = { · 160 unmodified lines
800796 static int ccs_init_controls(struct ccs_sensor *sensor)
801797 {
802798 struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
799+ struct v4l2_fwnode_device_properties props;
803800 int rval;
804801
805− rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 17);
802+ rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 19);
806803 if (rval)
807804 return rval;
808805
809806 sensor->pixel_array->ctrl_handler.lock = &sensor->mutex;
810807
808+ rval = v4l2_fwnode_device_parse(&client->dev, &props);
809+ if (rval)
810+ return rval;
811+
812+ rval = v4l2_ctrl_new_fwnode_properties(&sensor->pixel_array->ctrl_handler,
813+ &ccs_ctrl_ops, &props);
814+ if (rval)
815+ return rval;
816+
811817 switch (CCS_LIM(sensor, ANALOG_GAIN_CAPABILITY)) {
812818 case CCS_ANALOG_GAIN_CAPABILITY_GLOBAL: {
813819 struct {
@@ -2828,6 +2834,10 @@ static int ccs_identify_module(struct ccs_sensor *sensor) · 2014 unmodified lines
28282834 rval = ccs_read_addr_8only(sensor,
28292835 CCS_R_SENSOR_REVISION_NUMBER,
28302836 &minfo->sensor_revision_number);
2837+ if (!rval && !minfo->sensor_revision_number)
2838+ rval = ccs_read_addr_8only(sensor,
2839+ CCS_R_SENSOR_REVISION_NUMBER_16,
2840+ &minfo->sensor_revision_number);
28312841 if (!rval)
28322842 rval = ccs_read_addr_8only(sensor,
28332843 CCS_R_SENSOR_FIRMWARE_VERSION,
@@ -2870,7 +2880,7 @@ static int ccs_identify_module(struct ccs_sensor *sensor) · 36 unmodified lines
28702880 minfo->sensor_model_id);
28712881
28722882 dev_dbg(&client->dev,
2873− "sensor revision 0x%2.2x firmware version 0x%2.2x\n",
2883+ "sensor revision 0x%4.4x firmware version 0x%2.2x\n",
28742884 minfo->sensor_revision_number, minfo->sensor_firmware_version);
28752885
28762886 if (minfo->ccs_version) {
@@ -2884,19 +2894,18 @@ static int ccs_identify_module(struct ccs_sensor *sensor) · 7 unmodified lines
28842894 "smia version %2.2d smiapp version %2.2d\n",
28852895 minfo->smia_version, minfo->smiapp_version);
28862896 minfo->name = SMIAPP_NAME;
2887− }
2888−
2889− /*
2890− * Some modules have bad data in the lvalues below. Hope the
2891− * rvalues have better stuff. The lvalues are module
2892− * parameters whereas the rvalues are sensor parameters.
2893− */
2894− if (minfo->sensor_smia_manufacturer_id &&
2895− !minfo->smia_manufacturer_id && !minfo->model_id) {
2896− minfo->smia_manufacturer_id =
2897− minfo->sensor_smia_manufacturer_id;
2898− minfo->model_id = minfo->sensor_model_id;
2899− minfo->revision_number = minfo->sensor_revision_number;
2897+ /*
2898+ * Some modules have bad data in the lvalues below. Hope the
2899+ * rvalues have better stuff. The lvalues are module
2900+ * parameters whereas the rvalues are sensor parameters.
2901+ */
2902+ if (minfo->sensor_smia_manufacturer_id &&
2903+ !minfo->smia_manufacturer_id && !minfo->model_id) {
2904+ minfo->smia_manufacturer_id =
2905+ minfo->sensor_smia_manufacturer_id;
2906+ minfo->model_id = minfo->sensor_model_id;
2907+ minfo->revision_number = minfo->sensor_revision_number;
2908+ }
29002909 }
29012910
29022911 for (i = 0; i < ARRAY_SIZE(ccs_module_idents); i++) {
@@ -3185,7 +3194,6 @@ static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) · 282 unmodified lines
31853194 struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = V4L2_MBUS_UNKNOWN };
31863195 struct fwnode_handle *ep;
31873196 struct fwnode_handle *fwnode = dev_fwnode(dev);
3188− u32 rotation;
31893197 unsigned int i;
31903198 int rval;
31913199
@@ -3224,22 +3232,6 @@ static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) · 32 unmodified lines
32243232 goto out_err;
32253233 }
32263234
3227− rval = fwnode_property_read_u32(fwnode, "rotation", &rotation);
3228− if (!rval) {
3229− switch (rotation) {
3230− case 180:
3231− hwcfg->module_board_orient =
3232− CCS_MODULE_BOARD_ORIENT_180;
3233− fallthrough;
3234− case 0:
3235− break;
3236− default:
3237− dev_err(dev, "invalid rotation %u\n", rotation);
3238− rval = -EINVAL;
3239− goto out_err;
3240− }
3241− }
3242−
32433235 rval = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
32443236 &hwcfg->ext_clk);
32453237 if (rval)
@@ -3279,8 +3271,47 @@ out_err: · 33 unmodified lines
32793271 return rval;
32803272 }
32813273
3274+static int ccs_firmware_name(struct i2c_client *client,
3275+ struct ccs_sensor *sensor, char *filename,
3276+ size_t filename_size, bool is_module)
3277+{
3278+ const struct ccs_device *ccsdev = device_get_match_data(&client->dev);
3279+ bool is_ccs = !(ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA);
3280+ bool is_smiapp = sensor->minfo.smiapp_version;
3281+ u16 manufacturer_id;
3282+ u16 model_id;
3283+ u16 revision_number;
3284+
3285+ /*
3286+ * Old SMIA is module-agnostic. Its sensor identification is based on
3287+ * what now are those of the module.
3288+ */
3289+ if (is_module || (!is_ccs && !is_smiapp)) {
3290+ manufacturer_id = is_ccs ?
3291+ sensor->minfo.mipi_manufacturer_id :
3292+ sensor->minfo.smia_manufacturer_id;
3293+ model_id = sensor->minfo.model_id;
3294+ revision_number = sensor->minfo.revision_number;
3295+ } else {
3296+ manufacturer_id = is_ccs ?
3297+ sensor->minfo.sensor_mipi_manufacturer_id :
3298+ sensor->minfo.sensor_smia_manufacturer_id;
3299+ model_id = sensor->minfo.sensor_model_id;
3300+ revision_number = sensor->minfo.sensor_revision_number;
3301+ }
3302+
3303+ return snprintf(filename, filename_size,
3304+ "ccs/%s-%s-%0*x-%4.4x-%0*x.fw",
3305+ is_ccs ? "ccs" : is_smiapp ? "smiapp" : "smia",
3306+ is_module || (!is_ccs && !is_smiapp) ?
3307+ "module" : "sensor",
3308+ is_ccs ? 4 : 2, manufacturer_id, model_id,
3309+ !is_ccs && !is_module ? 2 : 4, revision_number);
3310+}
3311+
32823312 static int ccs_probe(struct i2c_client *client)
32833313 {
3314+ const struct ccs_device *ccsdev = device_get_match_data(&client->dev);
32843315 struct ccs_sensor *sensor;
32853316 const struct firmware *fw;
32863317 char filename[40];
@@ -3389,11 +3420,8 @@ static int ccs_probe(struct i2c_client *client) · 102 unmodified lines
33893420 goto out_power_off;
33903421 }
33913422
3392− rval = snprintf(filename, sizeof(filename),
3393− "ccs/ccs-sensor-%4.4x-%4.4x-%4.4x.fw",
3394− sensor->minfo.sensor_mipi_manufacturer_id,
3395− sensor->minfo.sensor_model_id,
3396− sensor->minfo.sensor_revision_number);
3423+ rval = ccs_firmware_name(client, sensor, filename, sizeof(filename),
3424+ false);
33973425 if (rval >= sizeof(filename)) {
33983426 rval = -ENOMEM;
33993427 goto out_power_off;
@@ -3406,21 +3434,21 @@ static int ccs_probe(struct i2c_client *client) · 6 unmodified lines
34063434 release_firmware(fw);
34073435 }
34083436
3409− rval = snprintf(filename, sizeof(filename),
3410− "ccs/ccs-module-%4.4x-%4.4x-%4.4x.fw",
3411− sensor->minfo.mipi_manufacturer_id,
3412− sensor->minfo.model_id,
3413− sensor->minfo.revision_number);
3414− if (rval >= sizeof(filename)) {
3415− rval = -ENOMEM;
3416− goto out_release_sdata;
3417− }
3437+ if (!(ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA) ||
3438+ sensor->minfo.smiapp_version) {
3439+ rval = ccs_firmware_name(client, sensor, filename,
3440+ sizeof(filename), true);
3441+ if (rval >= sizeof(filename)) {
3442+ rval = -ENOMEM;
3443+ goto out_release_sdata;
3444+ }
34183445
3419− rval = request_firmware(&fw, filename, &client->dev);
3420− if (!rval) {
3421− ccs_data_parse(&sensor->mdata, fw->data, fw->size, &client->dev,
3422− true);
3423− release_firmware(fw);
3446+ rval = request_firmware(&fw, filename, &client->dev);
3447+ if (!rval) {
3448+ ccs_data_parse(&sensor->mdata, fw->data, fw->size,
3449+ &client->dev, true);
3450+ release_firmware(fw);
3451+ }
34243452 }
34253453
34263454 rval = ccs_read_all_limits(sensor);
@@ -3437,25 +3465,6 @@ static int ccs_probe(struct i2c_client *client) · 10 unmodified lines
34373465 if (rval < 0)
34383466 goto out_free_ccs_limits;
34393467
3440− /*
3441− * Handle Sensor Module orientation on the board.
3442− *
3443− * The application of H-FLIP and V-FLIP on the sensor is modified by
3444− * the sensor orientation on the board.
3445− *
3446− * For CCS_BOARD_SENSOR_ORIENT_180 the default behaviour is to set
3447− * both H-FLIP and V-FLIP for normal operation which also implies
3448− * that a set/unset operation for user space HFLIP and VFLIP v4l2
3449− * controls will need to be internally inverted.
3450− *
3451− * Rotation also changes the bayer pattern.
3452− */
3453− if (sensor->hwcfg.module_board_orient ==
3454− CCS_MODULE_BOARD_ORIENT_180)
3455− sensor->hvflip_inv_mask =
3456− CCS_IMAGE_ORIENTATION_HORIZONTAL_MIRROR |
3457− CCS_IMAGE_ORIENTATION_VERTICAL_FLIP;
3458−
34593468 rval = ccs_call_quirk(sensor, limits);
34603469 if (rval) {
34613470 dev_err(&client->dev, "limits quirks failed\n");
drivers/media/i2c/ccs/ccs.h+0−14
@@ -57,17 +57,6 @@ · 56 unmodified lines
5757 #define CCS_LIM_AT(sensor, limit, offset) \
5858 ccs_get_limit(sensor, CCS_L_##limit, CCS_L_##limit##_OFFSET(offset))
5959
60−/*
61− * Sometimes due to board layout considerations the camera module can be
62− * mounted rotated. The typical rotation used is 180 degrees which can be
63− * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
64− * FIXME: rotation also changes the bayer pattern.
65− */
66−enum ccs_module_board_orient {
67− CCS_MODULE_BOARD_ORIENT_0 = 0,
68− CCS_MODULE_BOARD_ORIENT_180,
69−};
70−
7160 struct ccs_flash_strobe_parms {
7261 u8 mode;
7362 u32 strobe_width_high_us;
@@ -90,8 +79,6 @@ struct ccs_hwconfig { · 16 unmodified lines
9079 u32 csi_signalling_mode; /* CCS_CSI_SIGNALLING_MODE_* */
9180 u64 *op_sys_clock;
9281
93− enum ccs_module_board_orient module_board_orient;
94−
9582 struct ccs_flash_strobe_parms *strobe_setup;
9683 };
9784
@@ -243,7 +230,6 @@ struct ccs_sensor { · 145 unmodified lines
243230 u8 scale_m;
244231 u8 scaling_mode;
245232
246− u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
247233 u8 frame_skip;
248234 u16 embedded_start; /* embedded data start line */
249235 u16 embedded_end;
drivers/media/i2c/hi556.c+148−2
@@ -63,6 +63,14 @@ · 62 unmodified lines
6363 #define HI556_REG_ISP_TPG_EN 0x01
6464 #define HI556_REG_TEST_PATTERN 0x0201
6565
66+/* HI556 native and active pixel array size. */
67+#define HI556_NATIVE_WIDTH 2592U
68+#define HI556_NATIVE_HEIGHT 1944U
69+#define HI556_PIXEL_ARRAY_LEFT 0U
70+#define HI556_PIXEL_ARRAY_TOP 0U
71+#define HI556_PIXEL_ARRAY_WIDTH 2592U
72+#define HI556_PIXEL_ARRAY_HEIGHT 1944U
73+
6674 enum {
6775 HI556_LINK_FREQ_437MHZ_INDEX,
6876 };
@@ -88,6 +96,9 @@ struct hi556_mode { · 19 unmodified lines
8896 /* Frame height in pixels */
8997 u32 height;
9098
99+ /* Analog crop rectangle. */
100+ struct v4l2_rect crop;
101+
91102 /* Horizontal timining size */
92103 u32 llp;
93104
@@ -378,6 +389,49 @@ static const struct hi556_reg mode_2592x1944_regs[] = { · 284 unmodified lines
378389 {0x0958, 0xbb80},
379390 };
380391
392+static const struct hi556_reg mode_2592x1444_regs[] = {
393+ {0x0a00, 0x0000},
394+ {0x0b0a, 0x8252},
395+ {0x0f30, 0xe545},
396+ {0x0f32, 0x7067},
397+ {0x004a, 0x0100},
398+ {0x004c, 0x0000},
399+ {0x000c, 0x0022},
400+ {0x0008, 0x0b00},
401+ {0x005a, 0x0202},
402+ {0x0012, 0x000e},
403+ {0x0018, 0x0a33},
404+ {0x0022, 0x0008},
405+ {0x0028, 0x0017},
406+ {0x0024, 0x0122},
407+ {0x002a, 0x0127},
408+ {0x0026, 0x012a},
409+ {0x002c, 0x06cf},
410+ {0x002e, 0x1111},
411+ {0x0030, 0x1111},
412+ {0x0032, 0x1111},
413+ {0x0006, 0x0821},
414+ {0x0a22, 0x0000},
415+ {0x0a12, 0x0a20},
416+ {0x0a14, 0x05a4},
417+ {0x003e, 0x0000},
418+ {0x0074, 0x081f},
419+ {0x0070, 0x040f},
420+ {0x0804, 0x0300},
421+ {0x0806, 0x0100},
422+ {0x0a04, 0x014a},
423+ {0x090c, 0x0fdc},
424+ {0x090e, 0x002d},
425+ {0x0902, 0x4319},
426+ {0x0914, 0xc10a},
427+ {0x0916, 0x071f},
428+ {0x0918, 0x0408},
429+ {0x091a, 0x0c0d},
430+ {0x091c, 0x0f09},
431+ {0x091e, 0x0a00},
432+ {0x0958, 0xbb80},
433+};
434+
381435 static const struct hi556_reg mode_1296x972_regs[] = {
382436 {0x0a00, 0x0000},
383437 {0x0b0a, 0x8259},
@@ -450,8 +504,14 @@ static const struct hi556_link_freq_config link_freq_configs[] = { · 66 unmodified lines
450504
451505 static const struct hi556_mode supported_modes[] = {
452506 {
453− .width = 2592,
454− .height = 1944,
507+ .width = HI556_PIXEL_ARRAY_WIDTH,
508+ .height = HI556_PIXEL_ARRAY_HEIGHT,
509+ .crop = {
510+ .left = HI556_PIXEL_ARRAY_LEFT,
511+ .top = HI556_PIXEL_ARRAY_TOP,
512+ .width = HI556_PIXEL_ARRAY_WIDTH,
513+ .height = HI556_PIXEL_ARRAY_HEIGHT
514+ },
455515 .fll_def = HI556_FLL_30FPS,
456516 .fll_min = HI556_FLL_30FPS_MIN,
457517 .llp = 0x0b00,
@@ -461,9 +521,33 @@ static const struct hi556_mode supported_modes[] = { · 3 unmodified lines
461521 },
462522 .link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,
463523 },
524+ {
525+ .width = HI556_PIXEL_ARRAY_WIDTH,
526+ .height = 1444,
527+ .crop = {
528+ .left = HI556_PIXEL_ARRAY_LEFT,
529+ .top = 250,
530+ .width = HI556_PIXEL_ARRAY_WIDTH,
531+ .height = 1444
532+ },
533+ .fll_def = 0x821,
534+ .fll_min = 0x821,
535+ .llp = 0x0b00,
536+ .reg_list = {
537+ .num_of_regs = ARRAY_SIZE(mode_2592x1444_regs),
538+ .regs = mode_2592x1444_regs,
539+ },
540+ .link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,
541+ },
464542 {
465543 .width = 1296,
466544 .height = 972,
545+ .crop = {
546+ .left = HI556_PIXEL_ARRAY_LEFT,
547+ .top = HI556_PIXEL_ARRAY_TOP,
548+ .width = HI556_PIXEL_ARRAY_WIDTH,
549+ .height = HI556_PIXEL_ARRAY_HEIGHT
550+ },
467551 .fll_def = HI556_FLL_30FPS,
468552 .fll_min = HI556_FLL_30FPS_MIN,
469553 .llp = 0x0b00,
@@ -785,6 +869,58 @@ static int hi556_identify_module(struct hi556 *hi556) · 315 unmodified lines
785869 return 0;
786870 }
787871
872+static const struct v4l2_rect *
873+__hi556_get_pad_crop(struct hi556 *hi556,
874+ struct v4l2_subdev_state *sd_state,
875+ unsigned int pad, enum v4l2_subdev_format_whence which)
876+{
877+ switch (which) {
878+ case V4L2_SUBDEV_FORMAT_TRY:
879+ return v4l2_subdev_get_try_crop(&hi556->sd, sd_state, pad);
880+ case V4L2_SUBDEV_FORMAT_ACTIVE:
881+ return &hi556->cur_mode->crop;
882+ }
883+
884+ return NULL;
885+}
886+
887+static int hi556_get_selection(struct v4l2_subdev *sd,
888+ struct v4l2_subdev_state *sd_state,
889+ struct v4l2_subdev_selection *sel)
890+{
891+ switch (sel->target) {
892+ case V4L2_SEL_TGT_CROP: {
893+ struct hi556 *hi556 = to_hi556(sd);
894+
895+ mutex_lock(&hi556->mutex);
896+ sel->r = *__hi556_get_pad_crop(hi556, sd_state, sel->pad,
897+ sel->which);
898+ mutex_unlock(&hi556->mutex);
899+
900+ return 0;
901+ }
902+
903+ case V4L2_SEL_TGT_NATIVE_SIZE:
904+ sel->r.top = 0;
905+ sel->r.left = 0;
906+ sel->r.width = HI556_NATIVE_WIDTH;
907+ sel->r.height = HI556_NATIVE_HEIGHT;
908+
909+ return 0;
910+
911+ case V4L2_SEL_TGT_CROP_DEFAULT:
912+ case V4L2_SEL_TGT_CROP_BOUNDS:
913+ sel->r.top = HI556_PIXEL_ARRAY_TOP;
914+ sel->r.left = HI556_PIXEL_ARRAY_LEFT;
915+ sel->r.width = HI556_PIXEL_ARRAY_WIDTH;
916+ sel->r.height = HI556_PIXEL_ARRAY_HEIGHT;
917+
918+ return 0;
919+ }
920+
921+ return -EINVAL;
922+}
923+
788924 static int hi556_start_streaming(struct hi556 *hi556)
789925 {
790926 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
@@ -1000,10 +1136,19 @@ static int hi556_enum_frame_size(struct v4l2_subdev *sd, · 209 unmodified lines
10001136 static int hi556_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
10011137 {
10021138 struct hi556 *hi556 = to_hi556(sd);
1139+ struct v4l2_rect *try_crop;
10031140
10041141 mutex_lock(&hi556->mutex);
10051142 hi556_assign_pad_format(&supported_modes[0],
10061143 v4l2_subdev_get_try_format(sd, fh->state, 0));
1144+
1145+ /* Initialize try_crop rectangle. */
1146+ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
1147+ try_crop->top = HI556_PIXEL_ARRAY_TOP;
1148+ try_crop->left = HI556_PIXEL_ARRAY_LEFT;
1149+ try_crop->width = HI556_PIXEL_ARRAY_WIDTH;
1150+ try_crop->height = HI556_PIXEL_ARRAY_HEIGHT;
1151+
10071152 mutex_unlock(&hi556->mutex);
10081153
10091154 return 0;
@@ -1016,6 +1161,7 @@ static const struct v4l2_subdev_video_ops hi556_video_ops = { · 6 unmodified lines
10161161 static const struct v4l2_subdev_pad_ops hi556_pad_ops = {
10171162 .set_fmt = hi556_set_format,
10181163 .get_fmt = hi556_get_format,
1164+ .get_selection = hi556_get_selection,
10191165 .enum_mbus_code = hi556_enum_mbus_code,
10201166 .enum_frame_size = hi556_enum_frame_size,
10211167 };
drivers/media/i2c/hi846.c+8−3
@@ -1472,21 +1472,26 @@ static int hi846_init_controls(struct hi846 *hi846) · 1471 unmodified lines
14721472 if (ctrl_hdlr->error) {
14731473 dev_err(&client->dev, "v4l ctrl handler error: %d\n",
14741474 ctrl_hdlr->error);
1475− return ctrl_hdlr->error;
1475+ ret = ctrl_hdlr->error;
1476+ goto error;
14761477 }
14771478
14781479 ret = v4l2_fwnode_device_parse(&client->dev, &props);
14791480 if (ret)
1480− return ret;
1481+ goto error;
14811482
14821483 ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &hi846_ctrl_ops,
14831484 &props);
14841485 if (ret)
1485− return ret;
1486+ goto error;
14861487
14871488 hi846->sd.ctrl_handler = ctrl_hdlr;
14881489
14891490 return 0;
1491+
1492+error:
1493+ v4l2_ctrl_handler_free(ctrl_hdlr);
1494+ return ret;
14901495 }
14911496
14921497 static int hi846_set_video_mode(struct hi846 *hi846, int fps)
drivers/media/i2c/imx258.c+24−9
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <linux/pm_runtime.h>
1010 #include <media/v4l2-ctrls.h>
1111 #include <media/v4l2-device.h>
12+#include <media/v4l2-fwnode.h>
1213 #include <asm/unaligned.h>
1314
1415 #define IMX258_REG_VALUE_08BIT 1
@@ -1148,7 +1149,9 @@ static const struct v4l2_subdev_internal_ops imx258_internal_ops = { · 1133 unmodified lines
11481149 static int imx258_init_controls(struct imx258 *imx258)
11491150 {
11501151 struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
1152+ struct v4l2_fwnode_device_properties props;
11511153 struct v4l2_ctrl_handler *ctrl_hdlr;
1154+ struct v4l2_ctrl *vflip, *hflip;
11521155 s64 vblank_def;
11531156 s64 vblank_min;
11541157 s64 pixel_rate_min;
@@ -1156,7 +1159,7 @@ static int imx258_init_controls(struct imx258 *imx258) · 1 unmodified line
11561159 int ret;
11571160
11581161 ctrl_hdlr = &imx258->ctrl_handler;
1159− ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
1162+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 13);
11601163 if (ret)
11611164 return ret;
11621165
@@ -1172,6 +1175,17 @@ static int imx258_init_controls(struct imx258 *imx258) · 9 unmodified lines
11721175 if (imx258->link_freq)
11731176 imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
11741177
1178+ /* The driver only supports one bayer order and flips by default. */
1179+ hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
1180+ V4L2_CID_HFLIP, 1, 1, 1, 1);
1181+ if (hflip)
1182+ hflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1183+
1184+ vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
1185+ V4L2_CID_VFLIP, 1, 1, 1, 1);
1186+ if (vflip)
1187+ vflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1188+
11751189 pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
11761190 pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]);
11771191 /* By default, PIXEL_RATE is read only */
@@ -1232,6 +1246,15 @@ static int imx258_init_controls(struct imx258 *imx258) · 54 unmodified lines
12321246 goto error;
12331247 }
12341248
1249+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
1250+ if (ret)
1251+ goto error;
1252+
1253+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx258_ctrl_ops,
1254+ &props);
1255+ if (ret)
1256+ goto error;
1257+
12351258 imx258->sd.ctrl_handler = ctrl_hdlr;
12361259
12371260 return 0;
@@ -1276,14 +1299,6 @@ static int imx258_probe(struct i2c_client *client) · 38 unmodified lines
12761299 return -EINVAL;
12771300 }
12781301
1279− /*
1280− * Check that the device is mounted upside down. The driver only
1281− * supports a single pixel order right now.
1282− */
1283− ret = device_property_read_u32(&client->dev, "rotation", &val);
1284− if (ret || val != 180)
1285− return -EINVAL;
1286−
12871302 /* Initialize subdev */
12881303 v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
12891304
drivers/media/i2c/imx290.c+477−119
@@ -13,12 +13,17 @@ · 12 unmodified lines
1313 #include <linux/gpio/consumer.h>
1414 #include <linux/i2c.h>
1515 #include <linux/module.h>
16+#include <linux/of_device.h>
1617 #include <linux/pm_runtime.h>
1718 #include <linux/regmap.h>
1819 #include <linux/regulator/consumer.h>
20+
21+#include <asm/unaligned.h>
22+
1923 #include <media/media-entity.h>
2024 #include <media/v4l2-ctrls.h>
2125 #include <media/v4l2-device.h>
26+#include <media/v4l2-event.h>
2227 #include <media/v4l2-fwnode.h>
2328 #include <media/v4l2-subdev.h>
2429
@@ -44,7 +49,9 @@ · 19 unmodified lines
4449 #define IMX290_BLKLEVEL IMX290_REG_16BIT(0x300a)
4550 #define IMX290_GAIN IMX290_REG_8BIT(0x3014)
4651 #define IMX290_VMAX IMX290_REG_24BIT(0x3018)
52+#define IMX290_VMAX_MAX 0x3ffff
4753 #define IMX290_HMAX IMX290_REG_16BIT(0x301c)
54+#define IMX290_HMAX_MAX 0xffff
4855 #define IMX290_SHS1 IMX290_REG_24BIT(0x3020)
4956 #define IMX290_WINWV_OB IMX290_REG_8BIT(0x303a)
5057 #define IMX290_WINPV IMX290_REG_16BIT(0x303c)
@@ -98,13 +105,16 @@ · 47 unmodified lines
98105 #define IMX290_TCLKPREPARE IMX290_REG_16BIT(0x3452)
99106 #define IMX290_TLPX IMX290_REG_16BIT(0x3454)
100107 #define IMX290_X_OUT_SIZE IMX290_REG_16BIT(0x3472)
108+#define IMX290_INCKSEL7 IMX290_REG_8BIT(0x3480)
101109
102110 #define IMX290_PGCTRL_REGEN BIT(0)
103111 #define IMX290_PGCTRL_THRU BIT(1)
104112 #define IMX290_PGCTRL_MODE(n) ((n) << 4)
105113
106−#define IMX290_VMAX_DEFAULT 1125
114+/* Number of lines by which exposure must be less than VMAX */
115+#define IMX290_EXPOSURE_OFFSET 2
107116
117+#define IMX290_PIXEL_RATE 148500000
108118
109119 /*
110120 * The IMX290 pixel array is organized as follows:
@@ -157,26 +167,81 @@ · 46 unmodified lines
157167
158168 #define IMX290_NUM_SUPPLIES 3
159169
170+enum imx290_colour_variant {
171+ IMX290_VARIANT_COLOUR,
172+ IMX290_VARIANT_MONO,
173+ IMX290_VARIANT_MAX
174+};
175+
176+enum imx290_model {
177+ IMX290_MODEL_IMX290LQR,
178+ IMX290_MODEL_IMX290LLR,
179+ IMX290_MODEL_IMX327LQR,
180+};
181+
182+struct imx290_model_info {
183+ enum imx290_colour_variant colour_variant;
184+ const struct imx290_regval *init_regs;
185+ size_t init_regs_num;
186+ const char *name;
187+};
188+
189+enum imx290_clk_freq {
190+ IMX290_CLK_37_125,
191+ IMX290_CLK_74_25,
192+ IMX290_NUM_CLK
193+};
194+
160195 struct imx290_regval {
161196 u32 reg;
162197 u32 val;
163198 };
164199
200+/*
201+ * Clock configuration for registers INCKSEL1 to INCKSEL6.
202+ */
203+struct imx290_clk_cfg {
204+ u8 incksel1;
205+ u8 incksel2;
206+ u8 incksel3;
207+ u8 incksel4;
208+ u8 incksel5;
209+ u8 incksel6;
210+};
211+
165212 struct imx290_mode {
166213 u32 width;
167214 u32 height;
168− u32 hmax;
215+ u32 hmax_min;
216+ u32 vmax_min;
169217 u8 link_freq_index;
218+ u8 ctrl_07;
170219
171220 const struct imx290_regval *data;
172221 u32 data_size;
222+
223+ const struct imx290_clk_cfg *clk_cfg;
224+};
225+
226+struct imx290_csi_cfg {
227+ u16 repetition;
228+ u16 tclkpost;
229+ u16 thszero;
230+ u16 thsprepare;
231+ u16 tclktrail;
232+ u16 thstrail;
233+ u16 tclkzero;
234+ u16 tclkprepare;
235+ u16 tlpx;
173236 };
174237
175238 struct imx290 {
176239 struct device *dev;
177240 struct clk *xclk;
178241 struct regmap *regmap;
242+ enum imx290_clk_freq xclk_idx;
179243 u8 nlanes;
244+ const struct imx290_model_info *model;
180245
181246 struct v4l2_subdev sd;
182247 struct media_pad pad;
@@ -188,9 +253,13 @@ struct imx290 { · 5 unmodified lines
188253
189254 struct v4l2_ctrl_handler ctrls;
190255 struct v4l2_ctrl *link_freq;
191− struct v4l2_ctrl *pixel_rate;
192256 struct v4l2_ctrl *hblank;
193257 struct v4l2_ctrl *vblank;
258+ struct v4l2_ctrl *exposure;
259+ struct {
260+ struct v4l2_ctrl *hflip;
261+ struct v4l2_ctrl *vflip;
262+ };
194263 };
195264
196265 static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
@@ -203,9 +272,6 @@ static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd) · 6 unmodified lines
203272 */
204273
205274 static const struct imx290_regval imx290_global_init_settings[] = {
206− { IMX290_CTRL_07, IMX290_WINMODE_1080P },
207− { IMX290_VMAX, IMX290_VMAX_DEFAULT },
208− { IMX290_EXTCK_FREQ, 0x2520 },
209275 { IMX290_WINWV_OB, 12 },
210276 { IMX290_WINPH, 0 },
211277 { IMX290_WINPV, 0 },
@@ -213,10 +279,14 @@ static const struct imx290_regval imx290_global_init_settings[] = { · 1 unmodified line
213279 { IMX290_WINWV, 1097 },
214280 { IMX290_XSOUTSEL, IMX290_XSOUTSEL_XVSOUTSEL_VSYNC |
215281 IMX290_XSOUTSEL_XHSOUTSEL_HSYNC },
216− { IMX290_REG_8BIT(0x300f), 0x00 },
217− { IMX290_REG_8BIT(0x3010), 0x21 },
282+ { IMX290_REG_8BIT(0x3011), 0x02 },
218283 { IMX290_REG_8BIT(0x3012), 0x64 },
219284 { IMX290_REG_8BIT(0x3013), 0x00 },
285+};
286+
287+static const struct imx290_regval imx290_global_init_settings_290[] = {
288+ { IMX290_REG_8BIT(0x300f), 0x00 },
289+ { IMX290_REG_8BIT(0x3010), 0x21 },
220290 { IMX290_REG_8BIT(0x3016), 0x09 },
221291 { IMX290_REG_8BIT(0x3070), 0x02 },
222292 { IMX290_REG_8BIT(0x3071), 0x11 },
@@ -255,57 +325,40 @@ static const struct imx290_regval imx290_global_init_settings[] = { · 32 unmodified lines
255325 { IMX290_REG_8BIT(0x33b0), 0x50 },
256326 { IMX290_REG_8BIT(0x33b2), 0x1a },
257327 { IMX290_REG_8BIT(0x33b3), 0x04 },
258− { IMX290_REG_8BIT(0x3480), 0x49 },
328+};
329+
330+#define IMX290_NUM_CLK_REGS 2
331+static const struct imx290_regval xclk_regs[][IMX290_NUM_CLK_REGS] = {
332+ [IMX290_CLK_37_125] = {
333+ { IMX290_EXTCK_FREQ, (37125 * 256) / 1000 },
334+ { IMX290_INCKSEL7, 0x49 },
335+ },
336+ [IMX290_CLK_74_25] = {
337+ { IMX290_EXTCK_FREQ, (74250 * 256) / 1000 },
338+ { IMX290_INCKSEL7, 0x92 },
339+ },
340+};
341+
342+static const struct imx290_regval imx290_global_init_settings_327[] = {
343+ { IMX290_REG_8BIT(0x309e), 0x4A },
344+ { IMX290_REG_8BIT(0x309f), 0x4A },
345+ { IMX290_REG_8BIT(0x313b), 0x61 },
259346 };
260347
261348 static const struct imx290_regval imx290_1080p_settings[] = {
262349 /* mode settings */
263− { IMX290_CTRL_07, IMX290_WINMODE_1080P },
264350 { IMX290_WINWV_OB, 12 },
265351 { IMX290_OPB_SIZE_V, 10 },
266352 { IMX290_X_OUT_SIZE, 1920 },
267353 { IMX290_Y_OUT_SIZE, 1080 },
268− { IMX290_INCKSEL1, 0x18 },
269− { IMX290_INCKSEL2, 0x03 },
270− { IMX290_INCKSEL3, 0x20 },
271− { IMX290_INCKSEL4, 0x01 },
272− { IMX290_INCKSEL5, 0x1a },
273− { IMX290_INCKSEL6, 0x1a },
274− /* data rate settings */
275− { IMX290_REPETITION, 0x10 },
276− { IMX290_TCLKPOST, 87 },
277− { IMX290_THSZERO, 55 },
278− { IMX290_THSPREPARE, 31 },
279− { IMX290_TCLKTRAIL, 31 },
280− { IMX290_THSTRAIL, 31 },
281− { IMX290_TCLKZERO, 119 },
282− { IMX290_TCLKPREPARE, 31 },
283− { IMX290_TLPX, 23 },
284354 };
285355
286356 static const struct imx290_regval imx290_720p_settings[] = {
287357 /* mode settings */
288− { IMX290_CTRL_07, IMX290_WINMODE_720P },
289358 { IMX290_WINWV_OB, 6 },
290359 { IMX290_OPB_SIZE_V, 4 },
291360 { IMX290_X_OUT_SIZE, 1280 },
292361 { IMX290_Y_OUT_SIZE, 720 },
293− { IMX290_INCKSEL1, 0x20 },
294− { IMX290_INCKSEL2, 0x00 },
295− { IMX290_INCKSEL3, 0x20 },
296− { IMX290_INCKSEL4, 0x01 },
297− { IMX290_INCKSEL5, 0x1a },
298− { IMX290_INCKSEL6, 0x1a },
299− /* data rate settings */
300− { IMX290_REPETITION, 0x10 },
301− { IMX290_TCLKPOST, 79 },
302− { IMX290_THSZERO, 47 },
303− { IMX290_THSPREPARE, 23 },
304− { IMX290_TCLKTRAIL, 23 },
305− { IMX290_THSTRAIL, 23 },
306− { IMX290_TCLKZERO, 87 },
307− { IMX290_TCLKPREPARE, 23 },
308− { IMX290_TLPX, 23 },
309362 };
310363
311364 static const struct imx290_regval imx290_10bit_settings[] = {
@@ -326,6 +379,58 @@ static const struct imx290_regval imx290_12bit_settings[] = { · 14 unmodified lines
326379 { IMX290_CSI_DT_FMT, IMX290_CSI_DT_FMT_RAW12 },
327380 };
328381
382+static const struct imx290_csi_cfg imx290_csi_222_75mhz = {
383+ /* 222.75MHz or 445.5Mbit/s per lane */
384+ .repetition = 0x10,
385+ .tclkpost = 87,
386+ .thszero = 55,
387+ .thsprepare = 31,
388+ .tclktrail = 31,
389+ .thstrail = 31,
390+ .tclkzero = 119,
391+ .tclkprepare = 31,
392+ .tlpx = 23,
393+};
394+
395+static const struct imx290_csi_cfg imx290_csi_445_5mhz = {
396+ /* 445.5MHz or 891Mbit/s per lane */
397+ .repetition = 0x00,
398+ .tclkpost = 119,
399+ .thszero = 103,
400+ .thsprepare = 71,
401+ .tclktrail = 55,
402+ .thstrail = 63,
403+ .tclkzero = 255,
404+ .tclkprepare = 63,
405+ .tlpx = 55,
406+};
407+
408+static const struct imx290_csi_cfg imx290_csi_148_5mhz = {
409+ /* 148.5MHz or 297Mbit/s per lane */
410+ .repetition = 0x10,
411+ .tclkpost = 79,
412+ .thszero = 47,
413+ .thsprepare = 23,
414+ .tclktrail = 23,
415+ .thstrail = 23,
416+ .tclkzero = 87,
417+ .tclkprepare = 23,
418+ .tlpx = 23,
419+};
420+
421+static const struct imx290_csi_cfg imx290_csi_297mhz = {
422+ /* 297MHz or 594Mbit/s per lane */
423+ .repetition = 0x00,
424+ .tclkpost = 103,
425+ .thszero = 87,
426+ .thsprepare = 47,
427+ .tclktrail = 39,
428+ .thstrail = 47,
429+ .tclkzero = 191,
430+ .tclkprepare = 47,
431+ .tlpx = 39,
432+};
433+
329434 /* supported link frequencies */
330435 #define FREQ_INDEX_1080P 0
331436 #define FREQ_INDEX_720P 1
@@ -333,6 +438,7 @@ static const s64 imx290_link_freq_2lanes[] = { · 1 unmodified line
333438 [FREQ_INDEX_1080P] = 445500000,
334439 [FREQ_INDEX_720P] = 297000000,
335440 };
441+
336442 static const s64 imx290_link_freq_4lanes[] = {
337443 [FREQ_INDEX_1080P] = 222750000,
338444 [FREQ_INDEX_720P] = 148500000,
@@ -358,23 +464,71 @@ static inline int imx290_link_freqs_num(const struct imx290 *imx290) · 19 unmodified lines
358464 return ARRAY_SIZE(imx290_link_freq_4lanes);
359465 }
360466
467+static const struct imx290_clk_cfg imx290_1080p_clock_config[] = {
468+ [IMX290_CLK_37_125] = {
469+ /* 37.125MHz clock config */
470+ .incksel1 = 0x18,
471+ .incksel2 = 0x03,
472+ .incksel3 = 0x20,
473+ .incksel4 = 0x01,
474+ .incksel5 = 0x1a,
475+ .incksel6 = 0x1a,
476+ },
477+ [IMX290_CLK_74_25] = {
478+ /* 74.25MHz clock config */
479+ .incksel1 = 0x0c,
480+ .incksel2 = 0x03,
481+ .incksel3 = 0x10,
482+ .incksel4 = 0x01,
483+ .incksel5 = 0x1b,
484+ .incksel6 = 0x1b,
485+ },
486+};
487+
488+static const struct imx290_clk_cfg imx290_720p_clock_config[] = {
489+ [IMX290_CLK_37_125] = {
490+ /* 37.125MHz clock config */
491+ .incksel1 = 0x20,
492+ .incksel2 = 0x00,
493+ .incksel3 = 0x20,
494+ .incksel4 = 0x01,
495+ .incksel5 = 0x1a,
496+ .incksel6 = 0x1a,
497+ },
498+ [IMX290_CLK_74_25] = {
499+ /* 74.25MHz clock config */
500+ .incksel1 = 0x10,
501+ .incksel2 = 0x00,
502+ .incksel3 = 0x10,
503+ .incksel4 = 0x01,
504+ .incksel5 = 0x1b,
505+ .incksel6 = 0x1b,
506+ },
507+};
508+
361509 /* Mode configs */
362510 static const struct imx290_mode imx290_modes_2lanes[] = {
363511 {
364512 .width = 1920,
365513 .height = 1080,
366− .hmax = 4400,
514+ .hmax_min = 2200,
515+ .vmax_min = 1125,
367516 .link_freq_index = FREQ_INDEX_1080P,
517+ .ctrl_07 = IMX290_WINMODE_1080P,
368518 .data = imx290_1080p_settings,
369519 .data_size = ARRAY_SIZE(imx290_1080p_settings),
520+ .clk_cfg = imx290_1080p_clock_config,
370521 },
371522 {
372523 .width = 1280,
373524 .height = 720,
374− .hmax = 6600,
525+ .hmax_min = 3300,
526+ .vmax_min = 750,
375527 .link_freq_index = FREQ_INDEX_720P,
528+ .ctrl_07 = IMX290_WINMODE_720P,
376529 .data = imx290_720p_settings,
377530 .data_size = ARRAY_SIZE(imx290_720p_settings),
531+ .clk_cfg = imx290_720p_clock_config,
378532 },
379533 };
380534
@@ -382,18 +536,24 @@ static const struct imx290_mode imx290_modes_4lanes[] = { · 1 unmodified line
382536 {
383537 .width = 1920,
384538 .height = 1080,
385− .hmax = 2200,
539+ .hmax_min = 2200,
540+ .vmax_min = 1125,
386541 .link_freq_index = FREQ_INDEX_1080P,
542+ .ctrl_07 = IMX290_WINMODE_1080P,
387543 .data = imx290_1080p_settings,
388544 .data_size = ARRAY_SIZE(imx290_1080p_settings),
545+ .clk_cfg = imx290_1080p_clock_config,
389546 },
390547 {
391548 .width = 1280,
392549 .height = 720,
393− .hmax = 3300,
550+ .hmax_min = 3300,
551+ .vmax_min = 750,
394552 .link_freq_index = FREQ_INDEX_720P,
553+ .ctrl_07 = IMX290_WINMODE_720P,
395554 .data = imx290_720p_settings,
396555 .data_size = ARRAY_SIZE(imx290_720p_settings),
556+ .clk_cfg = imx290_720p_clock_config,
397557 },
398558 };
399559
@@ -414,7 +574,7 @@ static inline int imx290_modes_num(const struct imx290 *imx290) · 14 unmodified lines
414574 }
415575
416576 struct imx290_format_info {
417− u32 code;
577+ u32 code[IMX290_VARIANT_MAX];
418578 u8 bpp;
419579 const struct imx290_regval *regs;
420580 unsigned int num_regs;
@@ -422,26 +582,33 @@ struct imx290_format_info { · 1 unmodified line
422582
423583 static const struct imx290_format_info imx290_formats[] = {
424584 {
425− .code = MEDIA_BUS_FMT_SRGGB10_1X10,
585+ .code = {
586+ [IMX290_VARIANT_COLOUR] = MEDIA_BUS_FMT_SRGGB10_1X10,
587+ [IMX290_VARIANT_MONO] = MEDIA_BUS_FMT_Y10_1X10
588+ },
426589 .bpp = 10,
427590 .regs = imx290_10bit_settings,
428591 .num_regs = ARRAY_SIZE(imx290_10bit_settings),
429592 }, {
430− .code = MEDIA_BUS_FMT_SRGGB12_1X12,
593+ .code = {
594+ [IMX290_VARIANT_COLOUR] = MEDIA_BUS_FMT_SRGGB12_1X12,
595+ [IMX290_VARIANT_MONO] = MEDIA_BUS_FMT_Y12_1X12
596+ },
431597 .bpp = 12,
432598 .regs = imx290_12bit_settings,
433599 .num_regs = ARRAY_SIZE(imx290_12bit_settings),
434600 }
435601 };
436602
437−static const struct imx290_format_info *imx290_format_info(u32 code)
603+static const struct imx290_format_info *
604+imx290_format_info(const struct imx290 *imx290, u32 code)
438605 {
439606 unsigned int i;
440607
441608 for (i = 0; i < ARRAY_SIZE(imx290_formats); ++i) {
442609 const struct imx290_format_info *info = &imx290_formats[i];
443610
444− if (info->code == code)
611+ if (info->code[imx290->model->colour_variant] == code)
445612 return info;
446613 }
447614
@@ -461,28 +628,30 @@ static int __always_unused imx290_read(struct imx290 *imx290, u32 addr, u32 *val · 13 unmodified lines
461628 data, (addr >> IMX290_REG_SIZE_SHIFT) & 3);
462629 if (ret < 0) {
463630 dev_err(imx290->dev, "%u-bit read from 0x%04x failed: %d\n",
464− ((addr >> IMX290_REG_SIZE_SHIFT) & 3) * 8,
631+ ((addr >> IMX290_REG_SIZE_SHIFT) & 3) * 8,
465632 addr & IMX290_REG_ADDR_MASK, ret);
466633 return ret;
467634 }
468635
469− *value = (data[2] << 16) | (data[1] << 8) | data[0];
636+ *value = get_unaligned_le24(data);
470637 return 0;
471638 }
472639
473640 static int imx290_write(struct imx290 *imx290, u32 addr, u32 value, int *err)
474641 {
475− u8 data[3] = { value & 0xff, (value >> 8) & 0xff, value >> 16 };
642+ u8 data[3];
476643 int ret;
477644
478645 if (err && *err)
479646 return *err;
480647
648+ put_unaligned_le24(value, data);
649+
481650 ret = regmap_raw_write(imx290->regmap, addr & IMX290_REG_ADDR_MASK,
482651 data, (addr >> IMX290_REG_SIZE_SHIFT) & 3);
483652 if (ret < 0) {
484653 dev_err(imx290->dev, "%u-bit write to 0x%04x failed: %d\n",
485− ((addr >> IMX290_REG_SIZE_SHIFT) & 3) * 8,
654+ ((addr >> IMX290_REG_SIZE_SHIFT) & 3) * 8,
486655 addr & IMX290_REG_ADDR_MASK, ret);
487656 if (err)
488657 *err = ret;
@@ -510,24 +679,33 @@ static int imx290_set_register_array(struct imx290 *imx290, · 21 unmodified lines
510679 return 0;
511680 }
512681
682+static int imx290_set_clock(struct imx290 *imx290)
683+{
684+ const struct imx290_mode *mode = imx290->current_mode;
685+ enum imx290_clk_freq clk_idx = imx290->xclk_idx;
686+ const struct imx290_clk_cfg *clk_cfg = &mode->clk_cfg[clk_idx];
687+ int ret;
688+
689+ ret = imx290_set_register_array(imx290, xclk_regs[clk_idx],
690+ IMX290_NUM_CLK_REGS);
691+
692+ imx290_write(imx290, IMX290_INCKSEL1, clk_cfg->incksel1, &ret);
693+ imx290_write(imx290, IMX290_INCKSEL2, clk_cfg->incksel2, &ret);
694+ imx290_write(imx290, IMX290_INCKSEL3, clk_cfg->incksel3, &ret);
695+ imx290_write(imx290, IMX290_INCKSEL4, clk_cfg->incksel4, &ret);
696+ imx290_write(imx290, IMX290_INCKSEL5, clk_cfg->incksel5, &ret);
697+ imx290_write(imx290, IMX290_INCKSEL6, clk_cfg->incksel6, &ret);
698+
699+ return ret;
700+}
701+
513702 static int imx290_set_data_lanes(struct imx290 *imx290)
514703 {
515704 int ret = 0;
516− u32 frsel;
517−
518− switch (imx290->nlanes) {
519− case 2:
520− default:
521− frsel = 0x02;
522− break;
523− case 4:
524− frsel = 0x01;
525− break;
526− }
527705
528706 imx290_write(imx290, IMX290_PHY_LANE_NUM, imx290->nlanes - 1, &ret);
529707 imx290_write(imx290, IMX290_CSI_LANE_MODE, imx290->nlanes - 1, &ret);
530− imx290_write(imx290, IMX290_FR_FDG_SEL, frsel, &ret);
708+ imx290_write(imx290, IMX290_FR_FDG_SEL, 0x01, &ret);
531709
532710 return ret;
533711 }
@@ -536,19 +714,55 @@ static int imx290_set_black_level(struct imx290 *imx290, · 2 unmodified lines
536714 const struct v4l2_mbus_framefmt *format,
537715 unsigned int black_level, int *err)
538716 {
539− unsigned int bpp = imx290_format_info(format->code)->bpp;
717+ unsigned int bpp = imx290_format_info(imx290, format->code)->bpp;
540718
541719 return imx290_write(imx290, IMX290_BLKLEVEL,
542720 black_level >> (16 - bpp), err);
543721 }
544722
723+static int imx290_set_csi_config(struct imx290 *imx290)
724+{
725+ const s64 *link_freqs = imx290_link_freqs_ptr(imx290);
726+ const struct imx290_csi_cfg *csi_cfg;
727+ int ret = 0;
728+
729+ switch (link_freqs[imx290->current_mode->link_freq_index]) {
730+ case 445500000:
731+ csi_cfg = &imx290_csi_445_5mhz;
732+ break;
733+ case 297000000:
734+ csi_cfg = &imx290_csi_297mhz;
735+ break;
736+ case 222750000:
737+ csi_cfg = &imx290_csi_222_75mhz;
738+ break;
739+ case 148500000:
740+ csi_cfg = &imx290_csi_148_5mhz;
741+ break;
742+ default:
743+ return -EINVAL;
744+ }
745+
746+ imx290_write(imx290, IMX290_REPETITION, csi_cfg->repetition, &ret);
747+ imx290_write(imx290, IMX290_TCLKPOST, csi_cfg->tclkpost, &ret);
748+ imx290_write(imx290, IMX290_THSZERO, csi_cfg->thszero, &ret);
749+ imx290_write(imx290, IMX290_THSPREPARE, csi_cfg->thsprepare, &ret);
750+ imx290_write(imx290, IMX290_TCLKTRAIL, csi_cfg->tclktrail, &ret);
751+ imx290_write(imx290, IMX290_THSTRAIL, csi_cfg->thstrail, &ret);
752+ imx290_write(imx290, IMX290_TCLKZERO, csi_cfg->tclkzero, &ret);
753+ imx290_write(imx290, IMX290_TCLKPREPARE, csi_cfg->tclkprepare, &ret);
754+ imx290_write(imx290, IMX290_TLPX, csi_cfg->tlpx, &ret);
755+
756+ return ret;
757+}
758+
545759 static int imx290_setup_format(struct imx290 *imx290,
546760 const struct v4l2_mbus_framefmt *format)
547761 {
548762 const struct imx290_format_info *info;
549763 int ret;
550764
551− info = imx290_format_info(format->code);
765+ info = imx290_format_info(imx290, format->code);
552766
553767 ret = imx290_set_register_array(imx290, info->regs, info->num_regs);
554768 if (ret < 0) {
@@ -563,6 +777,16 @@ static int imx290_setup_format(struct imx290 *imx290, · 8 unmodified lines
563777 /* ----------------------------------------------------------------------------
564778 * Controls
565779 */
780+static void imx290_exposure_update(struct imx290 *imx290,
781+ const struct imx290_mode *mode)
782+{
783+ unsigned int exposure_max;
784+
785+ exposure_max = imx290->vblank->val + mode->height -
786+ IMX290_EXPOSURE_OFFSET;
787+ __v4l2_ctrl_modify_range(imx290->exposure, 1, exposure_max, 1,
788+ exposure_max);
789+}
566790
567791 static int imx290_set_ctrl(struct v4l2_ctrl *ctrl)
568792 {
@@ -570,7 +794,7 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) · 1 unmodified line
570794 struct imx290, ctrls);
571795 const struct v4l2_mbus_framefmt *format;
572796 struct v4l2_subdev_state *state;
573− int ret = 0;
797+ int ret = 0, vmax;
574798
575799 /*
576800 * Return immediately for controls that don't need to be applied to the
@@ -579,6 +803,11 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) · 2 unmodified lines
579803 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
580804 return 0;
581805
806+ if (ctrl->id == V4L2_CID_VBLANK) {
807+ /* Changing vblank changes the allowed range for exposure. */
808+ imx290_exposure_update(imx290, imx290->current_mode);
809+ }
810+
582811 /* V4L2 controls values will be applied only when power is already up */
583812 if (!pm_runtime_get_if_in_use(imx290->dev))
584813 return 0;
@@ -591,9 +820,23 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) · 6 unmodified lines
591820 ret = imx290_write(imx290, IMX290_GAIN, ctrl->val, NULL);
592821 break;
593822
823+ case V4L2_CID_VBLANK:
824+ ret = imx290_write(imx290, IMX290_VMAX,
825+ ctrl->val + imx290->current_mode->height,
826+ NULL);
827+ /*
828+ * Due to the way that exposure is programmed in this sensor in
829+ * relation to VMAX, we have to reprogramme it whenever VMAX is
830+ * changed.
831+ * Update ctrl so that the V4L2_CID_EXPOSURE case can refer to
832+ * it.
833+ */
834+ ctrl = imx290->exposure;
835+ fallthrough;
594836 case V4L2_CID_EXPOSURE:
837+ vmax = imx290->vblank->val + imx290->current_mode->height;
595838 ret = imx290_write(imx290, IMX290_SHS1,
596− IMX290_VMAX_DEFAULT - ctrl->val - 1, NULL);
839+ vmax - ctrl->val - 1, NULL);
597840 break;
598841
599842 case V4L2_CID_TEST_PATTERN:
@@ -612,6 +855,26 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) · 12 unmodified lines
612855 }
613856 break;
614857
858+ case V4L2_CID_HBLANK:
859+ ret = imx290_write(imx290, IMX290_HMAX,
860+ ctrl->val + imx290->current_mode->width,
861+ NULL);
862+ break;
863+
864+ case V4L2_CID_HFLIP:
865+ case V4L2_CID_VFLIP:
866+ {
867+ u32 reg;
868+
869+ reg = imx290->current_mode->ctrl_07;
870+ if (imx290->hflip->val)
871+ reg |= IMX290_HREVERSE;
872+ if (imx290->vflip->val)
873+ reg |= IMX290_VREVERSE;
874+ ret = imx290_write(imx290, IMX290_CTRL_07, reg, NULL);
875+ break;
876+ }
877+
615878 default:
616879 ret = -EINVAL;
617880 break;
@@ -642,20 +905,17 @@ static void imx290_ctrl_update(struct imx290 *imx290, · 24 unmodified lines
642905 const struct v4l2_mbus_framefmt *format,
643906 const struct imx290_mode *mode)
644907 {
645− unsigned int hblank = mode->hmax - mode->width;
646− unsigned int vblank = IMX290_VMAX_DEFAULT - mode->height;
647− s64 link_freq = imx290_link_freqs_ptr(imx290)[mode->link_freq_index];
648− u64 pixel_rate;
649−
650− /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
651− pixel_rate = link_freq * 2 * imx290->nlanes;
652− do_div(pixel_rate, imx290_format_info(format->code)->bpp);
908+ unsigned int hblank_min = mode->hmax_min - mode->width;
909+ unsigned int hblank_max = IMX290_HMAX_MAX - mode->width;
910+ unsigned int vblank_min = mode->vmax_min - mode->height;
911+ unsigned int vblank_max = IMX290_VMAX_MAX - mode->height;
653912
654913 __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
655− __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, pixel_rate);
656914
657− __v4l2_ctrl_modify_range(imx290->hblank, hblank, hblank, 1, hblank);
658− __v4l2_ctrl_modify_range(imx290->vblank, vblank, vblank, 1, vblank);
915+ __v4l2_ctrl_modify_range(imx290->hblank, hblank_min, hblank_max, 1,
916+ hblank_min);
917+ __v4l2_ctrl_modify_range(imx290->vblank, vblank_min, vblank_max, 1,
918+ vblank_min);
659919 }
660920
661921 static int imx290_ctrl_init(struct imx290 *imx290)
@@ -667,7 +927,7 @@ static int imx290_ctrl_init(struct imx290 *imx290) · 5 unmodified lines
667927 if (ret < 0)
668928 return ret;
669929
670− v4l2_ctrl_handler_init(&imx290->ctrls, 9);
930+ v4l2_ctrl_handler_init(&imx290->ctrls, 11);
671931
672932 /*
673933 * The sensor has an analog gain and a digital gain, both controlled
@@ -685,9 +945,13 @@ static int imx290_ctrl_init(struct imx290 *imx290) · 11 unmodified lines
685945 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
686946 V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0);
687947
688− v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
689− V4L2_CID_EXPOSURE, 1, IMX290_VMAX_DEFAULT - 2, 1,
690− IMX290_VMAX_DEFAULT - 2);
948+ /*
949+ * Correct range will be determined through imx290_ctrl_update setting
950+ * V4L2_CID_VBLANK.
951+ */
952+ imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
953+ V4L2_CID_EXPOSURE, 1, 65535, 1,
954+ 65535);
691955
692956 /*
693957 * Set the link frequency, pixel rate, horizontal blanking and vertical
@@ -702,24 +966,29 @@ static int imx290_ctrl_init(struct imx290 *imx290) · 8 unmodified lines
702966 if (imx290->link_freq)
703967 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
704968
705− imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
706− V4L2_CID_PIXEL_RATE,
707− 1, INT_MAX, 1, 1);
969+ v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, V4L2_CID_PIXEL_RATE,
970+ IMX290_PIXEL_RATE, IMX290_PIXEL_RATE, 1,
971+ IMX290_PIXEL_RATE);
708972
709973 v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops,
710974 V4L2_CID_TEST_PATTERN,
711975 ARRAY_SIZE(imx290_test_pattern_menu) - 1,
712976 0, 0, imx290_test_pattern_menu);
713977
978+ /*
979+ * Actual range will be set from imx290_ctrl_update later in the probe.
980+ */
714981 imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
715982 V4L2_CID_HBLANK, 1, 1, 1, 1);
716− if (imx290->hblank)
717− imx290->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
718983
719984 imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
720985 V4L2_CID_VBLANK, 1, 1, 1, 1);
721− if (imx290->vblank)
722− imx290->vblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
986+
987+ imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
988+ V4L2_CID_HFLIP, 0, 1, 1, 0);
989+ imx290->vflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
990+ V4L2_CID_VFLIP, 0, 1, 1, 0);
991+ v4l2_ctrl_cluster(2, &imx290->hflip);
723992
724993 v4l2_ctrl_new_fwnode_properties(&imx290->ctrls, &imx290_ctrl_ops,
725994 &props);
@@ -748,17 +1017,37 @@ static int imx290_start_streaming(struct imx290 *imx290, · 22 unmodified lines
7481017
7491018 /* Set init register settings */
7501019 ret = imx290_set_register_array(imx290, imx290_global_init_settings,
751− ARRAY_SIZE(
752− imx290_global_init_settings));
1020+ ARRAY_SIZE(imx290_global_init_settings));
7531021 if (ret < 0) {
7541022 dev_err(imx290->dev, "Could not set init registers\n");
7551023 return ret;
7561024 }
7571025
1026+ /* Set mdel specific init register settings */
1027+ ret = imx290_set_register_array(imx290, imx290->model->init_regs,
1028+ imx290->model->init_regs_num);
1029+ if (ret < 0) {
1030+ dev_err(imx290->dev, "Could not set model specific init registers\n");
1031+ return ret;
1032+ }
1033+
1034+ /* Set clock parameters based on mode and xclk */
1035+ ret = imx290_set_clock(imx290);
1036+ if (ret < 0) {
1037+ dev_err(imx290->dev, "Could not set clocks - %d\n", ret);
1038+ return ret;
1039+ }
1040+
7581041 /* Set data lane count */
7591042 ret = imx290_set_data_lanes(imx290);
7601043 if (ret < 0) {
761− dev_err(imx290->dev, "Could not set data lanes\n");
1044+ dev_err(imx290->dev, "Could not set data lanes - %d\n", ret);
1045+ return ret;
1046+ }
1047+
1048+ ret = imx290_set_csi_config(imx290);
1049+ if (ret < 0) {
1050+ dev_err(imx290->dev, "Could not set csi cfg - %d\n", ret);
7621051 return ret;
7631052 }
7641053
@@ -766,7 +1055,7 @@ static int imx290_start_streaming(struct imx290 *imx290, · 1 unmodified line
7661055 format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
7671056 ret = imx290_setup_format(imx290, format);
7681057 if (ret < 0) {
769− dev_err(imx290->dev, "Could not set frame format\n");
1058+ dev_err(imx290->dev, "Could not set frame format - %d\n", ret);
7701059 return ret;
7711060 }
7721061
@@ -774,19 +1063,14 @@ static int imx290_start_streaming(struct imx290 *imx290, · 1 unmodified line
7741063 ret = imx290_set_register_array(imx290, imx290->current_mode->data,
7751064 imx290->current_mode->data_size);
7761065 if (ret < 0) {
777− dev_err(imx290->dev, "Could not set current mode\n");
1066+ dev_err(imx290->dev, "Could not set current mode - %d\n", ret);
7781067 return ret;
7791068 }
7801069
781− ret = imx290_write(imx290, IMX290_HMAX, imx290->current_mode->hmax,
782− NULL);
783− if (ret)
784− return ret;
785−
7861070 /* Apply customized values from user */
7871071 ret = __v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
7881072 if (ret) {
789− dev_err(imx290->dev, "Could not sync v4l2 controls\n");
1073+ dev_err(imx290->dev, "Could not sync v4l2 controls - %d\n", ret);
7901074 return ret;
7911075 }
7921076
@@ -835,6 +1119,13 @@ static int imx290_set_stream(struct v4l2_subdev *sd, int enable) · 42 unmodified lines
8351119 pm_runtime_put_autosuspend(imx290->dev);
8361120 }
8371121
1122+ /*
1123+ * vflip and hflip should not be changed during streaming as the sensor
1124+ * will produce an invalid frame.
1125+ */
1126+ __v4l2_ctrl_grab(imx290->vflip, enable);
1127+ __v4l2_ctrl_grab(imx290->hflip, enable);
1128+
8381129 unlock:
8391130 v4l2_subdev_unlock_state(state);
8401131 return ret;
@@ -844,10 +1135,12 @@ static int imx290_enum_mbus_code(struct v4l2_subdev *sd, · 3 unmodified lines
8441135 struct v4l2_subdev_state *sd_state,
8451136 struct v4l2_subdev_mbus_code_enum *code)
8461137 {
1138+ const struct imx290 *imx290 = to_imx290(sd);
1139+
8471140 if (code->index >= ARRAY_SIZE(imx290_formats))
8481141 return -EINVAL;
8491142
850− code->code = imx290_formats[code->index].code;
1143+ code->code = imx290_formats[code->index].code[imx290->model->colour_variant];
8511144
8521145 return 0;
8531146 }
@@ -859,7 +1152,7 @@ static int imx290_enum_frame_size(struct v4l2_subdev *sd, · 5 unmodified lines
8591152 const struct imx290 *imx290 = to_imx290(sd);
8601153 const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290);
8611154
862− if (!imx290_format_info(fse->code))
1155+ if (!imx290_format_info(imx290, fse->code))
8631156 return -EINVAL;
8641157
8651158 if (fse->index >= imx290_modes_num(imx290))
@@ -888,10 +1181,14 @@ static int imx290_set_fmt(struct v4l2_subdev *sd, · 22 unmodified lines
8881181 fmt->format.width = mode->width;
8891182 fmt->format.height = mode->height;
8901183
891− if (!imx290_format_info(fmt->format.code))
892− fmt->format.code = imx290_formats[0].code;
1184+ if (!imx290_format_info(imx290, fmt->format.code))
1185+ fmt->format.code = imx290_formats[0].code[imx290->model->colour_variant];
8931186
8941187 fmt->format.field = V4L2_FIELD_NONE;
1188+ fmt->format.colorspace = V4L2_COLORSPACE_RAW;
1189+ fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_601;
1190+ fmt->format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
1191+ fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
8951192
8961193 format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
8971194
@@ -899,6 +1196,7 @@ static int imx290_set_fmt(struct v4l2_subdev *sd, · 1 unmodified line
8991196 imx290->current_mode = mode;
9001197
9011198 imx290_ctrl_update(imx290, &fmt->format, mode);
1199+ imx290_exposure_update(imx290, mode);
9021200 }
9031201
9041202 *format = fmt->format;
@@ -910,16 +1208,23 @@ static int imx290_get_selection(struct v4l2_subdev *sd, · 5 unmodified lines
9101208 struct v4l2_subdev_state *sd_state,
9111209 struct v4l2_subdev_selection *sel)
9121210 {
1211+ struct imx290 *imx290 = to_imx290(sd);
9131212 struct v4l2_mbus_framefmt *format;
9141213
9151214 switch (sel->target) {
9161215 case V4L2_SEL_TGT_CROP: {
9171216 format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
9181217
1218+ /*
1219+ * The sensor moves the readout by 1 pixel based on flips to
1220+ * keep the Bayer order the same.
1221+ */
9191222 sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP
920− + (IMX290_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2;
1223+ + (IMX290_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2
1224+ + imx290->vflip->val;
9211225 sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT
922− + (IMX290_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2;
1226+ + (IMX290_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2
1227+ + imx290->hflip->val;
9231228 sel->r.width = format->width;
9241229 sel->r.height = format->height;
9251230
@@ -964,6 +1269,11 @@ static int imx290_entity_init_cfg(struct v4l2_subdev *subdev, · 38 unmodified lines
9641269 return 0;
9651270 }
9661271
1272+static const struct v4l2_subdev_core_ops imx290_core_ops = {
1273+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1274+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1275+};
1276+
9671277 static const struct v4l2_subdev_video_ops imx290_video_ops = {
9681278 .s_stream = imx290_set_stream,
9691279 };
@@ -978,6 +1288,7 @@ static const struct v4l2_subdev_pad_ops imx290_pad_ops = { · 8 unmodified lines
9781288 };
9791289
9801290 static const struct v4l2_subdev_ops imx290_subdev_ops = {
1291+ .core = &imx290_core_ops,
9811292 .video = &imx290_video_ops,
9821293 .pad = &imx290_pad_ops,
9831294 };
@@ -996,7 +1307,8 @@ static int imx290_subdev_init(struct imx290 *imx290) · 12 unmodified lines
9961307 imx290->current_mode = &imx290_modes_ptr(imx290)[0];
9971308
9981309 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
999− imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1310+ imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1311+ V4L2_SUBDEV_FL_HAS_EVENTS;
10001312 imx290->sd.dev = imx290->dev;
10011313 imx290->sd.entity.ops = &imx290_subdev_entity_ops;
10021314 imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
@@ -1132,15 +1444,22 @@ static int imx290_init_clk(struct imx290 *imx290) · 129 unmodified lines
11321444 u32 xclk_freq;
11331445 int ret;
11341446
1135− ret = fwnode_property_read_u32(dev_fwnode(imx290->dev),
1136− "clock-frequency", &xclk_freq);
1447+ ret = device_property_read_u32(imx290->dev, "clock-frequency",
1448+ &xclk_freq);
11371449 if (ret) {
11381450 dev_err(imx290->dev, "Could not get xclk frequency\n");
11391451 return ret;
11401452 }
11411453
1142− /* external clock must be 37.125 MHz */
1143− if (xclk_freq != 37125000) {
1454+ /* external clock must be 37.125 MHz or 74.25MHz */
1455+ switch (xclk_freq) {
1456+ case 37125000:
1457+ imx290->xclk_idx = IMX290_CLK_37_125;
1458+ break;
1459+ case 74250000:
1460+ imx290->xclk_idx = IMX290_CLK_74_25;
1461+ break;
1462+ default:
11441463 dev_err(imx290->dev, "External clock frequency %u is not supported\n",
11451464 xclk_freq);
11461465 return -EINVAL;
@@ -1177,6 +1496,27 @@ static s64 imx290_check_link_freqs(const struct imx290 *imx290, · 30 unmodified lines
11771496 return 0;
11781497 }
11791498
1499+static const struct imx290_model_info imx290_models[] = {
1500+ [IMX290_MODEL_IMX290LQR] = {
1501+ .colour_variant = IMX290_VARIANT_COLOUR,
1502+ .init_regs = imx290_global_init_settings_290,
1503+ .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
1504+ .name = "imx290",
1505+ },
1506+ [IMX290_MODEL_IMX290LLR] = {
1507+ .colour_variant = IMX290_VARIANT_MONO,
1508+ .init_regs = imx290_global_init_settings_290,
1509+ .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290),
1510+ .name = "imx290",
1511+ },
1512+ [IMX290_MODEL_IMX327LQR] = {
1513+ .colour_variant = IMX290_VARIANT_COLOUR,
1514+ .init_regs = imx290_global_init_settings_327,
1515+ .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_327),
1516+ .name = "imx327",
1517+ },
1518+};
1519+
11801520 static int imx290_parse_dt(struct imx290 *imx290)
11811521 {
11821522 /* Only CSI2 is supported for now: */
@@ -1187,6 +1527,8 @@ static int imx290_parse_dt(struct imx290 *imx290) · 4 unmodified lines
11871527 int ret;
11881528 s64 fq;
11891529
1530+ imx290->model = of_device_get_match_data(imx290->dev);
1531+
11901532 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx290->dev), NULL);
11911533 if (!endpoint) {
11921534 dev_err(imx290->dev, "Endpoint node not found\n");
@@ -1260,7 +1602,7 @@ static int imx290_probe(struct i2c_client *client) · 67 unmodified lines
12601602 imx290->xclk = devm_clk_get(dev, "xclk");
12611603 if (IS_ERR(imx290->xclk))
12621604 return dev_err_probe(dev, PTR_ERR(imx290->xclk),
1263− "Could not get xclk");
1605+ "Could not get xclk\n");
12641606
12651607 ret = imx290_get_regulators(dev, imx290);
12661608 if (ret < 0)
@@ -1304,6 +1646,9 @@ static int imx290_probe(struct i2c_client *client) · 37 unmodified lines
13041646 if (ret)
13051647 goto err_pm;
13061648
1649+ v4l2_i2c_subdev_set_name(&imx290->sd, client,
1650+ imx290->model->name, NULL);
1651+
13071652 /*
13081653 * Finally, register the V4L2 subdev. This must be done after
13091654 * initializing everything as the subdev can be used immediately after
@@ -1352,8 +1697,21 @@ static void imx290_remove(struct i2c_client *client) · 42 unmodified lines
13521697 }
13531698
13541699 static const struct of_device_id imx290_of_match[] = {
1355− { .compatible = "sony,imx290" },
1356− { /* sentinel */ }
1700+ {
1701+ /* Deprecated - synonym for "sony,imx290lqr" */
1702+ .compatible = "sony,imx290",
1703+ .data = &imx290_models[IMX290_MODEL_IMX290LQR],
1704+ }, {
1705+ .compatible = "sony,imx290lqr",
1706+ .data = &imx290_models[IMX290_MODEL_IMX290LQR],
1707+ }, {
1708+ .compatible = "sony,imx290llr",
1709+ .data = &imx290_models[IMX290_MODEL_IMX290LLR],
1710+ }, {
1711+ .compatible = "sony,imx327lqr",
1712+ .data = &imx290_models[IMX290_MODEL_IMX327LQR],
1713+ },
1714+ { /* sentinel */ },
13571715 };
13581716 MODULE_DEVICE_TABLE(of, imx290_of_match);
13591717
drivers/media/i2c/imx296.c+1−10
@@ -685,15 +685,6 @@ static int imx296_enum_frame_size(struct v4l2_subdev *sd, · 684 unmodified lines
685685 return 0;
686686 }
687687
688−static int imx296_get_format(struct v4l2_subdev *sd,
689− struct v4l2_subdev_state *state,
690− struct v4l2_subdev_format *fmt)
691−{
692− fmt->format = *v4l2_subdev_get_pad_format(sd, state, fmt->pad);
693−
694− return 0;
695−}
696−
697688 static int imx296_set_format(struct v4l2_subdev *sd,
698689 struct v4l2_subdev_state *state,
699690 struct v4l2_subdev_format *fmt)
@@ -845,7 +836,7 @@ static const struct v4l2_subdev_video_ops imx296_subdev_video_ops = { · 145 unmodified lines
845836 static const struct v4l2_subdev_pad_ops imx296_subdev_pad_ops = {
846837 .enum_mbus_code = imx296_enum_mbus_code,
847838 .enum_frame_size = imx296_enum_frame_size,
848− .get_fmt = imx296_get_format,
839+ .get_fmt = v4l2_subdev_get_fmt,
849840 .set_fmt = imx296_set_format,
850841 .get_selection = imx296_get_selection,
851842 .set_selection = imx296_set_selection,
drivers/media/i2c/imx334.c+294−28
@@ -79,7 +79,6 @@ struct imx334_reg_list { · 78 unmodified lines
7979 * struct imx334_mode - imx334 sensor mode structure
8080 * @width: Frame width
8181 * @height: Frame height
82− * @code: Format code
8382 * @hblank: Horizontal blanking in lines
8483 * @vblank: Vertical blanking in lines
8584 * @vblank_min: Minimal vertical blanking in lines
@@ -91,7 +90,6 @@ struct imx334_reg_list { · 5 unmodified lines
9190 struct imx334_mode {
9291 u32 width;
9392 u32 height;
94− u32 code;
9593 u32 hblank;
9694 u32 vblank;
9795 u32 vblank_min;
@@ -119,6 +117,7 @@ struct imx334_mode { · 21 unmodified lines
119117 * @vblank: Vertical blanking in lines
120118 * @cur_mode: Pointer to current selected sensor mode
121119 * @mutex: Mutex for serializing sensor controls
120+ * @cur_code: current selected format code
122121 * @streaming: Flag indicating streaming state
123122 */
124123 struct imx334 {
@@ -140,6 +139,7 @@ struct imx334 { · 15 unmodified lines
140139 u32 vblank;
141140 const struct imx334_mode *cur_mode;
142141 struct mutex mutex;
142+ u32 cur_code;
143143 bool streaming;
144144 };
145145
@@ -147,7 +147,170 @@ static const s64 link_freq[] = { · 1 unmodified line
147147 IMX334_LINK_FREQ,
148148 };
149149
150−/* Sensor mode registers */
150+/* Sensor mode registers for 1920x1080@30fps */
151+static const struct imx334_reg mode_1920x1080_regs[] = {
152+ {0x3000, 0x01},
153+ {0x3018, 0x04},
154+ {0x3030, 0xca},
155+ {0x3031, 0x08},
156+ {0x3032, 0x00},
157+ {0x3034, 0x4c},
158+ {0x3035, 0x04},
159+ {0x302c, 0xf0},
160+ {0x302d, 0x03},
161+ {0x302e, 0x80},
162+ {0x302f, 0x07},
163+ {0x3074, 0xcc},
164+ {0x3075, 0x02},
165+ {0x308e, 0xcd},
166+ {0x308f, 0x02},
167+ {0x3076, 0x38},
168+ {0x3077, 0x04},
169+ {0x3090, 0x38},
170+ {0x3091, 0x04},
171+ {0x3308, 0x38},
172+ {0x3309, 0x04},
173+ {0x30C6, 0x00},
174+ {0x30c7, 0x00},
175+ {0x30ce, 0x00},
176+ {0x30cf, 0x00},
177+ {0x30d8, 0x18},
178+ {0x30d9, 0x0a},
179+ {0x304c, 0x00},
180+ {0x304e, 0x00},
181+ {0x304f, 0x00},
182+ {0x3050, 0x00},
183+ {0x30b6, 0x00},
184+ {0x30b7, 0x00},
185+ {0x3116, 0x08},
186+ {0x3117, 0x00},
187+ {0x31a0, 0x20},
188+ {0x31a1, 0x0f},
189+ {0x300c, 0x3b},
190+ {0x300d, 0x29},
191+ {0x314c, 0x29},
192+ {0x314d, 0x01},
193+ {0x315a, 0x06},
194+ {0x3168, 0xa0},
195+ {0x316a, 0x7e},
196+ {0x319e, 0x02},
197+ {0x3199, 0x00},
198+ {0x319d, 0x00},
199+ {0x31dd, 0x03},
200+ {0x3300, 0x00},
201+ {0x341c, 0xff},
202+ {0x341d, 0x01},
203+ {0x3a01, 0x03},
204+ {0x3a18, 0x7f},
205+ {0x3a19, 0x00},
206+ {0x3a1a, 0x37},
207+ {0x3a1b, 0x00},
208+ {0x3a1c, 0x37},
209+ {0x3a1d, 0x00},
210+ {0x3a1e, 0xf7},
211+ {0x3a1f, 0x00},
212+ {0x3a20, 0x3f},
213+ {0x3a21, 0x00},
214+ {0x3a20, 0x6f},
215+ {0x3a21, 0x00},
216+ {0x3a20, 0x3f},
217+ {0x3a21, 0x00},
218+ {0x3a20, 0x5f},
219+ {0x3a21, 0x00},
220+ {0x3a20, 0x2f},
221+ {0x3a21, 0x00},
222+ {0x3078, 0x02},
223+ {0x3079, 0x00},
224+ {0x307a, 0x00},
225+ {0x307b, 0x00},
226+ {0x3080, 0x02},
227+ {0x3081, 0x00},
228+ {0x3082, 0x00},
229+ {0x3083, 0x00},
230+ {0x3088, 0x02},
231+ {0x3094, 0x00},
232+ {0x3095, 0x00},
233+ {0x3096, 0x00},
234+ {0x309b, 0x02},
235+ {0x309c, 0x00},
236+ {0x309d, 0x00},
237+ {0x309e, 0x00},
238+ {0x30a4, 0x00},
239+ {0x30a5, 0x00},
240+ {0x3288, 0x21},
241+ {0x328a, 0x02},
242+ {0x3414, 0x05},
243+ {0x3416, 0x18},
244+ {0x35Ac, 0x0e},
245+ {0x3648, 0x01},
246+ {0x364a, 0x04},
247+ {0x364c, 0x04},
248+ {0x3678, 0x01},
249+ {0x367c, 0x31},
250+ {0x367e, 0x31},
251+ {0x3708, 0x02},
252+ {0x3714, 0x01},
253+ {0x3715, 0x02},
254+ {0x3716, 0x02},
255+ {0x3717, 0x02},
256+ {0x371c, 0x3d},
257+ {0x371d, 0x3f},
258+ {0x372c, 0x00},
259+ {0x372d, 0x00},
260+ {0x372e, 0x46},
261+ {0x372f, 0x00},
262+ {0x3730, 0x89},
263+ {0x3731, 0x00},
264+ {0x3732, 0x08},
265+ {0x3733, 0x01},
266+ {0x3734, 0xfe},
267+ {0x3735, 0x05},
268+ {0x375d, 0x00},
269+ {0x375e, 0x00},
270+ {0x375f, 0x61},
271+ {0x3760, 0x06},
272+ {0x3768, 0x1b},
273+ {0x3769, 0x1b},
274+ {0x376a, 0x1a},
275+ {0x376b, 0x19},
276+ {0x376c, 0x18},
277+ {0x376d, 0x14},
278+ {0x376e, 0x0f},
279+ {0x3776, 0x00},
280+ {0x3777, 0x00},
281+ {0x3778, 0x46},
282+ {0x3779, 0x00},
283+ {0x377a, 0x08},
284+ {0x377b, 0x01},
285+ {0x377c, 0x45},
286+ {0x377d, 0x01},
287+ {0x377e, 0x23},
288+ {0x377f, 0x02},
289+ {0x3780, 0xd9},
290+ {0x3781, 0x03},
291+ {0x3782, 0xf5},
292+ {0x3783, 0x06},
293+ {0x3784, 0xa5},
294+ {0x3788, 0x0f},
295+ {0x378a, 0xd9},
296+ {0x378b, 0x03},
297+ {0x378c, 0xeb},
298+ {0x378d, 0x05},
299+ {0x378e, 0x87},
300+ {0x378f, 0x06},
301+ {0x3790, 0xf5},
302+ {0x3792, 0x43},
303+ {0x3794, 0x7a},
304+ {0x3796, 0xa1},
305+ {0x37b0, 0x37},
306+ {0x3e04, 0x0e},
307+ {0x30e8, 0x50},
308+ {0x30e9, 0x00},
309+ {0x3e04, 0x0e},
310+ {0x3002, 0x00},
311+};
312+
313+/* Sensor mode registers for 3840x2160@30fps */
151314 static const struct imx334_reg mode_3840x2160_regs[] = {
152315 {0x3000, 0x01},
153316 {0x3002, 0x00},
@@ -166,6 +329,7 @@ static const struct imx334_reg mode_3840x2160_regs[] = { · 12 unmodified lines
166329 {0x3288, 0x21},
167330 {0x328a, 0x02},
168331 {0x302c, 0x3c},
332+ {0x302d, 0x00},
169333 {0x302e, 0x00},
170334 {0x302f, 0x0f},
171335 {0x3076, 0x70},
@@ -240,23 +404,75 @@ static const struct imx334_reg mode_3840x2160_regs[] = { · 68 unmodified lines
240404 {0x3794, 0x7a},
241405 {0x3796, 0xa1},
242406 {0x3e04, 0x0e},
407+ {0x319e, 0x00},
243408 {0x3a00, 0x01},
409+ {0x3a18, 0xbf},
410+ {0x3a19, 0x00},
411+ {0x3a1a, 0x67},
412+ {0x3a1b, 0x00},
413+ {0x3a1c, 0x6f},
414+ {0x3a1d, 0x00},
415+ {0x3a1e, 0xd7},
416+ {0x3a1f, 0x01},
417+ {0x3a20, 0x6f},
418+ {0x3a21, 0x00},
419+ {0x3a22, 0xcf},
420+ {0x3a23, 0x00},
421+ {0x3a24, 0x6f},
422+ {0x3a25, 0x00},
423+ {0x3a26, 0xb7},
424+ {0x3a27, 0x00},
425+ {0x3a28, 0x5f},
426+ {0x3a29, 0x00},
427+};
428+
429+static const struct imx334_reg raw10_framefmt_regs[] = {
430+ {0x3050, 0x00},
431+ {0x319d, 0x00},
432+ {0x341c, 0xff},
433+ {0x341d, 0x01},
434+};
435+
436+static const struct imx334_reg raw12_framefmt_regs[] = {
437+ {0x3050, 0x01},
438+ {0x319d, 0x01},
439+ {0x341c, 0x47},
440+ {0x341d, 0x00},
441+};
442+
443+static const u32 imx334_mbus_codes[] = {
444+ MEDIA_BUS_FMT_SRGGB12_1X12,
445+ MEDIA_BUS_FMT_SRGGB10_1X10,
244446 };
245447
246448 /* Supported sensor mode configurations */
247−static const struct imx334_mode supported_mode = {
248− .width = 3840,
249− .height = 2160,
250− .hblank = 560,
251− .vblank = 2340,
252− .vblank_min = 90,
253− .vblank_max = 132840,
254− .pclk = 594000000,
255− .link_freq_idx = 0,
256− .code = MEDIA_BUS_FMT_SRGGB12_1X12,
257− .reg_list = {
258− .num_of_regs = ARRAY_SIZE(mode_3840x2160_regs),
259− .regs = mode_3840x2160_regs,
449+static const struct imx334_mode supported_modes[] = {
450+ {
451+ .width = 3840,
452+ .height = 2160,
453+ .hblank = 560,
454+ .vblank = 2340,
455+ .vblank_min = 90,
456+ .vblank_max = 132840,
457+ .pclk = 594000000,
458+ .link_freq_idx = 0,
459+ .reg_list = {
460+ .num_of_regs = ARRAY_SIZE(mode_3840x2160_regs),
461+ .regs = mode_3840x2160_regs,
462+ },
463+ }, {
464+ .width = 1920,
465+ .height = 1080,
466+ .hblank = 2480,
467+ .vblank = 1170,
468+ .vblank_min = 45,
469+ .vblank_max = 132840,
470+ .pclk = 297000000,
471+ .link_freq_idx = 0,
472+ .reg_list = {
473+ .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
474+ .regs = mode_1920x1080_regs,
475+ },
260476 },
261477 };
262478
@@ -382,7 +598,8 @@ static int imx334_update_controls(struct imx334 *imx334, · 119 unmodified lines
382598 if (ret)
383599 return ret;
384600
385− ret = __v4l2_ctrl_s_ctrl(imx334->hblank_ctrl, mode->hblank);
601+ ret = __v4l2_ctrl_modify_range(imx334->hblank_ctrl, mode->hblank,
602+ mode->hblank, 1, mode->hblank);
386603 if (ret)
387604 return ret;
388605
@@ -480,6 +697,9 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl) · 91 unmodified lines
480697
481698 pm_runtime_put(imx334->dev);
482699
700+ break;
701+ case V4L2_CID_HBLANK:
702+ ret = 0;
483703 break;
484704 default:
485705 dev_err(imx334->dev, "Invalid control %d", ctrl->id);
@@ -494,6 +714,18 @@ static const struct v4l2_ctrl_ops imx334_ctrl_ops = { · 8 unmodified lines
494714 .s_ctrl = imx334_set_ctrl,
495715 };
496716
717+static int imx334_get_format_code(struct imx334 *imx334, u32 code)
718+{
719+ unsigned int i;
720+
721+ for (i = 0; i < ARRAY_SIZE(imx334_mbus_codes); i++) {
722+ if (imx334_mbus_codes[i] == code)
723+ return imx334_mbus_codes[i];
724+ }
725+
726+ return imx334_mbus_codes[0];
727+}
728+
497729 /**
498730 * imx334_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
499731 * @sd: pointer to imx334 V4L2 sub-device structure
@@ -506,10 +738,10 @@ static int imx334_enum_mbus_code(struct v4l2_subdev *sd, · 6 unmodified lines
506738 struct v4l2_subdev_state *sd_state,
507739 struct v4l2_subdev_mbus_code_enum *code)
508740 {
509− if (code->index > 0)
741+ if (code->index >= ARRAY_SIZE(imx334_mbus_codes))
510742 return -EINVAL;
511743
512− code->code = supported_mode.code;
744+ code->code = imx334_mbus_codes[code->index];
513745
514746 return 0;
515747 }
@@ -526,15 +758,20 @@ static int imx334_enum_frame_size(struct v4l2_subdev *sd, · 10 unmodified lines
526758 struct v4l2_subdev_state *sd_state,
527759 struct v4l2_subdev_frame_size_enum *fsize)
528760 {
529− if (fsize->index > 0)
761+ struct imx334 *imx334 = to_imx334(sd);
762+ u32 code;
763+
764+ if (fsize->index >= ARRAY_SIZE(supported_modes))
530765 return -EINVAL;
531766
532− if (fsize->code != supported_mode.code)
767+ code = imx334_get_format_code(imx334, fsize->code);
768+
769+ if (fsize->code != code)
533770 return -EINVAL;
534771
535− fsize->min_width = supported_mode.width;
772+ fsize->min_width = supported_modes[fsize->index].width;
536773 fsize->max_width = fsize->min_width;
537− fsize->min_height = supported_mode.height;
774+ fsize->min_height = supported_modes[fsize->index].height;
538775 fsize->max_height = fsize->min_height;
539776
540777 return 0;
@@ -553,7 +790,6 @@ static void imx334_fill_pad_format(struct imx334 *imx334, · 12 unmodified lines
553790 {
554791 fmt->format.width = mode->width;
555792 fmt->format.height = mode->height;
556− fmt->format.code = mode->code;
557793 fmt->format.field = V4L2_FIELD_NONE;
558794 fmt->format.colorspace = V4L2_COLORSPACE_RAW;
559795 fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
@@ -583,6 +819,7 @@ static int imx334_get_pad_format(struct v4l2_subdev *sd, · 23 unmodified lines
583819 framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
584820 fmt->format = *framefmt;
585821 } else {
822+ fmt->format.code = imx334->cur_code;
586823 imx334_fill_pad_format(imx334, imx334->cur_mode, fmt);
587824 }
588825
@@ -609,15 +846,21 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd, · 20 unmodified lines
609846
610847 mutex_lock(&imx334->mutex);
611848
612− mode = &supported_mode;
849+ mode = v4l2_find_nearest_size(supported_modes,
850+ ARRAY_SIZE(supported_modes),
851+ width, height,
852+ fmt->format.width, fmt->format.height);
853+
613854 imx334_fill_pad_format(imx334, mode, fmt);
855+ fmt->format.code = imx334_get_format_code(imx334, fmt->format.code);
614856
615857 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
616858 struct v4l2_mbus_framefmt *framefmt;
617859
618860 framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
619861 *framefmt = fmt->format;
620− } else {
862+ } else if (imx334->cur_mode != mode || imx334->cur_code != fmt->format.code) {
863+ imx334->cur_code = fmt->format.code;
621864 ret = imx334_update_controls(imx334, mode);
622865 if (!ret)
623866 imx334->cur_mode = mode;
@@ -642,11 +885,26 @@ static int imx334_init_pad_cfg(struct v4l2_subdev *sd, · 18 unmodified lines
642885 struct v4l2_subdev_format fmt = { 0 };
643886
644887 fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
645− imx334_fill_pad_format(imx334, &supported_mode, &fmt);
888+ imx334_fill_pad_format(imx334, &supported_modes[0], &fmt);
646889
647890 return imx334_set_pad_format(sd, sd_state, &fmt);
648891 }
649892
893+static int imx334_set_framefmt(struct imx334 *imx334)
894+{
895+ switch (imx334->cur_code) {
896+ case MEDIA_BUS_FMT_SRGGB10_1X10:
897+ return imx334_write_regs(imx334, raw10_framefmt_regs,
898+ ARRAY_SIZE(raw10_framefmt_regs));
899+
900+ case MEDIA_BUS_FMT_SRGGB12_1X12:
901+ return imx334_write_regs(imx334, raw12_framefmt_regs,
902+ ARRAY_SIZE(raw12_framefmt_regs));
903+ }
904+
905+ return -EINVAL;
906+}
907+
650908 /**
651909 * imx334_start_streaming() - Start sensor stream
652910 * @imx334: pointer to imx334 device
@@ -667,6 +925,13 @@ static int imx334_start_streaming(struct imx334 *imx334) · 14 unmodified lines
667925 return ret;
668926 }
669927
928+ ret = imx334_set_framefmt(imx334);
929+ if (ret) {
930+ dev_err(imx334->dev, "%s failed to set frame format: %d\n",
931+ __func__, ret);
932+ return ret;
933+ }
934+
670935 /* Setup handler will write actual exposure and gain */
671936 ret = __v4l2_ctrl_handler_setup(imx334->sd.ctrl_handler);
672937 if (ret) {
@@ -1037,7 +1302,8 @@ static int imx334_probe(struct i2c_client *client) · 364 unmodified lines
10371302 }
10381303
10391304 /* Set default mode to max resolution */
1040− imx334->cur_mode = &supported_mode;
1305+ imx334->cur_mode = &supported_modes[0];
1306+ imx334->cur_code = imx334_mbus_codes[0];
10411307 imx334->vblank = imx334->cur_mode->vblank;
10421308
10431309 ret = imx334_init_controls(imx334);
drivers/media/i2c/m5mols/Kconfig+0−8
@@ -1,8 +0,0 @@
1−# SPDX-License-Identifier: GPL-2.0-only
2−config VIDEO_M5MOLS
3− tristate "Fujitsu M-5MOLS 8MP sensor support"
4− depends on I2C && VIDEO_DEV
5− select MEDIA_CONTROLLER
6− select VIDEO_V4L2_SUBDEV_API
7− help
8− This driver supports Fujitsu M-5MOLS camera sensor with ISP
drivers/media/i2c/m5mols/Makefile+0−4
@@ -1,4 +0,0 @@
1−# SPDX-License-Identifier: GPL-2.0-only
2−m5mols-objs := m5mols_core.o m5mols_controls.o m5mols_capture.o
3−
4−obj-$(CONFIG_VIDEO_M5MOLS) += m5mols.o
drivers/media/i2c/m5mols/m5mols.h+0−349
@@ -1,349 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0-or-later */
2−/*
3− * Header for M-5MOLS 8M Pixel camera sensor with ISP
4− *
5− * Copyright (C) 2011 Samsung Electronics Co., Ltd.
6− * Author: HeungJun Kim <riverful.kim@samsung.com>
7− *
8− * Copyright (C) 2009 Samsung Electronics Co., Ltd.
9− * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
10− */
11−
12−#ifndef M5MOLS_H
13−#define M5MOLS_H
14−
15−#include <linux/sizes.h>
16−#include <linux/gpio/consumer.h>
17−#include <media/v4l2-subdev.h>
18−#include "m5mols_reg.h"
19−
20−
21−/* An amount of data transmitted in addition to the value
22− * determined by CAPP_JPEG_SIZE_MAX register.
23− */
24−#define M5MOLS_JPEG_TAGS_SIZE 0x20000
25−#define M5MOLS_MAIN_JPEG_SIZE_MAX (5 * SZ_1M)
26−
27−extern int m5mols_debug;
28−
29−enum m5mols_restype {
30− M5MOLS_RESTYPE_MONITOR,
31− M5MOLS_RESTYPE_CAPTURE,
32− M5MOLS_RESTYPE_MAX,
33−};
34−
35−/**
36− * struct m5mols_resolution - structure for the resolution
37− * @type: resolution type according to the pixel code
38− * @width: width of the resolution
39− * @height: height of the resolution
40− * @reg: resolution preset register value
41− */
42−struct m5mols_resolution {
43− u8 reg;
44− enum m5mols_restype type;
45− u16 width;
46− u16 height;
47−};
48−
49−/**
50− * struct m5mols_exif - structure for the EXIF information of M-5MOLS
51− * @exposure_time: exposure time register value
52− * @shutter_speed: speed of the shutter register value
53− * @aperture: aperture register value
54− * @brightness: brightness register value
55− * @exposure_bias: it calls also EV bias
56− * @iso_speed: ISO register value
57− * @flash: status register value of the flash
58− * @sdr: status register value of the Subject Distance Range
59− * @qval: not written exact meaning in document
60− */
61−struct m5mols_exif {
62− u32 exposure_time;
63− u32 shutter_speed;
64− u32 aperture;
65− u32 brightness;
66− u32 exposure_bias;
67− u16 iso_speed;
68− u16 flash;
69− u16 sdr;
70− u16 qval;
71−};
72−
73−/**
74− * struct m5mols_capture - Structure for the capture capability
75− * @exif: EXIF information
76− * @buf_size: internal JPEG frame buffer size, in bytes
77− * @main: size in bytes of the main image
78− * @thumb: size in bytes of the thumb image, if it was accompanied
79− * @total: total size in bytes of the produced image
80− */
81−struct m5mols_capture {
82− struct m5mols_exif exif;
83− unsigned int buf_size;
84− u32 main;
85− u32 thumb;
86− u32 total;
87−};
88−
89−/**
90− * struct m5mols_scenemode - structure for the scenemode capability
91− * @metering: metering light register value
92− * @ev_bias: EV bias register value
93− * @wb_mode: mode which means the WhiteBalance is Auto or Manual
94− * @wb_preset: whitebalance preset register value in the Manual mode
95− * @chroma_en: register value whether the Chroma capability is enabled or not
96− * @chroma_lvl: chroma's level register value
97− * @edge_en: register value Whether the Edge capability is enabled or not
98− * @edge_lvl: edge's level register value
99− * @af_range: Auto Focus's range
100− * @fd_mode: Face Detection mode
101− * @mcc: Multi-axis Color Conversion which means emotion color
102− * @light: status of the Light
103− * @flash: status of the Flash
104− * @tone: Tone color which means Contrast
105− * @iso: ISO register value
106− * @capt_mode: Mode of the Image Stabilization while the camera capturing
107− * @wdr: Wide Dynamic Range register value
108− *
109− * The each value according to each scenemode is recommended in the documents.
110− */
111−struct m5mols_scenemode {
112− u8 metering;
113− u8 ev_bias;
114− u8 wb_mode;
115− u8 wb_preset;
116− u8 chroma_en;
117− u8 chroma_lvl;
118− u8 edge_en;
119− u8 edge_lvl;
120− u8 af_range;
121− u8 fd_mode;
122− u8 mcc;
123− u8 light;
124− u8 flash;
125− u8 tone;
126− u8 iso;
127− u8 capt_mode;
128− u8 wdr;
129−};
130−
131−#define VERSION_STRING_SIZE 22
132−
133−/**
134− * struct m5mols_version - firmware version information
135− * @customer: customer information
136− * @project: version of project information according to customer
137− * @fw: firmware revision
138− * @hw: hardware revision
139− * @param: version of the parameter
140− * @awb: Auto WhiteBalance algorithm version
141− * @str: information about manufacturer and packaging vendor
142− * @af: Auto Focus version
143− *
144− * The register offset starts the customer version at 0x0, and it ends
145− * the awb version at 0x09. The customer, project information occupies 1 bytes
146− * each. And also the fw, hw, param, awb each requires 2 bytes. The str is
147− * unique string associated with firmware's version. It includes information
148− * about manufacturer and the vendor of the sensor's packaging. The least
149− * significant 2 bytes of the string indicate packaging manufacturer.
150− */
151−struct m5mols_version {
152− u8 customer;
153− u8 project;
154− u16 fw;
155− u16 hw;
156− u16 param;
157− u16 awb;
158− u8 str[VERSION_STRING_SIZE];
159− u8 af;
160−};
161−
162−/**
163− * struct m5mols_info - M-5MOLS driver data structure
164− * @pdata: platform data
165− * @sd: v4l-subdev instance
166− * @pad: media pad
167− * @irq_waitq: waitqueue for the capture
168− * @irq_done: set to 1 in the interrupt handler
169− * @handle: control handler
170− * @auto_exposure: auto/manual exposure control
171− * @exposure_bias: exposure compensation control
172− * @exposure: manual exposure control
173− * @metering: exposure metering control
174− * @auto_iso: auto/manual ISO sensitivity control
175− * @iso: manual ISO sensitivity control
176− * @auto_wb: auto white balance control
177− * @lock_3a: 3A lock control
178− * @colorfx: color effect control
179− * @saturation: saturation control
180− * @zoom: zoom control
181− * @wdr: wide dynamic range control
182− * @stabilization: image stabilization control
183− * @jpeg_quality: JPEG compression quality control
184− * @set_power: optional power callback to the board code
185− * @reset: GPIO driving the reset pin of M-5MOLS
186− * @lock: mutex protecting the structure fields below
187− * @ffmt: current fmt according to resolution type
188− * @res_type: current resolution type
189− * @ver: information of the version
190− * @cap: the capture mode attributes
191− * @isp_ready: 1 when the ISP controller has completed booting
192− * @power: current sensor's power status
193− * @ctrl_sync: 1 when the control handler state is restored in H/W
194− * @resolution: register value for current resolution
195− * @mode: register value for current operation mode
196− */
197−struct m5mols_info {
198− const struct m5mols_platform_data *pdata;
199− struct v4l2_subdev sd;
200− struct media_pad pad;
201−
202− wait_queue_head_t irq_waitq;
203− atomic_t irq_done;
204−
205− struct v4l2_ctrl_handler handle;
206− struct {
207− /* exposure/exposure bias/auto exposure cluster */
208− struct v4l2_ctrl *auto_exposure;
209− struct v4l2_ctrl *exposure_bias;
210− struct v4l2_ctrl *exposure;
211− struct v4l2_ctrl *metering;
212− };
213− struct {
214− /* iso/auto iso cluster */
215− struct v4l2_ctrl *auto_iso;
216− struct v4l2_ctrl *iso;
217− };
218− struct v4l2_ctrl *auto_wb;
219−
220− struct v4l2_ctrl *lock_3a;
221− struct v4l2_ctrl *colorfx;
222− struct v4l2_ctrl *saturation;
223− struct v4l2_ctrl *zoom;
224− struct v4l2_ctrl *wdr;
225− struct v4l2_ctrl *stabilization;
226− struct v4l2_ctrl *jpeg_quality;
227−
228− int (*set_power)(struct device *dev, int on);
229− struct gpio_desc *reset;
230−
231− struct mutex lock;
232−
233− struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
234− int res_type;
235−
236− struct m5mols_version ver;
237− struct m5mols_capture cap;
238−
239− unsigned int isp_ready:1;
240− unsigned int power:1;
241− unsigned int ctrl_sync:1;
242−
243− u8 resolution;
244− u8 mode;
245−};
246−
247−#define is_available_af(__info) (__info->ver.af)
248−#define is_code(__code, __type) (__code == m5mols_default_ffmt[__type].code)
249−#define is_manufacturer(__info, __manufacturer) \
250− (__info->ver.str[0] == __manufacturer[0] && \
251− __info->ver.str[1] == __manufacturer[1])
252−/*
253− * I2C operation of the M-5MOLS
254− *
255− * The I2C read operation of the M-5MOLS requires 2 messages. The first
256− * message sends the information about the command, command category, and total
257− * message size. The second message is used to retrieve the data specified in
258− * the first message
259− *
260− * 1st message 2nd message
261− * +-------+---+----------+-----+-------+ +------+------+------+------+
262− * | size1 | R | category | cmd | size2 | | d[0] | d[1] | d[2] | d[3] |
263− * +-------+---+----------+-----+-------+ +------+------+------+------+
264− * - size1: message data size(5 in this case)
265− * - size2: desired buffer size of the 2nd message
266− * - d[0..3]: according to size2
267− *
268− * The I2C write operation needs just one message. The message includes
269− * category, command, total size, and desired data.
270− *
271− * 1st message
272− * +-------+---+----------+-----+------+------+------+------+
273− * | size1 | W | category | cmd | d[0] | d[1] | d[2] | d[3] |
274− * +-------+---+----------+-----+------+------+------+------+
275− * - d[0..3]: according to size1
276− */
277−int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
278−int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
279−int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
280−int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
281−
282−int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
283− int timeout);
284−
285−/* Mask value for busy waiting until M-5MOLS I2C interface is initialized */
286−#define M5MOLS_I2C_RDY_WAIT_FL (1 << 16)
287−/* ISP state transition timeout, in ms */
288−#define M5MOLS_MODE_CHANGE_TIMEOUT 200
289−#define M5MOLS_BUSY_WAIT_DEF_TIMEOUT 250
290−
291−/*
292− * Mode operation of the M-5MOLS
293− *
294− * Changing the mode of the M-5MOLS is needed right executing order.
295− * There are three modes(PARAMETER, MONITOR, CAPTURE) which can be changed
296− * by user. There are various categories associated with each mode.
297− *
298− * +============================================================+
299− * | mode | category |
300− * +============================================================+
301− * | FLASH | FLASH(only after Stand-by or Power-on) |
302− * | SYSTEM | SYSTEM(only after sensor arm-booting) |
303− * | PARAMETER | PARAMETER |
304− * | MONITOR | MONITOR(preview), Auto Focus, Face Detection |
305− * | CAPTURE | Single CAPTURE, Preview(recording) |
306− * +============================================================+
307− *
308− * The available executing order between each modes are as follows:
309− * PARAMETER <---> MONITOR <---> CAPTURE
310− */
311−int m5mols_set_mode(struct m5mols_info *info, u8 mode);
312−
313−int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
314−int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 condition, u32 timeout);
315−int m5mols_restore_controls(struct m5mols_info *info);
316−int m5mols_start_capture(struct m5mols_info *info);
317−int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
318−int m5mols_lock_3a(struct m5mols_info *info, bool lock);
319−int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
320−int m5mols_init_controls(struct v4l2_subdev *sd);
321−
322−/* The firmware function */
323−int m5mols_update_fw(struct v4l2_subdev *sd,
324− int (*set_power)(struct m5mols_info *, bool));
325−
326−static inline struct m5mols_info *to_m5mols(struct v4l2_subdev *subdev)
327−{
328− return container_of(subdev, struct m5mols_info, sd);
329−}
330−
331−static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
332−{
333− struct m5mols_info *info = container_of(ctrl->handler,
334− struct m5mols_info, handle);
335− return &info->sd;
336−}
337−
338−static inline void m5mols_set_ctrl_mode(struct v4l2_ctrl *ctrl,
339− unsigned int mode)
340−{
341− ctrl->priv = (void *)(uintptr_t)mode;
342−}
343−
344−static inline unsigned int m5mols_get_ctrl_mode(struct v4l2_ctrl *ctrl)
345−{
346− return (unsigned int)(uintptr_t)ctrl->priv;
347−}
348−
349−#endif /* M5MOLS_H */
drivers/media/i2c/m5mols/m5mols_capture.c+0−158
@@ -1,158 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−
3−/*
4− * The Capture code for Fujitsu M-5MOLS ISP
5− *
6− * Copyright (C) 2011 Samsung Electronics Co., Ltd.
7− * Author: HeungJun Kim <riverful.kim@samsung.com>
8− *
9− * Copyright (C) 2009 Samsung Electronics Co., Ltd.
10− * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
11− */
12−
13−#include <linux/i2c.h>
14−#include <linux/slab.h>
15−#include <linux/irq.h>
16−#include <linux/interrupt.h>
17−#include <linux/delay.h>
18−#include <linux/regulator/consumer.h>
19−#include <linux/videodev2.h>
20−#include <media/v4l2-ctrls.h>
21−#include <media/v4l2-device.h>
22−#include <media/v4l2-subdev.h>
23−#include <media/i2c/m5mols.h>
24−#include <media/drv-intf/exynos-fimc.h>
25−
26−#include "m5mols.h"
27−#include "m5mols_reg.h"
28−
29−/**
30− * m5mols_read_rational - I2C read of a rational number
31− * @sd: sub-device, as pointed by struct v4l2_subdev
32− * @addr_num: numerator register
33− * @addr_den: denominator register
34− * @val: place to store the division result
35− *
36− * Read numerator and denominator from registers @addr_num and @addr_den
37− * respectively and return the division result in @val.
38− */
39−static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
40− u32 addr_den, u32 *val)
41−{
42− u32 num, den;
43−
44− int ret = m5mols_read_u32(sd, addr_num, &num);
45− if (!ret)
46− ret = m5mols_read_u32(sd, addr_den, &den);
47− if (ret)
48− return ret;
49− *val = den == 0 ? 0 : num / den;
50− return ret;
51−}
52−
53−/**
54− * m5mols_capture_info - Gather captured image information
55− * @info: M-5MOLS driver data structure
56− *
57− * For now it gathers only EXIF information and file size.
58− */
59−static int m5mols_capture_info(struct m5mols_info *info)
60−{
61− struct m5mols_exif *exif = &info->cap.exif;
62− struct v4l2_subdev *sd = &info->sd;
63− int ret;
64−
65− ret = m5mols_read_rational(sd, EXIF_INFO_EXPTIME_NU,
66− EXIF_INFO_EXPTIME_DE, &exif->exposure_time);
67− if (ret)
68− return ret;
69− ret = m5mols_read_rational(sd, EXIF_INFO_TV_NU, EXIF_INFO_TV_DE,
70− &exif->shutter_speed);
71− if (ret)
72− return ret;
73− ret = m5mols_read_rational(sd, EXIF_INFO_AV_NU, EXIF_INFO_AV_DE,
74− &exif->aperture);
75− if (ret)
76− return ret;
77− ret = m5mols_read_rational(sd, EXIF_INFO_BV_NU, EXIF_INFO_BV_DE,
78− &exif->brightness);
79− if (ret)
80− return ret;
81− ret = m5mols_read_rational(sd, EXIF_INFO_EBV_NU, EXIF_INFO_EBV_DE,
82− &exif->exposure_bias);
83− if (ret)
84− return ret;
85−
86− ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
87− if (!ret)
88− ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
89− if (!ret)
90− ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
91− if (!ret)
92− ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
93− if (ret)
94− return ret;
95−
96− if (!ret)
97− ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
98− if (!ret)
99− ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
100− if (!ret)
101− info->cap.total = info->cap.main + info->cap.thumb;
102−
103− return ret;
104−}
105−
106−int m5mols_start_capture(struct m5mols_info *info)
107−{
108− unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE;
109− struct v4l2_subdev *sd = &info->sd;
110− int ret;
111−
112− /*
113− * Synchronize the controls, set the capture frame resolution and color
114− * format. The frame capture is initiated during switching from Monitor
115− * to Capture mode.
116− */
117− ret = m5mols_set_mode(info, REG_MONITOR);
118− if (!ret)
119− ret = m5mols_restore_controls(info);
120− if (!ret)
121− ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
122− if (!ret)
123− ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
124− if (!ret)
125− ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize);
126− if (!ret)
127− ret = m5mols_set_mode(info, REG_CAPTURE);
128− if (!ret)
129− /* Wait until a frame is captured to ISP internal memory */
130− ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
131− if (ret)
132− return ret;
133−
134− /*
135− * Initiate the captured data transfer to a MIPI-CSI receiver.
136− */
137− ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
138− if (!ret)
139− ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
140− if (!ret) {
141− bool captured = false;
142− unsigned int size;
143−
144− /* Wait for the capture completion interrupt */
145− ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
146− if (!ret) {
147− captured = true;
148− ret = m5mols_capture_info(info);
149− }
150− size = captured ? info->cap.main : 0;
151− v4l2_dbg(1, m5mols_debug, sd, "%s: size: %d, thumb.: %d B\n",
152− __func__, size, info->cap.thumb);
153−
154− v4l2_subdev_notify(sd, S5P_FIMC_TX_END_NOTIFY, &size);
155− }
156−
157− return ret;
158−}
drivers/media/i2c/m5mols/m5mols_controls.c+0−625
@@ -1,625 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−/*
3− * Controls for M-5MOLS 8M Pixel camera sensor with ISP
4− *
5− * Copyright (C) 2011 Samsung Electronics Co., Ltd.
6− * Author: HeungJun Kim <riverful.kim@samsung.com>
7− *
8− * Copyright (C) 2009 Samsung Electronics Co., Ltd.
9− * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
10− */
11−
12−#include <linux/i2c.h>
13−#include <linux/delay.h>
14−#include <linux/videodev2.h>
15−#include <media/v4l2-ctrls.h>
16−
17−#include "m5mols.h"
18−#include "m5mols_reg.h"
19−
20−static struct m5mols_scenemode m5mols_default_scenemode[] = {
21− [REG_SCENE_NORMAL] = {
22− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
23− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
24− REG_AF_NORMAL, REG_FD_OFF,
25− REG_MCC_NORMAL, REG_LIGHT_OFF, REG_FLASH_OFF,
26− 5, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
27− },
28− [REG_SCENE_PORTRAIT] = {
29− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
30− REG_CHROMA_ON, 3, REG_EDGE_ON, 4,
31− REG_AF_NORMAL, BIT_FD_EN | BIT_FD_DRAW_FACE_FRAME,
32− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
33− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
34− },
35− [REG_SCENE_LANDSCAPE] = {
36− REG_AE_ALL, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
37− REG_CHROMA_ON, 4, REG_EDGE_ON, 6,
38− REG_AF_NORMAL, REG_FD_OFF,
39− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
40− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
41− },
42− [REG_SCENE_SPORTS] = {
43− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
44− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
45− REG_AF_NORMAL, REG_FD_OFF,
46− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
47− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
48− },
49− [REG_SCENE_PARTY_INDOOR] = {
50− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
51− REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
52− REG_AF_NORMAL, REG_FD_OFF,
53− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
54− 6, REG_ISO_200, REG_CAP_NONE, REG_WDR_OFF,
55− },
56− [REG_SCENE_BEACH_SNOW] = {
57− REG_AE_CENTER, REG_AE_INDEX_10_POS, REG_AWB_AUTO, 0,
58− REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
59− REG_AF_NORMAL, REG_FD_OFF,
60− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
61− 6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
62− },
63− [REG_SCENE_SUNSET] = {
64− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
65− REG_AWB_DAYLIGHT,
66− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
67− REG_AF_NORMAL, REG_FD_OFF,
68− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
69− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
70− },
71− [REG_SCENE_DAWN_DUSK] = {
72− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
73− REG_AWB_FLUORESCENT_1,
74− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
75− REG_AF_NORMAL, REG_FD_OFF,
76− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
77− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
78− },
79− [REG_SCENE_FALL] = {
80− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
81− REG_CHROMA_ON, 5, REG_EDGE_ON, 5,
82− REG_AF_NORMAL, REG_FD_OFF,
83− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
84− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
85− },
86− [REG_SCENE_NIGHT] = {
87− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
88− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
89− REG_AF_NORMAL, REG_FD_OFF,
90− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
91− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
92− },
93− [REG_SCENE_AGAINST_LIGHT] = {
94− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
95− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
96− REG_AF_NORMAL, REG_FD_OFF,
97− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
98− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
99− },
100− [REG_SCENE_FIRE] = {
101− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
102− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
103− REG_AF_NORMAL, REG_FD_OFF,
104− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
105− 6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
106− },
107− [REG_SCENE_TEXT] = {
108− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
109− REG_CHROMA_ON, 3, REG_EDGE_ON, 7,
110− REG_AF_MACRO, REG_FD_OFF,
111− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
112− 6, REG_ISO_AUTO, REG_CAP_ANTI_SHAKE, REG_WDR_ON,
113− },
114− [REG_SCENE_CANDLE] = {
115− REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
116− REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
117− REG_AF_NORMAL, REG_FD_OFF,
118− REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
119− 6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
120− },
121−};
122−
123−/**
124− * m5mols_do_scenemode() - Change current scenemode
125− * @info: M-5MOLS driver data structure
126− * @mode: Desired mode of the scenemode
127− *
128− * WARNING: The execution order is important. Do not change the order.
129− */
130−int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
131−{
132− struct v4l2_subdev *sd = &info->sd;
133− struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
134− int ret;
135−
136− if (mode > REG_SCENE_CANDLE)
137− return -EINVAL;
138−
139− ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
140− if (!ret)
141− ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
142− if (!ret)
143− ret = m5mols_write(sd, AE_EV_PRESET_CAPTURE, mode);
144− if (!ret)
145− ret = m5mols_write(sd, AE_MODE, scenemode.metering);
146− if (!ret)
147− ret = m5mols_write(sd, AE_INDEX, scenemode.ev_bias);
148− if (!ret)
149− ret = m5mols_write(sd, AWB_MODE, scenemode.wb_mode);
150− if (!ret)
151− ret = m5mols_write(sd, AWB_MANUAL, scenemode.wb_preset);
152− if (!ret)
153− ret = m5mols_write(sd, MON_CHROMA_EN, scenemode.chroma_en);
154− if (!ret)
155− ret = m5mols_write(sd, MON_CHROMA_LVL, scenemode.chroma_lvl);
156− if (!ret)
157− ret = m5mols_write(sd, MON_EDGE_EN, scenemode.edge_en);
158− if (!ret)
159− ret = m5mols_write(sd, MON_EDGE_LVL, scenemode.edge_lvl);
160− if (!ret && is_available_af(info))
161− ret = m5mols_write(sd, AF_MODE, scenemode.af_range);
162− if (!ret && is_available_af(info))
163− ret = m5mols_write(sd, FD_CTL, scenemode.fd_mode);
164− if (!ret)
165− ret = m5mols_write(sd, MON_TONE_CTL, scenemode.tone);
166− if (!ret)
167− ret = m5mols_write(sd, AE_ISO, scenemode.iso);
168− if (!ret)
169− ret = m5mols_set_mode(info, REG_CAPTURE);
170− if (!ret)
171− ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
172− if (!ret)
173− ret = m5mols_write(sd, CAPP_MCC_MODE, scenemode.mcc);
174− if (!ret)
175− ret = m5mols_write(sd, CAPP_LIGHT_CTRL, scenemode.light);
176− if (!ret)
177− ret = m5mols_write(sd, CAPP_FLASH_CTRL, scenemode.flash);
178− if (!ret)
179− ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
180− if (!ret)
181− ret = m5mols_set_mode(info, REG_MONITOR);
182−
183− return ret;
184−}
185−
186−static int m5mols_3a_lock(struct m5mols_info *info, struct v4l2_ctrl *ctrl)
187−{
188− bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
189− int ret = 0;
190−
191− if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
192− bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
193−
194− ret = m5mols_write(&info->sd, AE_LOCK, ae_lock ?
195− REG_AE_LOCK : REG_AE_UNLOCK);
196− if (ret)
197− return ret;
198− }
199−
200− if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
201− && info->auto_wb->val) {
202− bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
203−
204− ret = m5mols_write(&info->sd, AWB_LOCK, awb_lock ?
205− REG_AWB_LOCK : REG_AWB_UNLOCK);
206− if (ret)
207− return ret;
208− }
209−
210− if (!info->ver.af || !af_lock)
211− return ret;
212−
213− if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
214− ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
215−
216− return ret;
217−}
218−
219−static int m5mols_set_metering_mode(struct m5mols_info *info, int mode)
220−{
221− unsigned int metering;
222−
223− switch (mode) {
224− case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
225− metering = REG_AE_CENTER;
226− break;
227− case V4L2_EXPOSURE_METERING_SPOT:
228− metering = REG_AE_SPOT;
229− break;
230− default:
231− metering = REG_AE_ALL;
232− break;
233− }
234−
235− return m5mols_write(&info->sd, AE_MODE, metering);
236−}
237−
238−static int m5mols_set_exposure(struct m5mols_info *info, int exposure)
239−{
240− struct v4l2_subdev *sd = &info->sd;
241− int ret = 0;
242−
243− if (exposure == V4L2_EXPOSURE_AUTO) {
244− /* Unlock auto exposure */
245− info->lock_3a->val &= ~V4L2_LOCK_EXPOSURE;
246− m5mols_3a_lock(info, info->lock_3a);
247−
248− ret = m5mols_set_metering_mode(info, info->metering->val);
249− if (ret < 0)
250− return ret;
251−
252− v4l2_dbg(1, m5mols_debug, sd,
253− "%s: exposure bias: %#x, metering: %#x\n",
254− __func__, info->exposure_bias->val,
255− info->metering->val);
256−
257− return m5mols_write(sd, AE_INDEX, info->exposure_bias->val);
258− }
259−
260− if (exposure == V4L2_EXPOSURE_MANUAL) {
261− ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
262− if (ret == 0)
263− ret = m5mols_write(sd, AE_MAN_GAIN_MON,
264− info->exposure->val);
265− if (ret == 0)
266− ret = m5mols_write(sd, AE_MAN_GAIN_CAP,
267− info->exposure->val);
268−
269− v4l2_dbg(1, m5mols_debug, sd, "%s: exposure: %#x\n",
270− __func__, info->exposure->val);
271− }
272−
273− return ret;
274−}
275−
276−static int m5mols_set_white_balance(struct m5mols_info *info, int val)
277−{
278− static const unsigned short wb[][2] = {
279− { V4L2_WHITE_BALANCE_INCANDESCENT, REG_AWB_INCANDESCENT },
280− { V4L2_WHITE_BALANCE_FLUORESCENT, REG_AWB_FLUORESCENT_1 },
281− { V4L2_WHITE_BALANCE_FLUORESCENT_H, REG_AWB_FLUORESCENT_2 },
282− { V4L2_WHITE_BALANCE_HORIZON, REG_AWB_HORIZON },
283− { V4L2_WHITE_BALANCE_DAYLIGHT, REG_AWB_DAYLIGHT },
284− { V4L2_WHITE_BALANCE_FLASH, REG_AWB_LEDLIGHT },
285− { V4L2_WHITE_BALANCE_CLOUDY, REG_AWB_CLOUDY },
286− { V4L2_WHITE_BALANCE_SHADE, REG_AWB_SHADE },
287− { V4L2_WHITE_BALANCE_AUTO, REG_AWB_AUTO },
288− };
289− int i;
290− struct v4l2_subdev *sd = &info->sd;
291− int ret = -EINVAL;
292−
293− for (i = 0; i < ARRAY_SIZE(wb); i++) {
294− int awb;
295− if (wb[i][0] != val)
296− continue;
297−
298− v4l2_dbg(1, m5mols_debug, sd,
299− "Setting white balance to: %#x\n", wb[i][0]);
300−
301− awb = wb[i][0] == V4L2_WHITE_BALANCE_AUTO;
302− ret = m5mols_write(sd, AWB_MODE, awb ? REG_AWB_AUTO :
303− REG_AWB_PRESET);
304− if (ret < 0)
305− return ret;
306−
307− if (!awb)
308− ret = m5mols_write(sd, AWB_MANUAL, wb[i][1]);
309− }
310−
311− return ret;
312−}
313−
314−static int m5mols_set_saturation(struct m5mols_info *info, int val)
315−{
316− int ret = m5mols_write(&info->sd, MON_CHROMA_LVL, val);
317− if (ret < 0)
318− return ret;
319−
320− return m5mols_write(&info->sd, MON_CHROMA_EN, REG_CHROMA_ON);
321−}
322−
323−static int m5mols_set_color_effect(struct m5mols_info *info, int val)
324−{
325− unsigned int m_effect = REG_COLOR_EFFECT_OFF;
326− unsigned int p_effect = REG_EFFECT_OFF;
327− unsigned int cfix_r = 0, cfix_b = 0;
328− struct v4l2_subdev *sd = &info->sd;
329− int ret = 0;
330−
331− switch (val) {
332− case V4L2_COLORFX_BW:
333− m_effect = REG_COLOR_EFFECT_ON;
334− break;
335− case V4L2_COLORFX_NEGATIVE:
336− p_effect = REG_EFFECT_NEGA;
337− break;
338− case V4L2_COLORFX_EMBOSS:
339− p_effect = REG_EFFECT_EMBOSS;
340− break;
341− case V4L2_COLORFX_SEPIA:
342− m_effect = REG_COLOR_EFFECT_ON;
343− cfix_r = REG_CFIXR_SEPIA;
344− cfix_b = REG_CFIXB_SEPIA;
345− break;
346− }
347−
348− ret = m5mols_write(sd, PARM_EFFECT, p_effect);
349− if (!ret)
350− ret = m5mols_write(sd, MON_EFFECT, m_effect);
351−
352− if (ret == 0 && m_effect == REG_COLOR_EFFECT_ON) {
353− ret = m5mols_write(sd, MON_CFIXR, cfix_r);
354− if (!ret)
355− ret = m5mols_write(sd, MON_CFIXB, cfix_b);
356− }
357−
358− v4l2_dbg(1, m5mols_debug, sd,
359− "p_effect: %#x, m_effect: %#x, r: %#x, b: %#x (%d)\n",
360− p_effect, m_effect, cfix_r, cfix_b, ret);
361−
362− return ret;
363−}
364−
365−static int m5mols_set_iso(struct m5mols_info *info, int auto_iso)
366−{
367− u32 iso = auto_iso ? 0 : info->iso->val + 1;
368−
369− return m5mols_write(&info->sd, AE_ISO, iso);
370−}
371−
372−static int m5mols_set_wdr(struct m5mols_info *info, int wdr)
373−{
374− int ret;
375−
376− ret = m5mols_write(&info->sd, MON_TONE_CTL, wdr ? 9 : 5);
377− if (ret < 0)
378− return ret;
379−
380− ret = m5mols_set_mode(info, REG_CAPTURE);
381− if (ret < 0)
382− return ret;
383−
384− return m5mols_write(&info->sd, CAPP_WDR_EN, wdr);
385−}
386−
387−static int m5mols_set_stabilization(struct m5mols_info *info, int val)
388−{
389− struct v4l2_subdev *sd = &info->sd;
390− unsigned int evp = val ? 0xe : 0x0;
391− int ret;
392−
393− ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, evp);
394− if (ret < 0)
395− return ret;
396−
397− return m5mols_write(sd, AE_EV_PRESET_CAPTURE, evp);
398−}
399−
400−static int m5mols_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
401−{
402− struct v4l2_subdev *sd = to_sd(ctrl);
403− struct m5mols_info *info = to_m5mols(sd);
404− int ret = 0;
405− u8 status = REG_ISO_AUTO;
406−
407− v4l2_dbg(1, m5mols_debug, sd, "%s: ctrl: %s (%d)\n",
408− __func__, ctrl->name, info->isp_ready);
409−
410− if (!info->isp_ready)
411− return -EBUSY;
412−
413− switch (ctrl->id) {
414− case V4L2_CID_ISO_SENSITIVITY_AUTO:
415− ret = m5mols_read_u8(sd, AE_ISO, &status);
416− if (ret == 0)
417− ctrl->val = !status;
418− if (status != REG_ISO_AUTO)
419− info->iso->val = status - 1;
420− break;
421−
422− case V4L2_CID_3A_LOCK:
423− ctrl->val &= ~0x7;
424−
425− ret = m5mols_read_u8(sd, AE_LOCK, &status);
426− if (ret)
427− return ret;
428− if (status)
429− info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
430−
431− ret = m5mols_read_u8(sd, AWB_LOCK, &status);
432− if (ret)
433− return ret;
434− if (status)
435− info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
436−
437− ret = m5mols_read_u8(sd, AF_EXECUTE, &status);
438− if (!status)
439− info->lock_3a->val |= V4L2_LOCK_EXPOSURE;
440− break;
441− }
442−
443− return ret;
444−}
445−
446−static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
447−{
448− unsigned int ctrl_mode = m5mols_get_ctrl_mode(ctrl);
449− struct v4l2_subdev *sd = to_sd(ctrl);
450− struct m5mols_info *info = to_m5mols(sd);
451− int last_mode = info->mode;
452− int ret = 0;
453−
454− /*
455− * If needed, defer restoring the controls until
456− * the device is fully initialized.
457− */
458− if (!info->isp_ready) {
459− info->ctrl_sync = 0;
460− return 0;
461− }
462−
463− v4l2_dbg(1, m5mols_debug, sd, "%s: %s, val: %d, priv: %p\n",
464− __func__, ctrl->name, ctrl->val, ctrl->priv);
465−
466− if (ctrl_mode && ctrl_mode != info->mode) {
467− ret = m5mols_set_mode(info, ctrl_mode);
468− if (ret < 0)
469− return ret;
470− }
471−
472− switch (ctrl->id) {
473− case V4L2_CID_3A_LOCK:
474− ret = m5mols_3a_lock(info, ctrl);
475− break;
476−
477− case V4L2_CID_ZOOM_ABSOLUTE:
478− ret = m5mols_write(sd, MON_ZOOM, ctrl->val);
479− break;
480−
481− case V4L2_CID_EXPOSURE_AUTO:
482− ret = m5mols_set_exposure(info, ctrl->val);
483− break;
484−
485− case V4L2_CID_ISO_SENSITIVITY:
486− ret = m5mols_set_iso(info, ctrl->val);
487− break;
488−
489− case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
490− ret = m5mols_set_white_balance(info, ctrl->val);
491− break;
492−
493− case V4L2_CID_SATURATION:
494− ret = m5mols_set_saturation(info, ctrl->val);
495− break;
496−
497− case V4L2_CID_COLORFX:
498− ret = m5mols_set_color_effect(info, ctrl->val);
499− break;
500−
501− case V4L2_CID_WIDE_DYNAMIC_RANGE:
502− ret = m5mols_set_wdr(info, ctrl->val);
503− break;
504−
505− case V4L2_CID_IMAGE_STABILIZATION:
506− ret = m5mols_set_stabilization(info, ctrl->val);
507− break;
508−
509− case V4L2_CID_JPEG_COMPRESSION_QUALITY:
510− ret = m5mols_write(sd, CAPP_JPEG_RATIO, ctrl->val);
511− break;
512− }
513−
514− if (ret == 0 && info->mode != last_mode)
515− ret = m5mols_set_mode(info, last_mode);
516−
517− return ret;
518−}
519−
520−static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
521− .g_volatile_ctrl = m5mols_g_volatile_ctrl,
522− .s_ctrl = m5mols_s_ctrl,
523−};
524−
525−/* Supported manual ISO values */
526−static const s64 iso_qmenu[] = {
527− /* AE_ISO: 0x01...0x07 (ISO: 50...3200) */
528− 50000, 100000, 200000, 400000, 800000, 1600000, 3200000
529−};
530−
531−/* Supported Exposure Bias values, -2.0EV...+2.0EV */
532−static const s64 ev_bias_qmenu[] = {
533− /* AE_INDEX: 0x00...0x08 */
534− -2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
535−};
536−
537−int m5mols_init_controls(struct v4l2_subdev *sd)
538−{
539− struct m5mols_info *info = to_m5mols(sd);
540− u16 exposure_max;
541− u16 zoom_step;
542− int ret;
543−
544− /* Determine the firmware dependent control range and step values */
545− ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max);
546− if (ret < 0)
547− return ret;
548−
549− zoom_step = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
550− v4l2_ctrl_handler_init(&info->handle, 20);
551−
552− info->auto_wb = v4l2_ctrl_new_std_menu(&info->handle,
553− &m5mols_ctrl_ops, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
554− 9, ~0x3fe, V4L2_WHITE_BALANCE_AUTO);
555−
556− /* Exposure control cluster */
557− info->auto_exposure = v4l2_ctrl_new_std_menu(&info->handle,
558− &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
559− 1, ~0x03, V4L2_EXPOSURE_AUTO);
560−
561− info->exposure = v4l2_ctrl_new_std(&info->handle,
562− &m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
563− 0, exposure_max, 1, exposure_max / 2);
564−
565− info->exposure_bias = v4l2_ctrl_new_int_menu(&info->handle,
566− &m5mols_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
567− ARRAY_SIZE(ev_bias_qmenu) - 1,
568− ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
569− ev_bias_qmenu);
570−
571− info->metering = v4l2_ctrl_new_std_menu(&info->handle,
572− &m5mols_ctrl_ops, V4L2_CID_EXPOSURE_METERING,
573− 2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
574−
575− /* ISO control cluster */
576− info->auto_iso = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
577− V4L2_CID_ISO_SENSITIVITY_AUTO, 1, ~0x03, 1);
578−
579− info->iso = v4l2_ctrl_new_int_menu(&info->handle, &m5mols_ctrl_ops,
580− V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
581− ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
582−
583− info->saturation = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
584− V4L2_CID_SATURATION, 1, 5, 1, 3);
585−
586− info->zoom = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
587− V4L2_CID_ZOOM_ABSOLUTE, 1, 70, zoom_step, 1);
588−
589− info->colorfx = v4l2_ctrl_new_std_menu(&info->handle, &m5mols_ctrl_ops,
590− V4L2_CID_COLORFX, 4, 0, V4L2_COLORFX_NONE);
591−
592− info->wdr = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
593− V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
594−
595− info->stabilization = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
596− V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
597−
598− info->jpeg_quality = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
599− V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
600−
601− info->lock_3a = v4l2_ctrl_new_std(&info->handle, &m5mols_ctrl_ops,
602− V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
603−
604− if (info->handle.error) {
605− int ret = info->handle.error;
606− v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
607− v4l2_ctrl_handler_free(&info->handle);
608− return ret;
609− }
610−
611− v4l2_ctrl_auto_cluster(4, &info->auto_exposure, 1, false);
612− info->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
613− V4L2_CTRL_FLAG_UPDATE;
614− v4l2_ctrl_auto_cluster(2, &info->auto_iso, 0, false);
615−
616− info->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
617−
618− m5mols_set_ctrl_mode(info->auto_exposure, REG_PARAMETER);
619− m5mols_set_ctrl_mode(info->auto_wb, REG_PARAMETER);
620− m5mols_set_ctrl_mode(info->colorfx, REG_MONITOR);
621−
622− sd->ctrl_handler = &info->handle;
623−
624− return 0;
625−}
drivers/media/i2c/m5mols/m5mols_core.c+0−1051
@@ -1,1051 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−/*
3− * Driver for M-5MOLS 8M Pixel camera sensor with ISP
4− *
5− * Copyright (C) 2011 Samsung Electronics Co., Ltd.
6− * Author: HeungJun Kim <riverful.kim@samsung.com>
7− *
8− * Copyright (C) 2009 Samsung Electronics Co., Ltd.
9− * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
10− */
11−
12−#include <linux/i2c.h>
13−#include <linux/slab.h>
14−#include <linux/irq.h>
15−#include <linux/interrupt.h>
16−#include <linux/delay.h>
17−#include <linux/gpio/consumer.h>
18−#include <linux/regulator/consumer.h>
19−#include <linux/videodev2.h>
20−#include <linux/module.h>
21−#include <media/v4l2-ctrls.h>
22−#include <media/v4l2-device.h>
23−#include <media/v4l2-subdev.h>
24−#include <media/i2c/m5mols.h>
25−
26−#include "m5mols.h"
27−#include "m5mols_reg.h"
28−
29−int m5mols_debug;
30−module_param(m5mols_debug, int, 0644);
31−
32−#define MODULE_NAME "M5MOLS"
33−#define M5MOLS_I2C_CHECK_RETRY 500
34−
35−/* The regulator consumer names for external voltage regulators */
36−static struct regulator_bulk_data supplies[] = {
37− {
38− .supply = "core", /* ARM core power, 1.2V */
39− }, {
40− .supply = "dig_18", /* digital power 1, 1.8V */
41− }, {
42− .supply = "d_sensor", /* sensor power 1, 1.8V */
43− }, {
44− .supply = "dig_28", /* digital power 2, 2.8V */
45− }, {
46− .supply = "a_sensor", /* analog power */
47− }, {
48− .supply = "dig_12", /* digital power 3, 1.2V */
49− },
50−};
51−
52−static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = {
53− [M5MOLS_RESTYPE_MONITOR] = {
54− .width = 1920,
55− .height = 1080,
56− .code = MEDIA_BUS_FMT_VYUY8_2X8,
57− .field = V4L2_FIELD_NONE,
58− .colorspace = V4L2_COLORSPACE_JPEG,
59− },
60− [M5MOLS_RESTYPE_CAPTURE] = {
61− .width = 1920,
62− .height = 1080,
63− .code = MEDIA_BUS_FMT_JPEG_1X8,
64− .field = V4L2_FIELD_NONE,
65− .colorspace = V4L2_COLORSPACE_JPEG,
66− },
67−};
68−#define SIZE_DEFAULT_FFMT ARRAY_SIZE(m5mols_default_ffmt)
69−
70−static const struct m5mols_resolution m5mols_reg_res[] = {
71− { 0x01, M5MOLS_RESTYPE_MONITOR, 128, 96 }, /* SUB-QCIF */
72− { 0x03, M5MOLS_RESTYPE_MONITOR, 160, 120 }, /* QQVGA */
73− { 0x05, M5MOLS_RESTYPE_MONITOR, 176, 144 }, /* QCIF */
74− { 0x06, M5MOLS_RESTYPE_MONITOR, 176, 176 },
75− { 0x08, M5MOLS_RESTYPE_MONITOR, 240, 320 }, /* QVGA */
76− { 0x09, M5MOLS_RESTYPE_MONITOR, 320, 240 }, /* QVGA */
77− { 0x0c, M5MOLS_RESTYPE_MONITOR, 240, 400 }, /* WQVGA */
78− { 0x0d, M5MOLS_RESTYPE_MONITOR, 400, 240 }, /* WQVGA */
79− { 0x0e, M5MOLS_RESTYPE_MONITOR, 352, 288 }, /* CIF */
80− { 0x13, M5MOLS_RESTYPE_MONITOR, 480, 360 },
81− { 0x15, M5MOLS_RESTYPE_MONITOR, 640, 360 }, /* qHD */
82− { 0x17, M5MOLS_RESTYPE_MONITOR, 640, 480 }, /* VGA */
83− { 0x18, M5MOLS_RESTYPE_MONITOR, 720, 480 },
84− { 0x1a, M5MOLS_RESTYPE_MONITOR, 800, 480 }, /* WVGA */
85− { 0x1f, M5MOLS_RESTYPE_MONITOR, 800, 600 }, /* SVGA */
86− { 0x21, M5MOLS_RESTYPE_MONITOR, 1280, 720 }, /* HD */
87− { 0x25, M5MOLS_RESTYPE_MONITOR, 1920, 1080 }, /* 1080p */
88− { 0x29, M5MOLS_RESTYPE_MONITOR, 3264, 2448 }, /* 2.63fps 8M */
89− { 0x39, M5MOLS_RESTYPE_MONITOR, 800, 602 }, /* AHS_MON debug */
90−
91− { 0x02, M5MOLS_RESTYPE_CAPTURE, 320, 240 }, /* QVGA */
92− { 0x04, M5MOLS_RESTYPE_CAPTURE, 400, 240 }, /* WQVGA */
93− { 0x07, M5MOLS_RESTYPE_CAPTURE, 480, 360 },
94− { 0x08, M5MOLS_RESTYPE_CAPTURE, 640, 360 }, /* qHD */
95− { 0x09, M5MOLS_RESTYPE_CAPTURE, 640, 480 }, /* VGA */
96− { 0x0a, M5MOLS_RESTYPE_CAPTURE, 800, 480 }, /* WVGA */
97− { 0x10, M5MOLS_RESTYPE_CAPTURE, 1280, 720 }, /* HD */
98− { 0x14, M5MOLS_RESTYPE_CAPTURE, 1280, 960 }, /* 1M */
99− { 0x17, M5MOLS_RESTYPE_CAPTURE, 1600, 1200 }, /* 2M */
100− { 0x19, M5MOLS_RESTYPE_CAPTURE, 1920, 1080 }, /* Full-HD */
101− { 0x1a, M5MOLS_RESTYPE_CAPTURE, 2048, 1152 }, /* 3Mega */
102− { 0x1b, M5MOLS_RESTYPE_CAPTURE, 2048, 1536 },
103− { 0x1c, M5MOLS_RESTYPE_CAPTURE, 2560, 1440 }, /* 4Mega */
104− { 0x1d, M5MOLS_RESTYPE_CAPTURE, 2560, 1536 },
105− { 0x1f, M5MOLS_RESTYPE_CAPTURE, 2560, 1920 }, /* 5Mega */
106− { 0x21, M5MOLS_RESTYPE_CAPTURE, 3264, 1836 }, /* 6Mega */
107− { 0x22, M5MOLS_RESTYPE_CAPTURE, 3264, 1960 },
108− { 0x25, M5MOLS_RESTYPE_CAPTURE, 3264, 2448 }, /* 8Mega */
109−};
110−
111−/**
112− * m5mols_swap_byte - an byte array to integer conversion function
113− * @data: byte array
114− * @length: size in bytes of I2C packet defined in the M-5MOLS datasheet
115− *
116− * Convert I2C data byte array with performing any required byte
117− * reordering to assure proper values for each data type, regardless
118− * of the architecture endianness.
119− */
120−static u32 m5mols_swap_byte(u8 *data, u8 length)
121−{
122− if (length == 1)
123− return *data;
124− else if (length == 2)
125− return be16_to_cpu(*((__be16 *)data));
126− else
127− return be32_to_cpu(*((__be32 *)data));
128−}
129−
130−/**
131− * m5mols_read - I2C read function
132− * @sd: sub-device, as pointed by struct v4l2_subdev
133− * @size: desired size of I2C packet
134− * @reg: combination of size, category and command for the I2C packet
135− * @val: read value
136− *
137− * Returns 0 on success, or else negative errno.
138− */
139−static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
140−{
141− struct i2c_client *client = v4l2_get_subdevdata(sd);
142− struct m5mols_info *info = to_m5mols(sd);
143− u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
144− u8 category = I2C_CATEGORY(reg);
145− u8 cmd = I2C_COMMAND(reg);
146− struct i2c_msg msg[2];
147− u8 wbuf[5];
148− int ret;
149−
150− if (!client->adapter)
151− return -ENODEV;
152−
153− msg[0].addr = client->addr;
154− msg[0].flags = 0;
155− msg[0].len = 5;
156− msg[0].buf = wbuf;
157− wbuf[0] = 5;
158− wbuf[1] = M5MOLS_BYTE_READ;
159− wbuf[2] = category;
160− wbuf[3] = cmd;
161− wbuf[4] = size;
162−
163− msg[1].addr = client->addr;
164− msg[1].flags = I2C_M_RD;
165− msg[1].len = size + 1;
166− msg[1].buf = rbuf;
167−
168− /* minimum stabilization time */
169− usleep_range(200, 300);
170−
171− ret = i2c_transfer(client->adapter, msg, 2);
172−
173− if (ret == 2) {
174− *val = m5mols_swap_byte(&rbuf[1], size);
175− return 0;
176− }
177−
178− if (info->isp_ready)
179− v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
180− size, category, cmd, ret);
181−
182− return ret < 0 ? ret : -EIO;
183−}
184−
185−int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
186−{
187− u32 val_32;
188− int ret;
189−
190− if (I2C_SIZE(reg) != 1) {
191− v4l2_err(sd, "Wrong data size\n");
192− return -EINVAL;
193− }
194−
195− ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
196− if (ret)
197− return ret;
198−
199− *val = (u8)val_32;
200− return ret;
201−}
202−
203−int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
204−{
205− u32 val_32;
206− int ret;
207−
208− if (I2C_SIZE(reg) != 2) {
209− v4l2_err(sd, "Wrong data size\n");
210− return -EINVAL;
211− }
212−
213− ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
214− if (ret)
215− return ret;
216−
217− *val = (u16)val_32;
218− return ret;
219−}
220−
221−int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
222−{
223− if (I2C_SIZE(reg) != 4) {
224− v4l2_err(sd, "Wrong data size\n");
225− return -EINVAL;
226− }
227−
228− return m5mols_read(sd, I2C_SIZE(reg), reg, val);
229−}
230−
231−/**
232− * m5mols_write - I2C command write function
233− * @sd: sub-device, as pointed by struct v4l2_subdev
234− * @reg: combination of size, category and command for the I2C packet
235− * @val: value to write
236− *
237− * Returns 0 on success, or else negative errno.
238− */
239−int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
240−{
241− struct i2c_client *client = v4l2_get_subdevdata(sd);
242− struct m5mols_info *info = to_m5mols(sd);
243− u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
244− u8 category = I2C_CATEGORY(reg);
245− u8 cmd = I2C_COMMAND(reg);
246− u8 size = I2C_SIZE(reg);
247− u32 *buf = (u32 *)&wbuf[4];
248− struct i2c_msg msg[1];
249− int ret;
250−
251− if (!client->adapter)
252− return -ENODEV;
253−
254− if (size != 1 && size != 2 && size != 4) {
255− v4l2_err(sd, "Wrong data size\n");
256− return -EINVAL;
257− }
258−
259− msg->addr = client->addr;
260− msg->flags = 0;
261− msg->len = (u16)size + 4;
262− msg->buf = wbuf;
263− wbuf[0] = size + 4;
264− wbuf[1] = M5MOLS_BYTE_WRITE;
265− wbuf[2] = category;
266− wbuf[3] = cmd;
267−
268− *buf = m5mols_swap_byte((u8 *)&val, size);
269−
270− /* minimum stabilization time */
271− usleep_range(200, 300);
272−
273− ret = i2c_transfer(client->adapter, msg, 1);
274− if (ret == 1)
275− return 0;
276−
277− if (info->isp_ready)
278− v4l2_err(sd, "write failed: cat:%02x cmd:%02x ret:%d\n",
279− category, cmd, ret);
280−
281− return ret < 0 ? ret : -EIO;
282−}
283−
284−/**
285− * m5mols_busy_wait - Busy waiting with I2C register polling
286− * @sd: sub-device, as pointed by struct v4l2_subdev
287− * @reg: the I2C_REG() address of an 8-bit status register to check
288− * @value: expected status register value
289− * @mask: bit mask for the read status register value
290− * @timeout: timeout in milliseconds, or -1 for default timeout
291− *
292− * The @reg register value is ORed with @mask before comparing with @value.
293− *
294− * Return: 0 if the requested condition became true within less than
295− * @timeout ms, or else negative errno.
296− */
297−int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
298− int timeout)
299−{
300− int ms = timeout < 0 ? M5MOLS_BUSY_WAIT_DEF_TIMEOUT : timeout;
301− unsigned long end = jiffies + msecs_to_jiffies(ms);
302− u8 status;
303−
304− do {
305− int ret = m5mols_read_u8(sd, reg, &status);
306−
307− if (ret < 0 && !(mask & M5MOLS_I2C_RDY_WAIT_FL))
308− return ret;
309− if (!ret && (status & mask & 0xff) == (value & 0xff))
310− return 0;
311− usleep_range(100, 250);
312− } while (ms > 0 && time_is_after_jiffies(end));
313−
314− return -EBUSY;
315−}
316−
317−/**
318− * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
319− * @sd: sub-device, as pointed by struct v4l2_subdev
320− * @reg: combination of size, category and command for the I2C packet
321− *
322− * Before writing desired interrupt value the INT_FACTOR register should
323− * be read to clear pending interrupts.
324− */
325−int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
326−{
327− struct m5mols_info *info = to_m5mols(sd);
328− u8 mask = is_available_af(info) ? REG_INT_AF : 0;
329− u8 dummy;
330− int ret;
331−
332− ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
333− if (!ret)
334− ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
335− return ret;
336−}
337−
338−int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
339−{
340− struct m5mols_info *info = to_m5mols(sd);
341−
342− int ret = wait_event_interruptible_timeout(info->irq_waitq,
343− atomic_add_unless(&info->irq_done, -1, 0),
344− msecs_to_jiffies(timeout));
345− if (ret <= 0)
346− return ret ? ret : -ETIMEDOUT;
347−
348− return m5mols_busy_wait(sd, SYSTEM_INT_FACTOR, irq_mask,
349− M5MOLS_I2C_RDY_WAIT_FL | irq_mask, -1);
350−}
351−
352−/**
353− * m5mols_reg_mode - Write the mode and check busy status
354− * @sd: sub-device, as pointed by struct v4l2_subdev
355− * @mode: the required operation mode
356− *
357− * It always accompanies a little delay changing the M-5MOLS mode, so it is
358− * needed checking current busy status to guarantee right mode.
359− */
360−static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
361−{
362− int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
363− if (ret < 0)
364− return ret;
365− return m5mols_busy_wait(sd, SYSTEM_SYSMODE, mode, 0xff,
366− M5MOLS_MODE_CHANGE_TIMEOUT);
367−}
368−
369−/**
370− * m5mols_set_mode - set the M-5MOLS controller mode
371− * @info: M-5MOLS driver data structure
372− * @mode: the required operation mode
373− *
374− * The commands of M-5MOLS are grouped into specific modes. Each functionality
375− * can be guaranteed only when the sensor is operating in mode which a command
376− * belongs to.
377− */
378−int m5mols_set_mode(struct m5mols_info *info, u8 mode)
379−{
380− struct v4l2_subdev *sd = &info->sd;
381− int ret = -EINVAL;
382− u8 reg;
383−
384− if (mode < REG_PARAMETER || mode > REG_CAPTURE)
385− return ret;
386−
387− ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
388− if (ret || reg == mode)
389− return ret;
390−
391− switch (reg) {
392− case REG_PARAMETER:
393− ret = m5mols_reg_mode(sd, REG_MONITOR);
394− if (mode == REG_MONITOR)
395− break;
396− if (!ret)
397− ret = m5mols_reg_mode(sd, REG_CAPTURE);
398− break;
399−
400− case REG_MONITOR:
401− if (mode == REG_PARAMETER) {
402− ret = m5mols_reg_mode(sd, REG_PARAMETER);
403− break;
404− }
405−
406− ret = m5mols_reg_mode(sd, REG_CAPTURE);
407− break;
408−
409− case REG_CAPTURE:
410− ret = m5mols_reg_mode(sd, REG_MONITOR);
411− if (mode == REG_MONITOR)
412− break;
413− if (!ret)
414− ret = m5mols_reg_mode(sd, REG_PARAMETER);
415− break;
416−
417− default:
418− v4l2_warn(sd, "Wrong mode: %d\n", mode);
419− }
420−
421− if (!ret)
422− info->mode = mode;
423−
424− return ret;
425−}
426−
427−/**
428− * m5mols_get_version - retrieve full revisions information of M-5MOLS
429− * @sd: sub-device, as pointed by struct v4l2_subdev
430− *
431− * The version information includes revisions of hardware and firmware,
432− * AutoFocus alghorithm version and the version string.
433− */
434−static int m5mols_get_version(struct v4l2_subdev *sd)
435−{
436− struct m5mols_info *info = to_m5mols(sd);
437− struct m5mols_version *ver = &info->ver;
438− u8 *str = ver->str;
439− int i;
440− int ret;
441−
442− ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
443− if (!ret)
444− ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
445− if (!ret)
446− ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
447− if (!ret)
448− ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
449− if (!ret)
450− ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
451− if (!ret)
452− ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
453− if (!ret)
454− ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
455− if (ret)
456− return ret;
457−
458− for (i = 0; i < VERSION_STRING_SIZE; i++) {
459− ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
460− if (ret)
461− return ret;
462− }
463−
464− v4l2_info(sd, "Manufacturer\t[%s]\n",
465− is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
466− "Samsung Electro-Mechanics" :
467− is_manufacturer(info, REG_SAMSUNG_OPTICS) ?
468− "Samsung Fiber-Optics" :
469− is_manufacturer(info, REG_SAMSUNG_TECHWIN) ?
470− "Samsung Techwin" : "None");
471− v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n",
472− info->ver.customer, info->ver.project);
473−
474− if (!is_available_af(info))
475− v4l2_info(sd, "No support Auto Focus on this firmware\n");
476−
477− return ret;
478−}
479−
480−/**
481− * __find_restype - Lookup M-5MOLS resolution type according to pixel code
482− * @code: pixel code
483− */
484−static enum m5mols_restype __find_restype(u32 code)
485−{
486− enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR;
487−
488− do {
489− if (code == m5mols_default_ffmt[type].code)
490− return type;
491− } while (++type != SIZE_DEFAULT_FFMT);
492−
493− return 0;
494−}
495−
496−/**
497− * __find_resolution - Lookup preset and type of M-5MOLS's resolution
498− * @sd: sub-device, as pointed by struct v4l2_subdev
499− * @mf: pixel format to find/negotiate the resolution preset for
500− * @type: M-5MOLS resolution type
501− * @resolution: M-5MOLS resolution preset register value
502− *
503− * Find nearest resolution matching resolution preset and adjust mf
504− * to supported values.
505− */
506−static int __find_resolution(struct v4l2_subdev *sd,
507− struct v4l2_mbus_framefmt *mf,
508− enum m5mols_restype *type,
509− u32 *resolution)
510−{
511− const struct m5mols_resolution *fsize = &m5mols_reg_res[0];
512− const struct m5mols_resolution *match = NULL;
513− enum m5mols_restype stype = __find_restype(mf->code);
514− int i = ARRAY_SIZE(m5mols_reg_res);
515− unsigned int min_err = ~0;
516−
517− while (i--) {
518− int err;
519− if (stype == fsize->type) {
520− err = abs(fsize->width - mf->width)
521− + abs(fsize->height - mf->height);
522−
523− if (err < min_err) {
524− min_err = err;
525− match = fsize;
526− }
527− }
528− fsize++;
529− }
530− if (match) {
531− mf->width = match->width;
532− mf->height = match->height;
533− *resolution = match->reg;
534− *type = stype;
535− return 0;
536− }
537−
538− return -EINVAL;
539−}
540−
541−static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info,
542− struct v4l2_subdev_state *sd_state,
543− enum v4l2_subdev_format_whence which,
544− enum m5mols_restype type)
545−{
546− if (which == V4L2_SUBDEV_FORMAT_TRY)
547− return sd_state ? v4l2_subdev_get_try_format(&info->sd,
548− sd_state, 0) : NULL;
549−
550− return &info->ffmt[type];
551−}
552−
553−static int m5mols_get_fmt(struct v4l2_subdev *sd,
554− struct v4l2_subdev_state *sd_state,
555− struct v4l2_subdev_format *fmt)
556−{
557− struct m5mols_info *info = to_m5mols(sd);
558− struct v4l2_mbus_framefmt *format;
559− int ret = 0;
560−
561− mutex_lock(&info->lock);
562−
563− format = __find_format(info, sd_state, fmt->which, info->res_type);
564− if (format)
565− fmt->format = *format;
566− else
567− ret = -EINVAL;
568−
569− mutex_unlock(&info->lock);
570− return ret;
571−}
572−
573−static int m5mols_set_fmt(struct v4l2_subdev *sd,
574− struct v4l2_subdev_state *sd_state,
575− struct v4l2_subdev_format *fmt)
576−{
577− struct m5mols_info *info = to_m5mols(sd);
578− struct v4l2_mbus_framefmt *format = &fmt->format;
579− struct v4l2_mbus_framefmt *sfmt;
580− enum m5mols_restype type;
581− u32 resolution = 0;
582− int ret;
583−
584− ret = __find_resolution(sd, format, &type, &resolution);
585− if (ret < 0)
586− return ret;
587−
588− sfmt = __find_format(info, sd_state, fmt->which, type);
589− if (!sfmt)
590− return 0;
591−
592− mutex_lock(&info->lock);
593−
594− format->code = m5mols_default_ffmt[type].code;
595− format->colorspace = V4L2_COLORSPACE_JPEG;
596− format->field = V4L2_FIELD_NONE;
597−
598− if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
599− *sfmt = *format;
600− info->resolution = resolution;
601− info->res_type = type;
602− }
603−
604− mutex_unlock(&info->lock);
605− return ret;
606−}
607−
608−static int m5mols_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
609− struct v4l2_mbus_frame_desc *fd)
610−{
611− struct m5mols_info *info = to_m5mols(sd);
612−
613− if (pad != 0 || fd == NULL)
614− return -EINVAL;
615−
616− mutex_lock(&info->lock);
617− /*
618− * .get_frame_desc is only used for compressed formats,
619− * thus we always return the capture frame parameters here.
620− */
621− fd->entry[0].length = info->cap.buf_size;
622− fd->entry[0].pixelcode = info->ffmt[M5MOLS_RESTYPE_CAPTURE].code;
623− mutex_unlock(&info->lock);
624−
625− fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
626− fd->num_entries = 1;
627−
628− return 0;
629−}
630−
631−static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
632− struct v4l2_mbus_frame_desc *fd)
633−{
634− struct m5mols_info *info = to_m5mols(sd);
635− struct v4l2_mbus_framefmt *mf = &info->ffmt[M5MOLS_RESTYPE_CAPTURE];
636−
637− if (pad != 0 || fd == NULL)
638− return -EINVAL;
639−
640− fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX;
641− fd->num_entries = 1;
642− fd->entry[0].length = clamp_t(u32, fd->entry[0].length,
643− mf->width * mf->height,
644− M5MOLS_MAIN_JPEG_SIZE_MAX);
645− mutex_lock(&info->lock);
646− info->cap.buf_size = fd->entry[0].length;
647− mutex_unlock(&info->lock);
648−
649− return 0;
650−}
651−
652−
653−static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
654− struct v4l2_subdev_state *sd_state,
655− struct v4l2_subdev_mbus_code_enum *code)
656−{
657− if (!code || code->index >= SIZE_DEFAULT_FFMT)
658− return -EINVAL;
659−
660− code->code = m5mols_default_ffmt[code->index].code;
661−
662− return 0;
663−}
664−
665−static const struct v4l2_subdev_pad_ops m5mols_pad_ops = {
666− .enum_mbus_code = m5mols_enum_mbus_code,
667− .get_fmt = m5mols_get_fmt,
668− .set_fmt = m5mols_set_fmt,
669− .get_frame_desc = m5mols_get_frame_desc,
670− .set_frame_desc = m5mols_set_frame_desc,
671−};
672−
673−/**
674− * m5mols_restore_controls - Apply current control values to the registers
675− * @info: M-5MOLS driver data structure
676− *
677− * m5mols_do_scenemode() handles all parameters for which there is yet no
678− * individual control. It should be replaced at some point by setting each
679− * control individually, in required register set up order.
680− */
681−int m5mols_restore_controls(struct m5mols_info *info)
682−{
683− int ret;
684−
685− if (info->ctrl_sync)
686− return 0;
687−
688− ret = m5mols_do_scenemode(info, REG_SCENE_NORMAL);
689− if (ret)
690− return ret;
691−
692− ret = v4l2_ctrl_handler_setup(&info->handle);
693− info->ctrl_sync = !ret;
694−
695− return ret;
696−}
697−
698−/**
699− * m5mols_start_monitor - Start the monitor mode
700− * @info: M-5MOLS driver data structure
701− *
702− * Before applying the controls setup the resolution and frame rate
703− * in PARAMETER mode, and then switch over to MONITOR mode.
704− */
705−static int m5mols_start_monitor(struct m5mols_info *info)
706−{
707− struct v4l2_subdev *sd = &info->sd;
708− int ret;
709−
710− ret = m5mols_set_mode(info, REG_PARAMETER);
711− if (!ret)
712− ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
713− if (!ret)
714− ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
715− if (!ret)
716− ret = m5mols_set_mode(info, REG_MONITOR);
717− if (!ret)
718− ret = m5mols_restore_controls(info);
719−
720− return ret;
721−}
722−
723−static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
724−{
725− struct m5mols_info *info = to_m5mols(sd);
726− u32 code;
727− int ret;
728−
729− mutex_lock(&info->lock);
730− code = info->ffmt[info->res_type].code;
731−
732− if (enable) {
733− if (is_code(code, M5MOLS_RESTYPE_MONITOR))
734− ret = m5mols_start_monitor(info);
735− else if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
736− ret = m5mols_start_capture(info);
737− else
738− ret = -EINVAL;
739− } else {
740− ret = m5mols_set_mode(info, REG_PARAMETER);
741− }
742−
743− mutex_unlock(&info->lock);
744− return ret;
745−}
746−
747−static const struct v4l2_subdev_video_ops m5mols_video_ops = {
748− .s_stream = m5mols_s_stream,
749−};
750−
751−static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
752−{
753− struct v4l2_subdev *sd = &info->sd;
754− struct i2c_client *client = v4l2_get_subdevdata(sd);
755− int ret;
756−
757− if (info->power == enable)
758− return 0;
759−
760− if (enable) {
761− if (info->set_power) {
762− ret = info->set_power(&client->dev, 1);
763− if (ret)
764− return ret;
765− }
766−
767− ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
768− if (ret) {
769− if (info->set_power)
770− info->set_power(&client->dev, 0);
771− return ret;
772− }
773−
774− gpiod_set_value(info->reset, 0);
775− info->power = 1;
776−
777− return ret;
778− }
779−
780− ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
781− if (ret)
782− return ret;
783−
784− if (info->set_power)
785− info->set_power(&client->dev, 0);
786−
787− gpiod_set_value(info->reset, 1);
788−
789− info->isp_ready = 0;
790− info->power = 0;
791−
792− return ret;
793−}
794−
795−/* m5mols_update_fw - optional firmware update routine */
796−int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
797− int (*set_power)(struct m5mols_info *, bool))
798−{
799− return 0;
800−}
801−
802−/**
803− * m5mols_fw_start - M-5MOLS internal ARM controller initialization
804− * @sd: sub-device, as pointed by struct v4l2_subdev
805− *
806− * Execute the M-5MOLS internal ARM controller initialization sequence.
807− * This function should be called after the supply voltage has been
808− * applied and before any requests to the device are made.
809− */
810−static int m5mols_fw_start(struct v4l2_subdev *sd)
811−{
812− struct m5mols_info *info = to_m5mols(sd);
813− int ret;
814−
815− atomic_set(&info->irq_done, 0);
816− /* Wait until I2C slave is initialized in Flash Writer mode */
817− ret = m5mols_busy_wait(sd, FLASH_CAM_START, REG_IN_FLASH_MODE,
818− M5MOLS_I2C_RDY_WAIT_FL | 0xff, -1);
819− if (!ret)
820− ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
821− if (!ret)
822− ret = m5mols_wait_interrupt(sd, REG_INT_MODE, 2000);
823− if (ret < 0)
824− return ret;
825−
826− info->isp_ready = 1;
827−
828− ret = m5mols_get_version(sd);
829− if (!ret)
830− ret = m5mols_update_fw(sd, m5mols_sensor_power);
831− if (ret)
832− return ret;
833−
834− v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");
835−
836− ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
837− if (!ret)
838− ret = m5mols_enable_interrupt(sd,
839− REG_INT_AF | REG_INT_CAPTURE);
840−
841− return ret;
842−}
843−
844−/* Execute the lens soft-landing algorithm */
845−static int m5mols_auto_focus_stop(struct m5mols_info *info)
846−{
847− int ret;
848−
849− ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
850− if (!ret)
851− ret = m5mols_write(&info->sd, AF_MODE, REG_AF_POWEROFF);
852− if (!ret)
853− ret = m5mols_busy_wait(&info->sd, SYSTEM_STATUS, REG_AF_IDLE,
854− 0xff, -1);
855− return ret;
856−}
857−
858−/**
859− * m5mols_s_power - Main sensor power control function
860− * @sd: sub-device, as pointed by struct v4l2_subdev
861− * @on: if true, powers on the device; powers off otherwise.
862− *
863− * To prevent breaking the lens when the sensor is powered off the Soft-Landing
864− * algorithm is called where available. The Soft-Landing algorithm availability
865− * dependends on the firmware provider.
866− */
867−static int m5mols_s_power(struct v4l2_subdev *sd, int on)
868−{
869− struct m5mols_info *info = to_m5mols(sd);
870− int ret;
871−
872− mutex_lock(&info->lock);
873−
874− if (on) {
875− ret = m5mols_sensor_power(info, true);
876− if (!ret)
877− ret = m5mols_fw_start(sd);
878− } else {
879− if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
880− ret = m5mols_set_mode(info, REG_MONITOR);
881− if (!ret)
882− ret = m5mols_auto_focus_stop(info);
883− if (ret < 0)
884− v4l2_warn(sd, "Soft landing lens failed\n");
885− }
886− ret = m5mols_sensor_power(info, false);
887−
888− info->ctrl_sync = 0;
889− }
890−
891− mutex_unlock(&info->lock);
892− return ret;
893−}
894−
895−static int m5mols_log_status(struct v4l2_subdev *sd)
896−{
897− struct m5mols_info *info = to_m5mols(sd);
898−
899− v4l2_ctrl_handler_log_status(&info->handle, sd->name);
900−
901− return 0;
902−}
903−
904−static const struct v4l2_subdev_core_ops m5mols_core_ops = {
905− .s_power = m5mols_s_power,
906− .log_status = m5mols_log_status,
907−};
908−
909−/*
910− * V4L2 subdev internal operations
911− */
912−static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
913−{
914− struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd,
915− fh->state,
916− 0);
917−
918− *format = m5mols_default_ffmt[0];
919− return 0;
920−}
921−
922−static const struct v4l2_subdev_internal_ops m5mols_subdev_internal_ops = {
923− .open = m5mols_open,
924−};
925−
926−static const struct v4l2_subdev_ops m5mols_ops = {
927− .core = &m5mols_core_ops,
928− .pad = &m5mols_pad_ops,
929− .video = &m5mols_video_ops,
930−};
931−
932−static irqreturn_t m5mols_irq_handler(int irq, void *data)
933−{
934− struct m5mols_info *info = to_m5mols(data);
935−
936− atomic_set(&info->irq_done, 1);
937− wake_up_interruptible(&info->irq_waitq);
938−
939− return IRQ_HANDLED;
940−}
941−
942−static int m5mols_probe(struct i2c_client *client)
943−{
944− const struct m5mols_platform_data *pdata = client->dev.platform_data;
945− struct m5mols_info *info;
946− struct v4l2_subdev *sd;
947− int ret;
948−
949− if (pdata == NULL) {
950− dev_err(&client->dev, "No platform data\n");
951− return -EINVAL;
952− }
953−
954− if (!client->irq) {
955− dev_err(&client->dev, "Interrupt not assigned\n");
956− return -EINVAL;
957− }
958−
959− info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
960− if (!info)
961− return -ENOMEM;
962−
963− /* This asserts reset, descriptor shall have polarity specified */
964− info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
965− if (IS_ERR(info->reset))
966− return PTR_ERR(info->reset);
967− /* Notice: the "N" in M5MOLS_NRST implies active low */
968− gpiod_set_consumer_name(info->reset, "M5MOLS_NRST");
969−
970− info->pdata = pdata;
971− info->set_power = pdata->set_power;
972−
973− ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
974− supplies);
975− if (ret) {
976− dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
977− return ret;
978− }
979−
980− sd = &info->sd;
981− v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
982− /* Static name; NEVER use in new drivers! */
983− strscpy(sd->name, MODULE_NAME, sizeof(sd->name));
984− sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
985−
986− sd->internal_ops = &m5mols_subdev_internal_ops;
987− info->pad.flags = MEDIA_PAD_FL_SOURCE;
988− ret = media_entity_pads_init(&sd->entity, 1, &info->pad);
989− if (ret < 0)
990− return ret;
991− sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
992−
993− init_waitqueue_head(&info->irq_waitq);
994− mutex_init(&info->lock);
995−
996− ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
997− IRQF_TRIGGER_RISING, MODULE_NAME, sd);
998− if (ret) {
999− dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
1000− goto error;
1001− }
1002− info->res_type = M5MOLS_RESTYPE_MONITOR;
1003− info->ffmt[0] = m5mols_default_ffmt[0];
1004− info->ffmt[1] = m5mols_default_ffmt[1];
1005−
1006− ret = m5mols_sensor_power(info, true);
1007− if (ret)
1008− goto error;
1009−
1010− ret = m5mols_fw_start(sd);
1011− if (!ret)
1012− ret = m5mols_init_controls(sd);
1013−
1014− ret = m5mols_sensor_power(info, false);
1015− if (!ret)
1016− return 0;
1017−error:
1018− media_entity_cleanup(&sd->entity);
1019− return ret;
1020−}
1021−
1022−static void m5mols_remove(struct i2c_client *client)
1023−{
1024− struct v4l2_subdev *sd = i2c_get_clientdata(client);
1025−
1026− v4l2_device_unregister_subdev(sd);
1027− v4l2_ctrl_handler_free(sd->ctrl_handler);
1028− media_entity_cleanup(&sd->entity);
1029−}
1030−
1031−static const struct i2c_device_id m5mols_id[] = {
1032− { MODULE_NAME, 0 },
1033− { },
1034−};
1035−MODULE_DEVICE_TABLE(i2c, m5mols_id);
1036−
1037−static struct i2c_driver m5mols_i2c_driver = {
1038− .driver = {
1039− .name = MODULE_NAME,
1040− },
1041− .probe_new = m5mols_probe,
1042− .remove = m5mols_remove,
1043− .id_table = m5mols_id,
1044−};
1045−
1046−module_i2c_driver(m5mols_i2c_driver);
1047−
1048−MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
1049−MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
1050−MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver");
1051−MODULE_LICENSE("GPL");
drivers/media/i2c/m5mols/m5mols_reg.h+0−359
@@ -1,359 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0-or-later */
2−/*
3− * Register map for M-5MOLS 8M Pixel camera sensor with ISP
4− *
5− * Copyright (C) 2011 Samsung Electronics Co., Ltd.
6− * Author: HeungJun Kim <riverful.kim@samsung.com>
7− *
8− * Copyright (C) 2009 Samsung Electronics Co., Ltd.
9− * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
10− */
11−
12−#ifndef M5MOLS_REG_H
13−#define M5MOLS_REG_H
14−
15−#define M5MOLS_I2C_MAX_SIZE 4
16−#define M5MOLS_BYTE_READ 0x01
17−#define M5MOLS_BYTE_WRITE 0x02
18−
19−#define I2C_CATEGORY(__cat) ((__cat >> 16) & 0xff)
20−#define I2C_COMMAND(__comm) ((__comm >> 8) & 0xff)
21−#define I2C_SIZE(__reg_s) ((__reg_s) & 0xff)
22−#define I2C_REG(__cat, __cmd, __reg_s) ((__cat << 16) | (__cmd << 8) | __reg_s)
23−
24−/*
25− * Category section register
26− *
27− * The category means set including relevant command of M-5MOLS.
28− */
29−#define CAT_SYSTEM 0x00
30−#define CAT_PARAM 0x01
31−#define CAT_MONITOR 0x02
32−#define CAT_AE 0x03
33−#define CAT_WB 0x06
34−#define CAT_EXIF 0x07
35−#define CAT_FD 0x09
36−#define CAT_LENS 0x0a
37−#define CAT_CAPT_PARM 0x0b
38−#define CAT_CAPT_CTRL 0x0c
39−#define CAT_FLASH 0x0f /* related to FW, revisions, booting */
40−
41−/*
42− * Category 0 - SYSTEM mode
43− *
44− * The SYSTEM mode in the M-5MOLS means area available to handle with the whole
45− * & all-round system of sensor. It deals with version/interrupt/setting mode &
46− * even sensor's status. Especially, the M-5MOLS sensor with ISP varies by
47− * packaging & manufacturer, even the customer and project code. And the
48− * function details may vary among them. The version information helps to
49− * determine what methods shall be used in the driver.
50− *
51− * There is many registers between customer version address and awb one. For
52− * more specific contents, see definition if file m5mols.h.
53− */
54−#define SYSTEM_VER_CUSTOMER I2C_REG(CAT_SYSTEM, 0x00, 1)
55−#define SYSTEM_VER_PROJECT I2C_REG(CAT_SYSTEM, 0x01, 1)
56−#define SYSTEM_VER_FIRMWARE I2C_REG(CAT_SYSTEM, 0x02, 2)
57−#define SYSTEM_VER_HARDWARE I2C_REG(CAT_SYSTEM, 0x04, 2)
58−#define SYSTEM_VER_PARAMETER I2C_REG(CAT_SYSTEM, 0x06, 2)
59−#define SYSTEM_VER_AWB I2C_REG(CAT_SYSTEM, 0x08, 2)
60−
61−#define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, 0x0b, 1)
62−#define REG_SYSINIT 0x00 /* SYSTEM mode */
63−#define REG_PARAMETER 0x01 /* PARAMETER mode */
64−#define REG_MONITOR 0x02 /* MONITOR mode */
65−#define REG_CAPTURE 0x03 /* CAPTURE mode */
66−
67−#define SYSTEM_CMD(__cmd) I2C_REG(CAT_SYSTEM, cmd, 1)
68−#define SYSTEM_VER_STRING I2C_REG(CAT_SYSTEM, 0x0a, 1)
69−#define REG_SAMSUNG_ELECTRO "SE" /* Samsung Electro-Mechanics */
70−#define REG_SAMSUNG_OPTICS "OP" /* Samsung Fiber-Optics */
71−#define REG_SAMSUNG_TECHWIN "TB" /* Samsung Techwin */
72−/* SYSTEM mode status */
73−#define SYSTEM_STATUS I2C_REG(CAT_SYSTEM, 0x0c, 1)
74−
75−/* Interrupt pending register */
76−#define SYSTEM_INT_FACTOR I2C_REG(CAT_SYSTEM, 0x10, 1)
77−/* interrupt enable register */
78−#define SYSTEM_INT_ENABLE I2C_REG(CAT_SYSTEM, 0x11, 1)
79−#define REG_INT_MODE (1 << 0)
80−#define REG_INT_AF (1 << 1)
81−#define REG_INT_ZOOM (1 << 2)
82−#define REG_INT_CAPTURE (1 << 3)
83−#define REG_INT_FRAMESYNC (1 << 4)
84−#define REG_INT_FD (1 << 5)
85−#define REG_INT_LENS_INIT (1 << 6)
86−#define REG_INT_SOUND (1 << 7)
87−#define REG_INT_MASK 0x0f
88−
89−/*
90− * category 1 - PARAMETER mode
91− *
92− * This category supports function of camera features of M-5MOLS. It means we
93− * can handle with preview(MONITOR) resolution size/frame per second/interface
94− * between the sensor and the Application Processor/even the image effect.
95− */
96−
97−/* Resolution in the MONITOR mode */
98−#define PARM_MON_SIZE I2C_REG(CAT_PARAM, 0x01, 1)
99−
100−/* Frame rate */
101−#define PARM_MON_FPS I2C_REG(CAT_PARAM, 0x02, 1)
102−#define REG_FPS_30 0x02
103−
104−/* Video bus between the sensor and a host processor */
105−#define PARM_INTERFACE I2C_REG(CAT_PARAM, 0x00, 1)
106−#define REG_INTERFACE_MIPI 0x02
107−
108−/* Image effects */
109−#define PARM_EFFECT I2C_REG(CAT_PARAM, 0x0b, 1)
110−#define REG_EFFECT_OFF 0x00
111−#define REG_EFFECT_NEGA 0x01
112−#define REG_EFFECT_EMBOSS 0x06
113−#define REG_EFFECT_OUTLINE 0x07
114−#define REG_EFFECT_WATERCOLOR 0x08
115−
116−/*
117− * Category 2 - MONITOR mode
118− *
119− * The MONITOR mode is same as preview mode as we said. The M-5MOLS has another
120− * mode named "Preview", but this preview mode is used at the case specific
121− * vider-recording mode. This mmode supports only YUYV format. On the other
122− * hand, the JPEG & RAW formats is supports by CAPTURE mode. And, there are
123− * another options like zoom/color effect(different with effect in PARAMETER
124− * mode)/anti hand shaking algorithm.
125− */
126−
127−/* Target digital zoom position */
128−#define MON_ZOOM I2C_REG(CAT_MONITOR, 0x01, 1)
129−
130−/* CR value for color effect */
131−#define MON_CFIXR I2C_REG(CAT_MONITOR, 0x0a, 1)
132−/* CB value for color effect */
133−#define MON_CFIXB I2C_REG(CAT_MONITOR, 0x09, 1)
134−#define REG_CFIXB_SEPIA 0xd8
135−#define REG_CFIXR_SEPIA 0x18
136−
137−#define MON_EFFECT I2C_REG(CAT_MONITOR, 0x0b, 1)
138−#define REG_COLOR_EFFECT_OFF 0x00
139−#define REG_COLOR_EFFECT_ON 0x01
140−
141−/* Chroma enable */
142−#define MON_CHROMA_EN I2C_REG(CAT_MONITOR, 0x10, 1)
143−/* Chroma level */
144−#define MON_CHROMA_LVL I2C_REG(CAT_MONITOR, 0x0f, 1)
145−#define REG_CHROMA_OFF 0x00
146−#define REG_CHROMA_ON 0x01
147−
148−/* Sharpness on/off */
149−#define MON_EDGE_EN I2C_REG(CAT_MONITOR, 0x12, 1)
150−/* Sharpness level */
151−#define MON_EDGE_LVL I2C_REG(CAT_MONITOR, 0x11, 1)
152−#define REG_EDGE_OFF 0x00
153−#define REG_EDGE_ON 0x01
154−
155−/* Set color tone (contrast) */
156−#define MON_TONE_CTL I2C_REG(CAT_MONITOR, 0x25, 1)
157−
158−/*
159− * Category 3 - Auto Exposure
160− *
161− * The M-5MOLS exposure capbility is detailed as which is similar to digital
162− * camera. This category supports AE locking/various AE mode(range of exposure)
163− * /ISO/flickering/EV bias/shutter/meteoring, and anything else. And the
164− * maximum/minimum exposure gain value depending on M-5MOLS firmware, may be
165− * different. So, this category also provide getting the max/min values. And,
166− * each MONITOR and CAPTURE mode has each gain/shutter/max exposure values.
167− */
168−
169−/* Auto Exposure locking */
170−#define AE_LOCK I2C_REG(CAT_AE, 0x00, 1)
171−#define REG_AE_UNLOCK 0x00
172−#define REG_AE_LOCK 0x01
173−
174−/* Auto Exposure algorithm mode */
175−#define AE_MODE I2C_REG(CAT_AE, 0x01, 1)
176−#define REG_AE_OFF 0x00 /* AE off */
177−#define REG_AE_ALL 0x01 /* calc AE in all block integral */
178−#define REG_AE_CENTER 0x03 /* calc AE in center weighted */
179−#define REG_AE_SPOT 0x06 /* calc AE in specific spot */
180−
181−#define AE_ISO I2C_REG(CAT_AE, 0x05, 1)
182−#define REG_ISO_AUTO 0x00
183−#define REG_ISO_50 0x01
184−#define REG_ISO_100 0x02
185−#define REG_ISO_200 0x03
186−#define REG_ISO_400 0x04
187−#define REG_ISO_800 0x05
188−
189−/* EV (scenemode) preset for MONITOR */
190−#define AE_EV_PRESET_MONITOR I2C_REG(CAT_AE, 0x0a, 1)
191−/* EV (scenemode) preset for CAPTURE */
192−#define AE_EV_PRESET_CAPTURE I2C_REG(CAT_AE, 0x0b, 1)
193−#define REG_SCENE_NORMAL 0x00
194−#define REG_SCENE_PORTRAIT 0x01
195−#define REG_SCENE_LANDSCAPE 0x02
196−#define REG_SCENE_SPORTS 0x03
197−#define REG_SCENE_PARTY_INDOOR 0x04
198−#define REG_SCENE_BEACH_SNOW 0x05
199−#define REG_SCENE_SUNSET 0x06
200−#define REG_SCENE_DAWN_DUSK 0x07
201−#define REG_SCENE_FALL 0x08
202−#define REG_SCENE_NIGHT 0x09
203−#define REG_SCENE_AGAINST_LIGHT 0x0a
204−#define REG_SCENE_FIRE 0x0b
205−#define REG_SCENE_TEXT 0x0c
206−#define REG_SCENE_CANDLE 0x0d
207−
208−/* Manual gain in MONITOR mode */
209−#define AE_MAN_GAIN_MON I2C_REG(CAT_AE, 0x12, 2)
210−/* Maximum gain in MONITOR mode */
211−#define AE_MAX_GAIN_MON I2C_REG(CAT_AE, 0x1a, 2)
212−/* Manual gain in CAPTURE mode */
213−#define AE_MAN_GAIN_CAP I2C_REG(CAT_AE, 0x26, 2)
214−
215−#define AE_INDEX I2C_REG(CAT_AE, 0x38, 1)
216−#define REG_AE_INDEX_20_NEG 0x00
217−#define REG_AE_INDEX_15_NEG 0x01
218−#define REG_AE_INDEX_10_NEG 0x02
219−#define REG_AE_INDEX_05_NEG 0x03
220−#define REG_AE_INDEX_00 0x04
221−#define REG_AE_INDEX_05_POS 0x05
222−#define REG_AE_INDEX_10_POS 0x06
223−#define REG_AE_INDEX_15_POS 0x07
224−#define REG_AE_INDEX_20_POS 0x08
225−
226−/*
227− * Category 6 - White Balance
228− */
229−
230−/* Auto Whitebalance locking */
231−#define AWB_LOCK I2C_REG(CAT_WB, 0x00, 1)
232−#define REG_AWB_UNLOCK 0x00
233−#define REG_AWB_LOCK 0x01
234−
235−#define AWB_MODE I2C_REG(CAT_WB, 0x02, 1)
236−#define REG_AWB_AUTO 0x01 /* AWB off */
237−#define REG_AWB_PRESET 0x02 /* AWB preset */
238−
239−/* Manual WB (preset) */
240−#define AWB_MANUAL I2C_REG(CAT_WB, 0x03, 1)
241−#define REG_AWB_INCANDESCENT 0x01
242−#define REG_AWB_FLUORESCENT_1 0x02
243−#define REG_AWB_FLUORESCENT_2 0x03
244−#define REG_AWB_DAYLIGHT 0x04
245−#define REG_AWB_CLOUDY 0x05
246−#define REG_AWB_SHADE 0x06
247−#define REG_AWB_HORIZON 0x07
248−#define REG_AWB_LEDLIGHT 0x09
249−
250−/*
251− * Category 7 - EXIF information
252− */
253−#define EXIF_INFO_EXPTIME_NU I2C_REG(CAT_EXIF, 0x00, 4)
254−#define EXIF_INFO_EXPTIME_DE I2C_REG(CAT_EXIF, 0x04, 4)
255−#define EXIF_INFO_TV_NU I2C_REG(CAT_EXIF, 0x08, 4)
256−#define EXIF_INFO_TV_DE I2C_REG(CAT_EXIF, 0x0c, 4)
257−#define EXIF_INFO_AV_NU I2C_REG(CAT_EXIF, 0x10, 4)
258−#define EXIF_INFO_AV_DE I2C_REG(CAT_EXIF, 0x14, 4)
259−#define EXIF_INFO_BV_NU I2C_REG(CAT_EXIF, 0x18, 4)
260−#define EXIF_INFO_BV_DE I2C_REG(CAT_EXIF, 0x1c, 4)
261−#define EXIF_INFO_EBV_NU I2C_REG(CAT_EXIF, 0x20, 4)
262−#define EXIF_INFO_EBV_DE I2C_REG(CAT_EXIF, 0x24, 4)
263−#define EXIF_INFO_ISO I2C_REG(CAT_EXIF, 0x28, 2)
264−#define EXIF_INFO_FLASH I2C_REG(CAT_EXIF, 0x2a, 2)
265−#define EXIF_INFO_SDR I2C_REG(CAT_EXIF, 0x2c, 2)
266−#define EXIF_INFO_QVAL I2C_REG(CAT_EXIF, 0x2e, 2)
267−
268−/*
269− * Category 9 - Face Detection
270− */
271−#define FD_CTL I2C_REG(CAT_FD, 0x00, 1)
272−#define BIT_FD_EN 0
273−#define BIT_FD_DRAW_FACE_FRAME 4
274−#define BIT_FD_DRAW_SMILE_LVL 6
275−#define REG_FD(shift) (1 << shift)
276−#define REG_FD_OFF 0x0
277−
278−/*
279− * Category A - Lens Parameter
280− */
281−#define AF_MODE I2C_REG(CAT_LENS, 0x01, 1)
282−#define REG_AF_NORMAL 0x00 /* Normal AF, one time */
283−#define REG_AF_MACRO 0x01 /* Macro AF, one time */
284−#define REG_AF_POWEROFF 0x07
285−
286−#define AF_EXECUTE I2C_REG(CAT_LENS, 0x02, 1)
287−#define REG_AF_STOP 0x00
288−#define REG_AF_EXE_AUTO 0x01
289−#define REG_AF_EXE_CAF 0x02
290−
291−#define AF_STATUS I2C_REG(CAT_LENS, 0x03, 1)
292−#define REG_AF_FAIL 0x00
293−#define REG_AF_SUCCESS 0x02
294−#define REG_AF_IDLE 0x04
295−#define REG_AF_BUSY 0x05
296−
297−#define AF_VERSION I2C_REG(CAT_LENS, 0x0a, 1)
298−
299−/*
300− * Category B - CAPTURE Parameter
301− */
302−#define CAPP_YUVOUT_MAIN I2C_REG(CAT_CAPT_PARM, 0x00, 1)
303−#define REG_YUV422 0x00
304−#define REG_BAYER10 0x05
305−#define REG_BAYER8 0x06
306−#define REG_JPEG 0x10
307−
308−#define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1)
309−#define CAPP_JPEG_SIZE_MAX I2C_REG(CAT_CAPT_PARM, 0x0f, 4)
310−#define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1)
311−
312−#define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1)
313−#define REG_MCC_OFF 0x00
314−#define REG_MCC_NORMAL 0x01
315−
316−#define CAPP_WDR_EN I2C_REG(CAT_CAPT_PARM, 0x2c, 1)
317−#define REG_WDR_OFF 0x00
318−#define REG_WDR_ON 0x01
319−#define REG_WDR_AUTO 0x02
320−
321−#define CAPP_LIGHT_CTRL I2C_REG(CAT_CAPT_PARM, 0x40, 1)
322−#define REG_LIGHT_OFF 0x00
323−#define REG_LIGHT_ON 0x01
324−#define REG_LIGHT_AUTO 0x02
325−
326−#define CAPP_FLASH_CTRL I2C_REG(CAT_CAPT_PARM, 0x41, 1)
327−#define REG_FLASH_OFF 0x00
328−#define REG_FLASH_ON 0x01
329−#define REG_FLASH_AUTO 0x02
330−
331−/*
332− * Category C - CAPTURE Control
333− */
334−#define CAPC_MODE I2C_REG(CAT_CAPT_CTRL, 0x00, 1)
335−#define REG_CAP_NONE 0x00
336−#define REG_CAP_ANTI_SHAKE 0x02
337−
338−/* Select single- or multi-shot capture */
339−#define CAPC_SEL_FRAME I2C_REG(CAT_CAPT_CTRL, 0x06, 1)
340−
341−#define CAPC_START I2C_REG(CAT_CAPT_CTRL, 0x09, 1)
342−#define REG_CAP_START_MAIN 0x01
343−#define REG_CAP_START_THUMB 0x03
344−
345−#define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, 0x0d, 4)
346−#define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, 0x11, 4)
347−
348−/*
349− * Category F - Flash
350− *
351− * This mode provides functions about internal flash stuff and system startup.
352− */
353−
354−/* Starts internal ARM core booting after power-up */
355−#define FLASH_CAM_START I2C_REG(CAT_FLASH, 0x12, 1)
356−#define REG_START_ARM_BOOT 0x01 /* write value */
357−#define REG_IN_FLASH_MODE 0x00 /* read value */
358−
359−#endif /* M5MOLS_REG_H */
drivers/media/i2c/max9286.c+1−0
@@ -1122,6 +1122,7 @@ err_async: · 1121 unmodified lines
11221122 static void max9286_v4l2_unregister(struct max9286_priv *priv)
11231123 {
11241124 fwnode_handle_put(priv->sd.fwnode);
1125+ v4l2_ctrl_handler_free(&priv->ctrls);
11251126 v4l2_async_unregister_subdev(&priv->sd);
11261127 max9286_v4l2_notifier_unregister(priv);
11271128 }
drivers/media/i2c/mt9m032.c+0−891
@@ -1,891 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/*
3− * Driver for MT9M032 CMOS Image Sensor from Micron
4− *
5− * Copyright (C) 2010-2011 Lund Engineering
6− * Contact: Gil Lund <gwlund@lundeng.com>
7− * Author: Martin Hostettler <martin@neutronstar.dyndns.org>
8− */
9−
10−#include <linux/delay.h>
11−#include <linux/i2c.h>
12−#include <linux/init.h>
13−#include <linux/kernel.h>
14−#include <linux/math64.h>
15−#include <linux/module.h>
16−#include <linux/mutex.h>
17−#include <linux/slab.h>
18−#include <linux/v4l2-mediabus.h>
19−
20−#include <media/media-entity.h>
21−#include <media/i2c/mt9m032.h>
22−#include <media/v4l2-ctrls.h>
23−#include <media/v4l2-device.h>
24−#include <media/v4l2-subdev.h>
25−
26−#include "aptina-pll.h"
27−
28−/*
29− * width and height include active boundary and black parts
30− *
31− * column 0- 15 active boundary
32− * column 16-1455 image
33− * column 1456-1471 active boundary
34− * column 1472-1599 black
35− *
36− * row 0- 51 black
37− * row 53- 59 active boundary
38− * row 60-1139 image
39− * row 1140-1147 active boundary
40− * row 1148-1151 black
41− */
42−
43−#define MT9M032_PIXEL_ARRAY_WIDTH 1600
44−#define MT9M032_PIXEL_ARRAY_HEIGHT 1152
45−
46−#define MT9M032_CHIP_VERSION 0x00
47−#define MT9M032_CHIP_VERSION_VALUE 0x1402
48−#define MT9M032_ROW_START 0x01
49−#define MT9M032_ROW_START_MIN 0
50−#define MT9M032_ROW_START_MAX 1152
51−#define MT9M032_ROW_START_DEF 60
52−#define MT9M032_COLUMN_START 0x02
53−#define MT9M032_COLUMN_START_MIN 0
54−#define MT9M032_COLUMN_START_MAX 1600
55−#define MT9M032_COLUMN_START_DEF 16
56−#define MT9M032_ROW_SIZE 0x03
57−#define MT9M032_ROW_SIZE_MIN 32
58−#define MT9M032_ROW_SIZE_MAX 1152
59−#define MT9M032_ROW_SIZE_DEF 1080
60−#define MT9M032_COLUMN_SIZE 0x04
61−#define MT9M032_COLUMN_SIZE_MIN 32
62−#define MT9M032_COLUMN_SIZE_MAX 1600
63−#define MT9M032_COLUMN_SIZE_DEF 1440
64−#define MT9M032_HBLANK 0x05
65−#define MT9M032_VBLANK 0x06
66−#define MT9M032_VBLANK_MAX 0x7ff
67−#define MT9M032_SHUTTER_WIDTH_HIGH 0x08
68−#define MT9M032_SHUTTER_WIDTH_LOW 0x09
69−#define MT9M032_SHUTTER_WIDTH_MIN 1
70−#define MT9M032_SHUTTER_WIDTH_MAX 1048575
71−#define MT9M032_SHUTTER_WIDTH_DEF 1943
72−#define MT9M032_PIX_CLK_CTRL 0x0a
73−#define MT9M032_PIX_CLK_CTRL_INV_PIXCLK 0x8000
74−#define MT9M032_RESTART 0x0b
75−#define MT9M032_RESET 0x0d
76−#define MT9M032_PLL_CONFIG1 0x11
77−#define MT9M032_PLL_CONFIG1_PREDIV_MASK 0x3f
78−#define MT9M032_PLL_CONFIG1_MUL_SHIFT 8
79−#define MT9M032_READ_MODE1 0x1e
80−#define MT9M032_READ_MODE1_OUTPUT_BAD_FRAMES (1 << 13)
81−#define MT9M032_READ_MODE1_MAINTAIN_FRAME_RATE (1 << 12)
82−#define MT9M032_READ_MODE1_XOR_LINE_VALID (1 << 11)
83−#define MT9M032_READ_MODE1_CONT_LINE_VALID (1 << 10)
84−#define MT9M032_READ_MODE1_INVERT_TRIGGER (1 << 9)
85−#define MT9M032_READ_MODE1_SNAPSHOT (1 << 8)
86−#define MT9M032_READ_MODE1_GLOBAL_RESET (1 << 7)
87−#define MT9M032_READ_MODE1_BULB_EXPOSURE (1 << 6)
88−#define MT9M032_READ_MODE1_INVERT_STROBE (1 << 5)
89−#define MT9M032_READ_MODE1_STROBE_ENABLE (1 << 4)
90−#define MT9M032_READ_MODE1_STROBE_START_TRIG1 (0 << 2)
91−#define MT9M032_READ_MODE1_STROBE_START_EXP (1 << 2)
92−#define MT9M032_READ_MODE1_STROBE_START_SHUTTER (2 << 2)
93−#define MT9M032_READ_MODE1_STROBE_START_TRIG2 (3 << 2)
94−#define MT9M032_READ_MODE1_STROBE_END_TRIG1 (0 << 0)
95−#define MT9M032_READ_MODE1_STROBE_END_EXP (1 << 0)
96−#define MT9M032_READ_MODE1_STROBE_END_SHUTTER (2 << 0)
97−#define MT9M032_READ_MODE1_STROBE_END_TRIG2 (3 << 0)
98−#define MT9M032_READ_MODE2 0x20
99−#define MT9M032_READ_MODE2_VFLIP_SHIFT 15
100−#define MT9M032_READ_MODE2_HFLIP_SHIFT 14
101−#define MT9M032_READ_MODE2_ROW_BLC 0x40
102−#define MT9M032_GAIN_GREEN1 0x2b
103−#define MT9M032_GAIN_BLUE 0x2c
104−#define MT9M032_GAIN_RED 0x2d
105−#define MT9M032_GAIN_GREEN2 0x2e
106−
107−/* write only */
108−#define MT9M032_GAIN_ALL 0x35
109−#define MT9M032_GAIN_DIGITAL_MASK 0x7f
110−#define MT9M032_GAIN_DIGITAL_SHIFT 8
111−#define MT9M032_GAIN_AMUL_SHIFT 6
112−#define MT9M032_GAIN_ANALOG_MASK 0x3f
113−#define MT9M032_FORMATTER1 0x9e
114−#define MT9M032_FORMATTER1_PLL_P1_6 (1 << 8)
115−#define MT9M032_FORMATTER1_PARALLEL (1 << 12)
116−#define MT9M032_FORMATTER2 0x9f
117−#define MT9M032_FORMATTER2_DOUT_EN 0x1000
118−#define MT9M032_FORMATTER2_PIXCLK_EN 0x2000
119−
120−/*
121− * The available MT9M032 datasheet is missing documentation for register 0x10
122− * MT9P031 seems to be close enough, so use constants from that datasheet for
123− * now.
124− * But keep the name MT9P031 to remind us, that this isn't really confirmed
125− * for this sensor.
126− */
127−#define MT9P031_PLL_CONTROL 0x10
128−#define MT9P031_PLL_CONTROL_PWROFF 0x0050
129−#define MT9P031_PLL_CONTROL_PWRON 0x0051
130−#define MT9P031_PLL_CONTROL_USEPLL 0x0052
131−
132−struct mt9m032 {
133− struct v4l2_subdev subdev;
134− struct media_pad pad;
135− struct mt9m032_platform_data *pdata;
136−
137− unsigned int pix_clock;
138−
139− struct v4l2_ctrl_handler ctrls;
140− struct {
141− struct v4l2_ctrl *hflip;
142− struct v4l2_ctrl *vflip;
143− };
144−
145− struct mutex lock; /* Protects streaming, format, interval and crop */
146−
147− bool streaming;
148−
149− struct v4l2_mbus_framefmt format;
150− struct v4l2_rect crop;
151− struct v4l2_fract frame_interval;
152−};
153−
154−#define to_mt9m032(sd) container_of(sd, struct mt9m032, subdev)
155−#define to_dev(sensor) \
156− (&((struct i2c_client *)v4l2_get_subdevdata(&(sensor)->subdev))->dev)
157−
158−static int mt9m032_read(struct i2c_client *client, u8 reg)
159−{
160− return i2c_smbus_read_word_swapped(client, reg);
161−}
162−
163−static int mt9m032_write(struct i2c_client *client, u8 reg, const u16 data)
164−{
165− return i2c_smbus_write_word_swapped(client, reg, data);
166−}
167−
168−static u32 mt9m032_row_time(struct mt9m032 *sensor, unsigned int width)
169−{
170− unsigned int effective_width;
171− u32 ns;
172−
173− effective_width = width + 716; /* empirical value */
174− ns = div_u64(1000000000ULL * effective_width, sensor->pix_clock);
175− dev_dbg(to_dev(sensor), "MT9M032 line time: %u ns\n", ns);
176− return ns;
177−}
178−
179−static int mt9m032_update_timing(struct mt9m032 *sensor,
180− struct v4l2_fract *interval)
181−{
182− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
183− struct v4l2_rect *crop = &sensor->crop;
184− unsigned int min_vblank;
185− unsigned int vblank;
186− u32 row_time;
187−
188− if (!interval)
189− interval = &sensor->frame_interval;
190−
191− row_time = mt9m032_row_time(sensor, crop->width);
192−
193− vblank = div_u64(1000000000ULL * interval->numerator,
194− (u64)row_time * interval->denominator)
195− - crop->height;
196−
197− if (vblank > MT9M032_VBLANK_MAX) {
198− /* hardware limits to 11 bit values */
199− interval->denominator = 1000;
200− interval->numerator =
201− div_u64((crop->height + MT9M032_VBLANK_MAX) *
202− (u64)row_time * interval->denominator,
203− 1000000000ULL);
204− vblank = div_u64(1000000000ULL * interval->numerator,
205− (u64)row_time * interval->denominator)
206− - crop->height;
207− }
208− /* enforce minimal 1.6ms blanking time. */
209− min_vblank = 1600000 / row_time;
210− vblank = clamp_t(unsigned int, vblank, min_vblank, MT9M032_VBLANK_MAX);
211−
212− return mt9m032_write(client, MT9M032_VBLANK, vblank);
213−}
214−
215−static int mt9m032_update_geom_timing(struct mt9m032 *sensor)
216−{
217− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
218− int ret;
219−
220− ret = mt9m032_write(client, MT9M032_COLUMN_SIZE,
221− sensor->crop.width - 1);
222− if (!ret)
223− ret = mt9m032_write(client, MT9M032_ROW_SIZE,
224− sensor->crop.height - 1);
225− if (!ret)
226− ret = mt9m032_write(client, MT9M032_COLUMN_START,
227− sensor->crop.left);
228− if (!ret)
229− ret = mt9m032_write(client, MT9M032_ROW_START,
230− sensor->crop.top);
231− if (!ret)
232− ret = mt9m032_update_timing(sensor, NULL);
233− return ret;
234−}
235−
236−static int update_formatter2(struct mt9m032 *sensor, bool streaming)
237−{
238− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
239− u16 reg_val = MT9M032_FORMATTER2_DOUT_EN
240− | 0x0070; /* parts reserved! */
241− /* possibly for changing to 14-bit mode */
242−
243− if (streaming)
244− reg_val |= MT9M032_FORMATTER2_PIXCLK_EN; /* pixclock enable */
245−
246− return mt9m032_write(client, MT9M032_FORMATTER2, reg_val);
247−}
248−
249−static int mt9m032_setup_pll(struct mt9m032 *sensor)
250−{
251− static const struct aptina_pll_limits limits = {
252− .ext_clock_min = 8000000,
253− .ext_clock_max = 16500000,
254− .int_clock_min = 2000000,
255− .int_clock_max = 24000000,
256− .out_clock_min = 322000000,
257− .out_clock_max = 693000000,
258− .pix_clock_max = 99000000,
259− .n_min = 1,
260− .n_max = 64,
261− .m_min = 16,
262− .m_max = 255,
263− .p1_min = 6,
264− .p1_max = 7,
265− };
266−
267− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
268− struct mt9m032_platform_data *pdata = sensor->pdata;
269− struct aptina_pll pll;
270− u16 reg_val;
271− int ret;
272−
273− pll.ext_clock = pdata->ext_clock;
274− pll.pix_clock = pdata->pix_clock;
275−
276− ret = aptina_pll_calculate(&client->dev, &limits, &pll);
277− if (ret < 0)
278− return ret;
279−
280− sensor->pix_clock = pdata->pix_clock;
281−
282− ret = mt9m032_write(client, MT9M032_PLL_CONFIG1,
283− (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT) |
284− ((pll.n - 1) & MT9M032_PLL_CONFIG1_PREDIV_MASK));
285− if (!ret)
286− ret = mt9m032_write(client, MT9P031_PLL_CONTROL,
287− MT9P031_PLL_CONTROL_PWRON |
288− MT9P031_PLL_CONTROL_USEPLL);
289− if (!ret) /* more reserved, Continuous, Master Mode */
290− ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8000 |
291− MT9M032_READ_MODE1_STROBE_START_EXP |
292− MT9M032_READ_MODE1_STROBE_END_SHUTTER);
293− if (!ret) {
294− reg_val = (pll.p1 == 6 ? MT9M032_FORMATTER1_PLL_P1_6 : 0)
295− | MT9M032_FORMATTER1_PARALLEL | 0x001e; /* 14-bit */
296− ret = mt9m032_write(client, MT9M032_FORMATTER1, reg_val);
297− }
298−
299− return ret;
300−}
301−
302−/* -----------------------------------------------------------------------------
303− * Subdev pad operations
304− */
305−
306−static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev,
307− struct v4l2_subdev_state *sd_state,
308− struct v4l2_subdev_mbus_code_enum *code)
309−{
310− if (code->index != 0)
311− return -EINVAL;
312−
313− code->code = MEDIA_BUS_FMT_Y8_1X8;
314− return 0;
315−}
316−
317−static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev,
318− struct v4l2_subdev_state *sd_state,
319− struct v4l2_subdev_frame_size_enum *fse)
320−{
321− if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8)
322− return -EINVAL;
323−
324− fse->min_width = MT9M032_COLUMN_SIZE_DEF;
325− fse->max_width = MT9M032_COLUMN_SIZE_DEF;
326− fse->min_height = MT9M032_ROW_SIZE_DEF;
327− fse->max_height = MT9M032_ROW_SIZE_DEF;
328−
329− return 0;
330−}
331−
332−/**
333− * __mt9m032_get_pad_crop() - get crop rect
334− * @sensor: pointer to the sensor struct
335− * @sd_state: v4l2_subdev_state for getting the try crop rect from
336− * @which: select try or active crop rect
337− *
338− * Returns a pointer the current active or fh relative try crop rect
339− */
340−static struct v4l2_rect *
341−__mt9m032_get_pad_crop(struct mt9m032 *sensor,
342− struct v4l2_subdev_state *sd_state,
343− enum v4l2_subdev_format_whence which)
344−{
345− switch (which) {
346− case V4L2_SUBDEV_FORMAT_TRY:
347− return v4l2_subdev_get_try_crop(&sensor->subdev, sd_state, 0);
348− case V4L2_SUBDEV_FORMAT_ACTIVE:
349− return &sensor->crop;
350− default:
351− return NULL;
352− }
353−}
354−
355−/**
356− * __mt9m032_get_pad_format() - get format
357− * @sensor: pointer to the sensor struct
358− * @sd_state: v4l2_subdev_state for getting the try format from
359− * @which: select try or active format
360− *
361− * Returns a pointer the current active or fh relative try format
362− */
363−static struct v4l2_mbus_framefmt *
364−__mt9m032_get_pad_format(struct mt9m032 *sensor,
365− struct v4l2_subdev_state *sd_state,
366− enum v4l2_subdev_format_whence which)
367−{
368− switch (which) {
369− case V4L2_SUBDEV_FORMAT_TRY:
370− return v4l2_subdev_get_try_format(&sensor->subdev, sd_state,
371− 0);
372− case V4L2_SUBDEV_FORMAT_ACTIVE:
373− return &sensor->format;
374− default:
375− return NULL;
376− }
377−}
378−
379−static int mt9m032_get_pad_format(struct v4l2_subdev *subdev,
380− struct v4l2_subdev_state *sd_state,
381− struct v4l2_subdev_format *fmt)
382−{
383− struct mt9m032 *sensor = to_mt9m032(subdev);
384−
385− mutex_lock(&sensor->lock);
386− fmt->format = *__mt9m032_get_pad_format(sensor, sd_state, fmt->which);
387− mutex_unlock(&sensor->lock);
388−
389− return 0;
390−}
391−
392−static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
393− struct v4l2_subdev_state *sd_state,
394− struct v4l2_subdev_format *fmt)
395−{
396− struct mt9m032 *sensor = to_mt9m032(subdev);
397− int ret;
398−
399− mutex_lock(&sensor->lock);
400−
401− if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
402− ret = -EBUSY;
403− goto done;
404− }
405−
406− /* Scaling is not supported, the format is thus fixed. */
407− fmt->format = *__mt9m032_get_pad_format(sensor, sd_state, fmt->which);
408− ret = 0;
409−
410−done:
411− mutex_unlock(&sensor->lock);
412− return ret;
413−}
414−
415−static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev,
416− struct v4l2_subdev_state *sd_state,
417− struct v4l2_subdev_selection *sel)
418−{
419− struct mt9m032 *sensor = to_mt9m032(subdev);
420−
421− if (sel->target != V4L2_SEL_TGT_CROP)
422− return -EINVAL;
423−
424− mutex_lock(&sensor->lock);
425− sel->r = *__mt9m032_get_pad_crop(sensor, sd_state, sel->which);
426− mutex_unlock(&sensor->lock);
427−
428− return 0;
429−}
430−
431−static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev,
432− struct v4l2_subdev_state *sd_state,
433− struct v4l2_subdev_selection *sel)
434−{
435− struct mt9m032 *sensor = to_mt9m032(subdev);
436− struct v4l2_mbus_framefmt *format;
437− struct v4l2_rect *__crop;
438− struct v4l2_rect rect;
439− int ret = 0;
440−
441− if (sel->target != V4L2_SEL_TGT_CROP)
442− return -EINVAL;
443−
444− mutex_lock(&sensor->lock);
445−
446− if (sensor->streaming && sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
447− ret = -EBUSY;
448− goto done;
449− }
450−
451− /* Clamp the crop rectangle boundaries and align them to a multiple of 2
452− * pixels to ensure a GRBG Bayer pattern.
453− */
454− rect.left = clamp(ALIGN(sel->r.left, 2), MT9M032_COLUMN_START_MIN,
455− MT9M032_COLUMN_START_MAX);
456− rect.top = clamp(ALIGN(sel->r.top, 2), MT9M032_ROW_START_MIN,
457− MT9M032_ROW_START_MAX);
458− rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
459− MT9M032_COLUMN_SIZE_MIN, MT9M032_COLUMN_SIZE_MAX);
460− rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
461− MT9M032_ROW_SIZE_MIN, MT9M032_ROW_SIZE_MAX);
462−
463− rect.width = min_t(unsigned int, rect.width,
464− MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
465− rect.height = min_t(unsigned int, rect.height,
466− MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);
467−
468− __crop = __mt9m032_get_pad_crop(sensor, sd_state, sel->which);
469−
470− if (rect.width != __crop->width || rect.height != __crop->height) {
471− /* Reset the output image size if the crop rectangle size has
472− * been modified.
473− */
474− format = __mt9m032_get_pad_format(sensor, sd_state,
475− sel->which);
476− format->width = rect.width;
477− format->height = rect.height;
478− }
479−
480− *__crop = rect;
481− sel->r = rect;
482−
483− if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
484− ret = mt9m032_update_geom_timing(sensor);
485−
486−done:
487− mutex_unlock(&sensor->lock);
488− return ret;
489−}
490−
491−static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev,
492− struct v4l2_subdev_frame_interval *fi)
493−{
494− struct mt9m032 *sensor = to_mt9m032(subdev);
495−
496− mutex_lock(&sensor->lock);
497− memset(fi, 0, sizeof(*fi));
498− fi->interval = sensor->frame_interval;
499− mutex_unlock(&sensor->lock);
500−
501− return 0;
502−}
503−
504−static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev,
505− struct v4l2_subdev_frame_interval *fi)
506−{
507− struct mt9m032 *sensor = to_mt9m032(subdev);
508− int ret;
509−
510− mutex_lock(&sensor->lock);
511−
512− if (sensor->streaming) {
513− ret = -EBUSY;
514− goto done;
515− }
516−
517− /* Avoid divisions by 0. */
518− if (fi->interval.denominator == 0)
519− fi->interval.denominator = 1;
520−
521− ret = mt9m032_update_timing(sensor, &fi->interval);
522− if (!ret)
523− sensor->frame_interval = fi->interval;
524−
525−done:
526− mutex_unlock(&sensor->lock);
527− return ret;
528−}
529−
530−static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming)
531−{
532− struct mt9m032 *sensor = to_mt9m032(subdev);
533− int ret;
534−
535− mutex_lock(&sensor->lock);
536− ret = update_formatter2(sensor, streaming);
537− if (!ret)
538− sensor->streaming = streaming;
539− mutex_unlock(&sensor->lock);
540−
541− return ret;
542−}
543−
544−/* -----------------------------------------------------------------------------
545− * V4L2 subdev core operations
546− */
547−
548−#ifdef CONFIG_VIDEO_ADV_DEBUG
549−static int mt9m032_g_register(struct v4l2_subdev *sd,
550− struct v4l2_dbg_register *reg)
551−{
552− struct mt9m032 *sensor = to_mt9m032(sd);
553− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
554− int val;
555−
556− if (reg->reg > 0xff)
557− return -EINVAL;
558−
559− val = mt9m032_read(client, reg->reg);
560− if (val < 0)
561− return -EIO;
562−
563− reg->size = 2;
564− reg->val = val;
565−
566− return 0;
567−}
568−
569−static int mt9m032_s_register(struct v4l2_subdev *sd,
570− const struct v4l2_dbg_register *reg)
571−{
572− struct mt9m032 *sensor = to_mt9m032(sd);
573− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
574−
575− if (reg->reg > 0xff)
576− return -EINVAL;
577−
578− return mt9m032_write(client, reg->reg, reg->val);
579−}
580−#endif
581−
582−/* -----------------------------------------------------------------------------
583− * V4L2 subdev control operations
584− */
585−
586−static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip)
587−{
588− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
589− int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT)
590− | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT)
591− | MT9M032_READ_MODE2_ROW_BLC
592− | 0x0007;
593−
594− return mt9m032_write(client, MT9M032_READ_MODE2, reg_val);
595−}
596−
597−static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val)
598−{
599− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
600− int digital_gain_val; /* in 1/8th (0..127) */
601− int analog_mul; /* 0 or 1 */
602− int analog_gain_val; /* in 1/16th. (0..63) */
603− u16 reg_val;
604−
605− digital_gain_val = 51; /* from setup example */
606−
607− if (val < 63) {
608− analog_mul = 0;
609− analog_gain_val = val;
610− } else {
611− analog_mul = 1;
612− analog_gain_val = val / 2;
613− }
614−
615− /* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */
616− /* overall_gain = a_gain * (1 + digital_gain_val / 8) */
617−
618− reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK)
619− << MT9M032_GAIN_DIGITAL_SHIFT)
620− | ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT)
621− | (analog_gain_val & MT9M032_GAIN_ANALOG_MASK);
622−
623− return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val);
624−}
625−
626−static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl)
627−{
628− if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) {
629− /* round because of multiplier used for values >= 63 */
630− ctrl->val &= ~1;
631− }
632−
633− return 0;
634−}
635−
636−static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
637−{
638− struct mt9m032 *sensor =
639− container_of(ctrl->handler, struct mt9m032, ctrls);
640− struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
641− int ret;
642−
643− switch (ctrl->id) {
644− case V4L2_CID_GAIN:
645− return mt9m032_set_gain(sensor, ctrl->val);
646−
647− case V4L2_CID_HFLIP:
648− /* case V4L2_CID_VFLIP: -- In the same cluster */
649− return update_read_mode2(sensor, sensor->vflip->val,
650− sensor->hflip->val);
651−
652− case V4L2_CID_EXPOSURE:
653− ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH,
654− (ctrl->val >> 16) & 0xffff);
655− if (ret < 0)
656− return ret;
657−
658− return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW,
659− ctrl->val & 0xffff);
660− }
661−
662− return 0;
663−}
664−
665−static const struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
666− .s_ctrl = mt9m032_set_ctrl,
667− .try_ctrl = mt9m032_try_ctrl,
668−};
669−
670−/* -------------------------------------------------------------------------- */
671−
672−static const struct v4l2_subdev_core_ops mt9m032_core_ops = {
673−#ifdef CONFIG_VIDEO_ADV_DEBUG
674− .g_register = mt9m032_g_register,
675− .s_register = mt9m032_s_register,
676−#endif
677−};
678−
679−static const struct v4l2_subdev_video_ops mt9m032_video_ops = {
680− .s_stream = mt9m032_s_stream,
681− .g_frame_interval = mt9m032_get_frame_interval,
682− .s_frame_interval = mt9m032_set_frame_interval,
683−};
684−
685−static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = {
686− .enum_mbus_code = mt9m032_enum_mbus_code,
687− .enum_frame_size = mt9m032_enum_frame_size,
688− .get_fmt = mt9m032_get_pad_format,
689− .set_fmt = mt9m032_set_pad_format,
690− .set_selection = mt9m032_set_pad_selection,
691− .get_selection = mt9m032_get_pad_selection,
692−};
693−
694−static const struct v4l2_subdev_ops mt9m032_ops = {
695− .core = &mt9m032_core_ops,
696− .video = &mt9m032_video_ops,
697− .pad = &mt9m032_pad_ops,
698−};
699−
700−/* -----------------------------------------------------------------------------
701− * Driver initialization and probing
702− */
703−
704−static int mt9m032_probe(struct i2c_client *client)
705−{
706− struct mt9m032_platform_data *pdata = client->dev.platform_data;
707− struct i2c_adapter *adapter = client->adapter;
708− struct mt9m032 *sensor;
709− int chip_version;
710− int ret;
711−
712− if (pdata == NULL) {
713− dev_err(&client->dev, "No platform data\n");
714− return -EINVAL;
715− }
716−
717− if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
718− dev_warn(&client->dev,
719− "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
720− return -EIO;
721− }
722−
723− if (!client->dev.platform_data)
724− return -ENODEV;
725−
726− sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
727− if (sensor == NULL)
728− return -ENOMEM;
729−
730− mutex_init(&sensor->lock);
731−
732− sensor->pdata = pdata;
733−
734− v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
735− sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
736−
737− chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION);
738− if (chip_version != MT9M032_CHIP_VERSION_VALUE) {
739− dev_err(&client->dev, "MT9M032 not detected, wrong version "
740− "0x%04x\n", chip_version);
741− ret = -ENODEV;
742− goto error_sensor;
743− }
744−
745− dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n",
746− client->addr);
747−
748− sensor->frame_interval.numerator = 1;
749− sensor->frame_interval.denominator = 30;
750−
751− sensor->crop.left = MT9M032_COLUMN_START_DEF;
752− sensor->crop.top = MT9M032_ROW_START_DEF;
753− sensor->crop.width = MT9M032_COLUMN_SIZE_DEF;
754− sensor->crop.height = MT9M032_ROW_SIZE_DEF;
755−
756− sensor->format.width = sensor->crop.width;
757− sensor->format.height = sensor->crop.height;
758− sensor->format.code = MEDIA_BUS_FMT_Y8_1X8;
759− sensor->format.field = V4L2_FIELD_NONE;
760− sensor->format.colorspace = V4L2_COLORSPACE_SRGB;
761−
762− v4l2_ctrl_handler_init(&sensor->ctrls, 5);
763−
764− v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
765− V4L2_CID_GAIN, 0, 127, 1, 64);
766−
767− sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls,
768− &mt9m032_ctrl_ops,
769− V4L2_CID_HFLIP, 0, 1, 1, 0);
770− sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls,
771− &mt9m032_ctrl_ops,
772− V4L2_CID_VFLIP, 0, 1, 1, 0);
773−
774− v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
775− V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
776− MT9M032_SHUTTER_WIDTH_MAX, 1,
777− MT9M032_SHUTTER_WIDTH_DEF);
778− v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
779− V4L2_CID_PIXEL_RATE, pdata->pix_clock,
780− pdata->pix_clock, 1, pdata->pix_clock);
781−
782− if (sensor->ctrls.error) {
783− ret = sensor->ctrls.error;
784− dev_err(&client->dev, "control initialization error %d\n", ret);
785− goto error_ctrl;
786− }
787−
788− v4l2_ctrl_cluster(2, &sensor->hflip);
789−
790− sensor->subdev.ctrl_handler = &sensor->ctrls;
791− sensor->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
792− sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
793− ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad);
794− if (ret < 0)
795− goto error_ctrl;
796−
797− ret = mt9m032_write(client, MT9M032_RESET, 1); /* reset on */
798− if (ret < 0)
799− goto error_entity;
800− ret = mt9m032_write(client, MT9M032_RESET, 0); /* reset off */
801− if (ret < 0)
802− goto error_entity;
803−
804− ret = mt9m032_setup_pll(sensor);
805− if (ret < 0)
806− goto error_entity;
807− usleep_range(10000, 11000);
808−
809− ret = v4l2_ctrl_handler_setup(&sensor->ctrls);
810− if (ret < 0)
811− goto error_entity;
812−
813− /* SIZE */
814− ret = mt9m032_update_geom_timing(sensor);
815− if (ret < 0)
816− goto error_entity;
817−
818− ret = mt9m032_write(client, 0x41, 0x0000); /* reserved !!! */
819− if (ret < 0)
820− goto error_entity;
821− ret = mt9m032_write(client, 0x42, 0x0003); /* reserved !!! */
822− if (ret < 0)
823− goto error_entity;
824− ret = mt9m032_write(client, 0x43, 0x0003); /* reserved !!! */
825− if (ret < 0)
826− goto error_entity;
827− ret = mt9m032_write(client, 0x7f, 0x0000); /* reserved !!! */
828− if (ret < 0)
829− goto error_entity;
830− if (sensor->pdata->invert_pixclock) {
831− ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL,
832− MT9M032_PIX_CLK_CTRL_INV_PIXCLK);
833− if (ret < 0)
834− goto error_entity;
835− }
836−
837− ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */
838− if (ret < 0)
839− goto error_entity;
840− msleep(100);
841− ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */
842− if (ret < 0)
843− goto error_entity;
844− msleep(100);
845− ret = update_formatter2(sensor, false);
846− if (ret < 0)
847− goto error_entity;
848−
849− return ret;
850−
851−error_entity:
852− media_entity_cleanup(&sensor->subdev.entity);
853−error_ctrl:
854− v4l2_ctrl_handler_free(&sensor->ctrls);
855−error_sensor:
856− mutex_destroy(&sensor->lock);
857− return ret;
858−}
859−
860−static void mt9m032_remove(struct i2c_client *client)
861−{
862− struct v4l2_subdev *subdev = i2c_get_clientdata(client);
863− struct mt9m032 *sensor = to_mt9m032(subdev);
864−
865− v4l2_device_unregister_subdev(subdev);
866− v4l2_ctrl_handler_free(&sensor->ctrls);
867− media_entity_cleanup(&subdev->entity);
868− mutex_destroy(&sensor->lock);
869−}
870−
871−static const struct i2c_device_id mt9m032_id_table[] = {
872− { MT9M032_NAME, 0 },
873− { }
874−};
875−
876−MODULE_DEVICE_TABLE(i2c, mt9m032_id_table);
877−
878−static struct i2c_driver mt9m032_i2c_driver = {
879− .driver = {
880− .name = MT9M032_NAME,
881− },
882− .probe_new = mt9m032_probe,
883− .remove = mt9m032_remove,
884− .id_table = mt9m032_id_table,
885−};
886−
887−module_i2c_driver(mt9m032_i2c_driver);
888−
889−MODULE_AUTHOR("Martin Hostettler <martin@neutronstar.dyndns.org>");
890−MODULE_DESCRIPTION("MT9M032 camera sensor driver");
891−MODULE_LICENSE("GPL v2");
drivers/media/i2c/mt9t001.c+0−992
@@ -1,992 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/*
3− * Driver for MT9T001 CMOS Image Sensor from Aptina (Micron)
4− *
5− * Copyright (C) 2010-2011, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
6− *
7− * Based on the MT9M001 driver,
8− *
9− * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
10− */
11−
12−#include <linux/clk.h>
13−#include <linux/i2c.h>
14−#include <linux/log2.h>
15−#include <linux/module.h>
16−#include <linux/regulator/consumer.h>
17−#include <linux/slab.h>
18−#include <linux/videodev2.h>
19−#include <linux/v4l2-mediabus.h>
20−
21−#include <media/i2c/mt9t001.h>
22−#include <media/v4l2-ctrls.h>
23−#include <media/v4l2-device.h>
24−#include <media/v4l2-subdev.h>
25−
26−#define MT9T001_PIXEL_ARRAY_HEIGHT 1568
27−#define MT9T001_PIXEL_ARRAY_WIDTH 2112
28−
29−#define MT9T001_CHIP_VERSION 0x00
30−#define MT9T001_CHIP_ID 0x1621
31−#define MT9T001_ROW_START 0x01
32−#define MT9T001_ROW_START_MIN 0
33−#define MT9T001_ROW_START_DEF 20
34−#define MT9T001_ROW_START_MAX 1534
35−#define MT9T001_COLUMN_START 0x02
36−#define MT9T001_COLUMN_START_MIN 0
37−#define MT9T001_COLUMN_START_DEF 32
38−#define MT9T001_COLUMN_START_MAX 2046
39−#define MT9T001_WINDOW_HEIGHT 0x03
40−#define MT9T001_WINDOW_HEIGHT_MIN 1
41−#define MT9T001_WINDOW_HEIGHT_DEF 1535
42−#define MT9T001_WINDOW_HEIGHT_MAX 1567
43−#define MT9T001_WINDOW_WIDTH 0x04
44−#define MT9T001_WINDOW_WIDTH_MIN 1
45−#define MT9T001_WINDOW_WIDTH_DEF 2047
46−#define MT9T001_WINDOW_WIDTH_MAX 2111
47−#define MT9T001_HORIZONTAL_BLANKING 0x05
48−#define MT9T001_HORIZONTAL_BLANKING_MIN 21
49−#define MT9T001_HORIZONTAL_BLANKING_MAX 1023
50−#define MT9T001_VERTICAL_BLANKING 0x06
51−#define MT9T001_VERTICAL_BLANKING_MIN 3
52−#define MT9T001_VERTICAL_BLANKING_MAX 1023
53−#define MT9T001_OUTPUT_CONTROL 0x07
54−#define MT9T001_OUTPUT_CONTROL_SYNC (1 << 0)
55−#define MT9T001_OUTPUT_CONTROL_CHIP_ENABLE (1 << 1)
56−#define MT9T001_OUTPUT_CONTROL_TEST_DATA (1 << 6)
57−#define MT9T001_OUTPUT_CONTROL_DEF 0x0002
58−#define MT9T001_SHUTTER_WIDTH_HIGH 0x08
59−#define MT9T001_SHUTTER_WIDTH_LOW 0x09
60−#define MT9T001_SHUTTER_WIDTH_MIN 1
61−#define MT9T001_SHUTTER_WIDTH_DEF 1561
62−#define MT9T001_SHUTTER_WIDTH_MAX (1024 * 1024)
63−#define MT9T001_PIXEL_CLOCK 0x0a
64−#define MT9T001_PIXEL_CLOCK_INVERT (1 << 15)
65−#define MT9T001_PIXEL_CLOCK_SHIFT_MASK (7 << 8)
66−#define MT9T001_PIXEL_CLOCK_SHIFT_SHIFT 8
67−#define MT9T001_PIXEL_CLOCK_DIVIDE_MASK (0x7f << 0)
68−#define MT9T001_FRAME_RESTART 0x0b
69−#define MT9T001_SHUTTER_DELAY 0x0c
70−#define MT9T001_SHUTTER_DELAY_MAX 2047
71−#define MT9T001_RESET 0x0d
72−#define MT9T001_READ_MODE1 0x1e
73−#define MT9T001_READ_MODE_SNAPSHOT (1 << 8)
74−#define MT9T001_READ_MODE_STROBE_ENABLE (1 << 9)
75−#define MT9T001_READ_MODE_STROBE_WIDTH (1 << 10)
76−#define MT9T001_READ_MODE_STROBE_OVERRIDE (1 << 11)
77−#define MT9T001_READ_MODE2 0x20
78−#define MT9T001_READ_MODE_BAD_FRAMES (1 << 0)
79−#define MT9T001_READ_MODE_LINE_VALID_CONTINUOUS (1 << 9)
80−#define MT9T001_READ_MODE_LINE_VALID_FRAME (1 << 10)
81−#define MT9T001_READ_MODE3 0x21
82−#define MT9T001_READ_MODE_GLOBAL_RESET (1 << 0)
83−#define MT9T001_READ_MODE_GHST_CTL (1 << 1)
84−#define MT9T001_ROW_ADDRESS_MODE 0x22
85−#define MT9T001_ROW_SKIP_MASK (7 << 0)
86−#define MT9T001_ROW_BIN_MASK (3 << 3)
87−#define MT9T001_ROW_BIN_SHIFT 3
88−#define MT9T001_COLUMN_ADDRESS_MODE 0x23
89−#define MT9T001_COLUMN_SKIP_MASK (7 << 0)
90−#define MT9T001_COLUMN_BIN_MASK (3 << 3)
91−#define MT9T001_COLUMN_BIN_SHIFT 3
92−#define MT9T001_GREEN1_GAIN 0x2b
93−#define MT9T001_BLUE_GAIN 0x2c
94−#define MT9T001_RED_GAIN 0x2d
95−#define MT9T001_GREEN2_GAIN 0x2e
96−#define MT9T001_TEST_DATA 0x32
97−#define MT9T001_GLOBAL_GAIN 0x35
98−#define MT9T001_GLOBAL_GAIN_MIN 8
99−#define MT9T001_GLOBAL_GAIN_MAX 1024
100−#define MT9T001_BLACK_LEVEL 0x49
101−#define MT9T001_ROW_BLACK_DEFAULT_OFFSET 0x4b
102−#define MT9T001_BLC_DELTA_THRESHOLDS 0x5d
103−#define MT9T001_CAL_THRESHOLDS 0x5f
104−#define MT9T001_GREEN1_OFFSET 0x60
105−#define MT9T001_GREEN2_OFFSET 0x61
106−#define MT9T001_BLACK_LEVEL_CALIBRATION 0x62
107−#define MT9T001_BLACK_LEVEL_OVERRIDE (1 << 0)
108−#define MT9T001_BLACK_LEVEL_DISABLE_OFFSET (1 << 1)
109−#define MT9T001_BLACK_LEVEL_RECALCULATE (1 << 12)
110−#define MT9T001_BLACK_LEVEL_LOCK_RED_BLUE (1 << 13)
111−#define MT9T001_BLACK_LEVEL_LOCK_GREEN (1 << 14)
112−#define MT9T001_RED_OFFSET 0x63
113−#define MT9T001_BLUE_OFFSET 0x64
114−
115−struct mt9t001 {
116− struct v4l2_subdev subdev;
117− struct media_pad pad;
118−
119− struct clk *clk;
120− struct regulator_bulk_data regulators[2];
121−
122− struct mutex power_lock; /* lock to protect power_count */
123− int power_count;
124−
125− struct v4l2_mbus_framefmt format;
126− struct v4l2_rect crop;
127−
128− struct v4l2_ctrl_handler ctrls;
129− struct v4l2_ctrl *gains[4];
130−
131− u16 output_control;
132− u16 black_level;
133−};
134−
135−static inline struct mt9t001 *to_mt9t001(struct v4l2_subdev *sd)
136−{
137− return container_of(sd, struct mt9t001, subdev);
138−}
139−
140−static int mt9t001_read(struct i2c_client *client, u8 reg)
141−{
142− return i2c_smbus_read_word_swapped(client, reg);
143−}
144−
145−static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data)
146−{
147− return i2c_smbus_write_word_swapped(client, reg, data);
148−}
149−
150−static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
151− u16 set)
152−{
153− struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
154− u16 value = (mt9t001->output_control & ~clear) | set;
155− int ret;
156−
157− if (value == mt9t001->output_control)
158− return 0;
159−
160− ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, value);
161− if (ret < 0)
162− return ret;
163−
164− mt9t001->output_control = value;
165− return 0;
166−}
167−
168−static int mt9t001_reset(struct mt9t001 *mt9t001)
169−{
170− struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
171− int ret;
172−
173− /* Reset the chip and stop data read out */
174− ret = mt9t001_write(client, MT9T001_RESET, 1);
175− if (ret < 0)
176− return ret;
177−
178− ret = mt9t001_write(client, MT9T001_RESET, 0);
179− if (ret < 0)
180− return ret;
181−
182− mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
183−
184− return mt9t001_set_output_control(mt9t001,
185− MT9T001_OUTPUT_CONTROL_CHIP_ENABLE,
186− 0);
187−}
188−
189−static int mt9t001_power_on(struct mt9t001 *mt9t001)
190−{
191− int ret;
192−
193− /* Bring up the supplies */
194− ret = regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
195− mt9t001->regulators);
196− if (ret < 0)
197− return ret;
198−
199− /* Enable clock */
200− ret = clk_prepare_enable(mt9t001->clk);
201− if (ret < 0)
202− regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
203− mt9t001->regulators);
204−
205− return ret;
206−}
207−
208−static void mt9t001_power_off(struct mt9t001 *mt9t001)
209−{
210− regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
211− mt9t001->regulators);
212−
213− clk_disable_unprepare(mt9t001->clk);
214−}
215−
216−static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on)
217−{
218− struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
219− int ret;
220−
221− if (!on) {
222− mt9t001_power_off(mt9t001);
223− return 0;
224− }
225−
226− ret = mt9t001_power_on(mt9t001);
227− if (ret < 0)
228− return ret;
229−
230− ret = mt9t001_reset(mt9t001);
231− if (ret < 0) {
232− dev_err(&client->dev, "Failed to reset the camera\n");
233− goto e_power;
234− }
235−
236− ret = v4l2_ctrl_handler_setup(&mt9t001->ctrls);
237− if (ret < 0) {
238− dev_err(&client->dev, "Failed to set up control handlers\n");
239− goto e_power;
240− }
241−
242− return 0;
243−
244−e_power:
245− mt9t001_power_off(mt9t001);
246−
247− return ret;
248−}
249−
250−/* -----------------------------------------------------------------------------
251− * V4L2 subdev video operations
252− */
253−
254−static struct v4l2_mbus_framefmt *
255−__mt9t001_get_pad_format(struct mt9t001 *mt9t001,
256− struct v4l2_subdev_state *sd_state,
257− unsigned int pad, enum v4l2_subdev_format_whence which)
258−{
259− switch (which) {
260− case V4L2_SUBDEV_FORMAT_TRY:
261− return v4l2_subdev_get_try_format(&mt9t001->subdev, sd_state,
262− pad);
263− case V4L2_SUBDEV_FORMAT_ACTIVE:
264− return &mt9t001->format;
265− default:
266− return NULL;
267− }
268−}
269−
270−static struct v4l2_rect *
271−__mt9t001_get_pad_crop(struct mt9t001 *mt9t001,
272− struct v4l2_subdev_state *sd_state,
273− unsigned int pad, enum v4l2_subdev_format_whence which)
274−{
275− switch (which) {
276− case V4L2_SUBDEV_FORMAT_TRY:
277− return v4l2_subdev_get_try_crop(&mt9t001->subdev, sd_state,
278− pad);
279− case V4L2_SUBDEV_FORMAT_ACTIVE:
280− return &mt9t001->crop;
281− default:
282− return NULL;
283− }
284−}
285−
286−static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
287−{
288− const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE;
289− struct i2c_client *client = v4l2_get_subdevdata(subdev);
290− struct mt9t001_platform_data *pdata = client->dev.platform_data;
291− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
292− struct v4l2_mbus_framefmt *format = &mt9t001->format;
293− struct v4l2_rect *crop = &mt9t001->crop;
294− unsigned int hratio;
295− unsigned int vratio;
296− int ret;
297−
298− if (!enable)
299− return mt9t001_set_output_control(mt9t001, mode, 0);
300−
301− /* Configure the pixel clock polarity */
302− if (pdata->clk_pol) {
303− ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
304− MT9T001_PIXEL_CLOCK_INVERT);
305− if (ret < 0)
306− return ret;
307− }
308−
309− /* Configure the window size and row/column bin */
310− hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
311− vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
312−
313− ret = mt9t001_write(client, MT9T001_ROW_ADDRESS_MODE, hratio - 1);
314− if (ret < 0)
315− return ret;
316−
317− ret = mt9t001_write(client, MT9T001_COLUMN_ADDRESS_MODE, vratio - 1);
318− if (ret < 0)
319− return ret;
320−
321− ret = mt9t001_write(client, MT9T001_COLUMN_START, crop->left);
322− if (ret < 0)
323− return ret;
324−
325− ret = mt9t001_write(client, MT9T001_ROW_START, crop->top);
326− if (ret < 0)
327− return ret;
328−
329− ret = mt9t001_write(client, MT9T001_WINDOW_WIDTH, crop->width - 1);
330− if (ret < 0)
331− return ret;
332−
333− ret = mt9t001_write(client, MT9T001_WINDOW_HEIGHT, crop->height - 1);
334− if (ret < 0)
335− return ret;
336−
337− /* Switch to master "normal" mode */
338− return mt9t001_set_output_control(mt9t001, 0, mode);
339−}
340−
341−static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev,
342− struct v4l2_subdev_state *sd_state,
343− struct v4l2_subdev_mbus_code_enum *code)
344−{
345− if (code->index > 0)
346− return -EINVAL;
347−
348− code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
349− return 0;
350−}
351−
352−static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev,
353− struct v4l2_subdev_state *sd_state,
354− struct v4l2_subdev_frame_size_enum *fse)
355−{
356− if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
357− return -EINVAL;
358−
359− fse->min_width = (MT9T001_WINDOW_WIDTH_DEF + 1) / fse->index;
360− fse->max_width = fse->min_width;
361− fse->min_height = (MT9T001_WINDOW_HEIGHT_DEF + 1) / fse->index;
362− fse->max_height = fse->min_height;
363−
364− return 0;
365−}
366−
367−static int mt9t001_get_format(struct v4l2_subdev *subdev,
368− struct v4l2_subdev_state *sd_state,
369− struct v4l2_subdev_format *format)
370−{
371− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
372−
373− format->format = *__mt9t001_get_pad_format(mt9t001, sd_state,
374− format->pad,
375− format->which);
376− return 0;
377−}
378−
379−static int mt9t001_set_format(struct v4l2_subdev *subdev,
380− struct v4l2_subdev_state *sd_state,
381− struct v4l2_subdev_format *format)
382−{
383− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
384− struct v4l2_mbus_framefmt *__format;
385− struct v4l2_rect *__crop;
386− unsigned int width;
387− unsigned int height;
388− unsigned int hratio;
389− unsigned int vratio;
390−
391− __crop = __mt9t001_get_pad_crop(mt9t001, sd_state, format->pad,
392− format->which);
393−
394− /* Clamp the width and height to avoid dividing by zero. */
395− width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
396− max_t(unsigned int, __crop->width / 8,
397− MT9T001_WINDOW_HEIGHT_MIN + 1),
398− __crop->width);
399− height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
400− max_t(unsigned int, __crop->height / 8,
401− MT9T001_WINDOW_HEIGHT_MIN + 1),
402− __crop->height);
403−
404− hratio = DIV_ROUND_CLOSEST(__crop->width, width);
405− vratio = DIV_ROUND_CLOSEST(__crop->height, height);
406−
407− __format = __mt9t001_get_pad_format(mt9t001, sd_state, format->pad,
408− format->which);
409− __format->width = __crop->width / hratio;
410− __format->height = __crop->height / vratio;
411−
412− format->format = *__format;
413−
414− return 0;
415−}
416−
417−static int mt9t001_get_selection(struct v4l2_subdev *subdev,
418− struct v4l2_subdev_state *sd_state,
419− struct v4l2_subdev_selection *sel)
420−{
421− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
422−
423− if (sel->target != V4L2_SEL_TGT_CROP)
424− return -EINVAL;
425−
426− sel->r = *__mt9t001_get_pad_crop(mt9t001, sd_state, sel->pad,
427− sel->which);
428− return 0;
429−}
430−
431−static int mt9t001_set_selection(struct v4l2_subdev *subdev,
432− struct v4l2_subdev_state *sd_state,
433− struct v4l2_subdev_selection *sel)
434−{
435− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
436− struct v4l2_mbus_framefmt *__format;
437− struct v4l2_rect *__crop;
438− struct v4l2_rect rect;
439−
440− if (sel->target != V4L2_SEL_TGT_CROP)
441− return -EINVAL;
442−
443− /* Clamp the crop rectangle boundaries and align them to a multiple of 2
444− * pixels.
445− */
446− rect.left = clamp(ALIGN(sel->r.left, 2),
447− MT9T001_COLUMN_START_MIN,
448− MT9T001_COLUMN_START_MAX);
449− rect.top = clamp(ALIGN(sel->r.top, 2),
450− MT9T001_ROW_START_MIN,
451− MT9T001_ROW_START_MAX);
452− rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
453− MT9T001_WINDOW_WIDTH_MIN + 1,
454− MT9T001_WINDOW_WIDTH_MAX + 1);
455− rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
456− MT9T001_WINDOW_HEIGHT_MIN + 1,
457− MT9T001_WINDOW_HEIGHT_MAX + 1);
458−
459− rect.width = min_t(unsigned int, rect.width,
460− MT9T001_PIXEL_ARRAY_WIDTH - rect.left);
461− rect.height = min_t(unsigned int, rect.height,
462− MT9T001_PIXEL_ARRAY_HEIGHT - rect.top);
463−
464− __crop = __mt9t001_get_pad_crop(mt9t001, sd_state, sel->pad,
465− sel->which);
466−
467− if (rect.width != __crop->width || rect.height != __crop->height) {
468− /* Reset the output image size if the crop rectangle size has
469− * been modified.
470− */
471− __format = __mt9t001_get_pad_format(mt9t001, sd_state,
472− sel->pad,
473− sel->which);
474− __format->width = rect.width;
475− __format->height = rect.height;
476− }
477−
478− *__crop = rect;
479− sel->r = rect;
480−
481− return 0;
482−}
483−
484−/* -----------------------------------------------------------------------------
485− * V4L2 subdev control operations
486− */
487−
488−#define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001)
489−#define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002)
490−#define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003)
491−#define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004)
492−
493−#define V4L2_CID_GAIN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1001)
494−#define V4L2_CID_GAIN_GREEN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1002)
495−#define V4L2_CID_GAIN_GREEN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1003)
496−#define V4L2_CID_GAIN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1004)
497−
498−static u16 mt9t001_gain_value(s32 *gain)
499−{
500− /* Gain is controlled by 2 analog stages and a digital stage. Valid
501− * values for the 3 stages are
502− *
503− * Stage Min Max Step
504− * ------------------------------------------
505− * First analog stage x1 x2 1
506− * Second analog stage x1 x4 0.125
507− * Digital stage x1 x16 0.125
508− *
509− * To minimize noise, the gain stages should be used in the second
510− * analog stage, first analog stage, digital stage order. Gain from a
511− * previous stage should be pushed to its maximum value before the next
512− * stage is used.
513− */
514− if (*gain <= 32)
515− return *gain;
516−
517− if (*gain <= 64) {
518− *gain &= ~1;
519− return (1 << 6) | (*gain >> 1);
520− }
521−
522− *gain &= ~7;
523− return ((*gain - 64) << 5) | (1 << 6) | 32;
524−}
525−
526−static int mt9t001_ctrl_freeze(struct mt9t001 *mt9t001, bool freeze)
527−{
528− return mt9t001_set_output_control(mt9t001,
529− freeze ? 0 : MT9T001_OUTPUT_CONTROL_SYNC,
530− freeze ? MT9T001_OUTPUT_CONTROL_SYNC : 0);
531−}
532−
533−static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl)
534−{
535− static const u8 gains[4] = {
536− MT9T001_RED_GAIN, MT9T001_GREEN1_GAIN,
537− MT9T001_GREEN2_GAIN, MT9T001_BLUE_GAIN
538− };
539−
540− struct mt9t001 *mt9t001 =
541− container_of(ctrl->handler, struct mt9t001, ctrls);
542− struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
543− unsigned int count;
544− unsigned int i;
545− u16 value;
546− int ret;
547−
548− switch (ctrl->id) {
549− case V4L2_CID_GAIN_RED:
550− case V4L2_CID_GAIN_GREEN_RED:
551− case V4L2_CID_GAIN_GREEN_BLUE:
552− case V4L2_CID_GAIN_BLUE:
553−
554− /* Disable control updates if more than one control has changed
555− * in the cluster.
556− */
557− for (i = 0, count = 0; i < 4; ++i) {
558− struct v4l2_ctrl *gain = mt9t001->gains[i];
559−
560− if (gain->val != gain->cur.val)
561− count++;
562− }
563−
564− if (count > 1) {
565− ret = mt9t001_ctrl_freeze(mt9t001, true);
566− if (ret < 0)
567− return ret;
568− }
569−
570− /* Update the gain controls. */
571− for (i = 0; i < 4; ++i) {
572− struct v4l2_ctrl *gain = mt9t001->gains[i];
573−
574− if (gain->val == gain->cur.val)
575− continue;
576−
577− value = mt9t001_gain_value(&gain->val);
578− ret = mt9t001_write(client, gains[i], value);
579− if (ret < 0) {
580− mt9t001_ctrl_freeze(mt9t001, false);
581− return ret;
582− }
583− }
584−
585− /* Enable control updates. */
586− if (count > 1) {
587− ret = mt9t001_ctrl_freeze(mt9t001, false);
588− if (ret < 0)
589− return ret;
590− }
591−
592− break;
593−
594− case V4L2_CID_EXPOSURE:
595− ret = mt9t001_write(client, MT9T001_SHUTTER_WIDTH_LOW,
596− ctrl->val & 0xffff);
597− if (ret < 0)
598− return ret;
599−
600− return mt9t001_write(client, MT9T001_SHUTTER_WIDTH_HIGH,
601− ctrl->val >> 16);
602−
603− case V4L2_CID_TEST_PATTERN:
604− return mt9t001_set_output_control(mt9t001,
605− ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA,
606− ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0);
607−
608− case V4L2_CID_TEST_PATTERN_COLOR:
609− return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2);
610−
611− case V4L2_CID_BLACK_LEVEL_AUTO:
612− value = ctrl->val ? 0 : MT9T001_BLACK_LEVEL_OVERRIDE;
613− ret = mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION,
614− value);
615− if (ret < 0)
616− return ret;
617−
618− mt9t001->black_level = value;
619− break;
620−
621− case V4L2_CID_BLACK_LEVEL_OFFSET:
622− ret = mt9t001_write(client, MT9T001_GREEN1_OFFSET, ctrl->val);
623− if (ret < 0)
624− return ret;
625−
626− ret = mt9t001_write(client, MT9T001_GREEN2_OFFSET, ctrl->val);
627− if (ret < 0)
628− return ret;
629−
630− ret = mt9t001_write(client, MT9T001_RED_OFFSET, ctrl->val);
631− if (ret < 0)
632− return ret;
633−
634− return mt9t001_write(client, MT9T001_BLUE_OFFSET, ctrl->val);
635−
636− case V4L2_CID_BLACK_LEVEL_CALIBRATE:
637− return mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION,
638− MT9T001_BLACK_LEVEL_RECALCULATE |
639− mt9t001->black_level);
640− }
641−
642− return 0;
643−}
644−
645−static const struct v4l2_ctrl_ops mt9t001_ctrl_ops = {
646− .s_ctrl = mt9t001_s_ctrl,
647−};
648−
649−static const char * const mt9t001_test_pattern_menu[] = {
650− "Disabled",
651− "Enabled",
652−};
653−
654−static const struct v4l2_ctrl_config mt9t001_ctrls[] = {
655− {
656− .ops = &mt9t001_ctrl_ops,
657− .id = V4L2_CID_TEST_PATTERN_COLOR,
658− .type = V4L2_CTRL_TYPE_INTEGER,
659− .name = "Test Pattern Color",
660− .min = 0,
661− .max = 1023,
662− .step = 1,
663− .def = 0,
664− .flags = 0,
665− }, {
666− .ops = &mt9t001_ctrl_ops,
667− .id = V4L2_CID_BLACK_LEVEL_AUTO,
668− .type = V4L2_CTRL_TYPE_BOOLEAN,
669− .name = "Black Level, Auto",
670− .min = 0,
671− .max = 1,
672− .step = 1,
673− .def = 1,
674− .flags = 0,
675− }, {
676− .ops = &mt9t001_ctrl_ops,
677− .id = V4L2_CID_BLACK_LEVEL_OFFSET,
678− .type = V4L2_CTRL_TYPE_INTEGER,
679− .name = "Black Level, Offset",
680− .min = -256,
681− .max = 255,
682− .step = 1,
683− .def = 32,
684− .flags = 0,
685− }, {
686− .ops = &mt9t001_ctrl_ops,
687− .id = V4L2_CID_BLACK_LEVEL_CALIBRATE,
688− .type = V4L2_CTRL_TYPE_BUTTON,
689− .name = "Black Level, Calibrate",
690− .min = 0,
691− .max = 0,
692− .step = 0,
693− .def = 0,
694− .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
695− },
696−};
697−
698−static const struct v4l2_ctrl_config mt9t001_gains[] = {
699− {
700− .ops = &mt9t001_ctrl_ops,
701− .id = V4L2_CID_GAIN_RED,
702− .type = V4L2_CTRL_TYPE_INTEGER,
703− .name = "Gain, Red",
704− .min = MT9T001_GLOBAL_GAIN_MIN,
705− .max = MT9T001_GLOBAL_GAIN_MAX,
706− .step = 1,
707− .def = MT9T001_GLOBAL_GAIN_MIN,
708− .flags = 0,
709− }, {
710− .ops = &mt9t001_ctrl_ops,
711− .id = V4L2_CID_GAIN_GREEN_RED,
712− .type = V4L2_CTRL_TYPE_INTEGER,
713− .name = "Gain, Green (R)",
714− .min = MT9T001_GLOBAL_GAIN_MIN,
715− .max = MT9T001_GLOBAL_GAIN_MAX,
716− .step = 1,
717− .def = MT9T001_GLOBAL_GAIN_MIN,
718− .flags = 0,
719− }, {
720− .ops = &mt9t001_ctrl_ops,
721− .id = V4L2_CID_GAIN_GREEN_BLUE,
722− .type = V4L2_CTRL_TYPE_INTEGER,
723− .name = "Gain, Green (B)",
724− .min = MT9T001_GLOBAL_GAIN_MIN,
725− .max = MT9T001_GLOBAL_GAIN_MAX,
726− .step = 1,
727− .def = MT9T001_GLOBAL_GAIN_MIN,
728− .flags = 0,
729− }, {
730− .ops = &mt9t001_ctrl_ops,
731− .id = V4L2_CID_GAIN_BLUE,
732− .type = V4L2_CTRL_TYPE_INTEGER,
733− .name = "Gain, Blue",
734− .min = MT9T001_GLOBAL_GAIN_MIN,
735− .max = MT9T001_GLOBAL_GAIN_MAX,
736− .step = 1,
737− .def = MT9T001_GLOBAL_GAIN_MIN,
738− .flags = 0,
739− },
740−};
741−
742−/* -----------------------------------------------------------------------------
743− * V4L2 subdev core operations
744− */
745−
746−static int mt9t001_set_power(struct v4l2_subdev *subdev, int on)
747−{
748− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
749− int ret = 0;
750−
751− mutex_lock(&mt9t001->power_lock);
752−
753− /* If the power count is modified from 0 to != 0 or from != 0 to 0,
754− * update the power state.
755− */
756− if (mt9t001->power_count == !on) {
757− ret = __mt9t001_set_power(mt9t001, !!on);
758− if (ret < 0)
759− goto out;
760− }
761−
762− /* Update the power count. */
763− mt9t001->power_count += on ? 1 : -1;
764− WARN_ON(mt9t001->power_count < 0);
765−
766−out:
767− mutex_unlock(&mt9t001->power_lock);
768− return ret;
769−}
770−
771−/* -----------------------------------------------------------------------------
772− * V4L2 subdev internal operations
773− */
774−
775−static int mt9t001_registered(struct v4l2_subdev *subdev)
776−{
777− struct i2c_client *client = v4l2_get_subdevdata(subdev);
778− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
779− s32 data;
780− int ret;
781−
782− ret = mt9t001_power_on(mt9t001);
783− if (ret < 0) {
784− dev_err(&client->dev, "MT9T001 power up failed\n");
785− return ret;
786− }
787−
788− /* Read out the chip version register */
789− data = mt9t001_read(client, MT9T001_CHIP_VERSION);
790− mt9t001_power_off(mt9t001);
791−
792− if (data != MT9T001_CHIP_ID) {
793− dev_err(&client->dev,
794− "MT9T001 not detected, wrong version 0x%04x\n", data);
795− return -ENODEV;
796− }
797−
798− dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
799− client->addr);
800−
801− return 0;
802−}
803−
804−static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
805−{
806− struct v4l2_mbus_framefmt *format;
807− struct v4l2_rect *crop;
808−
809− crop = v4l2_subdev_get_try_crop(subdev, fh->state, 0);
810− crop->left = MT9T001_COLUMN_START_DEF;
811− crop->top = MT9T001_ROW_START_DEF;
812− crop->width = MT9T001_WINDOW_WIDTH_DEF + 1;
813− crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1;
814−
815− format = v4l2_subdev_get_try_format(subdev, fh->state, 0);
816− format->code = MEDIA_BUS_FMT_SGRBG10_1X10;
817− format->width = MT9T001_WINDOW_WIDTH_DEF + 1;
818− format->height = MT9T001_WINDOW_HEIGHT_DEF + 1;
819− format->field = V4L2_FIELD_NONE;
820− format->colorspace = V4L2_COLORSPACE_SRGB;
821−
822− return mt9t001_set_power(subdev, 1);
823−}
824−
825−static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
826−{
827− return mt9t001_set_power(subdev, 0);
828−}
829−
830−static const struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = {
831− .s_power = mt9t001_set_power,
832−};
833−
834−static const struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = {
835− .s_stream = mt9t001_s_stream,
836−};
837−
838−static const struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = {
839− .enum_mbus_code = mt9t001_enum_mbus_code,
840− .enum_frame_size = mt9t001_enum_frame_size,
841− .get_fmt = mt9t001_get_format,
842− .set_fmt = mt9t001_set_format,
843− .get_selection = mt9t001_get_selection,
844− .set_selection = mt9t001_set_selection,
845−};
846−
847−static const struct v4l2_subdev_ops mt9t001_subdev_ops = {
848− .core = &mt9t001_subdev_core_ops,
849− .video = &mt9t001_subdev_video_ops,
850− .pad = &mt9t001_subdev_pad_ops,
851−};
852−
853−static const struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = {
854− .registered = mt9t001_registered,
855− .open = mt9t001_open,
856− .close = mt9t001_close,
857−};
858−
859−static int mt9t001_probe(struct i2c_client *client)
860−{
861− struct mt9t001_platform_data *pdata = client->dev.platform_data;
862− struct mt9t001 *mt9t001;
863− unsigned int i;
864− int ret;
865−
866− if (pdata == NULL) {
867− dev_err(&client->dev, "No platform data\n");
868− return -EINVAL;
869− }
870−
871− if (!i2c_check_functionality(client->adapter,
872− I2C_FUNC_SMBUS_WORD_DATA)) {
873− dev_warn(&client->adapter->dev,
874− "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
875− return -EIO;
876− }
877−
878− mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
879− if (!mt9t001)
880− return -ENOMEM;
881−
882− mutex_init(&mt9t001->power_lock);
883− mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
884−
885− mt9t001->regulators[0].supply = "vdd";
886− mt9t001->regulators[1].supply = "vaa";
887−
888− ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators);
889− if (ret < 0) {
890− dev_err(&client->dev, "Unable to get regulators\n");
891− return ret;
892− }
893−
894− mt9t001->clk = devm_clk_get(&client->dev, NULL);
895− if (IS_ERR(mt9t001->clk)) {
896− dev_err(&client->dev, "Unable to get clock\n");
897− return PTR_ERR(mt9t001->clk);
898− }
899−
900− v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
901− ARRAY_SIZE(mt9t001_gains) + 4);
902−
903− v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
904− V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN,
905− MT9T001_SHUTTER_WIDTH_MAX, 1,
906− MT9T001_SHUTTER_WIDTH_DEF);
907− v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
908− V4L2_CID_BLACK_LEVEL, 1, 1, 1, 1);
909− v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
910− V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk,
911− 1, pdata->ext_clk);
912− v4l2_ctrl_new_std_menu_items(&mt9t001->ctrls, &mt9t001_ctrl_ops,
913− V4L2_CID_TEST_PATTERN,
914− ARRAY_SIZE(mt9t001_test_pattern_menu) - 1, 0,
915− 0, mt9t001_test_pattern_menu);
916−
917− for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i)
918− v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL);
919−
920− for (i = 0; i < ARRAY_SIZE(mt9t001_gains); ++i)
921− mt9t001->gains[i] = v4l2_ctrl_new_custom(&mt9t001->ctrls,
922− &mt9t001_gains[i], NULL);
923−
924− v4l2_ctrl_cluster(ARRAY_SIZE(mt9t001_gains), mt9t001->gains);
925−
926− mt9t001->subdev.ctrl_handler = &mt9t001->ctrls;
927−
928− if (mt9t001->ctrls.error) {
929− printk(KERN_INFO "%s: control initialization error %d\n",
930− __func__, mt9t001->ctrls.error);
931− ret = -EINVAL;
932− goto done;
933− }
934−
935− mt9t001->crop.left = MT9T001_COLUMN_START_DEF;
936− mt9t001->crop.top = MT9T001_ROW_START_DEF;
937− mt9t001->crop.width = MT9T001_WINDOW_WIDTH_DEF + 1;
938− mt9t001->crop.height = MT9T001_WINDOW_HEIGHT_DEF + 1;
939−
940− mt9t001->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
941− mt9t001->format.width = MT9T001_WINDOW_WIDTH_DEF + 1;
942− mt9t001->format.height = MT9T001_WINDOW_HEIGHT_DEF + 1;
943− mt9t001->format.field = V4L2_FIELD_NONE;
944− mt9t001->format.colorspace = V4L2_COLORSPACE_SRGB;
945−
946− v4l2_i2c_subdev_init(&mt9t001->subdev, client, &mt9t001_subdev_ops);
947− mt9t001->subdev.internal_ops = &mt9t001_subdev_internal_ops;
948− mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
949−
950− mt9t001->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
951− mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
952− ret = media_entity_pads_init(&mt9t001->subdev.entity, 1, &mt9t001->pad);
953−
954−done:
955− if (ret < 0) {
956− v4l2_ctrl_handler_free(&mt9t001->ctrls);
957− media_entity_cleanup(&mt9t001->subdev.entity);
958− }
959−
960− return ret;
961−}
962−
963−static void mt9t001_remove(struct i2c_client *client)
964−{
965− struct v4l2_subdev *subdev = i2c_get_clientdata(client);
966− struct mt9t001 *mt9t001 = to_mt9t001(subdev);
967−
968− v4l2_ctrl_handler_free(&mt9t001->ctrls);
969− v4l2_device_unregister_subdev(subdev);
970− media_entity_cleanup(&subdev->entity);
971−}
972−
973−static const struct i2c_device_id mt9t001_id[] = {
974− { "mt9t001", 0 },
975− { }
976−};
977−MODULE_DEVICE_TABLE(i2c, mt9t001_id);
978−
979−static struct i2c_driver mt9t001_driver = {
980− .driver = {
981− .name = "mt9t001",
982− },
983− .probe_new = mt9t001_probe,
984− .remove = mt9t001_remove,
985− .id_table = mt9t001_id,
986−};
987−
988−module_i2c_driver(mt9t001_driver);
989−
990−MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver");
991−MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
992−MODULE_LICENSE("GPL");
drivers/media/i2c/noon010pc30.c+0−821
@@ -1,821 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−/*
3− * Driver for SiliconFile NOON010PC30 CIF (1/11") Image Sensor with ISP
4− *
5− * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
6− * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
7− *
8− * Initial register configuration based on a driver authored by
9− * HeungJun Kim <riverful.kim@samsung.com>.
10− */
11−
12−#include <linux/delay.h>
13−#include <linux/gpio/consumer.h>
14−#include <linux/i2c.h>
15−#include <linux/slab.h>
16−#include <linux/regulator/consumer.h>
17−#include <media/i2c/noon010pc30.h>
18−#include <linux/videodev2.h>
19−#include <linux/module.h>
20−#include <media/v4l2-ctrls.h>
21−#include <media/v4l2-device.h>
22−#include <media/v4l2-mediabus.h>
23−#include <media/v4l2-subdev.h>
24−
25−static int debug;
26−module_param(debug, int, 0644);
27−MODULE_PARM_DESC(debug, "Enable module debug trace. Set to 1 to enable.");
28−
29−#define MODULE_NAME "NOON010PC30"
30−
31−/*
32− * Register offsets within a page
33− * b15..b8 - page id, b7..b0 - register address
34− */
35−#define POWER_CTRL_REG 0x0001
36−#define PAGEMODE_REG 0x03
37−#define DEVICE_ID_REG 0x0004
38−#define NOON010PC30_ID 0x86
39−#define VDO_CTL_REG(n) (0x0010 + (n))
40−#define SYNC_CTL_REG 0x0012
41−/* Window size and position */
42−#define WIN_ROWH_REG 0x0013
43−#define WIN_ROWL_REG 0x0014
44−#define WIN_COLH_REG 0x0015
45−#define WIN_COLL_REG 0x0016
46−#define WIN_HEIGHTH_REG 0x0017
47−#define WIN_HEIGHTL_REG 0x0018
48−#define WIN_WIDTHH_REG 0x0019
49−#define WIN_WIDTHL_REG 0x001A
50−#define HBLANKH_REG 0x001B
51−#define HBLANKL_REG 0x001C
52−#define VSYNCH_REG 0x001D
53−#define VSYNCL_REG 0x001E
54−/* VSYNC control */
55−#define VS_CTL_REG(n) (0x00A1 + (n))
56−/* page 1 */
57−#define ISP_CTL_REG(n) (0x0110 + (n))
58−#define YOFS_REG 0x0119
59−#define DARK_YOFS_REG 0x011A
60−#define SAT_CTL_REG 0x0120
61−#define BSAT_REG 0x0121
62−#define RSAT_REG 0x0122
63−/* Color correction */
64−#define CMC_CTL_REG 0x0130
65−#define CMC_OFSGH_REG 0x0133
66−#define CMC_OFSGL_REG 0x0135
67−#define CMC_SIGN_REG 0x0136
68−#define CMC_GOFS_REG 0x0137
69−#define CMC_COEF_REG(n) (0x0138 + (n))
70−#define CMC_OFS_REG(n) (0x0141 + (n))
71−/* Gamma correction */
72−#define GMA_CTL_REG 0x0160
73−#define GMA_COEF_REG(n) (0x0161 + (n))
74−/* Lens Shading */
75−#define LENS_CTRL_REG 0x01D0
76−#define LENS_XCEN_REG 0x01D1
77−#define LENS_YCEN_REG 0x01D2
78−#define LENS_RC_REG 0x01D3
79−#define LENS_GC_REG 0x01D4
80−#define LENS_BC_REG 0x01D5
81−#define L_AGON_REG 0x01D6
82−#define L_AGOFF_REG 0x01D7
83−/* Page 3 - Auto Exposure */
84−#define AE_CTL_REG(n) (0x0310 + (n))
85−#define AE_CTL9_REG 0x032C
86−#define AE_CTL10_REG 0x032D
87−#define AE_YLVL_REG 0x031C
88−#define AE_YTH_REG(n) (0x031D + (n))
89−#define AE_WGT_REG 0x0326
90−#define EXP_TIMEH_REG 0x0333
91−#define EXP_TIMEM_REG 0x0334
92−#define EXP_TIMEL_REG 0x0335
93−#define EXP_MMINH_REG 0x0336
94−#define EXP_MMINL_REG 0x0337
95−#define EXP_MMAXH_REG 0x0338
96−#define EXP_MMAXM_REG 0x0339
97−#define EXP_MMAXL_REG 0x033A
98−/* Page 4 - Auto White Balance */
99−#define AWB_CTL_REG(n) (0x0410 + (n))
100−#define AWB_ENABE 0x80
101−#define AWB_WGHT_REG 0x0419
102−#define BGAIN_PAR_REG(n) (0x044F + (n))
103−/* Manual white balance, when AWB_CTL2[0]=1 */
104−#define MWB_RGAIN_REG 0x0466
105−#define MWB_BGAIN_REG 0x0467
106−
107−/* The token to mark an array end */
108−#define REG_TERM 0xFFFF
109−
110−struct noon010_format {
111− u32 code;
112− enum v4l2_colorspace colorspace;
113− u16 ispctl1_reg;
114−};
115−
116−struct noon010_frmsize {
117− u16 width;
118− u16 height;
119− int vid_ctl1;
120−};
121−
122−static const char * const noon010_supply_name[] = {
123− "vdd_core", "vddio", "vdda"
124−};
125−
126−#define NOON010_NUM_SUPPLIES ARRAY_SIZE(noon010_supply_name)
127−
128−struct noon010_info {
129− struct v4l2_subdev sd;
130− struct media_pad pad;
131− struct v4l2_ctrl_handler hdl;
132− struct regulator_bulk_data supply[NOON010_NUM_SUPPLIES];
133− struct gpio_desc *reset;
134− struct gpio_desc *stby;
135−
136− /* Protects the struct members below */
137− struct mutex lock;
138−
139− const struct noon010_format *curr_fmt;
140− const struct noon010_frmsize *curr_win;
141− unsigned int apply_new_cfg:1;
142− unsigned int streaming:1;
143− unsigned int hflip:1;
144− unsigned int vflip:1;
145− unsigned int power:1;
146− u8 i2c_reg_page;
147−};
148−
149−struct i2c_regval {
150− u16 addr;
151− u16 val;
152−};
153−
154−/* Supported resolutions. */
155−static const struct noon010_frmsize noon010_sizes[] = {
156− {
157− .width = 352,
158− .height = 288,
159− .vid_ctl1 = 0,
160− }, {
161− .width = 176,
162− .height = 144,
163− .vid_ctl1 = 0x10,
164− }, {
165− .width = 88,
166− .height = 72,
167− .vid_ctl1 = 0x20,
168− },
169−};
170−
171−/* Supported pixel formats. */
172−static const struct noon010_format noon010_formats[] = {
173− {
174− .code = MEDIA_BUS_FMT_YUYV8_2X8,
175− .colorspace = V4L2_COLORSPACE_JPEG,
176− .ispctl1_reg = 0x03,
177− }, {
178− .code = MEDIA_BUS_FMT_YVYU8_2X8,
179− .colorspace = V4L2_COLORSPACE_JPEG,
180− .ispctl1_reg = 0x02,
181− }, {
182− .code = MEDIA_BUS_FMT_VYUY8_2X8,
183− .colorspace = V4L2_COLORSPACE_JPEG,
184− .ispctl1_reg = 0,
185− }, {
186− .code = MEDIA_BUS_FMT_UYVY8_2X8,
187− .colorspace = V4L2_COLORSPACE_JPEG,
188− .ispctl1_reg = 0x01,
189− }, {
190− .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
191− .colorspace = V4L2_COLORSPACE_JPEG,
192− .ispctl1_reg = 0x40,
193− },
194−};
195−
196−static const struct i2c_regval noon010_base_regs[] = {
197− { WIN_COLL_REG, 0x06 }, { HBLANKL_REG, 0x7C },
198− /* Color corection and saturation */
199− { ISP_CTL_REG(0), 0x30 }, { ISP_CTL_REG(2), 0x30 },
200− { YOFS_REG, 0x80 }, { DARK_YOFS_REG, 0x04 },
201− { SAT_CTL_REG, 0x1F }, { BSAT_REG, 0x90 },
202− { CMC_CTL_REG, 0x0F }, { CMC_OFSGH_REG, 0x3C },
203− { CMC_OFSGL_REG, 0x2C }, { CMC_SIGN_REG, 0x3F },
204− { CMC_COEF_REG(0), 0x79 }, { CMC_OFS_REG(0), 0x00 },
205− { CMC_COEF_REG(1), 0x39 }, { CMC_OFS_REG(1), 0x00 },
206− { CMC_COEF_REG(2), 0x00 }, { CMC_OFS_REG(2), 0x00 },
207− { CMC_COEF_REG(3), 0x11 }, { CMC_OFS_REG(3), 0x8B },
208− { CMC_COEF_REG(4), 0x65 }, { CMC_OFS_REG(4), 0x07 },
209− { CMC_COEF_REG(5), 0x14 }, { CMC_OFS_REG(5), 0x04 },
210− { CMC_COEF_REG(6), 0x01 }, { CMC_OFS_REG(6), 0x9C },
211− { CMC_COEF_REG(7), 0x33 }, { CMC_OFS_REG(7), 0x89 },
212− { CMC_COEF_REG(8), 0x74 }, { CMC_OFS_REG(8), 0x25 },
213− /* Automatic white balance */
214− { AWB_CTL_REG(0), 0x78 }, { AWB_CTL_REG(1), 0x2E },
215− { AWB_CTL_REG(2), 0x20 }, { AWB_CTL_REG(3), 0x85 },
216− /* Auto exposure */
217− { AE_CTL_REG(0), 0xDC }, { AE_CTL_REG(1), 0x81 },
218− { AE_CTL_REG(2), 0x30 }, { AE_CTL_REG(3), 0xA5 },
219− { AE_CTL_REG(4), 0x40 }, { AE_CTL_REG(5), 0x51 },
220− { AE_CTL_REG(6), 0x33 }, { AE_CTL_REG(7), 0x7E },
221− { AE_CTL9_REG, 0x00 }, { AE_CTL10_REG, 0x02 },
222− { AE_YLVL_REG, 0x44 }, { AE_YTH_REG(0), 0x34 },
223− { AE_YTH_REG(1), 0x30 }, { AE_WGT_REG, 0xD5 },
224− /* Lens shading compensation */
225− { LENS_CTRL_REG, 0x01 }, { LENS_XCEN_REG, 0x80 },
226− { LENS_YCEN_REG, 0x70 }, { LENS_RC_REG, 0x53 },
227− { LENS_GC_REG, 0x40 }, { LENS_BC_REG, 0x3E },
228− { REG_TERM, 0 },
229−};
230−
231−static inline struct noon010_info *to_noon010(struct v4l2_subdev *sd)
232−{
233− return container_of(sd, struct noon010_info, sd);
234−}
235−
236−static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
237−{
238− return &container_of(ctrl->handler, struct noon010_info, hdl)->sd;
239−}
240−
241−static inline int set_i2c_page(struct noon010_info *info,
242− struct i2c_client *client, unsigned int reg)
243−{
244− u32 page = reg >> 8 & 0xFF;
245− int ret = 0;
246−
247− if (info->i2c_reg_page != page && (reg & 0xFF) != 0x03) {
248− ret = i2c_smbus_write_byte_data(client, PAGEMODE_REG, page);
249− if (!ret)
250− info->i2c_reg_page = page;
251− }
252− return ret;
253−}
254−
255−static int cam_i2c_read(struct v4l2_subdev *sd, u32 reg_addr)
256−{
257− struct i2c_client *client = v4l2_get_subdevdata(sd);
258− struct noon010_info *info = to_noon010(sd);
259− int ret = set_i2c_page(info, client, reg_addr);
260−
261− if (ret)
262− return ret;
263− return i2c_smbus_read_byte_data(client, reg_addr & 0xFF);
264−}
265−
266−static int cam_i2c_write(struct v4l2_subdev *sd, u32 reg_addr, u32 val)
267−{
268− struct i2c_client *client = v4l2_get_subdevdata(sd);
269− struct noon010_info *info = to_noon010(sd);
270− int ret = set_i2c_page(info, client, reg_addr);
271−
272− if (ret)
273− return ret;
274− return i2c_smbus_write_byte_data(client, reg_addr & 0xFF, val);
275−}
276−
277−static inline int noon010_bulk_write_reg(struct v4l2_subdev *sd,
278− const struct i2c_regval *msg)
279−{
280− while (msg->addr != REG_TERM) {
281− int ret = cam_i2c_write(sd, msg->addr, msg->val);
282−
283− if (ret)
284− return ret;
285− msg++;
286− }
287− return 0;
288−}
289−
290−/* Device reset and sleep mode control */
291−static int noon010_power_ctrl(struct v4l2_subdev *sd, bool reset, bool sleep)
292−{
293− struct noon010_info *info = to_noon010(sd);
294− u8 reg = sleep ? 0xF1 : 0xF0;
295− int ret = 0;
296−
297− if (reset) {
298− ret = cam_i2c_write(sd, POWER_CTRL_REG, reg | 0x02);
299− udelay(20);
300− }
301− if (!ret) {
302− ret = cam_i2c_write(sd, POWER_CTRL_REG, reg);
303− if (reset && !ret)
304− info->i2c_reg_page = -1;
305− }
306− return ret;
307−}
308−
309−/* Automatic white balance control */
310−static int noon010_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
311−{
312− int ret;
313−
314− ret = cam_i2c_write(sd, AWB_CTL_REG(1), on ? 0x2E : 0x2F);
315− if (!ret)
316− ret = cam_i2c_write(sd, AWB_CTL_REG(0), on ? 0xFB : 0x7B);
317− return ret;
318−}
319−
320−/* Called with struct noon010_info.lock mutex held */
321−static int noon010_set_flip(struct v4l2_subdev *sd, int hflip, int vflip)
322−{
323− struct noon010_info *info = to_noon010(sd);
324− int reg, ret;
325−
326− reg = cam_i2c_read(sd, VDO_CTL_REG(1));
327− if (reg < 0)
328− return reg;
329−
330− reg &= 0x7C;
331− if (hflip)
332− reg |= 0x01;
333− if (vflip)
334− reg |= 0x02;
335−
336− ret = cam_i2c_write(sd, VDO_CTL_REG(1), reg | 0x80);
337− if (!ret) {
338− info->hflip = hflip;
339− info->vflip = vflip;
340− }
341− return ret;
342−}
343−
344−/* Configure resolution and color format */
345−static int noon010_set_params(struct v4l2_subdev *sd)
346−{
347− struct noon010_info *info = to_noon010(sd);
348−
349− int ret = cam_i2c_write(sd, VDO_CTL_REG(0),
350− info->curr_win->vid_ctl1);
351− if (ret)
352− return ret;
353− return cam_i2c_write(sd, ISP_CTL_REG(0),
354− info->curr_fmt->ispctl1_reg);
355−}
356−
357−/* Find nearest matching image pixel size. */
358−static int noon010_try_frame_size(struct v4l2_mbus_framefmt *mf,
359− const struct noon010_frmsize **size)
360−{
361− unsigned int min_err = ~0;
362− int i = ARRAY_SIZE(noon010_sizes);
363− const struct noon010_frmsize *fsize = &noon010_sizes[0],
364− *match = NULL;
365−
366− while (i--) {
367− int err = abs(fsize->width - mf->width)
368− + abs(fsize->height - mf->height);
369−
370− if (err < min_err) {
371− min_err = err;
372− match = fsize;
373− }
374− fsize++;
375− }
376− if (match) {
377− mf->width = match->width;
378− mf->height = match->height;
379− if (size)
380− *size = match;
381− return 0;
382− }
383− return -EINVAL;
384−}
385−
386−/* Called with info.lock mutex held */
387−static int power_enable(struct noon010_info *info)
388−{
389− int ret;
390−
391− if (info->power) {
392− v4l2_info(&info->sd, "%s: sensor is already on\n", __func__);
393− return 0;
394− }
395−
396− /* Assert standby: line should be flagged active low in descriptor */
397− if (info->stby)
398− gpiod_set_value(info->stby, 1);
399−
400− /* Assert reset: line should be flagged active low in descriptor */
401− if (info->reset)
402− gpiod_set_value(info->reset, 1);
403−
404− ret = regulator_bulk_enable(NOON010_NUM_SUPPLIES, info->supply);
405− if (ret)
406− return ret;
407−
408− /* De-assert reset and standby */
409− if (info->reset) {
410− msleep(50);
411− gpiod_set_value(info->reset, 0);
412− }
413− if (info->stby) {
414− udelay(1000);
415− gpiod_set_value(info->stby, 0);
416− }
417− /* Cycle reset: assert and deassert */
418− if (info->reset) {
419− udelay(1000);
420− gpiod_set_value(info->reset, 1);
421− msleep(100);
422− gpiod_set_value(info->reset, 0);
423− msleep(20);
424− }
425− info->power = 1;
426−
427− v4l2_dbg(1, debug, &info->sd, "%s: sensor is on\n", __func__);
428− return 0;
429−}
430−
431−/* Called with info.lock mutex held */
432−static int power_disable(struct noon010_info *info)
433−{
434− int ret;
435−
436− if (!info->power) {
437− v4l2_info(&info->sd, "%s: sensor is already off\n", __func__);
438− return 0;
439− }
440−
441− ret = regulator_bulk_disable(NOON010_NUM_SUPPLIES, info->supply);
442− if (ret)
443− return ret;
444−
445− /* Assert standby and reset */
446− if (info->stby)
447− gpiod_set_value(info->stby, 1);
448−
449− if (info->reset)
450− gpiod_set_value(info->reset, 1);
451−
452− info->power = 0;
453−
454− v4l2_dbg(1, debug, &info->sd, "%s: sensor is off\n", __func__);
455−
456− return 0;
457−}
458−
459−static int noon010_s_ctrl(struct v4l2_ctrl *ctrl)
460−{
461− struct v4l2_subdev *sd = to_sd(ctrl);
462− struct noon010_info *info = to_noon010(sd);
463− int ret = 0;
464−
465− v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
466− __func__, ctrl->id, ctrl->val);
467−
468− mutex_lock(&info->lock);
469− /*
470− * If the device is not powered up by the host driver do
471− * not apply any controls to H/W at this time. Instead
472− * the controls will be restored right after power-up.
473− */
474− if (!info->power)
475− goto unlock;
476−
477− switch (ctrl->id) {
478− case V4L2_CID_AUTO_WHITE_BALANCE:
479− ret = noon010_enable_autowhitebalance(sd, ctrl->val);
480− break;
481− case V4L2_CID_BLUE_BALANCE:
482− ret = cam_i2c_write(sd, MWB_BGAIN_REG, ctrl->val);
483− break;
484− case V4L2_CID_RED_BALANCE:
485− ret = cam_i2c_write(sd, MWB_RGAIN_REG, ctrl->val);
486− break;
487− default:
488− ret = -EINVAL;
489− }
490−unlock:
491− mutex_unlock(&info->lock);
492− return ret;
493−}
494−
495−static int noon010_enum_mbus_code(struct v4l2_subdev *sd,
496− struct v4l2_subdev_state *sd_state,
497− struct v4l2_subdev_mbus_code_enum *code)
498−{
499− if (code->index >= ARRAY_SIZE(noon010_formats))
500− return -EINVAL;
501−
502− code->code = noon010_formats[code->index].code;
503− return 0;
504−}
505−
506−static int noon010_get_fmt(struct v4l2_subdev *sd,
507− struct v4l2_subdev_state *sd_state,
508− struct v4l2_subdev_format *fmt)
509−{
510− struct noon010_info *info = to_noon010(sd);
511− struct v4l2_mbus_framefmt *mf;
512−
513− if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
514− if (sd_state) {
515− mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
516− fmt->format = *mf;
517− }
518− return 0;
519− }
520− mf = &fmt->format;
521−
522− mutex_lock(&info->lock);
523− mf->width = info->curr_win->width;
524− mf->height = info->curr_win->height;
525− mf->code = info->curr_fmt->code;
526− mf->colorspace = info->curr_fmt->colorspace;
527− mf->field = V4L2_FIELD_NONE;
528−
529− mutex_unlock(&info->lock);
530− return 0;
531−}
532−
533−/* Return nearest media bus frame format. */
534−static const struct noon010_format *noon010_try_fmt(struct v4l2_subdev *sd,
535− struct v4l2_mbus_framefmt *mf)
536−{
537− int i = ARRAY_SIZE(noon010_formats);
538−
539− while (--i)
540− if (mf->code == noon010_formats[i].code)
541− break;
542− mf->code = noon010_formats[i].code;
543−
544− return &noon010_formats[i];
545−}
546−
547−static int noon010_set_fmt(struct v4l2_subdev *sd,
548− struct v4l2_subdev_state *sd_state,
549− struct v4l2_subdev_format *fmt)
550−{
551− struct noon010_info *info = to_noon010(sd);
552− const struct noon010_frmsize *size = NULL;
553− const struct noon010_format *nf;
554− struct v4l2_mbus_framefmt *mf;
555− int ret = 0;
556−
557− nf = noon010_try_fmt(sd, &fmt->format);
558− noon010_try_frame_size(&fmt->format, &size);
559− fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
560− fmt->format.field = V4L2_FIELD_NONE;
561−
562− if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
563− if (sd_state) {
564− mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
565− *mf = fmt->format;
566− }
567− return 0;
568− }
569− mutex_lock(&info->lock);
570− if (!info->streaming) {
571− info->apply_new_cfg = 1;
572− info->curr_fmt = nf;
573− info->curr_win = size;
574− } else {
575− ret = -EBUSY;
576− }
577− mutex_unlock(&info->lock);
578− return ret;
579−}
580−
581−/* Called with struct noon010_info.lock mutex held */
582−static int noon010_base_config(struct v4l2_subdev *sd)
583−{
584− int ret = noon010_bulk_write_reg(sd, noon010_base_regs);
585− if (!ret)
586− ret = noon010_set_params(sd);
587− if (!ret)
588− ret = noon010_set_flip(sd, 1, 0);
589−
590− return ret;
591−}
592−
593−static int noon010_s_power(struct v4l2_subdev *sd, int on)
594−{
595− struct noon010_info *info = to_noon010(sd);
596− int ret;
597−
598− mutex_lock(&info->lock);
599− if (on) {
600− ret = power_enable(info);
601− if (!ret)
602− ret = noon010_base_config(sd);
603− } else {
604− noon010_power_ctrl(sd, false, true);
605− ret = power_disable(info);
606− }
607− mutex_unlock(&info->lock);
608−
609− /* Restore the controls state */
610− if (!ret && on)
611− ret = v4l2_ctrl_handler_setup(&info->hdl);
612−
613− return ret;
614−}
615−
616−static int noon010_s_stream(struct v4l2_subdev *sd, int on)
617−{
618− struct noon010_info *info = to_noon010(sd);
619− int ret = 0;
620−
621− mutex_lock(&info->lock);
622− if (!info->streaming != !on) {
623− ret = noon010_power_ctrl(sd, false, !on);
624− if (!ret)
625− info->streaming = on;
626− }
627− if (!ret && on && info->apply_new_cfg) {
628− ret = noon010_set_params(sd);
629− if (!ret)
630− info->apply_new_cfg = 0;
631− }
632− mutex_unlock(&info->lock);
633− return ret;
634−}
635−
636−static int noon010_log_status(struct v4l2_subdev *sd)
637−{
638− struct noon010_info *info = to_noon010(sd);
639−
640− v4l2_ctrl_handler_log_status(&info->hdl, sd->name);
641− return 0;
642−}
643−
644−static int noon010_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
645−{
646− struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd,
647− fh->state,
648− 0);
649−
650− mf->width = noon010_sizes[0].width;
651− mf->height = noon010_sizes[0].height;
652− mf->code = noon010_formats[0].code;
653− mf->colorspace = V4L2_COLORSPACE_JPEG;
654− mf->field = V4L2_FIELD_NONE;
655− return 0;
656−}
657−
658−static const struct v4l2_subdev_internal_ops noon010_subdev_internal_ops = {
659− .open = noon010_open,
660−};
661−
662−static const struct v4l2_ctrl_ops noon010_ctrl_ops = {
663− .s_ctrl = noon010_s_ctrl,
664−};
665−
666−static const struct v4l2_subdev_core_ops noon010_core_ops = {
667− .s_power = noon010_s_power,
668− .log_status = noon010_log_status,
669−};
670−
671−static const struct v4l2_subdev_pad_ops noon010_pad_ops = {
672− .enum_mbus_code = noon010_enum_mbus_code,
673− .get_fmt = noon010_get_fmt,
674− .set_fmt = noon010_set_fmt,
675−};
676−
677−static const struct v4l2_subdev_video_ops noon010_video_ops = {
678− .s_stream = noon010_s_stream,
679−};
680−
681−static const struct v4l2_subdev_ops noon010_ops = {
682− .core = &noon010_core_ops,
683− .pad = &noon010_pad_ops,
684− .video = &noon010_video_ops,
685−};
686−
687−/* Return 0 if NOON010PC30L sensor type was detected or -ENODEV otherwise. */
688−static int noon010_detect(struct i2c_client *client, struct noon010_info *info)
689−{
690− int ret;
691−
692− ret = power_enable(info);
693− if (ret)
694− return ret;
695−
696− ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG);
697− if (ret < 0)
698− dev_err(&client->dev, "I2C read failed: 0x%X\n", ret);
699−
700− power_disable(info);
701−
702− return ret == NOON010PC30_ID ? 0 : -ENODEV;
703−}
704−
705−static int noon010_probe(struct i2c_client *client)
706−{
707− struct noon010_info *info;
708− struct v4l2_subdev *sd;
709− const struct noon010pc30_platform_data *pdata
710− = client->dev.platform_data;
711− int ret;
712− int i;
713−
714− if (!pdata) {
715− dev_err(&client->dev, "No platform data!\n");
716− return -EIO;
717− }
718−
719− info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
720− if (!info)
721− return -ENOMEM;
722−
723− mutex_init(&info->lock);
724− sd = &info->sd;
725− v4l2_i2c_subdev_init(sd, client, &noon010_ops);
726− /* Static name; NEVER use in new drivers! */
727− strscpy(sd->name, MODULE_NAME, sizeof(sd->name));
728−
729− sd->internal_ops = &noon010_subdev_internal_ops;
730− sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
731−
732− v4l2_ctrl_handler_init(&info->hdl, 3);
733−
734− v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
735− V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
736− v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
737− V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
738− v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
739− V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
740−
741− sd->ctrl_handler = &info->hdl;
742−
743− ret = info->hdl.error;
744− if (ret)
745− goto np_err;
746−
747− info->i2c_reg_page = -1;
748− info->curr_fmt = &noon010_formats[0];
749− info->curr_win = &noon010_sizes[0];
750−
751− /* Request reset asserted so we get put into reset */
752− info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
753− if (IS_ERR(info->reset)) {
754− ret = PTR_ERR(info->reset);
755− goto np_err;
756− }
757− gpiod_set_consumer_name(info->reset, "NOON010PC30 NRST");
758−
759− /* Request standby asserted so we get put into standby */
760− info->stby = devm_gpiod_get(&client->dev, "standby", GPIOD_OUT_HIGH);
761− if (IS_ERR(info->stby)) {
762− ret = PTR_ERR(info->stby);
763− goto np_err;
764− }
765− gpiod_set_consumer_name(info->reset, "NOON010PC30 STBY");
766−
767− for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
768− info->supply[i].supply = noon010_supply_name[i];
769−
770− ret = devm_regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
771− info->supply);
772− if (ret)
773− goto np_err;
774−
775− info->pad.flags = MEDIA_PAD_FL_SOURCE;
776− sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
777− ret = media_entity_pads_init(&sd->entity, 1, &info->pad);
778− if (ret < 0)
779− goto np_err;
780−
781− ret = noon010_detect(client, info);
782− if (!ret)
783− return 0;
784−
785−np_err:
786− v4l2_ctrl_handler_free(&info->hdl);
787− v4l2_device_unregister_subdev(sd);
788− return ret;
789−}
790−
791−static void noon010_remove(struct i2c_client *client)
792−{
793− struct v4l2_subdev *sd = i2c_get_clientdata(client);
794− struct noon010_info *info = to_noon010(sd);
795−
796− v4l2_device_unregister_subdev(sd);
797− v4l2_ctrl_handler_free(&info->hdl);
798− media_entity_cleanup(&sd->entity);
799−}
800−
801−static const struct i2c_device_id noon010_id[] = {
802− { MODULE_NAME, 0 },
803− { },
804−};
805−MODULE_DEVICE_TABLE(i2c, noon010_id);
806−
807−
808−static struct i2c_driver noon010_i2c_driver = {
809− .driver = {
810− .name = MODULE_NAME
811− },
812− .probe_new = noon010_probe,
813− .remove = noon010_remove,
814− .id_table = noon010_id,
815−};
816−
817−module_i2c_driver(noon010_i2c_driver);
818−
819−MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver");
820−MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
821−MODULE_LICENSE("GPL");
drivers/media/i2c/ov13b10.c+47−28
@@ -243,7 +243,6 @@ static const struct ov13b10_reg mipi_data_rate_1120mbps[] = { · 242 unmodified lines
243243 {0x5047, 0xa4},
244244 {0x5048, 0x20},
245245 {0x5049, 0xa4},
246− {0x0100, 0x01},
247246 };
248247
249248 static const struct ov13b10_reg mode_4208x3120_regs[] = {
@@ -589,6 +588,9 @@ struct ov13b10 { · 339 unmodified lines
589588
590589 /* Streaming on/off */
591590 bool streaming;
591+
592+ /* True if the device has been identified */
593+ bool identified;
592594 };
593595
594596 #define to_ov13b10(_sd) container_of(_sd, struct ov13b10, sd)
@@ -1023,12 +1025,42 @@ ov13b10_set_pad_format(struct v4l2_subdev *sd, · 428 unmodified lines
10231025 return 0;
10241026 }
10251027
1028+/* Verify chip ID */
1029+static int ov13b10_identify_module(struct ov13b10 *ov13b)
1030+{
1031+ struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
1032+ int ret;
1033+ u32 val;
1034+
1035+ if (ov13b->identified)
1036+ return 0;
1037+
1038+ ret = ov13b10_read_reg(ov13b, OV13B10_REG_CHIP_ID,
1039+ OV13B10_REG_VALUE_24BIT, &val);
1040+ if (ret)
1041+ return ret;
1042+
1043+ if (val != OV13B10_CHIP_ID) {
1044+ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
1045+ OV13B10_CHIP_ID, val);
1046+ return -EIO;
1047+ }
1048+
1049+ ov13b->identified = true;
1050+
1051+ return 0;
1052+}
1053+
10261054 static int ov13b10_start_streaming(struct ov13b10 *ov13b)
10271055 {
10281056 struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
10291057 const struct ov13b10_reg_list *reg_list;
10301058 int ret, link_freq_index;
10311059
1060+ ret = ov13b10_identify_module(ov13b);
1061+ if (ret)
1062+ return ret;
1063+
10321064 /* Get out of from software reset */
10331065 ret = ov13b10_write_reg(ov13b, OV13B10_REG_SOFTWARE_RST,
10341066 OV13B10_REG_VALUE_08BIT, OV13B10_SOFTWARE_RST);
@@ -1144,27 +1176,6 @@ error: · 109 unmodified lines
11441176 return ret;
11451177 }
11461178
1147−/* Verify chip ID */
1148−static int ov13b10_identify_module(struct ov13b10 *ov13b)
1149−{
1150− struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
1151− int ret;
1152− u32 val;
1153−
1154− ret = ov13b10_read_reg(ov13b, OV13B10_REG_CHIP_ID,
1155− OV13B10_REG_VALUE_24BIT, &val);
1156− if (ret)
1157− return ret;
1158−
1159− if (val != OV13B10_CHIP_ID) {
1160− dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
1161− OV13B10_CHIP_ID, val);
1162− return -EIO;
1163− }
1164−
1165− return 0;
1166−}
1167−
11681179 static const struct v4l2_subdev_video_ops ov13b10_video_ops = {
11691180 .s_stream = ov13b10_set_stream,
11701181 };
@@ -1379,6 +1390,7 @@ out_err: · 208 unmodified lines
13791390 static int ov13b10_probe(struct i2c_client *client)
13801391 {
13811392 struct ov13b10 *ov13b;
1393+ bool full_power;
13821394 int ret;
13831395
13841396 /* Check HW config */
@@ -1395,11 +1407,14 @@ static int ov13b10_probe(struct i2c_client *client) · 10 unmodified lines
13951407 /* Initialize subdev */
13961408 v4l2_i2c_subdev_init(&ov13b->sd, client, &ov13b10_subdev_ops);
13971409
1398− /* Check module identity */
1399− ret = ov13b10_identify_module(ov13b);
1400− if (ret) {
1401− dev_err(&client->dev, "failed to find sensor: %d\n", ret);
1402− return ret;
1410+ full_power = acpi_dev_state_d0(&client->dev);
1411+ if (full_power) {
1412+ /* Check module identity */
1413+ ret = ov13b10_identify_module(ov13b);
1414+ if (ret) {
1415+ dev_err(&client->dev, "failed to find sensor: %d\n", ret);
1416+ return ret;
1417+ }
14031418 }
14041419
14051420 /* Set default mode to max resolution */
@@ -1431,7 +1446,10 @@ static int ov13b10_probe(struct i2c_client *client) · 25 unmodified lines
14311446 * Device is already turned on by i2c-core with ACPI domain PM.
14321447 * Enable runtime PM and turn off the device.
14331448 */
1434− pm_runtime_set_active(&client->dev);
1449+
1450+ /* Set the device's state to active if it's in D0 state. */
1451+ if (full_power)
1452+ pm_runtime_set_active(&client->dev);
14351453 pm_runtime_enable(&client->dev);
14361454 pm_runtime_idle(&client->dev);
14371455
@@ -1480,6 +1498,7 @@ static struct i2c_driver ov13b10_i2c_driver = { · 42 unmodified lines
14801498 },
14811499 .probe_new = ov13b10_probe,
14821500 .remove = ov13b10_remove,
1501+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
14831502 };
14841503
14851504 module_i2c_driver(ov13b10_i2c_driver);
drivers/media/i2c/ov2685.c+77−3
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <media/media-entity.h>
1818 #include <media/v4l2-async.h>
1919 #include <media/v4l2-ctrls.h>
20+#include <media/v4l2-fwnode.h>
2021 #include <media/v4l2-subdev.h>
2122
2223 #define CHIP_ID 0x2685
@@ -55,6 +56,9 @@ · 32 unmodified lines
5556 #define OV2685_REG_VALUE_16BIT 2
5657 #define OV2685_REG_VALUE_24BIT 3
5758
59+#define OV2685_NATIVE_WIDTH 1616
60+#define OV2685_NATIVE_HEIGHT 1216
61+
5862 #define OV2685_LANES 1
5963 #define OV2685_BITS_PER_SAMPLE 10
6064
@@ -77,6 +81,7 @@ struct ov2685_mode { · 16 unmodified lines
7781 u32 exp_def;
7882 u32 hts_def;
7983 u32 vts_def;
84+ const struct v4l2_rect *analog_crop;
8085 const struct regval *reg_list;
8186 };
8287
@@ -230,6 +235,13 @@ static const int ov2685_test_pattern_val[] = { · 147 unmodified lines
230235 OV2685_TEST_PATTERN_COLOR_SQUARE,
231236 };
232237
238+static const struct v4l2_rect ov2685_analog_crop = {
239+ .left = 8,
240+ .top = 8,
241+ .width = 1600,
242+ .height = 1200,
243+};
244+
233245 static const struct ov2685_mode supported_modes[] = {
234246 {
235247 .width = 1600,
@@ -237,6 +249,7 @@ static const struct ov2685_mode supported_modes[] = { · 1 unmodified line
237249 .exp_def = 0x04ee,
238250 .hts_def = 0x06a4,
239251 .vts_def = 0x050e,
252+ .analog_crop = &ov2685_analog_crop,
240253 .reg_list = ov2685_1600x1200_regs,
241254 },
242255 };
@@ -383,6 +396,53 @@ static int ov2685_enum_frame_sizes(struct v4l2_subdev *sd, · 140 unmodified lines
383396 return 0;
384397 }
385398
399+static const struct v4l2_rect *
400+__ov2685_get_pad_crop(struct ov2685 *ov2685,
401+ struct v4l2_subdev_state *state, unsigned int pad,
402+ enum v4l2_subdev_format_whence which)
403+{
404+ const struct ov2685_mode *mode = ov2685->cur_mode;
405+
406+ switch (which) {
407+ case V4L2_SUBDEV_FORMAT_TRY:
408+ return v4l2_subdev_get_try_crop(&ov2685->subdev, state, pad);
409+ case V4L2_SUBDEV_FORMAT_ACTIVE:
410+ return mode->analog_crop;
411+ }
412+
413+ return NULL;
414+}
415+
416+static int ov2685_get_selection(struct v4l2_subdev *sd,
417+ struct v4l2_subdev_state *sd_state,
418+ struct v4l2_subdev_selection *sel)
419+{
420+ struct ov2685 *ov2685 = to_ov2685(sd);
421+
422+ switch (sel->target) {
423+ case V4L2_SEL_TGT_CROP:
424+ mutex_lock(&ov2685->mutex);
425+ sel->r = *__ov2685_get_pad_crop(ov2685, sd_state, sel->pad,
426+ sel->which);
427+ mutex_unlock(&ov2685->mutex);
428+ break;
429+ case V4L2_SEL_TGT_NATIVE_SIZE:
430+ case V4L2_SEL_TGT_CROP_BOUNDS:
431+ sel->r.top = 0;
432+ sel->r.left = 0;
433+ sel->r.width = OV2685_NATIVE_WIDTH;
434+ sel->r.height = OV2685_NATIVE_HEIGHT;
435+ break;
436+ case V4L2_SEL_TGT_CROP_DEFAULT:
437+ sel->r = ov2685_analog_crop;
438+ break;
439+ default:
440+ return -EINVAL;
441+ }
442+
443+ return 0;
444+}
445+
386446 /* Calculate the delay in us by clock rate and clock cycles */
387447 static inline u32 ov2685_cal_delay(u32 cycles)
388448 {
@@ -419,8 +479,10 @@ static int __ov2685_power_on(struct ov2685 *ov2685) · 30 unmodified lines
419479 * writing register before .s_stream() as a workaround
420480 */
421481 ret = ov2685_write_array(ov2685->client, ov2685->cur_mode->reg_list);
422− if (ret)
482+ if (ret) {
483+ dev_err(dev, "Failed to set regs for power on\n");
423484 goto disable_supplies;
485+ }
424486
425487 return 0;
426488
@@ -589,6 +651,8 @@ static const struct v4l2_subdev_pad_ops ov2685_pad_ops = { · 162 unmodified lines
589651 .enum_frame_size = ov2685_enum_frame_sizes,
590652 .get_fmt = ov2685_get_fmt,
591653 .set_fmt = ov2685_set_fmt,
654+ .get_selection = ov2685_get_selection,
655+ .set_selection = ov2685_get_selection,
592656 };
593657
594658 static const struct v4l2_subdev_ops ov2685_subdev_ops = {
@@ -611,13 +675,14 @@ static int ov2685_initialize_controls(struct ov2685 *ov2685) · 16 unmodified lines
611675 const struct ov2685_mode *mode;
612676 struct v4l2_ctrl_handler *handler;
613677 struct v4l2_ctrl *ctrl;
678+ struct v4l2_fwnode_device_properties props;
614679 u64 exposure_max;
615680 u32 pixel_rate, h_blank;
616681 int ret;
617682
618683 handler = &ov2685->ctrl_handler;
619684 mode = ov2685->cur_mode;
620− ret = v4l2_ctrl_handler_init(handler, 8);
685+ ret = v4l2_ctrl_handler_init(handler, 10);
621686 if (ret)
622687 return ret;
623688 handler->lock = &ov2685->mutex;
@@ -659,6 +724,15 @@ static int ov2685_initialize_controls(struct ov2685 *ov2685) · 35 unmodified lines
659724 ARRAY_SIZE(ov2685_test_pattern_menu) - 1,
660725 0, 0, ov2685_test_pattern_menu);
661726
727+ /* set properties from fwnode (e.g. rotation, orientation) */
728+ ret = v4l2_fwnode_device_parse(&ov2685->client->dev, &props);
729+ if (ret)
730+ goto err_free_handler;
731+
732+ ret = v4l2_ctrl_new_fwnode_properties(handler, &ov2685_ctrl_ops, &props);
733+ if (ret)
734+ goto err_free_handler;
735+
662736 if (handler->error) {
663737 ret = handler->error;
664738 dev_err(&ov2685->client->dev,
@@ -733,7 +807,7 @@ static int ov2685_probe(struct i2c_client *client) · 68 unmodified lines
733807 if (clk_get_rate(ov2685->xvclk) != OV2685_XVCLK_FREQ)
734808 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
735809
736− ov2685->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
810+ ov2685->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
737811 if (IS_ERR(ov2685->reset_gpio)) {
738812 dev_err(dev, "Failed to get reset-gpios\n");
739813 return -EINVAL;
drivers/media/i2c/ov5647.c+43−13
@@ -58,6 +58,7 @@ · 57 unmodified lines
5858 #define OV5647_REG_MIPI_CTRL00 0x4800
5959 #define OV5647_REG_MIPI_CTRL14 0x4814
6060 #define OV5647_REG_AWB 0x5001
61+#define OV5647_REG_ISPCTRL3D 0x503d
6162
6263 #define REG_TERM 0xfffe
6364 #define VAL_TERM 0xfe
@@ -116,6 +117,20 @@ static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) · 52 unmodified lines
116117 return container_of(sd, struct ov5647, sd);
117118 }
118119
120+static const char * const ov5647_test_pattern_menu[] = {
121+ "Disabled",
122+ "Color Bars",
123+ "Color Squares",
124+ "Random Data",
125+};
126+
127+static const u8 ov5647_test_pattern_val[] = {
128+ 0x00, /* Disabled */
129+ 0x80, /* Color Bars */
130+ 0x82, /* Color Squares */
131+ 0x81, /* Random Data */
132+};
133+
119134 static const struct regval_list sensor_oe_disable_regs[] = {
120135 {0x3000, 0x00},
121136 {0x3001, 0x00},
@@ -614,23 +629,29 @@ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) · 492 unmodified lines
614629
615630 static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
616631 {
617− unsigned char data_w[2] = { reg >> 8, reg & 0xff };
618632 struct i2c_client *client = v4l2_get_subdevdata(sd);
633+ u8 buf[2] = { reg >> 8, reg & 0xff };
634+ struct i2c_msg msg[2];
619635 int ret;
620636
621− ret = i2c_master_send(client, data_w, 2);
622− if (ret < 0) {
623− dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
624− __func__, reg);
625− return ret;
637+ msg[0].addr = client->addr;
638+ msg[0].flags = client->flags;
639+ msg[0].buf = buf;
640+ msg[0].len = sizeof(buf);
641+
642+ msg[1].addr = client->addr;
643+ msg[1].flags = client->flags | I2C_M_RD;
644+ msg[1].buf = buf;
645+ msg[1].len = 1;
646+
647+ ret = i2c_transfer(client->adapter, msg, 2);
648+ if (ret != 2) {
649+ dev_err(&client->dev, "%s: i2c read error, reg: %x = %d\n",
650+ __func__, reg, ret);
651+ return ret >= 0 ? -EINVAL : ret;
626652 }
627653
628− ret = i2c_master_recv(client, val, 1);
629− if (ret < 0) {
630− dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
631− __func__, reg);
632− return ret;
633− }
654+ *val = buf[0];
634655
635656 return 0;
636657 }
@@ -1242,6 +1263,10 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) · 605 unmodified lines
12421263 ret = ov5647_write16(sd, OV5647_REG_VTS_HI,
12431264 sensor->mode->format.height + ctrl->val);
12441265 break;
1266+ case V4L2_CID_TEST_PATTERN:
1267+ ret = ov5647_write(sd, OV5647_REG_ISPCTRL3D,
1268+ ov5647_test_pattern_val[ctrl->val]);
1269+ break;
12451270
12461271 /* Read-only, but we adjust it based on mode. */
12471272 case V4L2_CID_PIXEL_RATE:
@@ -1270,7 +1295,7 @@ static int ov5647_init_controls(struct ov5647 *sensor) · 22 unmodified lines
12701295 struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
12711296 int hblank, exposure_max, exposure_def;
12721297
1273− v4l2_ctrl_handler_init(&sensor->ctrls, 8);
1298+ v4l2_ctrl_handler_init(&sensor->ctrls, 9);
12741299
12751300 v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
12761301 V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
@@ -1314,6 +1339,11 @@ static int ov5647_init_controls(struct ov5647 *sensor) · 37 unmodified lines
13141339 sensor->mode->vts -
13151340 sensor->mode->format.height);
13161341
1342+ v4l2_ctrl_new_std_menu_items(&sensor->ctrls, &ov5647_ctrl_ops,
1343+ V4L2_CID_TEST_PATTERN,
1344+ ARRAY_SIZE(ov5647_test_pattern_menu) - 1,
1345+ 0, 0, ov5647_test_pattern_menu);
1346+
13171347 if (sensor->ctrls.error)
13181348 goto handler_free;
13191349
drivers/media/i2c/ov5670.c+79−37
@@ -29,6 +29,12 @@ · 28 unmodified lines
2929 #define OV5670_REG_SOFTWARE_RST 0x0103
3030 #define OV5670_SOFTWARE_RST 0x01
3131
32+#define OV5670_MIPI_SC_CTRL0_REG 0x3018
33+#define OV5670_MIPI_SC_CTRL0_LANES(v) ((((v) - 1) << 5) & \
34+ GENMASK(7, 5))
35+#define OV5670_MIPI_SC_CTRL0_MIPI_EN BIT(4)
36+#define OV5670_MIPI_SC_CTRL0_RESERVED BIT(1)
37+
3238 /* vertical-timings from sensor */
3339 #define OV5670_REG_VTS 0x380e
3440 #define OV5670_VTS_30FPS 0x0808 /* default for 30 fps */
@@ -92,7 +98,6 @@ struct ov5670_reg_list { · 57 unmodified lines
9298 };
9399
94100 struct ov5670_link_freq_config {
95− u32 pixel_rate;
96101 const struct ov5670_reg_list reg_list;
97102 };
98103
@@ -163,7 +168,6 @@ static const struct ov5670_reg mode_2592x1944_regs[] = { · 64 unmodified lines
163168 {0x3005, 0xf0},
164169 {0x3007, 0x00},
165170 {0x3015, 0x0f},
166− {0x3018, 0x32},
167171 {0x301a, 0xf0},
168172 {0x301b, 0xf0},
169173 {0x301c, 0xf0},
@@ -429,7 +433,6 @@ static const struct ov5670_reg mode_1296x972_regs[] = { · 259 unmodified lines
429433 {0x3005, 0xf0},
430434 {0x3007, 0x00},
431435 {0x3015, 0x0f},
432− {0x3018, 0x32},
433436 {0x301a, 0xf0},
434437 {0x301b, 0xf0},
435438 {0x301c, 0xf0},
@@ -695,7 +698,6 @@ static const struct ov5670_reg mode_648x486_regs[] = { · 259 unmodified lines
695698 {0x3005, 0xf0},
696699 {0x3007, 0x00},
697700 {0x3015, 0x0f},
698− {0x3018, 0x32},
699701 {0x301a, 0xf0},
700702 {0x301b, 0xf0},
701703 {0x301c, 0xf0},
@@ -961,7 +963,6 @@ static const struct ov5670_reg mode_2560x1440_regs[] = { · 259 unmodified lines
961963 {0x3005, 0xf0},
962964 {0x3007, 0x00},
963965 {0x3015, 0x0f},
964− {0x3018, 0x32},
965966 {0x301a, 0xf0},
966967 {0x301b, 0xf0},
967968 {0x301c, 0xf0},
@@ -1226,7 +1227,6 @@ static const struct ov5670_reg mode_1280x720_regs[] = { · 258 unmodified lines
12261227 {0x3005, 0xf0},
12271228 {0x3007, 0x00},
12281229 {0x3015, 0x0f},
1229− {0x3018, 0x32},
12301230 {0x301a, 0xf0},
12311231 {0x301b, 0xf0},
12321232 {0x301c, 0xf0},
@@ -1492,7 +1492,6 @@ static const struct ov5670_reg mode_640x360_regs[] = { · 259 unmodified lines
14921492 {0x3005, 0xf0},
14931493 {0x3007, 0x00},
14941494 {0x3015, 0x0f},
1495− {0x3018, 0x32},
14961495 {0x301a, 0xf0},
14971496 {0x301b, 0xf0},
14981497 {0x301c, 0xf0},
@@ -1762,8 +1761,6 @@ static const char * const ov5670_test_pattern_menu[] = { · 263 unmodified lines
17621761 #define OV5670_LINK_FREQ_422MHZ_INDEX 0
17631762 static const struct ov5670_link_freq_config link_freq_configs[] = {
17641763 {
1765− /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
1766− .pixel_rate = (OV5670_LINK_FREQ_422MHZ * 2 * 2) / 10,
17671764 .reg_list = {
17681765 .num_of_regs = ARRAY_SIZE(mipi_data_rate_840mbps),
17691766 .regs = mipi_data_rate_840mbps,
@@ -1859,6 +1856,7 @@ static const struct ov5670_mode supported_modes[] = { · 89 unmodified lines
18591856 struct ov5670 {
18601857 struct v4l2_subdev sd;
18611858 struct media_pad pad;
1859+ struct v4l2_fwnode_endpoint endpoint;
18621860
18631861 struct v4l2_ctrl_handler ctrl_handler;
18641862 /* V4L2 Controls */
@@ -2101,9 +2099,13 @@ static const struct v4l2_ctrl_ops ov5670_ctrl_ops = { · 236 unmodified lines
21012099 /* Initialize control handlers */
21022100 static int ov5670_init_controls(struct ov5670 *ov5670)
21032101 {
2102+ struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
2103+ &ov5670->endpoint.bus.mipi_csi2;
21042104 struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
21052105 struct v4l2_fwnode_device_properties props;
21062106 struct v4l2_ctrl_handler *ctrl_hdlr;
2107+ unsigned int lanes_count;
2108+ s64 mipi_pixel_rate;
21072109 s64 vblank_max;
21082110 s64 vblank_def;
21092111 s64 vblank_min;
@@ -2124,12 +2126,15 @@ static int ov5670_init_controls(struct ov5670 *ov5670) · 14 unmodified lines
21242126 ov5670->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
21252127
21262128 /* By default, V4L2_CID_PIXEL_RATE is read only */
2129+ lanes_count = bus_mipi_csi2->num_data_lanes;
2130+ mipi_pixel_rate = OV5670_LINK_FREQ_422MHZ * 2 * lanes_count / 10;
2131+
21272132 ov5670->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops,
21282133 V4L2_CID_PIXEL_RATE,
2129− link_freq_configs[0].pixel_rate,
2130− link_freq_configs[0].pixel_rate,
2134+ mipi_pixel_rate,
2135+ mipi_pixel_rate,
21312136 1,
2132− link_freq_configs[0].pixel_rate);
2137+ mipi_pixel_rate);
21332138
21342139 vblank_max = OV5670_VTS_MAX - ov5670->cur_mode->height;
21352140 vblank_def = ov5670->cur_mode->vts_def - ov5670->cur_mode->height;
@@ -2288,8 +2293,13 @@ static int ov5670_set_pad_format(struct v4l2_subdev *sd, · 152 unmodified lines
22882293 struct v4l2_subdev_format *fmt)
22892294 {
22902295 struct ov5670 *ov5670 = to_ov5670(sd);
2296+ struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
2297+ &ov5670->endpoint.bus.mipi_csi2;
22912298 const struct ov5670_mode *mode;
2299+ unsigned int lanes_count;
2300+ s64 mipi_pixel_rate;
22922301 s32 vblank_def;
2302+ s64 link_freq;
22932303 s32 h_blank;
22942304
22952305 mutex_lock(&ov5670->mutex);
@@ -2306,9 +2316,14 @@ static int ov5670_set_pad_format(struct v4l2_subdev *sd, · 10 unmodified lines
23062316 } else {
23072317 ov5670->cur_mode = mode;
23082318 __v4l2_ctrl_s_ctrl(ov5670->link_freq, mode->link_freq_index);
2319+
2320+ lanes_count = bus_mipi_csi2->num_data_lanes;
2321+ link_freq = link_freq_menu_items[mode->link_freq_index];
2322+ /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
2323+ mipi_pixel_rate = div_s64(link_freq * 2 * lanes_count, 10);
23092324 __v4l2_ctrl_s_ctrl_int64(
23102325 ov5670->pixel_rate,
2311− link_freq_configs[mode->link_freq_index].pixel_rate);
2326+ mipi_pixel_rate);
23122327 /* Update limits and set FPS to default */
23132328 vblank_def = ov5670->cur_mode->vts_def -
23142329 ov5670->cur_mode->height;
@@ -2361,6 +2376,19 @@ static int ov5670_identify_module(struct ov5670 *ov5670) · 46 unmodified lines
23612376 return 0;
23622377 }
23632378
2379+static int ov5670_mipi_configure(struct ov5670 *ov5670)
2380+{
2381+ struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
2382+ &ov5670->endpoint.bus.mipi_csi2;
2383+ unsigned int lanes_count = bus_mipi_csi2->num_data_lanes;
2384+
2385+ return ov5670_write_reg(ov5670, OV5670_MIPI_SC_CTRL0_REG,
2386+ OV5670_REG_VALUE_08BIT,
2387+ OV5670_MIPI_SC_CTRL0_LANES(lanes_count) |
2388+ OV5670_MIPI_SC_CTRL0_MIPI_EN |
2389+ OV5670_MIPI_SC_CTRL0_RESERVED);
2390+}
2391+
23642392 /* Prepare streaming by writing default values and customized values */
23652393 static int ov5670_start_streaming(struct ov5670 *ov5670)
23662394 {
@@ -2399,6 +2427,12 @@ static int ov5670_start_streaming(struct ov5670 *ov5670) · 32 unmodified lines
23992427 return ret;
24002428 }
24012429
2430+ ret = ov5670_mipi_configure(ov5670);
2431+ if (ret) {
2432+ dev_err(&client->dev, "%s failed to configure MIPI\n", __func__);
2433+ return ret;
2434+ }
2435+
24022436 ret = __v4l2_ctrl_handler_setup(ov5670->sd.ctrl_handler);
24032437 if (ret)
24042438 return ret;
@@ -2647,23 +2681,20 @@ static int ov5670_gpio_probe(struct ov5670 *ov5670) · 242 unmodified lines
26472681
26482682 static int ov5670_probe(struct i2c_client *client)
26492683 {
2684+ struct fwnode_handle *handle;
26502685 struct ov5670 *ov5670;
2651− const char *err_msg;
26522686 u32 input_clk = 0;
26532687 bool full_power;
26542688 int ret;
26552689
26562690 ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL);
2657− if (!ov5670) {
2658− ret = -ENOMEM;
2659− err_msg = "devm_kzalloc() error";
2660− goto error_print;
2661− }
2691+ if (!ov5670)
2692+ return -ENOMEM;
26622693
2663− ov5670->xvclk = devm_clk_get(&client->dev, NULL);
2694+ ov5670->xvclk = devm_clk_get_optional(&client->dev, NULL);
26642695 if (!IS_ERR_OR_NULL(ov5670->xvclk))
26652696 input_clk = clk_get_rate(ov5670->xvclk);
2666− else if (PTR_ERR(ov5670->xvclk) == -ENOENT)
2697+ else if (!ov5670->xvclk || PTR_ERR(ov5670->xvclk) == -ENOENT)
26672698 device_property_read_u32(&client->dev, "clock-frequency",
26682699 &input_clk);
26692700 else
@@ -2680,29 +2711,38 @@ static int ov5670_probe(struct i2c_client *client) · 10 unmodified lines
26802711 v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
26812712
26822713 ret = ov5670_regulators_probe(ov5670);
2683− if (ret) {
2684− err_msg = "Regulators probe failed";
2685− goto error_print;
2686− }
2714+ if (ret)
2715+ return dev_err_probe(&client->dev, ret, "Regulators probe failed\n");
26872716
26882717 ret = ov5670_gpio_probe(ov5670);
2689− if (ret) {
2690− err_msg = "GPIO probe failed";
2691− goto error_print;
2692− }
2718+ if (ret)
2719+ return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");
2720+
2721+ /* Graph Endpoint */
2722+ handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
2723+ if (!handle)
2724+ return dev_err_probe(&client->dev, -ENXIO, "Endpoint for node get failed\n");
2725+
2726+ ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
2727+ ov5670->endpoint.bus.mipi_csi2.num_data_lanes = 2;
2728+
2729+ ret = v4l2_fwnode_endpoint_alloc_parse(handle, &ov5670->endpoint);
2730+ fwnode_handle_put(handle);
2731+ if (ret)
2732+ return dev_err_probe(&client->dev, ret, "Endpoint parse failed\n");
26932733
26942734 full_power = acpi_dev_state_d0(&client->dev);
26952735 if (full_power) {
26962736 ret = ov5670_runtime_resume(&client->dev);
26972737 if (ret) {
2698− err_msg = "Power up failed";
2699− goto error_print;
2738+ dev_err_probe(&client->dev, ret, "Power up failed\n");
2739+ goto error_endpoint;
27002740 }
27012741
27022742 /* Check module identity */
27032743 ret = ov5670_identify_module(ov5670);
27042744 if (ret) {
2705− err_msg = "ov5670_identify_module() error";
2745+ dev_err_probe(&client->dev, ret, "ov5670_identify_module() error\n");
27062746 goto error_power_off;
27072747 }
27082748 }
@@ -2714,7 +2754,7 @@ static int ov5670_probe(struct i2c_client *client) · 5 unmodified lines
27142754
27152755 ret = ov5670_init_controls(ov5670);
27162756 if (ret) {
2717− err_msg = "ov5670_init_controls() error";
2757+ dev_err_probe(&client->dev, ret, "ov5670_init_controls() error\n");
27182758 goto error_mutex_destroy;
27192759 }
27202760
@@ -2727,7 +2767,7 @@ static int ov5670_probe(struct i2c_client *client) · 6 unmodified lines
27272767 ov5670->pad.flags = MEDIA_PAD_FL_SOURCE;
27282768 ret = media_entity_pads_init(&ov5670->sd.entity, 1, &ov5670->pad);
27292769 if (ret) {
2730− err_msg = "media_entity_pads_init() error";
2770+ dev_err_probe(&client->dev, ret, "media_entity_pads_init() error\n");
27312771 goto error_handler_free;
27322772 }
27332773
@@ -2741,7 +2781,7 @@ static int ov5670_probe(struct i2c_client *client) · 7 unmodified lines
27412781 /* Async register for subdev */
27422782 ret = v4l2_async_register_subdev_sensor(&ov5670->sd);
27432783 if (ret < 0) {
2744− err_msg = "v4l2_async_register_subdev() error";
2784+ dev_err_probe(&client->dev, ret, "v4l2_async_register_subdev() error\n");
27452785 goto error_pm_disable;
27462786 }
27472787
@@ -2764,8 +2804,8 @@ error_power_off: · 16 unmodified lines
27642804 if (full_power)
27652805 ov5670_runtime_suspend(&client->dev);
27662806
2767−error_print:
2768− dev_err(&client->dev, "%s: %s %d\n", __func__, err_msg, ret);
2807+error_endpoint:
2808+ v4l2_fwnode_endpoint_free(&ov5670->endpoint);
27692809
27702810 return ret;
27712811 }
@@ -2782,6 +2822,8 @@ static void ov5670_remove(struct i2c_client *client) · 10 unmodified lines
27822822
27832823 pm_runtime_disable(&client->dev);
27842824 ov5670_runtime_suspend(&client->dev);
2825+
2826+ v4l2_fwnode_endpoint_free(&ov5670->endpoint);
27852827 }
27862828
27872829 static const struct dev_pm_ops ov5670_pm_ops = {
drivers/media/i2c/ov7670.c+3−8
@@ -1894,14 +1894,9 @@ static int ov7670_probe(struct i2c_client *client) · 1893 unmodified lines
18941894 info->pclk_hb_disable = true;
18951895 }
18961896
1897− info->clk = devm_clk_get(&client->dev, "xclk"); /* optional */
1898− if (IS_ERR(info->clk)) {
1899− ret = PTR_ERR(info->clk);
1900− if (ret == -ENOENT)
1901− info->clk = NULL;
1902− else
1903− return ret;
1904− }
1897+ info->clk = devm_clk_get_optional(&client->dev, "xclk");
1898+ if (IS_ERR(info->clk))
1899+ return PTR_ERR(info->clk);
19051900
19061901 ret = ov7670_init_gpio(client, info);
19071902 if (ret)
drivers/media/i2c/ov8856.c+0−40
@@ -1709,46 +1709,6 @@ static int ov8856_identify_module(struct ov8856 *ov8856) · 1708 unmodified lines
17091709 return -ENXIO;
17101710 }
17111711
1712− ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
1713− OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
1714− if (ret)
1715− return ret;
1716−
1717− ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL,
1718− OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO);
1719− if (ret) {
1720− dev_err(&client->dev, "failed to set otp mode");
1721− return ret;
1722− }
1723−
1724− ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL,
1725− OV8856_REG_VALUE_08BIT,
1726− OV8856_OTP_LOAD_CTRL_ENABLE);
1727− if (ret) {
1728− dev_err(&client->dev, "failed to enable load control");
1729− return ret;
1730− }
1731−
1732− ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION,
1733− OV8856_REG_VALUE_08BIT, &val);
1734− if (ret) {
1735− dev_err(&client->dev, "failed to read module revision");
1736− return ret;
1737− }
1738−
1739− dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n",
1740− val,
1741− val == OV8856_2A_MODULE ? "2A" :
1742− val == OV8856_1B_MODULE ? "1B" : "unknown revision",
1743− client->addr);
1744−
1745− ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
1746− OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY);
1747− if (ret) {
1748− dev_err(&client->dev, "failed to exit streaming mode");
1749− return ret;
1750− }
1751−
17521712 ov8856->identified = true;
17531713
17541714 return 0;
drivers/media/i2c/s5k6aa.c+0−1652
@@ -1,1652 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−/*
3− * Driver for Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor
4− * with embedded SoC ISP.
5− *
6− * Copyright (C) 2011, Samsung Electronics Co., Ltd.
7− * Sylwester Nawrocki <s.nawrocki@samsung.com>
8− *
9− * Based on a driver authored by Dongsoo Nathaniel Kim.
10− * Copyright (C) 2009, Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
11− */
12−
13−#include <linux/clk.h>
14−#include <linux/delay.h>
15−#include <linux/gpio.h>
16−#include <linux/i2c.h>
17−#include <linux/media.h>
18−#include <linux/module.h>
19−#include <linux/regulator/consumer.h>
20−#include <linux/slab.h>
21−
22−#include <media/media-entity.h>
23−#include <media/v4l2-ctrls.h>
24−#include <media/v4l2-device.h>
25−#include <media/v4l2-subdev.h>
26−#include <media/v4l2-mediabus.h>
27−#include <media/i2c/s5k6aa.h>
28−
29−static int debug;
30−module_param(debug, int, 0644);
31−
32−#define DRIVER_NAME "S5K6AA"
33−
34−/* The token to indicate array termination */
35−#define S5K6AA_TERM 0xffff
36−#define S5K6AA_OUT_WIDTH_DEF 640
37−#define S5K6AA_OUT_HEIGHT_DEF 480
38−#define S5K6AA_WIN_WIDTH_MAX 1280
39−#define S5K6AA_WIN_HEIGHT_MAX 1024
40−#define S5K6AA_WIN_WIDTH_MIN 8
41−#define S5K6AA_WIN_HEIGHT_MIN 8
42−
43−/*
44− * H/W register Interface (0xD0000000 - 0xD0000FFF)
45− */
46−#define AHB_MSB_ADDR_PTR 0xfcfc
47−#define GEN_REG_OFFSH 0xd000
48−#define REG_CMDWR_ADDRH 0x0028
49−#define REG_CMDWR_ADDRL 0x002a
50−#define REG_CMDRD_ADDRH 0x002c
51−#define REG_CMDRD_ADDRL 0x002e
52−#define REG_CMDBUF0_ADDR 0x0f12
53−#define REG_CMDBUF1_ADDR 0x0f10
54−
55−/*
56− * Host S/W Register interface (0x70000000 - 0x70002000)
57− * The value of the two most significant address bytes is 0x7000,
58− * (HOST_SWIF_OFFS_H). The register addresses below specify 2 LSBs.
59− */
60−#define HOST_SWIF_OFFSH 0x7000
61−
62−/* Initialization parameters */
63−/* Master clock frequency in KHz */
64−#define REG_I_INCLK_FREQ_L 0x01b8
65−#define REG_I_INCLK_FREQ_H 0x01ba
66−#define MIN_MCLK_FREQ_KHZ 6000U
67−#define MAX_MCLK_FREQ_KHZ 27000U
68−#define REG_I_USE_NPVI_CLOCKS 0x01c6
69−#define REG_I_USE_NMIPI_CLOCKS 0x01c8
70−
71−/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
72−#define REG_I_OPCLK_4KHZ(n) ((n) * 6 + 0x01cc)
73−#define REG_I_MIN_OUTRATE_4KHZ(n) ((n) * 6 + 0x01ce)
74−#define REG_I_MAX_OUTRATE_4KHZ(n) ((n) * 6 + 0x01d0)
75−#define SYS_PLL_OUT_FREQ (48000000 / 4000)
76−#define PCLK_FREQ_MIN (24000000 / 4000)
77−#define PCLK_FREQ_MAX (48000000 / 4000)
78−#define REG_I_INIT_PARAMS_UPDATED 0x01e0
79−#define REG_I_ERROR_INFO 0x01e2
80−
81−/* General purpose parameters */
82−#define REG_USER_BRIGHTNESS 0x01e4
83−#define REG_USER_CONTRAST 0x01e6
84−#define REG_USER_SATURATION 0x01e8
85−#define REG_USER_SHARPBLUR 0x01ea
86−
87−#define REG_G_SPEC_EFFECTS 0x01ee
88−#define REG_G_ENABLE_PREV 0x01f0
89−#define REG_G_ENABLE_PREV_CHG 0x01f2
90−#define REG_G_NEW_CFG_SYNC 0x01f8
91−#define REG_G_PREVZOOM_IN_WIDTH 0x020a
92−#define REG_G_PREVZOOM_IN_HEIGHT 0x020c
93−#define REG_G_PREVZOOM_IN_XOFFS 0x020e
94−#define REG_G_PREVZOOM_IN_YOFFS 0x0210
95−#define REG_G_INPUTS_CHANGE_REQ 0x021a
96−#define REG_G_ACTIVE_PREV_CFG 0x021c
97−#define REG_G_PREV_CFG_CHG 0x021e
98−#define REG_G_PREV_OPEN_AFTER_CH 0x0220
99−#define REG_G_PREV_CFG_ERROR 0x0222
100−
101−/* Preview control section. n = 0...4. */
102−#define PREG(n, x) ((n) * 0x26 + x)
103−#define REG_P_OUT_WIDTH(n) PREG(n, 0x0242)
104−#define REG_P_OUT_HEIGHT(n) PREG(n, 0x0244)
105−#define REG_P_FMT(n) PREG(n, 0x0246)
106−#define REG_P_MAX_OUT_RATE(n) PREG(n, 0x0248)
107−#define REG_P_MIN_OUT_RATE(n) PREG(n, 0x024a)
108−#define REG_P_PVI_MASK(n) PREG(n, 0x024c)
109−#define REG_P_CLK_INDEX(n) PREG(n, 0x024e)
110−#define REG_P_FR_RATE_TYPE(n) PREG(n, 0x0250)
111−#define FR_RATE_DYNAMIC 0
112−#define FR_RATE_FIXED 1
113−#define FR_RATE_FIXED_ACCURATE 2
114−#define REG_P_FR_RATE_Q_TYPE(n) PREG(n, 0x0252)
115−#define FR_RATE_Q_BEST_FRRATE 1 /* Binning enabled */
116−#define FR_RATE_Q_BEST_QUALITY 2 /* Binning disabled */
117−/* Frame period in 0.1 ms units */
118−#define REG_P_MAX_FR_TIME(n) PREG(n, 0x0254)
119−#define REG_P_MIN_FR_TIME(n) PREG(n, 0x0256)
120−/* Conversion to REG_P_[MAX/MIN]_FR_TIME value; __t: time in us */
121−#define US_TO_FR_TIME(__t) ((__t) / 100)
122−#define S5K6AA_MIN_FR_TIME 33300 /* us */
123−#define S5K6AA_MAX_FR_TIME 650000 /* us */
124−#define S5K6AA_MAX_HIGHRES_FR_TIME 666 /* x100 us */
125−/* The below 5 registers are for "device correction" values */
126−#define REG_P_COLORTEMP(n) PREG(n, 0x025e)
127−#define REG_P_PREV_MIRROR(n) PREG(n, 0x0262)
128−
129−/* Extended image property controls */
130−/* Exposure time in 10 us units */
131−#define REG_SF_USR_EXPOSURE_L 0x03c6
132−#define REG_SF_USR_EXPOSURE_H 0x03c8
133−#define REG_SF_USR_EXPOSURE_CHG 0x03ca
134−#define REG_SF_USR_TOT_GAIN 0x03cc
135−#define REG_SF_USR_TOT_GAIN_CHG 0x03ce
136−#define REG_SF_RGAIN 0x03d0
137−#define REG_SF_RGAIN_CHG 0x03d2
138−#define REG_SF_GGAIN 0x03d4
139−#define REG_SF_GGAIN_CHG 0x03d6
140−#define REG_SF_BGAIN 0x03d8
141−#define REG_SF_BGAIN_CHG 0x03da
142−#define REG_SF_FLICKER_QUANT 0x03dc
143−#define REG_SF_FLICKER_QUANT_CHG 0x03de
144−
145−/* Output interface (parallel/MIPI) setup */
146−#define REG_OIF_EN_MIPI_LANES 0x03fa
147−#define REG_OIF_EN_PACKETS 0x03fc
148−#define REG_OIF_CFG_CHG 0x03fe
149−
150−/* Auto-algorithms enable mask */
151−#define REG_DBG_AUTOALG_EN 0x0400
152−#define AALG_ALL_EN_MASK (1 << 0)
153−#define AALG_AE_EN_MASK (1 << 1)
154−#define AALG_DIVLEI_EN_MASK (1 << 2)
155−#define AALG_WB_EN_MASK (1 << 3)
156−#define AALG_FLICKER_EN_MASK (1 << 5)
157−#define AALG_FIT_EN_MASK (1 << 6)
158−#define AALG_WRHW_EN_MASK (1 << 7)
159−
160−/* Firmware revision information */
161−#define REG_FW_APIVER 0x012e
162−#define S5K6AAFX_FW_APIVER 0x0001
163−#define REG_FW_REVISION 0x0130
164−
165−/* For now we use only one user configuration register set */
166−#define S5K6AA_MAX_PRESETS 1
167−
168−static const char * const s5k6aa_supply_names[] = {
169− "vdd_core", /* Digital core supply 1.5V (1.4V to 1.6V) */
170− "vdda", /* Analog power supply 2.8V (2.6V to 3.0V) */
171− "vdd_reg", /* Regulator input power 1.8V (1.7V to 1.9V)
172− or 2.8V (2.6V to 3.0) */
173− "vddio", /* I/O supply 1.8V (1.65V to 1.95V)
174− or 2.8V (2.5V to 3.1V) */
175−};
176−#define S5K6AA_NUM_SUPPLIES ARRAY_SIZE(s5k6aa_supply_names)
177−
178−enum s5k6aa_gpio_id {
179− STBY,
180− RSET,
181− GPIO_NUM,
182−};
183−
184−struct s5k6aa_regval {
185− u16 addr;
186− u16 val;
187−};
188−
189−struct s5k6aa_pixfmt {
190− u32 code;
191− u32 colorspace;
192− /* REG_P_FMT(x) register value */
193− u16 reg_p_fmt;
194−};
195−
196−struct s5k6aa_preset {
197− /* output pixel format and resolution */
198− struct v4l2_mbus_framefmt mbus_fmt;
199− u8 clk_id;
200− u8 index;
201−};
202−
203−struct s5k6aa_ctrls {
204− struct v4l2_ctrl_handler handler;
205− /* Auto / manual white balance cluster */
206− struct v4l2_ctrl *awb;
207− struct v4l2_ctrl *gain_red;
208− struct v4l2_ctrl *gain_blue;
209− struct v4l2_ctrl *gain_green;
210− /* Mirror cluster */
211− struct v4l2_ctrl *hflip;
212− struct v4l2_ctrl *vflip;
213− /* Auto exposure / manual exposure and gain cluster */
214− struct v4l2_ctrl *auto_exp;
215− struct v4l2_ctrl *exposure;
216− struct v4l2_ctrl *gain;
217−};
218−
219−struct s5k6aa_interval {
220− u16 reg_fr_time;
221− struct v4l2_fract interval;
222− /* Maximum rectangle for the interval */
223− struct v4l2_frmsize_discrete size;
224−};
225−
226−struct s5k6aa {
227− struct v4l2_subdev sd;
228− struct media_pad pad;
229−
230− enum v4l2_mbus_type bus_type;
231− u8 mipi_lanes;
232−
233− int (*s_power)(int enable);
234− struct regulator_bulk_data supplies[S5K6AA_NUM_SUPPLIES];
235− struct s5k6aa_gpio gpio[GPIO_NUM];
236−
237− /* external master clock frequency */
238− unsigned long mclk_frequency;
239− /* ISP internal master clock frequency */
240− u16 clk_fop;
241− /* output pixel clock frequency range */
242− u16 pclk_fmin;
243− u16 pclk_fmax;
244−
245− unsigned int inv_hflip:1;
246− unsigned int inv_vflip:1;
247−
248− /* protects the struct members below */
249− struct mutex lock;
250−
251− /* sensor matrix scan window */
252− struct v4l2_rect ccd_rect;
253−
254− struct s5k6aa_ctrls ctrls;
255− struct s5k6aa_preset presets[S5K6AA_MAX_PRESETS];
256− struct s5k6aa_preset *preset;
257− const struct s5k6aa_interval *fiv;
258−
259− unsigned int streaming:1;
260− unsigned int apply_cfg:1;
261− unsigned int apply_crop:1;
262− unsigned int power;
263−};
264−
265−static struct s5k6aa_regval s5k6aa_analog_config[] = {
266− /* Analog settings */
267− { 0x112a, 0x0000 }, { 0x1132, 0x0000 },
268− { 0x113e, 0x0000 }, { 0x115c, 0x0000 },
269− { 0x1164, 0x0000 }, { 0x1174, 0x0000 },
270− { 0x1178, 0x0000 }, { 0x077a, 0x0000 },
271− { 0x077c, 0x0000 }, { 0x077e, 0x0000 },
272− { 0x0780, 0x0000 }, { 0x0782, 0x0000 },
273− { 0x0784, 0x0000 }, { 0x0786, 0x0000 },
274− { 0x0788, 0x0000 }, { 0x07a2, 0x0000 },
275− { 0x07a4, 0x0000 }, { 0x07a6, 0x0000 },
276− { 0x07a8, 0x0000 }, { 0x07b6, 0x0000 },
277− { 0x07b8, 0x0002 }, { 0x07ba, 0x0004 },
278− { 0x07bc, 0x0004 }, { 0x07be, 0x0005 },
279− { 0x07c0, 0x0005 }, { S5K6AA_TERM, 0 },
280−};
281−
282−/* TODO: Add RGB888 and Bayer format */
283−static const struct s5k6aa_pixfmt s5k6aa_formats[] = {
284− { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 },
285− /* range 16-240 */
286− { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 },
287− { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 },
288−};
289−
290−static const struct s5k6aa_interval s5k6aa_intervals[] = {
291− { 1000, {10000, 1000000}, {1280, 1024} }, /* 10 fps */
292− { 666, {15000, 1000000}, {1280, 1024} }, /* 15 fps */
293− { 500, {20000, 1000000}, {1280, 720} }, /* 20 fps */
294− { 400, {25000, 1000000}, {640, 480} }, /* 25 fps */
295− { 333, {33300, 1000000}, {640, 480} }, /* 30 fps */
296−};
297−
298−#define S5K6AA_INTERVAL_DEF_INDEX 1 /* 15 fps */
299−
300−static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
301−{
302− return &container_of(ctrl->handler, struct s5k6aa, ctrls.handler)->sd;
303−}
304−
305−static inline struct s5k6aa *to_s5k6aa(struct v4l2_subdev *sd)
306−{
307− return container_of(sd, struct s5k6aa, sd);
308−}
309−
310−/* Set initial values for all preview presets */
311−static void s5k6aa_presets_data_init(struct s5k6aa *s5k6aa)
312−{
313− struct s5k6aa_preset *preset = &s5k6aa->presets[0];
314− int i;
315−
316− for (i = 0; i < S5K6AA_MAX_PRESETS; i++) {
317− preset->mbus_fmt.width = S5K6AA_OUT_WIDTH_DEF;
318− preset->mbus_fmt.height = S5K6AA_OUT_HEIGHT_DEF;
319− preset->mbus_fmt.code = s5k6aa_formats[0].code;
320− preset->index = i;
321− preset->clk_id = 0;
322− preset++;
323− }
324−
325− s5k6aa->fiv = &s5k6aa_intervals[S5K6AA_INTERVAL_DEF_INDEX];
326− s5k6aa->preset = &s5k6aa->presets[0];
327−}
328−
329−static int s5k6aa_i2c_read(struct i2c_client *client, u16 addr, u16 *val)
330−{
331− u8 wbuf[2] = {addr >> 8, addr & 0xFF};
332− struct i2c_msg msg[2];
333− u8 rbuf[2];
334− int ret;
335−
336− msg[0].addr = client->addr;
337− msg[0].flags = 0;
338− msg[0].len = 2;
339− msg[0].buf = wbuf;
340−
341− msg[1].addr = client->addr;
342− msg[1].flags = I2C_M_RD;
343− msg[1].len = 2;
344− msg[1].buf = rbuf;
345−
346− ret = i2c_transfer(client->adapter, msg, 2);
347− *val = be16_to_cpu(*((__be16 *)rbuf));
348−
349− v4l2_dbg(3, debug, client, "i2c_read: 0x%04X : 0x%04x\n", addr, *val);
350−
351− return ret == 2 ? 0 : ret;
352−}
353−
354−static int s5k6aa_i2c_write(struct i2c_client *client, u16 addr, u16 val)
355−{
356− u8 buf[4] = {addr >> 8, addr & 0xFF, val >> 8, val & 0xFF};
357−
358− int ret = i2c_master_send(client, buf, 4);
359− v4l2_dbg(3, debug, client, "i2c_write: 0x%04X : 0x%04x\n", addr, val);
360−
361− return ret == 4 ? 0 : ret;
362−}
363−
364−/* The command register write, assumes Command_Wr_addH = 0x7000. */
365−static int s5k6aa_write(struct i2c_client *c, u16 addr, u16 val)
366−{
367− int ret = s5k6aa_i2c_write(c, REG_CMDWR_ADDRL, addr);
368− if (ret)
369− return ret;
370− return s5k6aa_i2c_write(c, REG_CMDBUF0_ADDR, val);
371−}
372−
373−/* The command register read, assumes Command_Rd_addH = 0x7000. */
374−static int s5k6aa_read(struct i2c_client *client, u16 addr, u16 *val)
375−{
376− int ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRL, addr);
377− if (ret)
378− return ret;
379− return s5k6aa_i2c_read(client, REG_CMDBUF0_ADDR, val);
380−}
381−
382−static int s5k6aa_write_array(struct v4l2_subdev *sd,
383− const struct s5k6aa_regval *msg)
384−{
385− struct i2c_client *client = v4l2_get_subdevdata(sd);
386− u16 addr_incr = 0;
387− int ret = 0;
388−
389− while (msg->addr != S5K6AA_TERM) {
390− if (addr_incr != 2)
391− ret = s5k6aa_i2c_write(client, REG_CMDWR_ADDRL,
392− msg->addr);
393− if (ret)
394− break;
395− ret = s5k6aa_i2c_write(client, REG_CMDBUF0_ADDR, msg->val);
396− if (ret)
397− break;
398− /* Assume that msg->addr is always less than 0xfffc */
399− addr_incr = (msg + 1)->addr - msg->addr;
400− msg++;
401− }
402−
403− return ret;
404−}
405−
406−/* Configure the AHB high address bytes for GTG registers access */
407−static int s5k6aa_set_ahb_address(struct i2c_client *client)
408−{
409− int ret = s5k6aa_i2c_write(client, AHB_MSB_ADDR_PTR, GEN_REG_OFFSH);
410− if (ret)
411− return ret;
412− ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRH, HOST_SWIF_OFFSH);
413− if (ret)
414− return ret;
415− return s5k6aa_i2c_write(client, REG_CMDWR_ADDRH, HOST_SWIF_OFFSH);
416−}
417−
418−/**
419− * s5k6aa_configure_pixel_clocks - apply ISP main clock/PLL configuration
420− * @s5k6aa: pointer to &struct s5k6aa describing the device
421− *
422− * Configure the internal ISP PLL for the required output frequency.
423− * Locking: called with s5k6aa.lock mutex held.
424− */
425−static int s5k6aa_configure_pixel_clocks(struct s5k6aa *s5k6aa)
426−{
427− struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
428− unsigned long fmclk = s5k6aa->mclk_frequency / 1000;
429− u16 status;
430− int ret;
431−
432− if (WARN(fmclk < MIN_MCLK_FREQ_KHZ || fmclk > MAX_MCLK_FREQ_KHZ,
433− "Invalid clock frequency: %ld\n", fmclk))
434− return -EINVAL;
435−
436− s5k6aa->pclk_fmin = PCLK_FREQ_MIN;
437− s5k6aa->pclk_fmax = PCLK_FREQ_MAX;
438− s5k6aa->clk_fop = SYS_PLL_OUT_FREQ;
439−
440− /* External input clock frequency in kHz */
441− ret = s5k6aa_write(c, REG_I_INCLK_FREQ_H, fmclk >> 16);
442− if (!ret)
443− ret = s5k6aa_write(c, REG_I_INCLK_FREQ_L, fmclk & 0xFFFF);
444− if (!ret)
445− ret = s5k6aa_write(c, REG_I_USE_NPVI_CLOCKS, 1);
446− /* Internal PLL frequency */
447− if (!ret)
448− ret = s5k6aa_write(c, REG_I_OPCLK_4KHZ(0), s5k6aa->clk_fop);
449− if (!ret)
450− ret = s5k6aa_write(c, REG_I_MIN_OUTRATE_4KHZ(0),
451− s5k6aa->pclk_fmin);
452− if (!ret)
453− ret = s5k6aa_write(c, REG_I_MAX_OUTRATE_4KHZ(0),
454− s5k6aa->pclk_fmax);
455− if (!ret)
456− ret = s5k6aa_write(c, REG_I_INIT_PARAMS_UPDATED, 1);
457− if (!ret)
458− ret = s5k6aa_read(c, REG_I_ERROR_INFO, &status);
459−
460− return ret ? ret : (status ? -EINVAL : 0);
461−}
462−
463−/* Set horizontal and vertical image flipping */
464−static int s5k6aa_set_mirror(struct s5k6aa *s5k6aa, int horiz_flip)
465−{
466− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
467− int index = s5k6aa->preset->index;
468−
469− unsigned int vflip = s5k6aa->ctrls.vflip->val ^ s5k6aa->inv_vflip;
470− unsigned int flip = (horiz_flip ^ s5k6aa->inv_hflip) | (vflip << 1);
471−
472− return s5k6aa_write(client, REG_P_PREV_MIRROR(index), flip);
473−}
474−
475−/* Configure auto/manual white balance and R/G/B gains */
476−static int s5k6aa_set_awb(struct s5k6aa *s5k6aa, int awb)
477−{
478− struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
479− struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
480− u16 reg;
481−
482− int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &reg);
483−
484− if (!ret && !awb) {
485− ret = s5k6aa_write(c, REG_SF_RGAIN, ctrls->gain_red->val);
486− if (!ret)
487− ret = s5k6aa_write(c, REG_SF_RGAIN_CHG, 1);
488− if (ret)
489− return ret;
490−
491− ret = s5k6aa_write(c, REG_SF_GGAIN, ctrls->gain_green->val);
492− if (!ret)
493− ret = s5k6aa_write(c, REG_SF_GGAIN_CHG, 1);
494− if (ret)
495− return ret;
496−
497− ret = s5k6aa_write(c, REG_SF_BGAIN, ctrls->gain_blue->val);
498− if (!ret)
499− ret = s5k6aa_write(c, REG_SF_BGAIN_CHG, 1);
500− }
501− if (!ret) {
502− reg = awb ? reg | AALG_WB_EN_MASK : reg & ~AALG_WB_EN_MASK;
503− ret = s5k6aa_write(c, REG_DBG_AUTOALG_EN, reg);
504− }
505−
506− return ret;
507−}
508−
509−/* Program FW with exposure time, 'exposure' in us units */
510−static int s5k6aa_set_user_exposure(struct i2c_client *client, int exposure)
511−{
512− unsigned int time = exposure / 10;
513−
514− int ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_L, time & 0xffff);
515− if (!ret)
516− ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_H, time >> 16);
517− if (ret)
518− return ret;
519− return s5k6aa_write(client, REG_SF_USR_EXPOSURE_CHG, 1);
520−}
521−
522−static int s5k6aa_set_user_gain(struct i2c_client *client, int gain)
523−{
524− int ret = s5k6aa_write(client, REG_SF_USR_TOT_GAIN, gain);
525− if (ret)
526− return ret;
527− return s5k6aa_write(client, REG_SF_USR_TOT_GAIN_CHG, 1);
528−}
529−
530−/* Set auto/manual exposure and total gain */
531−static int s5k6aa_set_auto_exposure(struct s5k6aa *s5k6aa, int value)
532−{
533− struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
534− unsigned int exp_time = s5k6aa->ctrls.exposure->val;
535− u16 auto_alg;
536−
537− int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &auto_alg);
538− if (ret)
539− return ret;
540−
541− v4l2_dbg(1, debug, c, "man_exp: %d, auto_exp: %d, a_alg: 0x%x\n",
542− exp_time, value, auto_alg);
543−
544− if (value == V4L2_EXPOSURE_AUTO) {
545− auto_alg |= AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK;
546− } else {
547− ret = s5k6aa_set_user_exposure(c, exp_time);
548− if (ret)
549− return ret;
550− ret = s5k6aa_set_user_gain(c, s5k6aa->ctrls.gain->val);
551− if (ret)
552− return ret;
553− auto_alg &= ~(AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK);
554− }
555−
556− return s5k6aa_write(c, REG_DBG_AUTOALG_EN, auto_alg);
557−}
558−
559−static int s5k6aa_set_anti_flicker(struct s5k6aa *s5k6aa, int value)
560−{
561− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
562− u16 auto_alg;
563− int ret;
564−
565− ret = s5k6aa_read(client, REG_DBG_AUTOALG_EN, &auto_alg);
566− if (ret)
567− return ret;
568−
569− if (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
570− auto_alg |= AALG_FLICKER_EN_MASK;
571− } else {
572− auto_alg &= ~AALG_FLICKER_EN_MASK;
573− /* The V4L2_CID_LINE_FREQUENCY control values match
574− * the register values */
575− ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT, value);
576− if (ret)
577− return ret;
578− ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT_CHG, 1);
579− if (ret)
580− return ret;
581− }
582−
583− return s5k6aa_write(client, REG_DBG_AUTOALG_EN, auto_alg);
584−}
585−
586−static int s5k6aa_set_colorfx(struct s5k6aa *s5k6aa, int val)
587−{
588− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
589− static const struct v4l2_control colorfx[] = {
590− { V4L2_COLORFX_NONE, 0 },
591− { V4L2_COLORFX_BW, 1 },
592− { V4L2_COLORFX_NEGATIVE, 2 },
593− { V4L2_COLORFX_SEPIA, 3 },
594− { V4L2_COLORFX_SKY_BLUE, 4 },
595− { V4L2_COLORFX_SKETCH, 5 },
596− };
597− int i;
598−
599− for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
600− if (colorfx[i].id == val)
601− return s5k6aa_write(client, REG_G_SPEC_EFFECTS,
602− colorfx[i].value);
603− }
604− return -EINVAL;
605−}
606−
607−static int s5k6aa_preview_config_status(struct i2c_client *client)
608−{
609− u16 error = 0;
610− int ret = s5k6aa_read(client, REG_G_PREV_CFG_ERROR, &error);
611−
612− v4l2_dbg(1, debug, client, "error: 0x%x (%d)\n", error, ret);
613− return ret ? ret : (error ? -EINVAL : 0);
614−}
615−
616−static int s5k6aa_get_pixfmt_index(struct s5k6aa *s5k6aa,
617− struct v4l2_mbus_framefmt *mf)
618−{
619− unsigned int i;
620−
621− for (i = 0; i < ARRAY_SIZE(s5k6aa_formats); i++)
622− if (mf->colorspace == s5k6aa_formats[i].colorspace &&
623− mf->code == s5k6aa_formats[i].code)
624− return i;
625− return 0;
626−}
627−
628−static int s5k6aa_set_output_framefmt(struct s5k6aa *s5k6aa,
629− struct s5k6aa_preset *preset)
630−{
631− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
632− int fmt_index = s5k6aa_get_pixfmt_index(s5k6aa, &preset->mbus_fmt);
633− int ret;
634−
635− ret = s5k6aa_write(client, REG_P_OUT_WIDTH(preset->index),
636− preset->mbus_fmt.width);
637− if (!ret)
638− ret = s5k6aa_write(client, REG_P_OUT_HEIGHT(preset->index),
639− preset->mbus_fmt.height);
640− if (!ret)
641− ret = s5k6aa_write(client, REG_P_FMT(preset->index),
642− s5k6aa_formats[fmt_index].reg_p_fmt);
643− return ret;
644−}
645−
646−static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
647−{
648− struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
649− struct v4l2_rect *r = &s5k6aa->ccd_rect;
650− int ret;
651−
652− ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_WIDTH, r->width);
653− if (!ret)
654− ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_HEIGHT, r->height);
655− if (!ret)
656− ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_XOFFS, r->left);
657− if (!ret)
658− ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_YOFFS, r->top);
659− if (!ret)
660− ret = s5k6aa_write(c, REG_G_INPUTS_CHANGE_REQ, 1);
661− if (!ret)
662− s5k6aa->apply_crop = 0;
663−
664− return ret;
665−}
666−
667−/**
668− * s5k6aa_configure_video_bus - configure the video output interface
669− * @s5k6aa: pointer to &struct s5k6aa describing the device
670− * @bus_type: video bus type: parallel or MIPI-CSI
671− * @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
672− *
673− * Note: Only parallel bus operation has been tested.
674− */
675−static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa,
676− enum v4l2_mbus_type bus_type, int nlanes)
677−{
678− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
679− u16 cfg = 0;
680− int ret;
681−
682− /*
683− * TODO: The sensor is supposed to support BT.601 and BT.656
684− * but there is nothing indicating how to switch between both
685− * in the datasheet. For now default BT.601 interface is assumed.
686− */
687− if (bus_type == V4L2_MBUS_CSI2_DPHY)
688− cfg = nlanes;
689− else if (bus_type != V4L2_MBUS_PARALLEL)
690− return -EINVAL;
691−
692− ret = s5k6aa_write(client, REG_OIF_EN_MIPI_LANES, cfg);
693− if (ret)
694− return ret;
695− return s5k6aa_write(client, REG_OIF_CFG_CHG, 1);
696−}
697−
698−/* This function should be called when switching to new user configuration set*/
699−static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
700− int cid)
701−{
702− unsigned long end = jiffies + msecs_to_jiffies(timeout);
703− u16 reg = 1;
704− int ret;
705−
706− ret = s5k6aa_write(client, REG_G_ACTIVE_PREV_CFG, cid);
707− if (!ret)
708− ret = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
709− if (!ret)
710− ret = s5k6aa_write(client, REG_G_NEW_CFG_SYNC, 1);
711− if (timeout == 0)
712− return ret;
713−
714− while (ret >= 0 && time_is_after_jiffies(end)) {
715− ret = s5k6aa_read(client, REG_G_NEW_CFG_SYNC, &reg);
716− if (!reg)
717− return 0;
718− usleep_range(1000, 5000);
719− }
720− return ret ? ret : -ETIMEDOUT;
721−}
722−
723−/**
724− * s5k6aa_set_prev_config - write user preview register set
725− * @s5k6aa: pointer to &struct s5k6aa describing the device
726− * @preset: s5kaa preset to be applied
727− *
728− * Configure output resolution and color format, pixel clock
729− * frequency range, device frame rate type and frame period range.
730− */
731−static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
732− struct s5k6aa_preset *preset)
733−{
734− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
735− int idx = preset->index;
736− u16 frame_rate_q;
737− int ret;
738−
739− if (s5k6aa->fiv->reg_fr_time >= S5K6AA_MAX_HIGHRES_FR_TIME)
740− frame_rate_q = FR_RATE_Q_BEST_FRRATE;
741− else
742− frame_rate_q = FR_RATE_Q_BEST_QUALITY;
743−
744− ret = s5k6aa_set_output_framefmt(s5k6aa, preset);
745− if (!ret)
746− ret = s5k6aa_write(client, REG_P_MAX_OUT_RATE(idx),
747− s5k6aa->pclk_fmax);
748− if (!ret)
749− ret = s5k6aa_write(client, REG_P_MIN_OUT_RATE(idx),
750− s5k6aa->pclk_fmin);
751− if (!ret)
752− ret = s5k6aa_write(client, REG_P_CLK_INDEX(idx),
753− preset->clk_id);
754− if (!ret)
755− ret = s5k6aa_write(client, REG_P_FR_RATE_TYPE(idx),
756− FR_RATE_DYNAMIC);
757− if (!ret)
758− ret = s5k6aa_write(client, REG_P_FR_RATE_Q_TYPE(idx),
759− frame_rate_q);
760− if (!ret)
761− ret = s5k6aa_write(client, REG_P_MAX_FR_TIME(idx),
762− s5k6aa->fiv->reg_fr_time + 33);
763− if (!ret)
764− ret = s5k6aa_write(client, REG_P_MIN_FR_TIME(idx),
765− s5k6aa->fiv->reg_fr_time - 33);
766− if (!ret)
767− ret = s5k6aa_new_config_sync(client, 250, idx);
768− if (!ret)
769− ret = s5k6aa_preview_config_status(client);
770− if (!ret)
771− s5k6aa->apply_cfg = 0;
772−
773− v4l2_dbg(1, debug, client, "Frame interval: %d +/- 3.3ms. (%d)\n",
774− s5k6aa->fiv->reg_fr_time, ret);
775− return ret;
776−}
777−
778−/**
779− * s5k6aa_initialize_isp - basic ISP MCU initialization
780− * @sd: pointer to V4L2 sub-device descriptor
781− *
782− * Configure AHB addresses for registers read/write; configure PLLs for
783− * required output pixel clock. The ISP power supply needs to be already
784− * enabled, with an optional H/W reset.
785− * Locking: called with s5k6aa.lock mutex held.
786− */
787−static int s5k6aa_initialize_isp(struct v4l2_subdev *sd)
788−{
789− struct i2c_client *client = v4l2_get_subdevdata(sd);
790− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
791− int ret;
792−
793− s5k6aa->apply_crop = 1;
794− s5k6aa->apply_cfg = 1;
795− msleep(100);
796−
797− ret = s5k6aa_set_ahb_address(client);
798− if (ret)
799− return ret;
800− ret = s5k6aa_configure_video_bus(s5k6aa, s5k6aa->bus_type,
801− s5k6aa->mipi_lanes);
802− if (ret)
803− return ret;
804− ret = s5k6aa_write_array(sd, s5k6aa_analog_config);
805− if (ret)
806− return ret;
807− msleep(20);
808−
809− return s5k6aa_configure_pixel_clocks(s5k6aa);
810−}
811−
812−static int s5k6aa_gpio_set_value(struct s5k6aa *priv, int id, u32 val)
813−{
814− if (!gpio_is_valid(priv->gpio[id].gpio))
815− return 0;
816− gpio_set_value(priv->gpio[id].gpio, !!val);
817− return 1;
818−}
819−
820−static int s5k6aa_gpio_assert(struct s5k6aa *priv, int id)
821−{
822− return s5k6aa_gpio_set_value(priv, id, priv->gpio[id].level);
823−}
824−
825−static int s5k6aa_gpio_deassert(struct s5k6aa *priv, int id)
826−{
827− return s5k6aa_gpio_set_value(priv, id, !priv->gpio[id].level);
828−}
829−
830−static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
831−{
832− int ret;
833−
834− ret = regulator_bulk_enable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
835− if (ret)
836− return ret;
837− if (s5k6aa_gpio_deassert(s5k6aa, STBY))
838− usleep_range(150, 200);
839−
840− if (s5k6aa->s_power)
841− ret = s5k6aa->s_power(1);
842− usleep_range(4000, 5000);
843−
844− if (s5k6aa_gpio_deassert(s5k6aa, RSET))
845− msleep(20);
846−
847− return ret;
848−}
849−
850−static int __s5k6aa_power_off(struct s5k6aa *s5k6aa)
851−{
852− int ret;
853−
854− if (s5k6aa_gpio_assert(s5k6aa, RSET))
855− usleep_range(100, 150);
856−
857− if (s5k6aa->s_power) {
858− ret = s5k6aa->s_power(0);
859− if (ret)
860− return ret;
861− }
862− if (s5k6aa_gpio_assert(s5k6aa, STBY))
863− usleep_range(50, 100);
864− s5k6aa->streaming = 0;
865−
866− return regulator_bulk_disable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
867−}
868−
869−/*
870− * V4L2 subdev core and video operations
871− */
872−static int s5k6aa_set_power(struct v4l2_subdev *sd, int on)
873−{
874− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
875− int ret = 0;
876−
877− mutex_lock(&s5k6aa->lock);
878−
879− if (s5k6aa->power == !on) {
880− if (on) {
881− ret = __s5k6aa_power_on(s5k6aa);
882− if (!ret)
883− ret = s5k6aa_initialize_isp(sd);
884− } else {
885− ret = __s5k6aa_power_off(s5k6aa);
886− }
887−
888− if (!ret)
889− s5k6aa->power += on ? 1 : -1;
890− }
891−
892− mutex_unlock(&s5k6aa->lock);
893−
894− if (!on || ret || s5k6aa->power != 1)
895− return ret;
896−
897− return v4l2_ctrl_handler_setup(sd->ctrl_handler);
898−}
899−
900−static int __s5k6aa_stream(struct s5k6aa *s5k6aa, int enable)
901−{
902− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
903− int ret = 0;
904−
905− ret = s5k6aa_write(client, REG_G_ENABLE_PREV, enable);
906− if (!ret)
907− ret = s5k6aa_write(client, REG_G_ENABLE_PREV_CHG, 1);
908− if (!ret)
909− s5k6aa->streaming = enable;
910−
911− return ret;
912−}
913−
914−static int s5k6aa_s_stream(struct v4l2_subdev *sd, int on)
915−{
916− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
917− int ret = 0;
918−
919− mutex_lock(&s5k6aa->lock);
920−
921− if (s5k6aa->streaming == !on) {
922− if (!ret && s5k6aa->apply_cfg)
923− ret = s5k6aa_set_prev_config(s5k6aa, s5k6aa->preset);
924− if (s5k6aa->apply_crop)
925− ret = s5k6aa_set_input_params(s5k6aa);
926− if (!ret)
927− ret = __s5k6aa_stream(s5k6aa, !!on);
928− }
929− mutex_unlock(&s5k6aa->lock);
930−
931− return ret;
932−}
933−
934−static int s5k6aa_g_frame_interval(struct v4l2_subdev *sd,
935− struct v4l2_subdev_frame_interval *fi)
936−{
937− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
938−
939− mutex_lock(&s5k6aa->lock);
940− fi->interval = s5k6aa->fiv->interval;
941− mutex_unlock(&s5k6aa->lock);
942−
943− return 0;
944−}
945−
946−static int __s5k6aa_set_frame_interval(struct s5k6aa *s5k6aa,
947− struct v4l2_subdev_frame_interval *fi)
948−{
949− struct v4l2_mbus_framefmt *mbus_fmt = &s5k6aa->preset->mbus_fmt;
950− const struct s5k6aa_interval *fiv = &s5k6aa_intervals[0];
951− unsigned int err, min_err = UINT_MAX;
952− unsigned int i, fr_time;
953−
954− if (fi->interval.denominator == 0)
955− return -EINVAL;
956−
957− fr_time = fi->interval.numerator * 10000 / fi->interval.denominator;
958−
959− for (i = 0; i < ARRAY_SIZE(s5k6aa_intervals); i++) {
960− const struct s5k6aa_interval *iv = &s5k6aa_intervals[i];
961−
962− if (mbus_fmt->width > iv->size.width ||
963− mbus_fmt->height > iv->size.height)
964− continue;
965−
966− err = abs(iv->reg_fr_time - fr_time);
967− if (err < min_err) {
968− fiv = iv;
969− min_err = err;
970− }
971− }
972− s5k6aa->fiv = fiv;
973−
974− v4l2_dbg(1, debug, &s5k6aa->sd, "Changed frame interval to %d us\n",
975− fiv->reg_fr_time * 100);
976− return 0;
977−}
978−
979−static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd,
980− struct v4l2_subdev_frame_interval *fi)
981−{
982− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
983− int ret;
984−
985− v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n",
986− fi->interval.numerator, fi->interval.denominator);
987−
988− mutex_lock(&s5k6aa->lock);
989− ret = __s5k6aa_set_frame_interval(s5k6aa, fi);
990− s5k6aa->apply_cfg = 1;
991−
992− mutex_unlock(&s5k6aa->lock);
993− return ret;
994−}
995−
996−/*
997− * V4L2 subdev pad level and video operations
998− */
999−static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
1000− struct v4l2_subdev_state *sd_state,
1001− struct v4l2_subdev_frame_interval_enum *fie)
1002−{
1003− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1004− const struct s5k6aa_interval *fi;
1005− int ret = 0;
1006−
1007− if (fie->index >= ARRAY_SIZE(s5k6aa_intervals))
1008− return -EINVAL;
1009−
1010− v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
1011− S5K6AA_WIN_WIDTH_MAX, 1,
1012− &fie->height, S5K6AA_WIN_HEIGHT_MIN,
1013− S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1014−
1015− mutex_lock(&s5k6aa->lock);
1016− fi = &s5k6aa_intervals[fie->index];
1017− if (fie->width > fi->size.width || fie->height > fi->size.height)
1018− ret = -EINVAL;
1019− else
1020− fie->interval = fi->interval;
1021− mutex_unlock(&s5k6aa->lock);
1022−
1023− return ret;
1024−}
1025−
1026−static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd,
1027− struct v4l2_subdev_state *sd_state,
1028− struct v4l2_subdev_mbus_code_enum *code)
1029−{
1030− if (code->index >= ARRAY_SIZE(s5k6aa_formats))
1031− return -EINVAL;
1032−
1033− code->code = s5k6aa_formats[code->index].code;
1034− return 0;
1035−}
1036−
1037−static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd,
1038− struct v4l2_subdev_state *sd_state,
1039− struct v4l2_subdev_frame_size_enum *fse)
1040−{
1041− int i = ARRAY_SIZE(s5k6aa_formats);
1042−
1043− if (fse->index > 0)
1044− return -EINVAL;
1045−
1046− while (--i)
1047− if (fse->code == s5k6aa_formats[i].code)
1048− break;
1049−
1050− fse->code = s5k6aa_formats[i].code;
1051− fse->min_width = S5K6AA_WIN_WIDTH_MIN;
1052− fse->max_width = S5K6AA_WIN_WIDTH_MAX;
1053− fse->max_height = S5K6AA_WIN_HEIGHT_MIN;
1054− fse->min_height = S5K6AA_WIN_HEIGHT_MAX;
1055−
1056− return 0;
1057−}
1058−
1059−static struct v4l2_rect *
1060−__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa,
1061− struct v4l2_subdev_state *sd_state,
1062− enum v4l2_subdev_format_whence which)
1063−{
1064− if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
1065− return &s5k6aa->ccd_rect;
1066−
1067− WARN_ON(which != V4L2_SUBDEV_FORMAT_TRY);
1068− return v4l2_subdev_get_try_crop(&s5k6aa->sd, sd_state, 0);
1069−}
1070−
1071−static void s5k6aa_try_format(struct s5k6aa *s5k6aa,
1072− struct v4l2_mbus_framefmt *mf)
1073−{
1074− unsigned int index;
1075−
1076− v4l_bound_align_image(&mf->width, S5K6AA_WIN_WIDTH_MIN,
1077− S5K6AA_WIN_WIDTH_MAX, 1,
1078− &mf->height, S5K6AA_WIN_HEIGHT_MIN,
1079− S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1080−
1081− if (mf->colorspace != V4L2_COLORSPACE_JPEG &&
1082− mf->colorspace != V4L2_COLORSPACE_REC709)
1083− mf->colorspace = V4L2_COLORSPACE_JPEG;
1084−
1085− index = s5k6aa_get_pixfmt_index(s5k6aa, mf);
1086−
1087− mf->colorspace = s5k6aa_formats[index].colorspace;
1088− mf->code = s5k6aa_formats[index].code;
1089− mf->field = V4L2_FIELD_NONE;
1090−}
1091−
1092−static int s5k6aa_get_fmt(struct v4l2_subdev *sd,
1093− struct v4l2_subdev_state *sd_state,
1094− struct v4l2_subdev_format *fmt)
1095−{
1096− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1097− struct v4l2_mbus_framefmt *mf;
1098−
1099− memset(fmt->reserved, 0, sizeof(fmt->reserved));
1100−
1101− if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1102− mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
1103− fmt->format = *mf;
1104− return 0;
1105− }
1106−
1107− mutex_lock(&s5k6aa->lock);
1108− fmt->format = s5k6aa->preset->mbus_fmt;
1109− mutex_unlock(&s5k6aa->lock);
1110−
1111− return 0;
1112−}
1113−
1114−static int s5k6aa_set_fmt(struct v4l2_subdev *sd,
1115− struct v4l2_subdev_state *sd_state,
1116− struct v4l2_subdev_format *fmt)
1117−{
1118− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1119− struct s5k6aa_preset *preset = s5k6aa->preset;
1120− struct v4l2_mbus_framefmt *mf;
1121− struct v4l2_rect *crop;
1122− int ret = 0;
1123−
1124− mutex_lock(&s5k6aa->lock);
1125− s5k6aa_try_format(s5k6aa, &fmt->format);
1126−
1127− if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1128− mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
1129− crop = v4l2_subdev_get_try_crop(sd, sd_state, 0);
1130− } else {
1131− if (s5k6aa->streaming) {
1132− ret = -EBUSY;
1133− } else {
1134− mf = &preset->mbus_fmt;
1135− crop = &s5k6aa->ccd_rect;
1136− s5k6aa->apply_cfg = 1;
1137− }
1138− }
1139−
1140− if (ret == 0) {
1141− struct v4l2_subdev_frame_interval fiv = {
1142− .interval = {0, 1}
1143− };
1144−
1145− *mf = fmt->format;
1146− /*
1147− * Make sure the crop window is valid, i.e. its size is
1148− * greater than the output window, as the ISP supports
1149− * only down-scaling.
1150− */
1151− crop->width = clamp_t(unsigned int, crop->width, mf->width,
1152− S5K6AA_WIN_WIDTH_MAX);
1153− crop->height = clamp_t(unsigned int, crop->height, mf->height,
1154− S5K6AA_WIN_HEIGHT_MAX);
1155− crop->left = clamp_t(unsigned int, crop->left, 0,
1156− S5K6AA_WIN_WIDTH_MAX - crop->width);
1157− crop->top = clamp_t(unsigned int, crop->top, 0,
1158− S5K6AA_WIN_HEIGHT_MAX - crop->height);
1159−
1160− /* Reset to minimum possible frame interval */
1161− ret = __s5k6aa_set_frame_interval(s5k6aa, &fiv);
1162− }
1163− mutex_unlock(&s5k6aa->lock);
1164−
1165− return ret;
1166−}
1167−
1168−static int s5k6aa_get_selection(struct v4l2_subdev *sd,
1169− struct v4l2_subdev_state *sd_state,
1170− struct v4l2_subdev_selection *sel)
1171−{
1172− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1173− struct v4l2_rect *rect;
1174−
1175− if (sel->target != V4L2_SEL_TGT_CROP)
1176− return -EINVAL;
1177−
1178− memset(sel->reserved, 0, sizeof(sel->reserved));
1179−
1180− mutex_lock(&s5k6aa->lock);
1181− rect = __s5k6aa_get_crop_rect(s5k6aa, sd_state, sel->which);
1182− sel->r = *rect;
1183− mutex_unlock(&s5k6aa->lock);
1184−
1185− v4l2_dbg(1, debug, sd, "Current crop rectangle: (%d,%d)/%dx%d\n",
1186− rect->left, rect->top, rect->width, rect->height);
1187−
1188− return 0;
1189−}
1190−
1191−static int s5k6aa_set_selection(struct v4l2_subdev *sd,
1192− struct v4l2_subdev_state *sd_state,
1193− struct v4l2_subdev_selection *sel)
1194−{
1195− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1196− struct v4l2_mbus_framefmt *mf;
1197− unsigned int max_x, max_y;
1198− struct v4l2_rect *crop_r;
1199−
1200− if (sel->target != V4L2_SEL_TGT_CROP)
1201− return -EINVAL;
1202−
1203− mutex_lock(&s5k6aa->lock);
1204− crop_r = __s5k6aa_get_crop_rect(s5k6aa, sd_state, sel->which);
1205−
1206− if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1207− mf = &s5k6aa->preset->mbus_fmt;
1208− s5k6aa->apply_crop = 1;
1209− } else {
1210− mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
1211− }
1212− v4l_bound_align_image(&sel->r.width, mf->width,
1213− S5K6AA_WIN_WIDTH_MAX, 1,
1214− &sel->r.height, mf->height,
1215− S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1216−
1217− max_x = (S5K6AA_WIN_WIDTH_MAX - sel->r.width) & ~1;
1218− max_y = (S5K6AA_WIN_HEIGHT_MAX - sel->r.height) & ~1;
1219−
1220− sel->r.left = clamp_t(unsigned int, sel->r.left, 0, max_x);
1221− sel->r.top = clamp_t(unsigned int, sel->r.top, 0, max_y);
1222−
1223− *crop_r = sel->r;
1224−
1225− mutex_unlock(&s5k6aa->lock);
1226−
1227− v4l2_dbg(1, debug, sd, "Set crop rectangle: (%d,%d)/%dx%d\n",
1228− crop_r->left, crop_r->top, crop_r->width, crop_r->height);
1229−
1230− return 0;
1231−}
1232−
1233−static const struct v4l2_subdev_pad_ops s5k6aa_pad_ops = {
1234− .enum_mbus_code = s5k6aa_enum_mbus_code,
1235− .enum_frame_size = s5k6aa_enum_frame_size,
1236− .enum_frame_interval = s5k6aa_enum_frame_interval,
1237− .get_fmt = s5k6aa_get_fmt,
1238− .set_fmt = s5k6aa_set_fmt,
1239− .get_selection = s5k6aa_get_selection,
1240− .set_selection = s5k6aa_set_selection,
1241−};
1242−
1243−static const struct v4l2_subdev_video_ops s5k6aa_video_ops = {
1244− .g_frame_interval = s5k6aa_g_frame_interval,
1245− .s_frame_interval = s5k6aa_s_frame_interval,
1246− .s_stream = s5k6aa_s_stream,
1247−};
1248−
1249−/*
1250− * V4L2 subdev controls
1251− */
1252−
1253−static int s5k6aa_s_ctrl(struct v4l2_ctrl *ctrl)
1254−{
1255− struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1256− struct i2c_client *client = v4l2_get_subdevdata(sd);
1257− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1258− int idx, err = 0;
1259−
1260− v4l2_dbg(1, debug, sd, "ctrl: 0x%x, value: %d\n", ctrl->id, ctrl->val);
1261−
1262− mutex_lock(&s5k6aa->lock);
1263− /*
1264− * If the device is not powered up by the host driver do
1265− * not apply any controls to H/W at this time. Instead
1266− * the controls will be restored right after power-up.
1267− */
1268− if (s5k6aa->power == 0)
1269− goto unlock;
1270− idx = s5k6aa->preset->index;
1271−
1272− switch (ctrl->id) {
1273− case V4L2_CID_AUTO_WHITE_BALANCE:
1274− err = s5k6aa_set_awb(s5k6aa, ctrl->val);
1275− break;
1276−
1277− case V4L2_CID_BRIGHTNESS:
1278− err = s5k6aa_write(client, REG_USER_BRIGHTNESS, ctrl->val);
1279− break;
1280−
1281− case V4L2_CID_COLORFX:
1282− err = s5k6aa_set_colorfx(s5k6aa, ctrl->val);
1283− break;
1284−
1285− case V4L2_CID_CONTRAST:
1286− err = s5k6aa_write(client, REG_USER_CONTRAST, ctrl->val);
1287− break;
1288−
1289− case V4L2_CID_EXPOSURE_AUTO:
1290− err = s5k6aa_set_auto_exposure(s5k6aa, ctrl->val);
1291− break;
1292−
1293− case V4L2_CID_HFLIP:
1294− err = s5k6aa_set_mirror(s5k6aa, ctrl->val);
1295− if (err)
1296− break;
1297− err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
1298− break;
1299−
1300− case V4L2_CID_POWER_LINE_FREQUENCY:
1301− err = s5k6aa_set_anti_flicker(s5k6aa, ctrl->val);
1302− break;
1303−
1304− case V4L2_CID_SATURATION:
1305− err = s5k6aa_write(client, REG_USER_SATURATION, ctrl->val);
1306− break;
1307−
1308− case V4L2_CID_SHARPNESS:
1309− err = s5k6aa_write(client, REG_USER_SHARPBLUR, ctrl->val);
1310− break;
1311−
1312− case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
1313− err = s5k6aa_write(client, REG_P_COLORTEMP(idx), ctrl->val);
1314− if (err)
1315− break;
1316− err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
1317− break;
1318− }
1319−unlock:
1320− mutex_unlock(&s5k6aa->lock);
1321− return err;
1322−}
1323−
1324−static const struct v4l2_ctrl_ops s5k6aa_ctrl_ops = {
1325− .s_ctrl = s5k6aa_s_ctrl,
1326−};
1327−
1328−static int s5k6aa_log_status(struct v4l2_subdev *sd)
1329−{
1330− v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
1331− return 0;
1332−}
1333−
1334−#define V4L2_CID_RED_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1001)
1335−#define V4L2_CID_GREEN_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1002)
1336−#define V4L2_CID_BLUE_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1003)
1337−
1338−static const struct v4l2_ctrl_config s5k6aa_ctrls[] = {
1339− {
1340− .ops = &s5k6aa_ctrl_ops,
1341− .id = V4L2_CID_RED_GAIN,
1342− .type = V4L2_CTRL_TYPE_INTEGER,
1343− .name = "Gain, Red",
1344− .min = 0,
1345− .max = 256,
1346− .def = 127,
1347− .step = 1,
1348− }, {
1349− .ops = &s5k6aa_ctrl_ops,
1350− .id = V4L2_CID_GREEN_GAIN,
1351− .type = V4L2_CTRL_TYPE_INTEGER,
1352− .name = "Gain, Green",
1353− .min = 0,
1354− .max = 256,
1355− .def = 127,
1356− .step = 1,
1357− }, {
1358− .ops = &s5k6aa_ctrl_ops,
1359− .id = V4L2_CID_BLUE_GAIN,
1360− .type = V4L2_CTRL_TYPE_INTEGER,
1361− .name = "Gain, Blue",
1362− .min = 0,
1363− .max = 256,
1364− .def = 127,
1365− .step = 1,
1366− },
1367−};
1368−
1369−static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa)
1370−{
1371− const struct v4l2_ctrl_ops *ops = &s5k6aa_ctrl_ops;
1372− struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
1373− struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1374−
1375− int ret = v4l2_ctrl_handler_init(hdl, 16);
1376− if (ret)
1377− return ret;
1378− /* Auto white balance cluster */
1379− ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
1380− 0, 1, 1, 1);
1381− ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[0], NULL);
1382− ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[1], NULL);
1383− ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[2], NULL);
1384− v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
1385−
1386− ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1387− ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1388− v4l2_ctrl_cluster(2, &ctrls->hflip);
1389−
1390− ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
1391− V4L2_CID_EXPOSURE_AUTO,
1392− V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
1393− /* Exposure time: x 1 us */
1394− ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
1395− 0, 6000000U, 1, 100000U);
1396− /* Total gain: 256 <=> 1x */
1397− ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
1398− 0, 256, 1, 256);
1399− v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
1400−
1401− v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
1402− V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
1403− V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
1404−
1405− v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
1406− V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
1407−
1408− v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
1409− 0, 256, 1, 0);
1410−
1411− v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
1412− v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
1413− v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
1414− v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
1415−
1416− if (hdl->error) {
1417− ret = hdl->error;
1418− v4l2_ctrl_handler_free(hdl);
1419− return ret;
1420− }
1421−
1422− s5k6aa->sd.ctrl_handler = hdl;
1423− return 0;
1424−}
1425−
1426−/*
1427− * V4L2 subdev internal operations
1428− */
1429−static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1430−{
1431− struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd,
1432− fh->state,
1433− 0);
1434− struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
1435−
1436− format->colorspace = s5k6aa_formats[0].colorspace;
1437− format->code = s5k6aa_formats[0].code;
1438− format->width = S5K6AA_OUT_WIDTH_DEF;
1439− format->height = S5K6AA_OUT_HEIGHT_DEF;
1440− format->field = V4L2_FIELD_NONE;
1441−
1442− crop->width = S5K6AA_WIN_WIDTH_MAX;
1443− crop->height = S5K6AA_WIN_HEIGHT_MAX;
1444− crop->left = 0;
1445− crop->top = 0;
1446−
1447− return 0;
1448−}
1449−
1450−static int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
1451−{
1452− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
1453− u16 api_ver = 0, fw_rev = 0;
1454−
1455− int ret = s5k6aa_set_ahb_address(client);
1456−
1457− if (!ret)
1458− ret = s5k6aa_read(client, REG_FW_APIVER, &api_ver);
1459− if (!ret)
1460− ret = s5k6aa_read(client, REG_FW_REVISION, &fw_rev);
1461− if (ret) {
1462− v4l2_err(&s5k6aa->sd, "FW revision check failed!\n");
1463− return ret;
1464− }
1465−
1466− v4l2_info(&s5k6aa->sd, "FW API ver.: 0x%X, FW rev.: 0x%X\n",
1467− api_ver, fw_rev);
1468−
1469− return api_ver == S5K6AAFX_FW_APIVER ? 0 : -ENODEV;
1470−}
1471−
1472−static int s5k6aa_registered(struct v4l2_subdev *sd)
1473−{
1474− struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1475− int ret;
1476−
1477− mutex_lock(&s5k6aa->lock);
1478− ret = __s5k6aa_power_on(s5k6aa);
1479− if (!ret) {
1480− msleep(100);
1481− ret = s5k6aa_check_fw_revision(s5k6aa);
1482− __s5k6aa_power_off(s5k6aa);
1483− }
1484− mutex_unlock(&s5k6aa->lock);
1485−
1486− return ret;
1487−}
1488−
1489−static const struct v4l2_subdev_internal_ops s5k6aa_subdev_internal_ops = {
1490− .registered = s5k6aa_registered,
1491− .open = s5k6aa_open,
1492−};
1493−
1494−static const struct v4l2_subdev_core_ops s5k6aa_core_ops = {
1495− .s_power = s5k6aa_set_power,
1496− .log_status = s5k6aa_log_status,
1497−};
1498−
1499−static const struct v4l2_subdev_ops s5k6aa_subdev_ops = {
1500− .core = &s5k6aa_core_ops,
1501− .pad = &s5k6aa_pad_ops,
1502− .video = &s5k6aa_video_ops,
1503−};
1504−
1505−/*
1506− * GPIO setup
1507− */
1508−
1509−static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
1510− const struct s5k6aa_platform_data *pdata)
1511−{
1512− struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
1513− const struct s5k6aa_gpio *gpio;
1514− unsigned long flags;
1515− int ret;
1516−
1517− s5k6aa->gpio[STBY].gpio = -EINVAL;
1518− s5k6aa->gpio[RSET].gpio = -EINVAL;
1519−
1520− gpio = &pdata->gpio_stby;
1521− if (gpio_is_valid(gpio->gpio)) {
1522− flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
1523− | GPIOF_EXPORT;
1524− ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
1525− "S5K6AA_STBY");
1526− if (ret < 0)
1527− return ret;
1528−
1529− s5k6aa->gpio[STBY] = *gpio;
1530− }
1531−
1532− gpio = &pdata->gpio_reset;
1533− if (gpio_is_valid(gpio->gpio)) {
1534− flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
1535− | GPIOF_EXPORT;
1536− ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
1537− "S5K6AA_RST");
1538− if (ret < 0)
1539− return ret;
1540−
1541− s5k6aa->gpio[RSET] = *gpio;
1542− }
1543−
1544− return 0;
1545−}
1546−
1547−static int s5k6aa_probe(struct i2c_client *client)
1548−{
1549− const struct s5k6aa_platform_data *pdata = client->dev.platform_data;
1550− struct v4l2_subdev *sd;
1551− struct s5k6aa *s5k6aa;
1552− int i, ret;
1553−
1554− if (pdata == NULL) {
1555− dev_err(&client->dev, "Platform data not specified\n");
1556− return -EINVAL;
1557− }
1558−
1559− if (pdata->mclk_frequency == 0) {
1560− dev_err(&client->dev, "MCLK frequency not specified\n");
1561− return -EINVAL;
1562− }
1563−
1564− s5k6aa = devm_kzalloc(&client->dev, sizeof(*s5k6aa), GFP_KERNEL);
1565− if (!s5k6aa)
1566− return -ENOMEM;
1567−
1568− mutex_init(&s5k6aa->lock);
1569−
1570− s5k6aa->mclk_frequency = pdata->mclk_frequency;
1571− s5k6aa->bus_type = pdata->bus_type;
1572− s5k6aa->mipi_lanes = pdata->nlanes;
1573− s5k6aa->s_power = pdata->set_power;
1574− s5k6aa->inv_hflip = pdata->horiz_flip;
1575− s5k6aa->inv_vflip = pdata->vert_flip;
1576−
1577− sd = &s5k6aa->sd;
1578− v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
1579− /* Static name; NEVER use in new drivers! */
1580− strscpy(sd->name, DRIVER_NAME, sizeof(sd->name));
1581−
1582− sd->internal_ops = &s5k6aa_subdev_internal_ops;
1583− sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1584−
1585− s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
1586− sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1587− ret = media_entity_pads_init(&sd->entity, 1, &s5k6aa->pad);
1588− if (ret)
1589− return ret;
1590−
1591− ret = s5k6aa_configure_gpios(s5k6aa, pdata);
1592− if (ret)
1593− goto out_err;
1594−
1595− for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
1596− s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
1597−
1598− ret = devm_regulator_bulk_get(&client->dev, S5K6AA_NUM_SUPPLIES,
1599− s5k6aa->supplies);
1600− if (ret) {
1601− dev_err(&client->dev, "Failed to get regulators\n");
1602− goto out_err;
1603− }
1604−
1605− ret = s5k6aa_initialize_ctrls(s5k6aa);
1606− if (ret)
1607− goto out_err;
1608−
1609− s5k6aa_presets_data_init(s5k6aa);
1610−
1611− s5k6aa->ccd_rect.width = S5K6AA_WIN_WIDTH_MAX;
1612− s5k6aa->ccd_rect.height = S5K6AA_WIN_HEIGHT_MAX;
1613− s5k6aa->ccd_rect.left = 0;
1614− s5k6aa->ccd_rect.top = 0;
1615−
1616− return 0;
1617−
1618−out_err:
1619− media_entity_cleanup(&s5k6aa->sd.entity);
1620− return ret;
1621−}
1622−
1623−static void s5k6aa_remove(struct i2c_client *client)
1624−{
1625− struct v4l2_subdev *sd = i2c_get_clientdata(client);
1626−
1627− v4l2_device_unregister_subdev(sd);
1628− v4l2_ctrl_handler_free(sd->ctrl_handler);
1629− media_entity_cleanup(&sd->entity);
1630−}
1631−
1632−static const struct i2c_device_id s5k6aa_id[] = {
1633− { DRIVER_NAME, 0 },
1634− { },
1635−};
1636−MODULE_DEVICE_TABLE(i2c, s5k6aa_id);
1637−
1638−
1639−static struct i2c_driver s5k6aa_i2c_driver = {
1640− .driver = {
1641− .name = DRIVER_NAME
1642− },
1643− .probe_new = s5k6aa_probe,
1644− .remove = s5k6aa_remove,
1645− .id_table = s5k6aa_id,
1646−};
1647−
1648−module_i2c_driver(s5k6aa_i2c_driver);
1649−
1650−MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver");
1651−MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1652−MODULE_LICENSE("GPL");
drivers/media/i2c/sr030pc30.c+0−762
@@ -1,762 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−/*
3− * Driver for SiliconFile SR030PC30 VGA (1/10-Inch) Image Sensor with ISP
4− *
5− * Copyright (C) 2010 Samsung Electronics Co., Ltd
6− * Author: Sylwester Nawrocki, s.nawrocki@samsung.com
7− *
8− * Based on original driver authored by Dongsoo Nathaniel Kim
9− * and HeungJun Kim <riverful.kim@samsung.com>.
10− *
11− * Based on mt9v011 Micron Digital Image Sensor driver
12− * Copyright (c) 2009 Mauro Carvalho Chehab
13− */
14−
15−#include <linux/i2c.h>
16−#include <linux/delay.h>
17−#include <linux/slab.h>
18−#include <linux/module.h>
19−#include <media/v4l2-device.h>
20−#include <media/v4l2-subdev.h>
21−#include <media/v4l2-mediabus.h>
22−#include <media/v4l2-ctrls.h>
23−#include <media/i2c/sr030pc30.h>
24−
25−static int debug;
26−module_param(debug, int, 0644);
27−
28−#define MODULE_NAME "SR030PC30"
29−
30−/*
31− * Register offsets within a page
32− * b15..b8 - page id, b7..b0 - register address
33− */
34−#define POWER_CTRL_REG 0x0001
35−#define PAGEMODE_REG 0x03
36−#define DEVICE_ID_REG 0x0004
37−#define NOON010PC30_ID 0x86
38−#define SR030PC30_ID 0x8C
39−#define VDO_CTL1_REG 0x0010
40−#define SUBSAMPL_NONE_VGA 0
41−#define SUBSAMPL_QVGA 0x10
42−#define SUBSAMPL_QQVGA 0x20
43−#define VDO_CTL2_REG 0x0011
44−#define SYNC_CTL_REG 0x0012
45−#define WIN_ROWH_REG 0x0020
46−#define WIN_ROWL_REG 0x0021
47−#define WIN_COLH_REG 0x0022
48−#define WIN_COLL_REG 0x0023
49−#define WIN_HEIGHTH_REG 0x0024
50−#define WIN_HEIGHTL_REG 0x0025
51−#define WIN_WIDTHH_REG 0x0026
52−#define WIN_WIDTHL_REG 0x0027
53−#define HBLANKH_REG 0x0040
54−#define HBLANKL_REG 0x0041
55−#define VSYNCH_REG 0x0042
56−#define VSYNCL_REG 0x0043
57−/* page 10 */
58−#define ISP_CTL_REG(n) (0x1010 + (n))
59−#define YOFS_REG 0x1040
60−#define DARK_YOFS_REG 0x1041
61−#define AG_ABRTH_REG 0x1050
62−#define SAT_CTL_REG 0x1060
63−#define BSAT_REG 0x1061
64−#define RSAT_REG 0x1062
65−#define AG_SAT_TH_REG 0x1063
66−/* page 11 */
67−#define ZLPF_CTRL_REG 0x1110
68−#define ZLPF_CTRL2_REG 0x1112
69−#define ZLPF_AGH_THR_REG 0x1121
70−#define ZLPF_THR_REG 0x1160
71−#define ZLPF_DYN_THR_REG 0x1160
72−/* page 12 */
73−#define YCLPF_CTL1_REG 0x1240
74−#define YCLPF_CTL2_REG 0x1241
75−#define YCLPF_THR_REG 0x1250
76−#define BLPF_CTL_REG 0x1270
77−#define BLPF_THR1_REG 0x1274
78−#define BLPF_THR2_REG 0x1275
79−/* page 14 - Lens Shading Compensation */
80−#define LENS_CTRL_REG 0x1410
81−#define LENS_XCEN_REG 0x1420
82−#define LENS_YCEN_REG 0x1421
83−#define LENS_R_COMP_REG 0x1422
84−#define LENS_G_COMP_REG 0x1423
85−#define LENS_B_COMP_REG 0x1424
86−/* page 15 - Color correction */
87−#define CMC_CTL_REG 0x1510
88−#define CMC_OFSGH_REG 0x1514
89−#define CMC_OFSGL_REG 0x1516
90−#define CMC_SIGN_REG 0x1517
91−/* Color correction coefficients */
92−#define CMC_COEF_REG(n) (0x1530 + (n))
93−/* Color correction offset coefficients */
94−#define CMC_OFS_REG(n) (0x1540 + (n))
95−/* page 16 - Gamma correction */
96−#define GMA_CTL_REG 0x1610
97−/* Gamma correction coefficients 0.14 */
98−#define GMA_COEF_REG(n) (0x1630 + (n))
99−/* page 20 - Auto Exposure */
100−#define AE_CTL1_REG 0x2010
101−#define AE_CTL2_REG 0x2011
102−#define AE_FRM_CTL_REG 0x2020
103−#define AE_FINE_CTL_REG(n) (0x2028 + (n))
104−#define EXP_TIMEH_REG 0x2083
105−#define EXP_TIMEM_REG 0x2084
106−#define EXP_TIMEL_REG 0x2085
107−#define EXP_MMINH_REG 0x2086
108−#define EXP_MMINL_REG 0x2087
109−#define EXP_MMAXH_REG 0x2088
110−#define EXP_MMAXM_REG 0x2089
111−#define EXP_MMAXL_REG 0x208A
112−/* page 22 - Auto White Balance */
113−#define AWB_CTL1_REG 0x2210
114−#define AWB_ENABLE 0x80
115−#define AWB_CTL2_REG 0x2211
116−#define MWB_ENABLE 0x01
117−/* RGB gain control (manual WB) when AWB_CTL1[7]=0 */
118−#define AWB_RGAIN_REG 0x2280
119−#define AWB_GGAIN_REG 0x2281
120−#define AWB_BGAIN_REG 0x2282
121−#define AWB_RMAX_REG 0x2283
122−#define AWB_RMIN_REG 0x2284
123−#define AWB_BMAX_REG 0x2285
124−#define AWB_BMIN_REG 0x2286
125−/* R, B gain range in bright light conditions */
126−#define AWB_RMAXB_REG 0x2287
127−#define AWB_RMINB_REG 0x2288
128−#define AWB_BMAXB_REG 0x2289
129−#define AWB_BMINB_REG 0x228A
130−/* manual white balance, when AWB_CTL2[0]=1 */
131−#define MWB_RGAIN_REG 0x22B2
132−#define MWB_BGAIN_REG 0x22B3
133−/* the token to mark an array end */
134−#define REG_TERM 0xFFFF
135−
136−/* Minimum and maximum exposure time in ms */
137−#define EXPOS_MIN_MS 1
138−#define EXPOS_MAX_MS 125
139−
140−struct sr030pc30_info {
141− struct v4l2_subdev sd;
142− struct v4l2_ctrl_handler hdl;
143− const struct sr030pc30_platform_data *pdata;
144− const struct sr030pc30_format *curr_fmt;
145− const struct sr030pc30_frmsize *curr_win;
146− unsigned int hflip:1;
147− unsigned int vflip:1;
148− unsigned int sleep:1;
149− struct {
150− /* auto whitebalance control cluster */
151− struct v4l2_ctrl *awb;
152− struct v4l2_ctrl *red;
153− struct v4l2_ctrl *blue;
154− };
155− struct {
156− /* auto exposure control cluster */
157− struct v4l2_ctrl *autoexp;
158− struct v4l2_ctrl *exp;
159− };
160− u8 i2c_reg_page;
161−};
162−
163−struct sr030pc30_format {
164− u32 code;
165− enum v4l2_colorspace colorspace;
166− u16 ispctl1_reg;
167−};
168−
169−struct sr030pc30_frmsize {
170− u16 width;
171− u16 height;
172− int vid_ctl1;
173−};
174−
175−struct i2c_regval {
176− u16 addr;
177− u16 val;
178−};
179−
180−/* supported resolutions */
181−static const struct sr030pc30_frmsize sr030pc30_sizes[] = {
182− {
183− .width = 640,
184− .height = 480,
185− .vid_ctl1 = SUBSAMPL_NONE_VGA,
186− }, {
187− .width = 320,
188− .height = 240,
189− .vid_ctl1 = SUBSAMPL_QVGA,
190− }, {
191− .width = 160,
192− .height = 120,
193− .vid_ctl1 = SUBSAMPL_QQVGA,
194− },
195−};
196−
197−/* supported pixel formats */
198−static const struct sr030pc30_format sr030pc30_formats[] = {
199− {
200− .code = MEDIA_BUS_FMT_YUYV8_2X8,
201− .colorspace = V4L2_COLORSPACE_JPEG,
202− .ispctl1_reg = 0x03,
203− }, {
204− .code = MEDIA_BUS_FMT_YVYU8_2X8,

558 more lines aren’t shown here.

drivers/media/i2c/st-vgxy61.c+11−12

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

drivers/media/i2c/tc358746.c+2−2

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

drivers/media/i2c/vs6624.c+0−854

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

drivers/media/i2c/vs6624_regs.h+0−325

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

drivers/media/mc/mc-device.c+1−2

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

drivers/media/pci/bt8xx/Kconfig+1−1

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

drivers/media/pci/bt8xx/btcx-risc.c+0−153

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

drivers/media/pci/bt8xx/btcx-risc.h+0−9

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

drivers/media/pci/bt8xx/bttv-cards.c+0−15

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

drivers/media/pci/bt8xx/bttv-driver.c+9−427

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

drivers/media/pci/bt8xx/bttv-risc.c+0−131

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

drivers/media/pci/bt8xx/bttvp.h+1−27

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

drivers/media/pci/cobalt/cobalt-v4l2.c+13−8

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

drivers/media/pci/cx18/Kconfig+1−1

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

drivers/media/pci/cx18/cx18-driver.c+2−2

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

drivers/media/pci/cx18/cx18-driver.h+12−12

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

drivers/media/pci/cx18/cx18-fileops.c+16−69

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

drivers/media/pci/cx18/cx18-fileops.h+2−1

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

drivers/media/pci/cx18/cx18-ioctl.c+159−232

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

drivers/media/pci/cx18/cx18-mailbox.c+14−13

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

drivers/media/pci/cx18/cx18-streams.c+145−133

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

drivers/media/pci/cx23885/cx23885-core.c+3−1

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

drivers/media/pci/cx23885/cx23885-video.c+7−6

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

drivers/media/pci/dm1105/dm1105.c+1−0

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

drivers/media/pci/intel/ipu3/cio2-bridge.c+19−4

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

drivers/media/pci/intel/ipu3/cio2-bridge.h+2−1

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

drivers/media/pci/intel/ipu3/ipu3-cio2-main.c+1−0

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

drivers/media/pci/saa7134/saa7134-cards.c+0−1

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

drivers/media/pci/saa7134/saa7134-core.c+0−32

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

drivers/media/pci/saa7134/saa7134-empress.c+2−2

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

drivers/media/pci/saa7134/saa7134-ts.c+1−0

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

drivers/media/pci/saa7134/saa7134-vbi.c+1−0

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

drivers/media/pci/saa7134/saa7134-video.c+5−407

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

drivers/media/pci/saa7134/saa7134.h+0−13

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

drivers/media/pci/saa7146/hexium_gemini.c+12−11

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

drivers/media/pci/saa7146/hexium_orion.c+13−11

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

drivers/media/pci/saa7146/mxb.c+29−24

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

drivers/media/pci/ttpci/budget-av.c+3−2

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

drivers/media/pci/tw68/tw68-video.c+9−7

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

drivers/media/pci/zoran/zoran_device.h+0−2

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

drivers/media/platform/allegro-dvt/allegro-core.c+2−4

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

drivers/media/platform/amlogic/meson-ge2d/ge2d.c+2−4

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

drivers/media/platform/amphion/vdec.c+53−0

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

drivers/media/platform/amphion/vpu_codec.h+2−1

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

drivers/media/platform/amphion/vpu_core.c+2−4

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

drivers/media/platform/amphion/vpu_drv.c+2−4

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

drivers/media/platform/amphion/vpu_malone.c+44−1

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

drivers/media/platform/amphion/vpu_malone.h+1−0

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

drivers/media/platform/aspeed/aspeed-video.c+2−4

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

drivers/media/platform/atmel/atmel-isi.c+4−6

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

drivers/media/platform/cadence/cdns-csi2rx.c+2−4

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

drivers/media/platform/cadence/cdns-csi2tx.c+2−4

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

drivers/media/platform/chips-media/coda-common.c+2−3

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

drivers/media/platform/intel/pxa_camera.c+4−6

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

drivers/media/platform/m2m-deinterlace.c+2−4

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

drivers/media/platform/marvell/mcam-core.c+2−2

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

drivers/media/platform/marvell/mmp-driver.c+3−13

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

drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c+84−56

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

drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h+12−16

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

drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c+13−30

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

drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c+8−30

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

drivers/media/platform/mediatek/mdp/mtk_mdp_core.c+2−3

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

drivers/media/platform/mediatek/mdp3/Makefile+1−1

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

drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c+453−0

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

drivers/media/platform/mediatek/mdp3/mdp_sm_mt8183.h+144−0

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

drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h+24−165

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h+20−0

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c+101−47

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c+346−193

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h+22−2

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c+13−40

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h+16−2

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c+19−17

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.h+0−1

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c+27−266

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h+109−105

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-type.h+53−0

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c+83−110

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

drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.h+7−22

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c+10−21

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c+5−5

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c+8−0

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateful.c+11−1

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c+8−6

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c+1−1

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

drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c+15−8

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

drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c+1−1

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

drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c+1−1

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

drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c+82−13

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

drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h+12−0

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

drivers/media/platform/mediatek/vpu/mtk_vpu.c+2−4

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

drivers/media/platform/microchip/microchip-csi2dc.c+2−4

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

drivers/media/platform/microchip/microchip-isc-base.c+3−2

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

drivers/media/platform/microchip/microchip-sama5d2-isc.c+2−4

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

drivers/media/platform/microchip/microchip-sama7g5-isc.c+2−4

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

drivers/media/platform/nvidia/tegra-vde/vde.c+2−4

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

drivers/media/platform/nxp/Kconfig+2−0

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

drivers/media/platform/nxp/Makefile+1−0

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

drivers/media/platform/nxp/dw100/dw100.c+3−7

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

drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c+15−4

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

drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h+3−2

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

drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c+316−28

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

drivers/media/platform/nxp/imx-mipi-csis.c+2−4

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

drivers/media/platform/nxp/imx-pxp.c+2−4

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

drivers/media/platform/nxp/imx7-media-csi.c+19−14

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

drivers/media/platform/nxp/imx8-isi/Kconfig+22−0

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

drivers/media/platform/nxp/imx8-isi/Makefile+8−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c+539−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h+394−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c+529−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-debug.c+109−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c+650−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c+858−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c+867−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-regs.h+418−0

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

drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c+1512−0

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

drivers/media/platform/nxp/mx2_emmaprp.c+2−4

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

drivers/media/platform/qcom/camss/camss-csid-gen2.c+34−20

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

drivers/media/platform/qcom/camss/camss-csid.c+31−13

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

drivers/media/platform/qcom/camss/camss-csid.h+9−2

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

drivers/media/platform/qcom/camss/camss-vfe-170.c+2−2

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

drivers/media/platform/qcom/camss/camss-vfe-480.c+40−21

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

drivers/media/platform/qcom/camss/camss-vfe-gen1.c+2−2

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

drivers/media/platform/qcom/camss/camss-vfe.c+1−0

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

drivers/media/platform/qcom/camss/camss-video.c+21−5

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

drivers/media/platform/qcom/camss/camss.c+3−5

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

drivers/media/platform/qcom/venus/core.c+2−4

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

drivers/media/platform/qcom/venus/core.h+9−1

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

drivers/media/platform/qcom/venus/helpers.c+2−2

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

drivers/media/platform/qcom/venus/hfi_cmds.c+23−0

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

drivers/media/platform/qcom/venus/hfi_helper.h+18−0

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

drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c+2−2

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

drivers/media/platform/qcom/venus/vdec.c+20−9

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

drivers/media/platform/qcom/venus/venc.c+103−12

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

drivers/media/platform/renesas/rcar-fcp.c+2−4

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

drivers/media/platform/renesas/rcar-isp.c+3−8

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

drivers/media/platform/renesas/rcar-vin/rcar-core.c+2−40

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

drivers/media/platform/renesas/rcar-vin/rcar-csi2.c+5−16

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

drivers/media/platform/renesas/rcar_drif.c+3−5

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

drivers/media/platform/renesas/rcar_fdp1.c+10−11

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

drivers/media/platform/renesas/rcar_jpu.c+2−4

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

drivers/media/platform/renesas/renesas-ceu.c+4−6

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

drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c+2−4

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

drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c+2−4

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

drivers/media/platform/renesas/sh_vou.c+2−3

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

drivers/media/platform/renesas/vsp1/vsp1_drm.c+15−11

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

drivers/media/platform/renesas/vsp1/vsp1_drv.c+12−5

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

drivers/media/platform/renesas/vsp1/vsp1_entity.c+5−6

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

drivers/media/platform/renesas/vsp1/vsp1_entity.h+0−2

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

drivers/media/platform/renesas/vsp1/vsp1_pipe.h+2−0

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

drivers/media/platform/renesas/vsp1/vsp1_regs.h+2−0

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

drivers/media/platform/renesas/vsp1/vsp1_video.c+4−3

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

drivers/media/platform/rockchip/rga/rga.c+2−4

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

drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c+52−0

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

drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c+2−4

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

drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c+7−7

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

drivers/media/platform/samsung/exynos-gsc/gsc-core.c+2−3

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

drivers/media/platform/samsung/exynos4-is/fimc-capture.c+11−7

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

drivers/media/platform/samsung/exynos4-is/fimc-core.c+2−3

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

drivers/media/platform/samsung/exynos4-is/fimc-is-errno.c+1−1

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

drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h+1−1

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

drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.c+2−4

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

drivers/media/platform/samsung/exynos4-is/fimc-is.c+2−4

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

drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c+7−3

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

drivers/media/platform/samsung/exynos4-is/fimc-lite.c+8−6

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

drivers/media/platform/samsung/exynos4-is/media-dev.c+9−9

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

drivers/media/platform/samsung/exynos4-is/mipi-csis.c+2−4

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

drivers/media/platform/samsung/s3c-camif/camif-capture.c+3−2

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

drivers/media/platform/samsung/s3c-camif/camif-core.c+5−6

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

drivers/media/platform/samsung/s5p-g2d/g2d.c+2−3

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

drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c+2−4

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

drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c+2−3

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

drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c+4−4

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

drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c+2−4

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

drivers/media/platform/st/sti/delta/delta-v4l2.c+2−4

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

drivers/media/platform/st/sti/hva/hva-v4l2.c+2−4

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

drivers/media/platform/st/stm32/dma2d/dma2d.c+3−8

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

drivers/media/platform/st/stm32/dma2d/dma2d.h+0−2

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

drivers/media/platform/st/stm32/stm32-dcmi.c+3−4

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

drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c+2−4

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

drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c+2−4

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

drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c+2−4

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

drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c+2−4

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

drivers/media/platform/sunxi/sun8i-di/sun8i-di.c+2−4

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

drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c+2−4

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

drivers/media/platform/ti/am437x/am437x-vpfe.c+21−20

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

drivers/media/platform/ti/cal/cal-video.c+20−17

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

drivers/media/platform/ti/cal/cal.c+2−4

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

drivers/media/platform/ti/davinci/vpif.c+2−4

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

drivers/media/platform/ti/davinci/vpif_capture.c+2−3

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

drivers/media/platform/ti/davinci/vpif_display.c+2−4

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

drivers/media/platform/ti/omap/omap_vout.c+2−3

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

drivers/media/platform/ti/omap3isp/isp.c+2−4

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

drivers/media/platform/ti/omap3isp/ispccdc.c+3−2

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

drivers/media/platform/ti/omap3isp/ispvideo.c+12−8

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

drivers/media/platform/ti/vpe/vpe.c+2−4

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

drivers/media/platform/verisilicon/hantro_drv.c+41−15

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

drivers/media/platform/verisilicon/hantro_postproc.c+1−1

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

drivers/media/platform/verisilicon/hantro_v4l2.c+45−55

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

drivers/media/platform/verisilicon/hantro_v4l2.h+2−1

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

drivers/media/platform/verisilicon/imx8m_vpu_hw.c+2−0

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

drivers/media/platform/via/via-camera.c+7−6

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

drivers/media/platform/video-mux.c+2−4

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

drivers/media/platform/xilinx/xilinx-csi2rxss.c+2−4

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

drivers/media/platform/xilinx/xilinx-dma.c+3−2

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

drivers/media/platform/xilinx/xilinx-tpg.c+2−4

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

drivers/media/platform/xilinx/xilinx-vipp.c+2−4

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

drivers/media/platform/xilinx/xilinx-vtc.c+3−5

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

drivers/media/radio/radio-si476x.c+2−4

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

drivers/media/radio/radio-timb.c+2−3

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

drivers/media/radio/radio-wl1273.c+2−4

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

drivers/media/radio/si4713/radio-platform-si4713.c+2−4

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

drivers/media/rc/gpio-ir-recv.c+4−4

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

drivers/media/rc/img-ir/img-ir-core.c+2−3

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

drivers/media/rc/ir-hix5hd2.c+2−3

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

drivers/media/rc/keymaps/Makefile+2−0

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

drivers/media/rc/keymaps/rc-beelink-mxiii.c+57−0

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

drivers/media/rc/keymaps/rc-dreambox.c+151−0

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

drivers/media/rc/meson-ir-tx.c+2−4

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

drivers/media/rc/meson-ir.c+2−4

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

drivers/media/rc/mtk-cir.c+2−4

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

drivers/media/rc/st_rc.c+2−3

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

drivers/media/rc/sunxi-cir.c+2−4

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

drivers/media/test-drivers/vicodec/vicodec-core.c+2−4

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

drivers/media/test-drivers/vidtv/vidtv_bridge.c+2−4

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

drivers/media/test-drivers/vim2m.c+2−4

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

drivers/media/test-drivers/vimc/vimc-common.c+4−4

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

drivers/media/test-drivers/vimc/vimc-core.c+2−4

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

drivers/media/test-drivers/visl/visl-core.c+2−4

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

drivers/media/test-drivers/vivid/vivid-core.c+8−46

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

drivers/media/test-drivers/vivid/vivid-core.h+0−19

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

drivers/media/test-drivers/vivid/vivid-kthread-cap.c+1−130

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

drivers/media/test-drivers/vivid/vivid-vid-cap.c+0−272

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

drivers/media/test-drivers/vivid/vivid-vid-cap.h+0−3

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

drivers/media/test-drivers/vivid/vivid-vid-out.c+0−74

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

drivers/media/tuners/it913x.c+2−4

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

drivers/media/tuners/mxl5005s.c+8−4

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

drivers/media/usb/au0828/au0828-core.c+3−8

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

drivers/media/usb/au0828/au0828-dvb.c+2−2

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

drivers/media/usb/dvb-usb/cxusb-analog.c+7−7

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

drivers/media/usb/dvb-usb/pctv452e.c+2−0

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

drivers/media/usb/pvrusb2/Kconfig+1−1

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

drivers/media/usb/usbtv/usbtv-core.c+1−1

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

drivers/media/v4l2-core/v4l2-async.c+8−5

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

drivers/media/v4l2-core/v4l2-common.c+6−0

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

drivers/media/v4l2-core/v4l2-compat-ioctl32.c+12−73

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

drivers/media/v4l2-core/v4l2-dev.c+3−2

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

drivers/media/v4l2-core/v4l2-ioctl.c+34−52

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

drivers/media/v4l2-core/v4l2-mc.c+6−9

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

drivers/media/v4l2-core/v4l2-subdev.c+166−34

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

drivers/staging/media/atomisp/i2c/atomisp-gc0310.c+218−785

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

drivers/staging/media/atomisp/i2c/atomisp-ov2680.c+8−25

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

drivers/staging/media/atomisp/i2c/gc0310.h+165−251

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

drivers/staging/media/atomisp/i2c/ov2680.h+0−1

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

drivers/staging/media/atomisp/include/linux/atomisp.h+0−28

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

drivers/staging/media/atomisp/include/linux/atomisp_platform.h+5−6

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

drivers/staging/media/atomisp/pci/atomisp_cmd.c+142−936

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

drivers/staging/media/atomisp/pci/atomisp_cmd.h+0−9

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

drivers/staging/media/atomisp/pci/atomisp_compat.h+1−10

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

drivers/staging/media/atomisp/pci/atomisp_compat_css20.c+66−354

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

drivers/staging/media/atomisp/pci/atomisp_fops.c+5−114

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

drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c+270−19

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

drivers/staging/media/atomisp/pci/atomisp_internal.h+2−39

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

drivers/staging/media/atomisp/pci/atomisp_ioctl.c+21−205

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

drivers/staging/media/atomisp/pci/atomisp_ioctl.h+0−6

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

drivers/staging/media/atomisp/pci/atomisp_subdev.c+39−150

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

drivers/staging/media/atomisp/pci/atomisp_subdev.h+0−22

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

drivers/staging/media/atomisp/pci/atomisp_v4l2.c+15−60

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

drivers/staging/media/av7110/av7110.c+4−2

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

drivers/staging/media/av7110/av7110_av.c+2−2

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

drivers/staging/media/av7110/av7110_hw.c+2−1

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

drivers/staging/media/av7110/av7110_v4l.c+76−72

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

drivers/staging/media/deprecated/atmel/atmel-isc-base.c+5−4

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

drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c+3−7

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

drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c+3−7

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

drivers/staging/media/imx/imx-media-capture.c+22−18

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

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

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

drivers/staging/media/imx/imx-media-dev-common.c+0−14

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

drivers/staging/media/imx/imx-media-dev.c+2−4

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

drivers/staging/media/imx/imx-media-of.c+2−3

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

drivers/staging/media/imx/imx-media-utils.c+4−72

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

drivers/staging/media/imx/imx-media.h+0−13

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

drivers/staging/media/imx/imx6-mipi-csi2.c+2−4

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

drivers/staging/media/imx/imx8mq-mipi-csi2.c+60−98

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

drivers/staging/media/meson/vdec/vdec.c+2−4

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

drivers/staging/media/omap4iss/iss.c+2−4

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

drivers/staging/media/omap4iss/iss_video.c+9−7

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

drivers/staging/media/rkvdec/rkvdec.c+4−3

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

drivers/staging/media/sunxi/cedrus/cedrus.c+3−4

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

drivers/staging/media/sunxi/sun6i-isp/sun6i_isp.c+2−4

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

drivers/staging/media/tegra-video/vi.c+6−4

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

include/media/drv-intf/saa7146_vv.h+10−55

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

include/media/dvb_net.h+2−4

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

include/media/i2c/ad9389b.h+0−37

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

include/media/i2c/m5mols.h+0−25

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

include/media/i2c/mt9m032.h+0−22

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

include/media/i2c/mt9t001.h+0−10

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

include/media/i2c/noon010pc30.h+0−21

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

include/media/i2c/s5k6aa.h+0−48

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

include/media/i2c/sr030pc30.h+0−17

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

include/media/media-device.h+2−3

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

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

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

include/media/tveeprom.h+1−1

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

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

This diff is large: its 9 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-subdev.h+28−5

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

include/uapi/linux/v4l2-subdev.h+21−0

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

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

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