summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/cec/core/cec-core.c2
-rw-r--r--drivers/media/cec/platform/cec-gpio/cec-gpio.c2
-rw-r--r--drivers/media/cec/platform/stm32/stm32-cec.c1
-rw-r--r--drivers/media/cec/usb/extron-da-hd-4k-plus/Makefile6
-rw-r--r--drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c6
-rw-r--r--drivers/media/cec/usb/pulse8/pulse8-cec.c4
-rw-r--r--drivers/media/cec/usb/rainshadow/rainshadow-cec.c4
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c2
-rw-r--r--drivers/media/common/b2c2/flexcop.c22
-rw-r--r--drivers/media/common/cx2341x.c2
-rw-r--r--drivers/media/common/videobuf2/videobuf2-v4l2.c12
-rw-r--r--drivers/media/dvb-frontends/Kconfig4
-rw-r--r--drivers/media/i2c/Kconfig50
-rw-r--r--drivers/media/i2c/Makefile5
-rw-r--r--drivers/media/i2c/adv7180.c338
-rw-r--r--drivers/media/i2c/adv7604.c2
-rw-r--r--drivers/media/i2c/adv7842.c2
-rw-r--r--drivers/media/i2c/ar0521.c9
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.c4
-rw-r--r--drivers/media/i2c/ds90ub913.c17
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_driver.c34
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_mode.c9
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_reg.h1
-rw-r--r--drivers/media/i2c/gc0310.c783
-rw-r--r--drivers/media/i2c/gc05a2.c8
-rw-r--r--drivers/media/i2c/gc08a3.c8
-rw-r--r--drivers/media/i2c/gc2145.c2
-rw-r--r--drivers/media/i2c/hi556.c92
-rw-r--r--drivers/media/i2c/hi846.c11
-rw-r--r--drivers/media/i2c/hi847.c84
-rw-r--r--drivers/media/i2c/imx208.c91
-rw-r--r--drivers/media/i2c/imx214.c247
-rw-r--r--drivers/media/i2c/imx219.c6
-rw-r--r--drivers/media/i2c/imx258.c105
-rw-r--r--drivers/media/i2c/imx274.c2
-rw-r--r--drivers/media/i2c/imx283.c5
-rw-r--r--drivers/media/i2c/imx290.c27
-rw-r--r--drivers/media/i2c/imx296.c4
-rw-r--r--drivers/media/i2c/imx319.c92
-rw-r--r--drivers/media/i2c/imx334.c15
-rw-r--r--drivers/media/i2c/imx335.c9
-rw-r--r--drivers/media/i2c/imx355.c90
-rw-r--r--drivers/media/i2c/imx412.c9
-rw-r--r--drivers/media/i2c/imx415.c2
-rw-r--r--drivers/media/i2c/ir-kbd-i2c.c6
-rw-r--r--drivers/media/i2c/mt9m001.c5
-rw-r--r--drivers/media/i2c/mt9m111.c5
-rw-r--r--drivers/media/i2c/mt9m114.c75
-rw-r--r--drivers/media/i2c/mt9p031.c9
-rw-r--r--drivers/media/i2c/mt9t112.c11
-rw-r--r--drivers/media/i2c/mt9v032.c105
-rw-r--r--drivers/media/i2c/mt9v111.c9
-rw-r--r--drivers/media/i2c/og01a1b.c115
-rw-r--r--drivers/media/i2c/og0ve1b.c816
-rw-r--r--drivers/media/i2c/ov02a10.c45
-rw-r--r--drivers/media/i2c/ov02c10.c108
-rw-r--r--drivers/media/i2c/ov02e10.c107
-rw-r--r--drivers/media/i2c/ov08d10.c82
-rw-r--r--drivers/media/i2c/ov08x40.c95
-rw-r--r--drivers/media/i2c/ov13858.c69
-rw-r--r--drivers/media/i2c/ov13b10.c110
-rw-r--r--drivers/media/i2c/ov2659.c5
-rw-r--r--drivers/media/i2c/ov2680.c29
-rw-r--r--drivers/media/i2c/ov2685.c16
-rw-r--r--drivers/media/i2c/ov2735.c1109
-rw-r--r--drivers/media/i2c/ov2740.c91
-rw-r--r--drivers/media/i2c/ov4689.c12
-rw-r--r--drivers/media/i2c/ov5640.c9
-rw-r--r--drivers/media/i2c/ov5645.c13
-rw-r--r--drivers/media/i2c/ov5647.c9
-rw-r--r--drivers/media/i2c/ov5648.c10
-rw-r--r--drivers/media/i2c/ov5670.c105
-rw-r--r--drivers/media/i2c/ov5675.c89
-rw-r--r--drivers/media/i2c/ov5693.c16
-rw-r--r--drivers/media/i2c/ov5695.c16
-rw-r--r--drivers/media/i2c/ov6211.c793
-rw-r--r--drivers/media/i2c/ov64a40.c2
-rw-r--r--drivers/media/i2c/ov6650.c1149
-rw-r--r--drivers/media/i2c/ov7251.c26
-rw-r--r--drivers/media/i2c/ov7740.c11
-rw-r--r--drivers/media/i2c/ov8856.c95
-rw-r--r--drivers/media/i2c/ov8858.c2
-rw-r--r--drivers/media/i2c/ov8865.c50
-rw-r--r--drivers/media/i2c/ov9282.c9
-rw-r--r--drivers/media/i2c/ov9640.c5
-rw-r--r--drivers/media/i2c/ov9650.c5
-rw-r--r--drivers/media/i2c/ov9734.c82
-rw-r--r--drivers/media/i2c/rj54n1cb0c.c9
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c19
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3.h2
-rw-r--r--drivers/media/i2c/s5k5baf.c21
-rw-r--r--drivers/media/i2c/s5k6a3.c20
-rw-r--r--drivers/media/i2c/saa6752hs.c2
-rw-r--r--drivers/media/i2c/saa7115.c2
-rw-r--r--drivers/media/i2c/saa7127.c2
-rw-r--r--drivers/media/i2c/saa717x.c2
-rw-r--r--drivers/media/i2c/tc358743.c113
-rw-r--r--drivers/media/i2c/tc358743_regs.h57
-rw-r--r--drivers/media/i2c/tda9840.c2
-rw-r--r--drivers/media/i2c/tea6415c.c2
-rw-r--r--drivers/media/i2c/tea6420.c2
-rw-r--r--drivers/media/i2c/ths7303.c2
-rw-r--r--drivers/media/i2c/tlv320aic23b.c2
-rw-r--r--drivers/media/i2c/upd64031a.c2
-rw-r--r--drivers/media/i2c/upd64083.c2
-rw-r--r--drivers/media/i2c/vd55g1.c4
-rw-r--r--drivers/media/i2c/vd56g3.c2
-rw-r--r--drivers/media/i2c/vgxy61.c26
-rw-r--r--drivers/media/i2c/vp27smpx.c2
-rw-r--r--drivers/media/i2c/wm8739.c2
-rw-r--r--drivers/media/i2c/wm8775.c2
-rw-r--r--drivers/media/mc/mc-devnode.c6
-rw-r--r--drivers/media/mc/mc-entity.c6
-rw-r--r--drivers/media/mc/mc-request.c2
-rw-r--r--drivers/media/pci/b2c2/flexcop-pci.c2
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c14
-rw-r--r--drivers/media/pci/bt8xx/bttv-vbi.c6
-rw-r--r--drivers/media/pci/cobalt/cobalt-driver.c2
-rw-r--r--drivers/media/pci/cobalt/cobalt-v4l2.c60
-rw-r--r--drivers/media/pci/cx18/cx18-audio.c2
-rw-r--r--drivers/media/pci/cx18/cx18-audio.h2
-rw-r--r--drivers/media/pci/cx18/cx18-av-audio.c2
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.c2
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.h2
-rw-r--r--drivers/media/pci/cx18/cx18-av-firmware.c2
-rw-r--r--drivers/media/pci/cx18/cx18-av-vbi.c2
-rw-r--r--drivers/media/pci/cx18/cx18-cards.c2
-rw-r--r--drivers/media/pci/cx18/cx18-cards.h2
-rw-r--r--drivers/media/pci/cx18/cx18-controls.c2
-rw-r--r--drivers/media/pci/cx18/cx18-controls.h2
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c2
-rw-r--r--drivers/media/pci/cx18/cx18-driver.h4
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.c13
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.h2
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.c2
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.h2
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.c2
-rw-r--r--drivers/media/pci/cx18/cx18-gpio.h2
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.h2
-rw-r--r--drivers/media/pci/cx18/cx18-io.c2
-rw-r--r--drivers/media/pci/cx18/cx18-io.h2
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.c66
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.h2
-rw-r--r--drivers/media/pci/cx18/cx18-irq.c2
-rw-r--r--drivers/media/pci/cx18/cx18-irq.h2
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.c2
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.h2
-rw-r--r--drivers/media/pci/cx18/cx18-queue.c15
-rw-r--r--drivers/media/pci/cx18/cx18-queue.h2
-rw-r--r--drivers/media/pci/cx18/cx18-scb.c2
-rw-r--r--drivers/media/pci/cx18/cx18-scb.h2
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c2
-rw-r--r--drivers/media/pci/cx18/cx18-streams.h2
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.c2
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.h2
-rw-r--r--drivers/media/pci/cx18/cx18-version.h2
-rw-r--r--drivers/media/pci/cx18/cx18-video.c2
-rw-r--r--drivers/media/pci/cx18/cx18-video.h2
-rw-r--r--drivers/media/pci/cx18/cx23418.h2
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c2
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c6
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-video.c1
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-pcm.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-cards.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-cards.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-controls.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-controls.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c17
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.h24
-rw-r--r--drivers/media/pci/ivtv/ivtv-fileops.c42
-rw-r--r--drivers/media/pci/ivtv/ivtv-fileops.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-firmware.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-gpio.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-gpio.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c126
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.c8
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-mailbox.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-mailbox.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-queue.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-queue.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-routing.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-routing.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.c17
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-vbi.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.c8
-rw-r--r--drivers/media/pci/mgb4/mgb4_trigger.c2
-rw-r--r--drivers/media/pci/mgb4/mgb4_vin.c3
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c4
-rw-r--r--drivers/media/pci/saa7164/saa7164-encoder.c30
-rw-r--r--drivers/media/pci/saa7164/saa7164-vbi.c25
-rw-r--r--drivers/media/pci/saa7164/saa7164.h10
-rw-r--r--drivers/media/pci/tw68/tw68-core.c4
-rw-r--r--drivers/media/pci/tw68/tw68-reg.h2
-rw-r--r--drivers/media/pci/tw68/tw68-risc.c2
-rw-r--r--drivers/media/pci/tw68/tw68-video.c2
-rw-r--r--drivers/media/pci/tw68/tw68.h2
-rw-r--r--drivers/media/pci/zoran/zoran.h6
-rw-r--r--drivers/media/pci/zoran/zoran_card.c4
-rw-r--r--drivers/media/pci/zoran/zoran_card.h2
-rw-r--r--drivers/media/pci/zoran/zoran_driver.c35
-rw-r--r--drivers/media/platform/allegro-dvt/allegro-core.c33
-rw-r--r--drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c7
-rw-r--r--drivers/media/platform/amlogic/meson-ge2d/ge2d.c25
-rw-r--r--drivers/media/platform/amphion/vpu.h2
-rw-r--r--drivers/media/platform/amphion/vpu_v4l2.c22
-rw-r--r--drivers/media/platform/amphion/vpu_v4l2.h8
-rw-r--r--drivers/media/platform/aspeed/aspeed-video.c199
-rw-r--r--drivers/media/platform/cadence/cdns-csi2rx.c75
-rw-r--r--drivers/media/platform/chips-media/coda/coda-common.c50
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-helper.c10
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-helper.h2
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c23
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c31
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu.h5
-rw-r--r--drivers/media/platform/imagination/e5010-jpeg-enc.c23
-rw-r--r--drivers/media/platform/imagination/e5010-jpeg-enc.h5
-rw-r--r--drivers/media/platform/m2m-deinterlace.c26
-rw-r--r--drivers/media/platform/marvell/cafe-driver.c2
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c37
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c29
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c3
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c2
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c25
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c2
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c36
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c9
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h5
-rw-r--r--drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c37
-rw-r--r--drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c9
-rw-r--r--drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h4
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/v4l2.c35
-rw-r--r--drivers/media/platform/nxp/dw100/dw100.c7
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c45
-rw-r--r--drivers/media/platform/nxp/imx-mipi-csis.c353
-rw-r--r--drivers/media/platform/nxp/imx-pxp.c7
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c8
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h14
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c2
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c292
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c2
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c156
-rw-r--r--drivers/media/platform/nxp/mx2_emmaprp.c24
-rw-r--r--drivers/media/platform/qcom/camss/Makefile6
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-340.c190
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-gen3.c (renamed from drivers/media/platform/qcom/camss/camss-csid-780.c)34
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid-gen3.h (renamed from drivers/media/platform/qcom/camss/camss-csid-780.h)8
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.h3
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c175
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-340.c320
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-gen3.c (renamed from drivers/media/platform/qcom/camss/camss-vfe-780.c)76
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.c28
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.h3
-rw-r--r--drivers/media/platform/qcom/camss/camss-video.c43
-rw-r--r--drivers/media/platform/qcom/camss/camss.c705
-rw-r--r--drivers/media/platform/qcom/camss/camss.h4
-rw-r--r--drivers/media/platform/qcom/iris/Makefile5
-rw-r--r--drivers/media/platform/qcom/iris/iris_buffer.c222
-rw-r--r--drivers/media/platform/qcom/iris/iris_buffer.h7
-rw-r--r--drivers/media/platform/qcom/iris/iris_common.c232
-rw-r--r--drivers/media/platform/qcom/iris/iris_common.h18
-rw-r--r--drivers/media/platform/qcom/iris/iris_core.c10
-rw-r--r--drivers/media/platform/qcom/iris/iris_core.h20
-rw-r--r--drivers/media/platform/qcom/iris/iris_ctrls.c675
-rw-r--r--drivers/media/platform/qcom/iris/iris_ctrls.h15
-rw-r--r--drivers/media/platform/qcom/iris/iris_firmware.c15
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_common.h2
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c482
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h112
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c60
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c359
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h44
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c46
-rw-r--r--drivers/media/platform/qcom/iris/iris_instance.h24
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_common.h82
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_gen2.c609
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_qcs8300.h352
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_sm8250.c236
-rw-r--r--drivers/media/platform/qcom/iris/iris_platform_sm8750.h22
-rw-r--r--drivers/media/platform/qcom/iris/iris_probe.c37
-rw-r--r--drivers/media/platform/qcom/iris/iris_state.c9
-rw-r--r--drivers/media/platform/qcom/iris/iris_state.h1
-rw-r--r--drivers/media/platform/qcom/iris/iris_utils.c36
-rw-r--r--drivers/media/platform/qcom/iris/iris_utils.h2
-rw-r--r--drivers/media/platform/qcom/iris/iris_vb2.c58
-rw-r--r--drivers/media/platform/qcom/iris/iris_vdec.c251
-rw-r--r--drivers/media/platform/qcom/iris/iris_vdec.h13
-rw-r--r--drivers/media/platform/qcom/iris/iris_venc.c579
-rw-r--r--drivers/media/platform/qcom/iris/iris_venc.h27
-rw-r--r--drivers/media/platform/qcom/iris/iris_vidc.c335
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu2.c2
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu3x.c202
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu_buffer.c922
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu_buffer.h24
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu_common.c14
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu_common.h6
-rw-r--r--drivers/media/platform/qcom/venus/core.c113
-rw-r--r--drivers/media/platform/qcom/venus/core.h22
-rw-r--r--drivers/media/platform/qcom/venus/firmware.c42
-rw-r--r--drivers/media/platform/qcom/venus/firmware.h2
-rw-r--r--drivers/media/platform/qcom/venus/helpers.c12
-rw-r--r--drivers/media/platform/qcom/venus/hfi_msgs.c11
-rw-r--r--drivers/media/platform/qcom/venus/hfi_parser.c2
-rw-r--r--drivers/media/platform/qcom/venus/hfi_platform.c23
-rw-r--r--drivers/media/platform/qcom/venus/hfi_platform.h34
-rw-r--r--drivers/media/platform/qcom/venus/hfi_platform_v4.c188
-rw-r--r--drivers/media/platform/qcom/venus/hfi_platform_v6.c33
-rw-r--r--drivers/media/platform/qcom/venus/hfi_venus.c25
-rw-r--r--drivers/media/platform/qcom/venus/hfi_venus_io.h4
-rw-r--r--drivers/media/platform/qcom/venus/pm_helpers.c11
-rw-r--r--drivers/media/platform/qcom/venus/vdec.c5
-rw-r--r--drivers/media/platform/qcom/venus/venc.c5
-rw-r--r--drivers/media/platform/raspberrypi/rp1-cfe/csi2.c2
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-core.c8
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c2
-rw-r--r--drivers/media/platform/renesas/rcar_drif.c12
-rw-r--r--drivers/media/platform/renesas/rcar_fdp1.c27
-rw-r--r--drivers/media/platform/renesas/rcar_jpu.c29
-rw-r--r--drivers/media/platform/renesas/renesas-ceu.c10
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c2
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h9
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c31
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_drv.c14
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_histo.c6
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_video.c18
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_vspx.c1
-rw-r--r--drivers/media/platform/rockchip/rga/rga.c30
-rw-r--r--drivers/media/platform/rockchip/rga/rga.h5
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-common.h17
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c123
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec.c21
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec.h4
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-core.h6
-rw-r--r--drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c37
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-core.h5
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-m2m.c19
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-capture.c26
-rw-r--r--drivers/media/platform/samsung/s5p-g2d/g2d.c40
-rw-r--r--drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c33
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c17
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c35
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h6
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c34
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c38
-rw-r--r--drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c30
-rw-r--r--drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c20
-rw-r--r--drivers/media/platform/st/sti/delta/delta-v4l2.c41
-rw-r--r--drivers/media/platform/st/sti/hva/hva-v4l2.c38
-rw-r--r--drivers/media/platform/st/sti/hva/hva.h2
-rw-r--r--drivers/media/platform/st/stm32/dma2d/dma2d.c28
-rw-r--r--drivers/media/platform/st/stm32/stm32-csi.c4
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmi.c4
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c16
-rw-r--r--drivers/media/platform/sunxi/sun8i-di/sun8i-di.c10
-rw-r--r--drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c10
-rw-r--r--drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c8
-rw-r--r--drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h6
-rw-r--r--drivers/media/platform/ti/Kconfig3
-rw-r--r--drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c67
-rw-r--r--drivers/media/platform/ti/omap/omap_vout.c6
-rw-r--r--drivers/media/platform/ti/omap3isp/ispccdc.c8
-rw-r--r--drivers/media/platform/ti/omap3isp/isph3a_aewb.c2
-rw-r--r--drivers/media/platform/ti/omap3isp/isph3a_af.c2
-rw-r--r--drivers/media/platform/ti/omap3isp/isphist.c2
-rw-r--r--drivers/media/platform/ti/omap3isp/ispstat.c7
-rw-r--r--drivers/media/platform/ti/omap3isp/ispstat.h3
-rw-r--r--drivers/media/platform/ti/omap3isp/ispvideo.c36
-rw-r--r--drivers/media/platform/ti/omap3isp/ispvideo.h6
-rw-r--r--drivers/media/platform/ti/vpe/vpe.c21
-rw-r--r--drivers/media/platform/verisilicon/hantro.h4
-rw-r--r--drivers/media/platform/verisilicon/hantro_drv.c12
-rw-r--r--drivers/media/platform/verisilicon/hantro_v4l2.c28
-rw-r--r--drivers/media/platform/verisilicon/imx8m_vpu_hw.c20
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.c10
-rw-r--r--drivers/media/radio/Kconfig17
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-aztech.c2
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-isa.c2
-rw-r--r--drivers/media/radio/radio-isa.h2
-rw-r--r--drivers/media/radio/radio-keene.c4
-rw-r--r--drivers/media/radio/radio-miropcm20.c2
-rw-r--r--drivers/media/radio/radio-raremono.c4
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-terratec.c2
-rw-r--r--drivers/media/radio/radio-wl1273.c2159
-rw-r--r--drivers/media/radio/radio-zoltrix.c2
-rw-r--r--drivers/media/radio/si4713/radio-platform-si4713.c10
-rw-r--r--drivers/media/rc/imon.c99
-rw-r--r--drivers/media/rc/lirc_dev.c9
-rw-r--r--drivers/media/rc/redrat3.c2
-rw-r--r--drivers/media/test-drivers/vicodec/vicodec-core.c23
-rw-r--r--drivers/media/test-drivers/vim2m.c23
-rw-r--r--drivers/media/test-drivers/vimc/vimc-capture.c4
-rw-r--r--drivers/media/test-drivers/vimc/vimc-core.c2
-rw-r--r--drivers/media/test-drivers/visl/visl-core.c5
-rw-r--r--drivers/media/test-drivers/visl/visl.h7
-rw-r--r--drivers/media/test-drivers/vivid/vivid-cec.c12
-rw-r--r--drivers/media/test-drivers/vivid/vivid-core.c100
-rw-r--r--drivers/media/test-drivers/vivid/vivid-radio-rx.c12
-rw-r--r--drivers/media/test-drivers/vivid/vivid-radio-rx.h8
-rw-r--r--drivers/media/test-drivers/vivid/vivid-radio-tx.c8
-rw-r--r--drivers/media/test-drivers/vivid/vivid-radio-tx.h4
-rw-r--r--drivers/media/test-drivers/vivid/vivid-sdr-cap.c18
-rw-r--r--drivers/media/test-drivers/vivid/vivid-sdr-cap.h18
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vbi-cap.c10
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vbi-cap.h8
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vbi-out.c8
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vbi-out.h6
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-cap.c24
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-cap.h24
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-common.c8
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-common.h8
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-out.c16
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-out.h16
-rw-r--r--drivers/media/tuners/xc4000.c8
-rw-r--r--drivers/media/tuners/xc5000.c14
-rw-r--r--drivers/media/usb/au0828/au0828-video.c5
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-417.c2
-rw-r--r--drivers/media/usb/em28xx/Kconfig1
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c4
-rw-r--r--drivers/media/usb/gspca/gspca.c18
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-video.c69
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.c69
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c3
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c7
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c56
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c115
-rw-r--r--drivers/media/usb/uvc/uvc_entity.c4
-rw-r--r--drivers/media/usb/uvc/uvc_metadata.c71
-rw-r--r--drivers/media/usb/uvc/uvc_status.c7
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c128
-rw-r--r--drivers/media/usb/uvc/uvc_video.c10
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h21
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c90
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c11
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-api.c13
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-core.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-defs.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-priv.h2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-request.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c45
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-fh.c16
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c456
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c50
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c40
459 files changed, 15316 insertions, 8599 deletions
diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
index e10bd588a586..d7259599029f 100644
--- a/drivers/media/cec/core/cec-core.c
+++ b/drivers/media/cec/core/cec-core.c
@@ -439,6 +439,6 @@ static void __exit cec_devnode_exit(void)
subsys_initcall(cec_devnode_init);
module_exit(cec_devnode_exit)
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_DESCRIPTION("Device node registration for cec drivers");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/platform/cec-gpio/cec-gpio.c b/drivers/media/cec/platform/cec-gpio/cec-gpio.c
index 3c27789d8657..842555ed42c7 100644
--- a/drivers/media/cec/platform/cec-gpio/cec-gpio.c
+++ b/drivers/media/cec/platform/cec-gpio/cec-gpio.c
@@ -291,6 +291,6 @@ static struct platform_driver cec_gpio_pdrv = {
module_platform_driver(cec_gpio_pdrv);
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("CEC GPIO driver");
diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c
index fea2d65acffc..1ec0cece0a5b 100644
--- a/drivers/media/cec/platform/stm32/stm32-cec.c
+++ b/drivers/media/cec/platform/stm32/stm32-cec.c
@@ -248,7 +248,6 @@ static const struct regmap_config stm32_cec_regmap_cfg = {
.val_bits = 32,
.reg_stride = sizeof(u32),
.max_register = 0x14,
- .fast_io = true,
};
static int stm32_cec_probe(struct platform_device *pdev)
diff --git a/drivers/media/cec/usb/extron-da-hd-4k-plus/Makefile b/drivers/media/cec/usb/extron-da-hd-4k-plus/Makefile
index 2e8f7f60263f..08d58524419f 100644
--- a/drivers/media/cec/usb/extron-da-hd-4k-plus/Makefile
+++ b/drivers/media/cec/usb/extron-da-hd-4k-plus/Makefile
@@ -1,8 +1,2 @@
extron-da-hd-4k-plus-cec-objs := extron-da-hd-4k-plus.o cec-splitter.o
obj-$(CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC) := extron-da-hd-4k-plus-cec.o
-
-all:
- $(MAKE) -C $(KDIR) M=$(shell pwd) modules
-
-install:
- $(MAKE) -C $(KDIR) M=$(shell pwd) modules_install
diff --git a/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c b/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
index 41d019b01ec0..e2eff17952ab 100644
--- a/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
+++ b/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
@@ -28,7 +28,7 @@
#include "extron-da-hd-4k-plus.h"
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_DESCRIPTION("Extron DA HD 4K PLUS HDMI CEC driver");
MODULE_LICENSE("GPL");
@@ -1252,7 +1252,7 @@ static int extron_s_output(struct file *file, void *priv, unsigned int o)
return o ? -EINVAL : 0;
}
-static int extron_g_edid(struct file *file, void *_fh,
+static int extron_g_edid(struct file *file, void *priv,
struct v4l2_edid *edid)
{
struct extron_port *port = video_drvdata(file);
@@ -1280,7 +1280,7 @@ static int extron_g_edid(struct file *file, void *_fh,
return 0;
}
-static int extron_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid)
+static int extron_s_edid(struct file *file, void *priv, struct v4l2_edid *edid)
{
struct extron_port *port = video_drvdata(file);
diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c
index 171366fe3544..60569f1670fe 100644
--- a/drivers/media/cec/usb/pulse8/pulse8-cec.c
+++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c
@@ -2,7 +2,7 @@
/*
* Pulse Eight HDMI CEC driver
*
- * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
+ * Copyright 2016 Hans Verkuil <hverkuil@kernel.org>
*/
/*
@@ -41,7 +41,7 @@
#include <media/cec.h>
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/usb/rainshadow/rainshadow-cec.c b/drivers/media/cec/usb/rainshadow/rainshadow-cec.c
index 6f8d6797c614..08f58456d682 100644
--- a/drivers/media/cec/usb/rainshadow/rainshadow-cec.c
+++ b/drivers/media/cec/usb/rainshadow/rainshadow-cec.c
@@ -2,7 +2,7 @@
/*
* RainShadow Tech HDMI CEC driver
*
- * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
+ * Copyright 2016 Hans Verkuil <hverkuil@kernel.org>
*/
/*
@@ -31,7 +31,7 @@
#include <media/cec.h>
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
index d97962eb0112..dba03769f263 100644
--- a/drivers/media/common/b2c2/flexcop-sram.c
+++ b/drivers/media/common/b2c2/flexcop-sram.c
@@ -352,7 +352,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
- dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
+ dprintk("%s: SRAM detection failed. Set to 32K\n", __func__);
return 0;
}
diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c
index e7a88a2d248c..8506de48ba45 100644
--- a/drivers/media/common/b2c2/flexcop.c
+++ b/drivers/media/common/b2c2/flexcop.c
@@ -170,7 +170,7 @@ static void flexcop_reset(struct flexcop_device *fc)
flexcop_ibi_value v210, v204;
/* reset the flexcop itself */
- fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+ fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
v210.raw = 0;
v210.sw_reset_210.reset_block_000 = 1;
@@ -183,17 +183,17 @@ static void flexcop_reset(struct flexcop_device *fc)
v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
v210.sw_reset_210.Special_controls = 0xc259;
- fc->write_ibi_reg(fc,sw_reset_210,v210);
+ fc->write_ibi_reg(fc, sw_reset_210, v210);
msleep(1);
/* reset the periphical devices */
- v204 = fc->read_ibi_reg(fc,misc_204);
+ v204 = fc->read_ibi_reg(fc, misc_204);
v204.misc_204.Per_reset_sig = 0;
- fc->write_ibi_reg(fc,misc_204,v204);
+ fc->write_ibi_reg(fc, misc_204, v204);
msleep(1);
v204.misc_204.Per_reset_sig = 1;
- fc->write_ibi_reg(fc,misc_204,v204);
+ fc->write_ibi_reg(fc, misc_204, v204);
}
void flexcop_reset_block_300(struct flexcop_device *fc)
@@ -202,13 +202,13 @@ void flexcop_reset_block_300(struct flexcop_device *fc)
v210 = fc->read_ibi_reg(fc, sw_reset_210);
deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
- fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+ fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
v210.sw_reset_210.reset_block_300 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
- fc->write_ibi_reg(fc,sw_reset_210,v210);
- fc->write_ibi_reg(fc,ctrl_208,v208_save);
+ fc->write_ibi_reg(fc, sw_reset_210, v210);
+ fc->write_ibi_reg(fc, ctrl_208, v208_save);
}
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
@@ -266,8 +266,8 @@ int flexcop_device_initialize(struct flexcop_device *fc)
if (fc->get_mac_addr(fc, 0) == 0) {
u8 *b = fc->dvb_adapter.proposed_mac;
info("MAC address = %pM", b);
- flexcop_set_mac_filter(fc,b);
- flexcop_mac_filter_ctrl(fc,1);
+ flexcop_set_mac_filter(fc, b);
+ flexcop_mac_filter_ctrl(fc, 1);
} else
warn("reading of MAC address failed.\n");
@@ -275,7 +275,7 @@ int flexcop_device_initialize(struct flexcop_device *fc)
if (ret)
goto error;
- flexcop_device_name(fc,"initialization of","complete");
+ flexcop_device_name(fc, "initialization of", "complete");
return 0;
error:
diff --git a/drivers/media/common/cx2341x.c b/drivers/media/common/cx2341x.c
index 1392bd6b0026..1ee159ef7f38 100644
--- a/drivers/media/common/cx2341x.c
+++ b/drivers/media/common/cx2341x.c
@@ -2,7 +2,7 @@
/*
* cx2341x - generic code for cx23415/6/8 based devices
*
- * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2006 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 1cd26faee503..d911021c1bb0 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -973,18 +973,14 @@ EXPORT_SYMBOL_GPL(vb2_queue_change_type);
__poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
{
- struct video_device *vfd = video_devdata(file);
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
__poll_t res;
res = vb2_core_poll(q, file, wait);
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
- struct v4l2_fh *fh = file->private_data;
-
- poll_wait(file, &fh->wait, wait);
- if (v4l2_event_pending(fh))
- res |= EPOLLPRI;
- }
+ poll_wait(file, &fh->wait, wait);
+ if (v4l2_event_pending(fh))
+ res |= EPOLLPRI;
return res;
}
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 2ef2ff2a38ff..bcc97ca86ed5 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -163,7 +163,7 @@ config DVB_CX24123
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_DS3000
- tristate "Montage Tehnology DS3000 based"
+ tristate "Montage Technology DS3000 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
@@ -270,7 +270,7 @@ config DVB_TDA826X
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_TS2020
- tristate "Montage Tehnology TS2020 based tuners"
+ tristate "Montage Technology TS2020 based tuners"
depends on DVB_CORE && I2C
select REGMAP_I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 6237fe804a5c..cdd7ba5da0d5 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -27,7 +27,7 @@ config VIDEO_IR_I2C
menuconfig VIDEO_CAMERA_SENSOR
bool "Camera sensor devices"
- depends on MEDIA_CAMERA_SUPPORT && I2C
+ depends on MEDIA_CAMERA_SUPPORT && I2C && HAVE_CLK
select MEDIA_CONTROLLER
select V4L2_FWNODE
select VIDEO_V4L2_SUBDEV_API
@@ -70,6 +70,16 @@ config VIDEO_GC0308
To compile this driver as a module, choose M here: the
module will be called gc0308.
+config VIDEO_GC0310
+ tristate "GalaxyCore GC0310 sensor support"
+ select V4L2_CCI_I2C
+ help
+ This is a Video4Linux2 sensor-level driver for the Galaxycore
+ GC0310 0.3MP sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gc0310.
+
config VIDEO_GC05A2
tristate "GalaxyCore gc05a2 sensor support"
select V4L2_CCI_I2C
@@ -317,6 +327,7 @@ config VIDEO_MT9V011
config VIDEO_MT9V032
tristate "Micron MT9V032 sensor support"
+ depends on OF
select REGMAP_I2C
help
This is a Video4Linux2 sensor driver for the Micron
@@ -340,6 +351,16 @@ config VIDEO_OG01A1B
To compile this driver as a module, choose M here: the
module will be called og01a1b.
+config VIDEO_OG0VE1B
+ tristate "OmniVision OG0VE1B sensor support"
+ select V4L2_CCI_I2C
+ help
+ This is a Video4Linux2 sensor driver for the OmniVision
+ OG0VE1B camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called og0ve1b.
+
config VIDEO_OV01A10
tristate "OmniVision OV01A10 sensor support"
help
@@ -446,6 +467,16 @@ config VIDEO_OV2685
To compile this driver as a module, choose M here: the
module will be called ov2685.
+config VIDEO_OV2735
+ tristate "OmniVision OV2735 sensor support"
+ select V4L2_CCI_I2C
+ help
+ This is a Video4Linux2 sensor driver for the Sony
+ OV2735 camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov2735.
+
config VIDEO_OV2740
tristate "OmniVision OV2740 sensor support"
depends on ACPI || COMPILE_TEST
@@ -542,24 +573,25 @@ config VIDEO_OV5695
To compile this driver as a module, choose M here: the
module will be called ov5695.
-config VIDEO_OV64A40
- tristate "OmniVision OV64A40 sensor support"
+config VIDEO_OV6211
+ tristate "OmniVision OV6211 sensor support"
select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the OmniVision
- OV64A40 camera.
+ OV6211 camera.
To compile this driver as a module, choose M here: the
- module will be called ov64a40.
+ module will be called ov6211.
-config VIDEO_OV6650
- tristate "OmniVision OV6650 sensor support"
+config VIDEO_OV64A40
+ tristate "OmniVision OV64A40 sensor support"
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the OmniVision
- OV6650 camera.
+ OV64A40 camera.
To compile this driver as a module, choose M here: the
- module will be called ov6650.
+ module will be called ov64a40.
config VIDEO_OV7251
tristate "OmniVision OV7251 sensor support"
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 5873d29433ee..57cdd8dc96f6 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
+obj-$(CONFIG_VIDEO_GC0310) += gc0310.o
obj-$(CONFIG_VIDEO_GC05A2) += gc05a2.o
obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
@@ -81,6 +82,7 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o
obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o
+obj-$(CONFIG_VIDEO_OG0VE1B) += og0ve1b.o
obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o
obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
obj-$(CONFIG_VIDEO_OV02C10) += ov02c10.o
@@ -93,6 +95,7 @@ obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_OV2680) += ov2680.o
obj-$(CONFIG_VIDEO_OV2685) += ov2685.o
+obj-$(CONFIG_VIDEO_OV2735) += ov2735.o
obj-$(CONFIG_VIDEO_OV2740) += ov2740.o
obj-$(CONFIG_VIDEO_OV4689) += ov4689.o
obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
@@ -103,8 +106,8 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
+obj-$(CONFIG_VIDEO_OV6211) += ov6211.o
obj-$(CONFIG_VIDEO_OV64A40) += ov64a40.o
-obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 5d90b8ab9b6d..378f4e6af12c 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -214,7 +214,6 @@ struct adv7180_state {
struct gpio_desc *pwdn_gpio;
struct gpio_desc *rst_gpio;
v4l2_std_id curr_norm;
- bool powered;
bool streaming;
u8 input;
@@ -274,6 +273,38 @@ static int adv7180_vpp_write(struct adv7180_state *state, unsigned int reg,
return i2c_smbus_write_byte_data(state->vpp_client, reg, value);
}
+static int adv7180_set_power(struct adv7180_state *state, bool on)
+{
+ u8 val;
+ int ret;
+
+ if (on)
+ val = ADV7180_PWR_MAN_ON;
+ else
+ val = ADV7180_PWR_MAN_OFF;
+
+ ret = adv7180_write(state, ADV7180_REG_PWR_MAN, val);
+ if (ret)
+ return ret;
+
+ if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
+ if (on) {
+ adv7180_csi_write(state, 0xDE, 0x02);
+ adv7180_csi_write(state, 0xD2, 0xF7);
+ adv7180_csi_write(state, 0xD8, 0x65);
+ adv7180_csi_write(state, 0xE0, 0x09);
+ adv7180_csi_write(state, 0x2C, 0x00);
+ if (state->field == V4L2_FIELD_NONE)
+ adv7180_csi_write(state, 0x1D, 0x80);
+ adv7180_csi_write(state, 0x00, 0x00);
+ } else {
+ adv7180_csi_write(state, 0x00, 0x80);
+ }
+ }
+
+ return 0;
+}
+
static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
{
/* in case V4L2_IN_ST_NO_SIGNAL */
@@ -357,32 +388,27 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
struct adv7180_state *state = to_state(sd);
- int err = mutex_lock_interruptible(&state->mutex);
- if (err)
- return err;
-
- if (state->streaming) {
- err = -EBUSY;
- goto unlock;
- }
+ int ret;
- err = adv7180_set_video_standard(state,
- ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM);
- if (err)
- goto unlock;
+ guard(mutex)(&state->mutex);
- msleep(100);
- __adv7180_status(state, NULL, std);
+ /*
+ * We can't sample the standard if the device is streaming as that would
+ * interfere with the capture session as the VID_SEL reg is touched.
+ */
+ if (state->streaming)
+ return -EBUSY;
- err = v4l2_std_to_adv7180(state->curr_norm);
- if (err < 0)
- goto unlock;
+ /* Set the standard to autodetect PAL B/G/H/I/D, NTSC J or SECAM */
+ ret = adv7180_set_video_standard(state,
+ ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM);
+ if (ret)
+ return ret;
- err = adv7180_set_video_standard(state, err);
+ /* Allow some time for the autodetection to run. */
+ msleep(100);
-unlock:
- mutex_unlock(&state->mutex);
- return err;
+ return __adv7180_status(state, NULL, std);
}
static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
@@ -437,22 +463,18 @@ static int adv7180_program_std(struct adv7180_state *state)
static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct adv7180_state *state = to_state(sd);
- int ret = mutex_lock_interruptible(&state->mutex);
+ int ret;
- if (ret)
- return ret;
+ guard(mutex)(&state->mutex);
/* Make sure we can support this std */
ret = v4l2_std_to_adv7180(std);
if (ret < 0)
- goto out;
+ return ret;
state->curr_norm = std;
- ret = adv7180_program_std(state);
-out:
- mutex_unlock(&state->mutex);
- return ret;
+ return 0;
}
static int adv7180_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
@@ -514,55 +536,6 @@ static void adv7180_set_reset_pin(struct adv7180_state *state, bool on)
}
}
-static int adv7180_set_power(struct adv7180_state *state, bool on)
-{
- u8 val;
- int ret;
-
- if (on)
- val = ADV7180_PWR_MAN_ON;
- else
- val = ADV7180_PWR_MAN_OFF;
-
- ret = adv7180_write(state, ADV7180_REG_PWR_MAN, val);
- if (ret)
- return ret;
-
- if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
- if (on) {
- adv7180_csi_write(state, 0xDE, 0x02);
- adv7180_csi_write(state, 0xD2, 0xF7);
- adv7180_csi_write(state, 0xD8, 0x65);
- adv7180_csi_write(state, 0xE0, 0x09);
- adv7180_csi_write(state, 0x2C, 0x00);
- if (state->field == V4L2_FIELD_NONE)
- adv7180_csi_write(state, 0x1D, 0x80);
- adv7180_csi_write(state, 0x00, 0x00);
- } else {
- adv7180_csi_write(state, 0x00, 0x80);
- }
- }
-
- return 0;
-}
-
-static int adv7180_s_power(struct v4l2_subdev *sd, int on)
-{
- struct adv7180_state *state = to_state(sd);
- int ret;
-
- ret = mutex_lock_interruptible(&state->mutex);
- if (ret)
- return ret;
-
- ret = adv7180_set_power(state, on);
- if (ret == 0)
- state->powered = on;
-
- mutex_unlock(&state->mutex);
- return ret;
-}
-
static const char * const test_pattern_menu[] = {
"Single color",
"Color bars",
@@ -601,11 +574,11 @@ static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
struct adv7180_state *state = to_state(sd);
- int ret = mutex_lock_interruptible(&state->mutex);
+ int ret = 0;
int val;
- if (ret)
- return ret;
+ lockdep_assert_held(&state->mutex);
+
val = ctrl->val;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
@@ -647,7 +620,6 @@ static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
ret = -EINVAL;
}
- mutex_unlock(&state->mutex);
return ret;
}
@@ -668,6 +640,7 @@ static const struct v4l2_ctrl_config adv7180_ctrl_fast_switch = {
static int adv7180_init_controls(struct adv7180_state *state)
{
v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
+ state->ctrl_hdl.lock = &state->mutex;
v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
@@ -700,7 +673,6 @@ static int adv7180_init_controls(struct adv7180_state *state)
v4l2_ctrl_handler_free(&state->ctrl_hdl);
return err;
}
- v4l2_ctrl_handler_setup(&state->ctrl_hdl);
return 0;
}
@@ -812,12 +784,7 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd,
ret = adv7180_mbus_fmt(sd, &format->format);
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- if (state->field != format->format.field) {
- state->field = format->format.field;
- adv7180_set_power(state, false);
- adv7180_set_field_mode(state);
- adv7180_set_power(state, true);
- }
+ state->field = format->format.field;
} else {
framefmt = v4l2_subdev_state_get_format(sd_state, 0);
*framefmt = format->format;
@@ -874,23 +841,117 @@ static int adv7180_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
return 0;
}
-static int adv7180_s_stream(struct v4l2_subdev *sd, int enable)
+static int init_device(struct adv7180_state *state)
{
- struct adv7180_state *state = to_state(sd);
int ret;
- /* It's always safe to stop streaming, no need to take the lock */
- if (!enable) {
- state->streaming = enable;
- return 0;
+ lockdep_assert_held(&state->mutex);
+
+ ret = adv7180_program_std(state);
+ if (ret)
+ return ret;
+
+ adv7180_set_field_mode(state);
+
+ __v4l2_ctrl_handler_setup(&state->ctrl_hdl);
+
+ return ret;
+}
+
+static int adv7180_reset_device(struct adv7180_state *state)
+{
+ int ret;
+
+ lockdep_assert_held(&state->mutex);
+
+ adv7180_set_power_pin(state, true);
+ adv7180_set_reset_pin(state, false);
+
+ adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
+ usleep_range(5000, 10000);
+
+ /*
+ * If the devices decoder is power on after reset, power off so the
+ * device can be configured.
+ */
+ if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
+ adv7180_set_power(state, false);
+
+ ret = state->chip_info->init(state);
+ if (ret)
+ return ret;
+
+ ret = init_device(state);
+ if (ret)
+ return ret;
+
+ /* register for interrupts */
+ if (state->irq > 0) {
+ /* config the Interrupt pin to be active low */
+ ret = adv7180_write(state, ADV7180_REG_ICONF1,
+ ADV7180_ICONF1_ACTIVE_LOW |
+ ADV7180_ICONF1_PSYNC_ONLY);
+ if (ret < 0)
+ return ret;
+
+ ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
+ if (ret < 0)
+ return ret;
+
+ /* enable AD change interrupts */
+ ret = adv7180_write(state, ADV7180_REG_IMR3,
+ ADV7180_IRQ3_AD_CHANGE);
+ if (ret < 0)
+ return ret;
+
+ ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
+ if (ret < 0)
+ return ret;
}
+ /*
+ * If the devices decoder is power on after reset, restore the power
+ * after configuration. This is to preserve the behavior of the driver,
+ * not doing this result in the first 35+ frames captured being garbage.
+ */
+ if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
+ adv7180_set_power(state, true);
+
+ return 0;
+}
+
+static int adv7180_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct adv7180_state *state = to_state(sd);
+ int ret;
+
/* Must wait until querystd released the lock */
- ret = mutex_lock_interruptible(&state->mutex);
+ guard(mutex)(&state->mutex);
+
+ /*
+ * Always power off the decoder even if streaming is to be enabled, the
+ * decoder needs to be off for the device to be configured.
+ */
+ ret = adv7180_set_power(state, false);
if (ret)
return ret;
+
+ if (enable) {
+ ret = init_device(state);
+ if (ret)
+ return ret;
+
+ ret = adv7180_set_power(state, true);
+ if (ret)
+ return ret;
+ }
+
state->streaming = enable;
- mutex_unlock(&state->mutex);
+
return 0;
}
@@ -919,7 +980,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
};
static const struct v4l2_subdev_core_ops adv7180_core_ops = {
- .s_power = adv7180_s_power,
.subscribe_event = adv7180_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
@@ -1343,62 +1403,6 @@ static const struct adv7180_chip_info adv7282_m_info = {
.select_input = adv7182_select_input,
};
-static int init_device(struct adv7180_state *state)
-{
- int ret;
-
- mutex_lock(&state->mutex);
-
- adv7180_set_power_pin(state, true);
- adv7180_set_reset_pin(state, false);
-
- adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
- usleep_range(5000, 10000);
-
- ret = state->chip_info->init(state);
- if (ret)
- goto out_unlock;
-
- ret = adv7180_program_std(state);
- if (ret)
- goto out_unlock;
-
- adv7180_set_field_mode(state);
-
- /* register for interrupts */
- if (state->irq > 0) {
- /* config the Interrupt pin to be active low */
- ret = adv7180_write(state, ADV7180_REG_ICONF1,
- ADV7180_ICONF1_ACTIVE_LOW |
- ADV7180_ICONF1_PSYNC_ONLY);
- if (ret < 0)
- goto out_unlock;
-
- ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
- if (ret < 0)
- goto out_unlock;
-
- ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
- if (ret < 0)
- goto out_unlock;
-
- /* enable AD change interrupts interrupts */
- ret = adv7180_write(state, ADV7180_REG_IMR3,
- ADV7180_IRQ3_AD_CHANGE);
- if (ret < 0)
- goto out_unlock;
-
- ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
- if (ret < 0)
- goto out_unlock;
- }
-
-out_unlock:
- mutex_unlock(&state->mutex);
-
- return ret;
-}
-
static int adv7180_probe(struct i2c_client *client)
{
struct device_node *np = client->dev.of_node;
@@ -1457,10 +1461,7 @@ static int adv7180_probe(struct i2c_client *client)
state->irq = client->irq;
mutex_init(&state->mutex);
state->curr_norm = V4L2_STD_NTSC;
- if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
- state->powered = true;
- else
- state->powered = false;
+
state->input = 0;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
@@ -1477,7 +1478,9 @@ static int adv7180_probe(struct i2c_client *client)
if (ret)
goto err_free_ctrl;
- ret = init_device(state);
+ mutex_lock(&state->mutex);
+ ret = adv7180_reset_device(state);
+ mutex_unlock(&state->mutex);
if (ret)
goto err_media_entity_cleanup;
@@ -1549,6 +1552,8 @@ static int adv7180_suspend(struct device *dev)
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct adv7180_state *state = to_state(sd);
+ guard(mutex)(&state->mutex);
+
return adv7180_set_power(state, false);
}
@@ -1558,13 +1563,18 @@ static int adv7180_resume(struct device *dev)
struct adv7180_state *state = to_state(sd);
int ret;
- ret = init_device(state);
+ guard(mutex)(&state->mutex);
+
+ ret = adv7180_reset_device(state);
if (ret < 0)
return ret;
- ret = adv7180_set_power(state, state->powered);
- if (ret)
- return ret;
+ /* If we were streaming when suspending, start decoder. */
+ if (state->streaming) {
+ ret = adv7180_set_power(state, true);
+ if (ret)
+ return ret;
+ }
return 0;
}
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index afed38596362..8fe7c2f72883 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -42,7 +42,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-2)");
MODULE_DESCRIPTION("Analog Devices ADV7604/10/11/12 video decoder driver");
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 5545cd23e113..9780082db841 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -38,7 +38,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-2)");
MODULE_DESCRIPTION("Analog Devices ADV7842 video decoder driver");
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_AUTHOR("Martin Bugge <marbugge@cisco.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c
index 24873149096c..939bf590d4b2 100644
--- a/drivers/media/i2c/ar0521.c
+++ b/drivers/media/i2c/ar0521.c
@@ -1077,11 +1077,10 @@ static int ar0521_probe(struct i2c_client *client)
}
/* Get master clock (extclk) */
- sensor->extclk = devm_clk_get(dev, "extclk");
- if (IS_ERR(sensor->extclk)) {
- dev_err(dev, "failed to get extclk\n");
- return PTR_ERR(sensor->extclk);
- }
+ sensor->extclk = devm_v4l2_sensor_clk_get(dev, "extclk");
+ if (IS_ERR(sensor->extclk))
+ return dev_err_probe(dev, PTR_ERR(sensor->extclk),
+ "failed to get extclk\n");
sensor->extclk_freq = clk_get_rate(sensor->extclk);
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index a90a9e5705a0..a86306304330 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -9,10 +9,10 @@
* Changes by Tyler Trafford <tatrafford@comcast.net>
* - cleanup/rewrite for V4L2 API (2005)
*
- * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
+ * VBI support by Hans Verkuil <hverkuil@kernel.org>.
*
* NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
- * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
+ * with additional fixes by Hans Verkuil <hverkuil@kernel.org>.
*
* CX23885 support by Steven Toth <stoth@linuxtv.org>.
*
diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
index a80da2b4a8fa..73150061ea45 100644
--- a/drivers/media/i2c/ds90ub913.c
+++ b/drivers/media/i2c/ds90ub913.c
@@ -333,8 +333,7 @@ static int _ub913_set_routing(struct v4l2_subdev *sd,
.quantization = V4L2_QUANTIZATION_LIM_RANGE,
.xfer_func = V4L2_XFER_FUNC_SRGB,
};
- struct v4l2_subdev_stream_configs *stream_configs;
- unsigned int i;
+ struct v4l2_subdev_route *route;
int ret;
ret = v4l2_subdev_routing_validate(sd, routing,
@@ -346,13 +345,15 @@ static int _ub913_set_routing(struct v4l2_subdev *sd,
if (ret)
return ret;
- stream_configs = &state->stream_configs;
+ for_each_active_route(&state->routing, route) {
+ struct v4l2_mbus_framefmt *fmt;
- for (i = 0; i < stream_configs->num_configs; i++) {
- if (stream_configs->configs[i].pad == UB913_PAD_SINK)
- stream_configs->configs[i].fmt = in_format;
- else
- stream_configs->configs[i].fmt = out_format;
+ fmt = v4l2_subdev_state_get_format(state, route->sink_pad,
+ route->sink_stream);
+ *fmt = in_format;
+ fmt = v4l2_subdev_state_get_format(state, route->source_pad,
+ route->source_stream);
+ *fmt = out_format;
}
return 0;
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index 7519863d77b1..2cb7b718782b 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -816,7 +816,6 @@ static int et8ek8_power_on(struct et8ek8_sensor *sensor)
{
struct v4l2_subdev *subdev = &sensor->subdev;
struct i2c_client *client = v4l2_get_subdevdata(subdev);
- unsigned int xclk_freq;
int val, rval;
rval = regulator_enable(sensor->vana);
@@ -825,17 +824,6 @@ static int et8ek8_power_on(struct et8ek8_sensor *sensor)
return rval;
}
- if (sensor->current_reglist)
- xclk_freq = sensor->current_reglist->mode.ext_clock;
- else
- xclk_freq = sensor->xclk_freq;
-
- rval = clk_set_rate(sensor->ext_clk, xclk_freq);
- if (rval < 0) {
- dev_err(&client->dev, "unable to set extclk clock freq to %u\n",
- xclk_freq);
- goto out;
- }
rval = clk_prepare_enable(sensor->ext_clk);
if (rval < 0) {
dev_err(&client->dev, "failed to enable extclk\n");
@@ -849,7 +837,7 @@ static int et8ek8_power_on(struct et8ek8_sensor *sensor)
gpiod_set_value(sensor->reset, 1);
- msleep(5000 * 1000 / xclk_freq + 1); /* Wait 5000 cycles */
+ msleep(5000 * 1000 / sensor->xclk_freq + 1); /* Wait 5000 cycles */
rval = et8ek8_i2c_reglist_find_write(client, &meta_reglist,
ET8EK8_REGLIST_POWERON);
@@ -1085,9 +1073,6 @@ static int et8ek8_set_frame_interval(struct v4l2_subdev *subdev,
if (!reglist)
return -EINVAL;
- if (sensor->current_reglist->mode.ext_clock != reglist->mode.ext_clock)
- return -EINVAL;
-
sensor->current_reglist = reglist;
et8ek8_update_controls(sensor);
@@ -1433,18 +1418,13 @@ static int et8ek8_probe(struct i2c_client *client)
return PTR_ERR(sensor->vana);
}
- sensor->ext_clk = devm_clk_get(dev, NULL);
- if (IS_ERR(sensor->ext_clk)) {
- dev_err(&client->dev, "could not get clock\n");
- return PTR_ERR(sensor->ext_clk);
- }
+ sensor->ext_clk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, true,
+ 9600000);
+ if (IS_ERR(sensor->ext_clk))
+ return dev_err_probe(&client->dev, PTR_ERR(sensor->ext_clk),
+ "could not get clock\n");
- ret = of_property_read_u32(dev->of_node, "clock-frequency",
- &sensor->xclk_freq);
- if (ret) {
- dev_warn(dev, "can't get clock-frequency\n");
- return ret;
- }
+ sensor->xclk_freq = clk_get_rate(sensor->ext_clk);
mutex_init(&sensor->power_lock);
diff --git a/drivers/media/i2c/et8ek8/et8ek8_mode.c b/drivers/media/i2c/et8ek8/et8ek8_mode.c
index c9088eb0a812..914be1007099 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_mode.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_mode.c
@@ -44,7 +44,6 @@ static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
.window_width = 2592,
.window_height = 1968,
.pixel_clock = 80000000,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 1207
@@ -145,7 +144,6 @@ static struct et8ek8_reglist mode1_16vga_2592x1968_13_12fps_dpcm10_8 = {
.window_width = 2592,
.window_height = 1968,
.pixel_clock = 80000000,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 1292
@@ -201,7 +199,6 @@ static struct et8ek8_reglist mode3_4vga_1296x984_29_99fps_dpcm10_8 = {
.window_width = 1296,
.window_height = 984,
.pixel_clock = 96533333,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 3000
@@ -257,7 +254,6 @@ static struct et8ek8_reglist mode4_svga_864x656_29_88fps = {
.window_width = 864,
.window_height = 656,
.pixel_clock = 80000000,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 2988
@@ -313,7 +309,6 @@ static struct et8ek8_reglist mode5_vga_648x492_29_93fps = {
.window_width = 648,
.window_height = 492,
.pixel_clock = 80000000,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 2993
@@ -369,7 +364,6 @@ static struct et8ek8_reglist mode2_16vga_2592x1968_3_99fps = {
.window_width = 2592,
.window_height = 1968,
.pixel_clock = 80000000,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 399
@@ -424,7 +418,6 @@ static struct et8ek8_reglist mode_648x492_5fps = {
.window_width = 648,
.window_height = 492,
.pixel_clock = 13333333,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 499
@@ -480,7 +473,6 @@ static struct et8ek8_reglist mode3_4vga_1296x984_5fps = {
.window_width = 1296,
.window_height = 984,
.pixel_clock = 49400000,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 501
@@ -536,7 +528,6 @@ static struct et8ek8_reglist mode_4vga_1296x984_25fps_dpcm10_8 = {
.window_width = 1296,
.window_height = 984,
.pixel_clock = 84266667,
- .ext_clock = 9600000,
.timeperframe = {
.numerator = 100,
.denominator = 2500
diff --git a/drivers/media/i2c/et8ek8/et8ek8_reg.h b/drivers/media/i2c/et8ek8/et8ek8_reg.h
index c90e74935f12..3305986c7c9c 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_reg.h
+++ b/drivers/media/i2c/et8ek8/et8ek8_reg.h
@@ -37,7 +37,6 @@ struct et8ek8_mode {
u16 window_height;
u32 pixel_clock; /* in Hz */
- u32 ext_clock; /* in Hz */
struct v4l2_fract timeperframe;
u32 max_exp; /* Maximum exposure value */
u32 bus_format; /* MEDIA_BUS_FMT_ */
diff --git a/drivers/media/i2c/gc0310.c b/drivers/media/i2c/gc0310.c
new file mode 100644
index 000000000000..7af4d66f42a0
--- /dev/null
+++ b/drivers/media/i2c/gc0310.c
@@ -0,0 +1,783 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for GalaxyCore GC0310 VGA camera sensor.
+ *
+ * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
+ * Copyright (c) 2023-2025 Hans de Goede <hansg@kernel.org>
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define GC0310_NATIVE_WIDTH 656
+#define GC0310_NATIVE_HEIGHT 496
+
+/*
+ * The actual PLL output rate is unknown, the datasheet
+ * says that the formula for the frame-time in pixels is:
+ * rowtime = win-width + hblank + sh-delay + 4
+ * frametime = rowtime * (win-height + vblank)
+ * Filling this in and multiplying by 30 fps gives:
+ * pixelrate = (660 + 178 + 42 + 4) * (498 + 27) * 30 = 13923000
+ */
+#define GC0310_PIXELRATE 13923000
+/* single lane, bus-format is 8 bpp, CSI-2 is double data rate */
+#define GC0310_LINK_FREQ (GC0310_PIXELRATE * 8 / 2)
+#define GC0310_MCLK_FREQ 19200000
+#define GC0310_FPS 30
+#define GC0310_SKIP_FRAMES 3
+
+#define GC0310_ID 0xa310
+
+#define GC0310_RESET_RELATED_REG CCI_REG8(0xfe)
+#define GC0310_REGISTER_PAGE_0 0x0
+#define GC0310_REGISTER_PAGE_3 0x3
+
+/*
+ * GC0310 System control registers
+ */
+#define GC0310_SW_STREAM_REG CCI_REG8(0x10)
+
+#define GC0310_START_STREAMING 0x94 /* 8-bit enable */
+#define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */
+
+#define GC0310_SC_CMMN_CHIP_ID_REG CCI_REG16(0xf0)
+
+#define GC0310_AEC_PK_EXPO_REG CCI_REG16(0x03)
+#define GC0310_AGC_ADJ_REG CCI_REG8(0x48)
+#define GC0310_DGC_ADJ_REG CCI_REG8(0x71)
+
+#define GC0310_H_CROP_START_REG CCI_REG16(0x09)
+#define GC0310_V_CROP_START_REG CCI_REG16(0x0b)
+#define GC0310_H_OUTSIZE_REG CCI_REG16(0x0f)
+#define GC0310_V_OUTSIZE_REG CCI_REG16(0x0d)
+
+#define GC0310_H_BLANKING_REG CCI_REG16(0x05)
+/* Hblank-register + sh-delay + H-crop + 4 (from hw) */
+#define GC0310_H_BLANK_DEFAULT (178 + 42 + 4 + 4)
+
+#define GC0310_V_BLANKING_REG CCI_REG16(0x07)
+/* Vblank needs an offset compensate for the small V-crop done */
+#define GC0310_V_BLANK_OFFSET 2
+/* Vsync start time + 1 row vsync + vsync end time + offset */
+#define GC0310_V_BLANK_MIN (9 + 1 + 4 + GC0310_V_BLANK_OFFSET)
+#define GC0310_V_BLANK_DEFAULT (27 + GC0310_V_BLANK_OFFSET)
+#define GC0310_V_BLANK_MAX (4095 - GC0310_NATIVE_HEIGHT)
+
+#define GC0310_SH_DELAY_REG CCI_REG8(0x11)
+#define GC0310_VS_START_TIME_REG CCI_REG8(0x12)
+#define GC0310_VS_END_TIME_REG CCI_REG8(0x13)
+
+#define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd)
+
+struct gc0310_device {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
+ struct regmap *regmap;
+ struct gpio_desc *reset;
+ struct gpio_desc *powerdown;
+
+ struct gc0310_ctrls {
+ struct v4l2_ctrl_handler handler;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *gain;
+ struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *hblank;
+ } ctrls;
+};
+
+struct gc0310_reg {
+ u8 reg;
+ u8 val;
+};
+
+static const struct reg_sequence gc0310_reset_register[] = {
+ /* System registers */
+ { 0xfe, 0xf0 },
+ { 0xfe, 0xf0 },
+ { 0xfe, 0x00 },
+
+ { 0xfc, 0x0e }, /* 4e */
+ { 0xfc, 0x0e }, /* 16//4e // [0]apwd [6]regf_clk_gate */
+ { 0xf2, 0x80 }, /* sync output */
+ { 0xf3, 0x00 }, /* 1f//01 data output */
+ { 0xf7, 0x33 }, /* f9 */
+ { 0xf8, 0x05 }, /* 00 */
+ { 0xf9, 0x0e }, /* 0x8e //0f */
+ { 0xfa, 0x11 },
+
+ /* MIPI */
+ { 0xfe, 0x03 },
+ { 0x01, 0x03 }, /* mipi 1lane */
+ { 0x02, 0x22 }, /* 0x33 */
+ { 0x03, 0x94 },
+ { 0x04, 0x01 }, /* fifo_prog */
+ { 0x05, 0x00 }, /* fifo_prog */
+ { 0x06, 0x80 }, /* b0 //YUV ISP data */
+ { 0x11, 0x2a }, /* 1e //LDI set YUV422 */
+ { 0x12, 0x90 }, /* 00 //04 //00 //04//00 //LWC[7:0] */
+ { 0x13, 0x02 }, /* 05 //05 //LWC[15:8] */
+ { 0x15, 0x12 }, /* 0x10 //DPHYY_MODE read_ready */
+ { 0x17, 0x01 },
+ { 0x40, 0x08 },
+ { 0x41, 0x00 },
+ { 0x42, 0x00 },
+ { 0x43, 0x00 },
+ { 0x21, 0x02 }, /* 0x01 */
+ { 0x22, 0x02 }, /* 0x01 */
+ { 0x23, 0x01 }, /* 0x05 //Nor:0x05 DOU:0x06 */
+ { 0x29, 0x00 },
+ { 0x2A, 0x25 }, /* 0x05 //data zero 0x7a de */
+ { 0x2B, 0x02 },
+
+ { 0xfe, 0x00 },
+
+ /* CISCTL */
+ { 0x00, 0x2f }, /* 2f//0f//02//01 */
+ { 0x01, 0x0f }, /* 06 */
+ { 0x02, 0x04 },
+ { 0x4f, 0x00 }, /* AEC 0FF */
+ { 0x03, 0x01 }, /* 0x03 //04 */
+ { 0x04, 0xc0 }, /* 0xe8 //58 */
+ { 0x05, 0x00 },
+ { 0x06, 0xb2 }, /* 0x0a //HB */
+ /* Vblank (reg 0x07 + 0x08) gets set by the vblank ctrl */
+ { 0x09, 0x00 }, /* row start */
+ { 0x0a, 0x00 },
+ { 0x0b, 0x00 }, /* col start */
+ { 0x0c, 0x00 },
+ { 0x0d, 0x01 }, /* height */
+ { 0x0e, 0xf2 }, /* 0xf7 //height */
+ { 0x0f, 0x02 }, /* width */
+ { 0x10, 0x94 }, /* 0xa0 //height */
+ { 0x17, 0x14 },
+ { 0x18, 0x1a }, /* 0a//[4]double reset */
+ { 0x19, 0x14 }, /* AD pipeline */
+ { 0x1b, 0x48 },
+ { 0x1e, 0x6b }, /* 3b//col bias */
+ { 0x1f, 0x28 }, /* 20//00//08//txlow */
+ { 0x20, 0x89 }, /* 88//0c//[3:2]DA15 */
+ { 0x21, 0x49 }, /* 48//[3] txhigh */
+ { 0x22, 0xb0 },
+ { 0x23, 0x04 }, /* [1:0]vcm_r */
+ { 0x24, 0x16 }, /* 15 */
+ { 0x34, 0x20 }, /* [6:4] rsg high//range */
+
+ /* BLK */
+ { 0x26, 0x23 }, /* [1]dark_current_en [0]offset_en */
+ { 0x28, 0xff }, /* BLK_limie_value */
+ { 0x29, 0x00 }, /* global offset */
+ { 0x33, 0x18 }, /* offset_ratio */
+ { 0x37, 0x20 }, /* dark_current_ratio */
+ { 0x2a, 0x00 },
+ { 0x2b, 0x00 },
+ { 0x2c, 0x00 },
+ { 0x2d, 0x00 },
+ { 0x2e, 0x00 },
+ { 0x2f, 0x00 },
+ { 0x30, 0x00 },
+ { 0x31, 0x00 },
+ { 0x47, 0x80 }, /* a7 */
+ { 0x4e, 0x66 }, /* select_row */
+ { 0xa8, 0x02 }, /* win_width_dark, same with crop_win_width */
+ { 0xa9, 0x80 },
+
+ /* ISP */
+ { 0x40, 0x06 }, /* 0xff //ff //48 */
+ { 0x41, 0x00 }, /* 0x21 //00//[0]curve_en */
+ { 0x42, 0x04 }, /* 0xcf //0a//[1]awn_en */
+ { 0x44, 0x18 }, /* 0x18 //02 */
+ { 0x46, 0x02 }, /* 0x03 //sync */
+ { 0x49, 0x03 },
+ { 0x4c, 0x20 }, /* 00[5]pretect exp */
+ { 0x50, 0x01 }, /* crop enable */
+ { 0x51, 0x00 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x01 },
+ { 0x55, 0x01 }, /* crop window height */
+ { 0x56, 0xf0 },
+ { 0x57, 0x02 }, /* crop window width */
+ { 0x58, 0x90 },
+
+ /* Gain */
+ { 0x70, 0x70 }, /* 70 //80//global gain */
+ { 0x71, 0x20 }, /* pregain gain */
+ { 0x72, 0x40 }, /* post gain */
+ { 0x5a, 0x84 }, /* 84//analog gain 0 */
+ { 0x5b, 0xc9 }, /* c9 */
+ { 0x5c, 0xed }, /* ed//not use pga gain highest level */
+ { 0x77, 0x40 }, /* R gain 0x74 //awb gain */
+ { 0x78, 0x40 }, /* G gain */
+ { 0x79, 0x40 }, /* B gain 0x5f */
+
+ { 0x48, 0x00 },
+ { 0xfe, 0x01 },
+ { 0x0a, 0x45 }, /* [7]col gain mode */
+
+ { 0x3e, 0x40 },
+ { 0x3f, 0x5c },
+ { 0x40, 0x7b },
+ { 0x41, 0xbd },
+ { 0x42, 0xf6 },
+ { 0x43, 0x63 },
+ { 0x03, 0x60 },
+ { 0x44, 0x03 },
+
+ /* Dark / Sun mode related */
+ { 0xfe, 0x01 },
+ { 0x45, 0xa4 }, /* 0xf7 */
+ { 0x46, 0xf0 }, /* 0xff //f0//sun value th */
+ { 0x48, 0x03 }, /* sun mode */
+ { 0x4f, 0x60 }, /* sun_clamp */
+ { 0xfe, 0x00 },
+};
+
+static const struct reg_sequence gc0310_VGA_30fps[] = {
+ { 0xfe, 0x00 },
+ { 0x0d, 0x01 }, /* height */
+ { 0x0e, 0xf2 }, /* 0xf7 //height */
+ { 0x0f, 0x02 }, /* width */
+ { 0x10, 0x94 }, /* 0xa0 //height */
+
+ { 0x50, 0x01 }, /* crop enable */
+ { 0x51, 0x00 },
+ { 0x52, 0x00 },
+ { 0x53, 0x00 },
+ { 0x54, 0x01 },
+ { 0x55, 0x01 }, /* crop window height */
+ { 0x56, 0xf0 },
+ { 0x57, 0x02 }, /* crop window width */
+ { 0x58, 0x90 },
+
+ { 0xfe, 0x03 },
+ { 0x12, 0x90 }, /* 00 //04 //00 //04//00 //LWC[7:0] */
+ { 0x13, 0x02 }, /* 05 //05 //LWC[15:8] */
+
+ { 0xfe, 0x00 },
+};
+
+static const s64 link_freq_menu_items[] = {
+ GC0310_LINK_FREQ,
+};
+
+static int gc0310_gain_set(struct gc0310_device *sensor, u32 gain)
+{
+ u8 again, dgain;
+ int ret = 0;
+
+ /* Taken from original driver, this never sets dgain lower then 32? */
+
+ /* Change 0 - 95 to 32 - 127 */
+ gain += 32;
+
+ if (gain < 64) {
+ again = 0x0; /* sqrt(2) */
+ dgain = gain;
+ } else {
+ again = 0x2; /* 2 * sqrt(2) */
+ dgain = gain / 2;
+ }
+
+ cci_write(sensor->regmap, GC0310_AGC_ADJ_REG, again, &ret);
+ cci_write(sensor->regmap, GC0310_DGC_ADJ_REG, dgain, &ret);
+ return ret;
+}
+
+static int gc0310_exposure_update_range(struct gc0310_device *sensor)
+{
+ int exp_max = GC0310_NATIVE_HEIGHT + sensor->ctrls.vblank->val;
+
+ return __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 0, exp_max,
+ 1, exp_max);
+}
+
+static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct gc0310_device *sensor =
+ container_of(ctrl->handler, struct gc0310_device, ctrls.handler);
+ int ret;
+
+ /* Update exposure range on vblank changes */
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ ret = gc0310_exposure_update_range(sensor);
+ if (ret)
+ return ret;
+ }
+
+ /* Only apply changes to the controls if the device is powered up */
+ if (!pm_runtime_get_if_in_use(sensor->sd.dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ ret = cci_write(sensor->regmap, GC0310_AEC_PK_EXPO_REG,
+ ctrl->val, NULL);
+ break;
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = gc0310_gain_set(sensor, ctrl->val);
+ break;
+ case V4L2_CID_VBLANK:
+ ret = cci_write(sensor->regmap, GC0310_V_BLANKING_REG,
+ ctrl->val - GC0310_V_BLANK_OFFSET,
+ NULL);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ pm_runtime_put(sensor->sd.dev);
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops ctrl_ops = {
+ .s_ctrl = gc0310_s_ctrl,
+};
+
+/* The GC0310 currently only supports 1 fixed fmt */
+static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt)
+{
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->width = GC0310_NATIVE_WIDTH;
+ fmt->height = GC0310_NATIVE_HEIGHT;
+ fmt->field = V4L2_FIELD_NONE;
+ fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
+}
+
+static int gc0310_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_selection *sel)
+{
+ /* Only the single fixed 656x496 mode is supported, without croping */
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = GC0310_NATIVE_WIDTH;
+ sel->r.height = GC0310_NATIVE_HEIGHT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int gc0310_power_off(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
+
+ gpiod_set_value_cansleep(sensor->powerdown, 1);
+ gpiod_set_value_cansleep(sensor->reset, 1);
+ return 0;
+}
+
+static int gc0310_power_on(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
+
+ fsleep(10 * USEC_PER_MSEC);
+ gpiod_set_value_cansleep(sensor->reset, 0);
+ fsleep(10 * USEC_PER_MSEC);
+ gpiod_set_value_cansleep(sensor->powerdown, 0);
+ fsleep(10 * USEC_PER_MSEC);
+
+ return 0;
+}
+
+static int gc0310_detect(struct gc0310_device *sensor)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
+ u64 val;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
+
+ ret = cci_read(sensor->regmap, GC0310_SC_CMMN_CHIP_ID_REG, &val, NULL);
+ if (ret < 0) {
+ dev_err(&client->dev, "read sensor_id failed: %d\n", ret);
+ return -ENODEV;
+ }
+
+ dev_dbg(&client->dev, "sensor ID = 0x%llx\n", val);
+
+ if (val != GC0310_ID) {
+ dev_err(&client->dev, "sensor ID error, read id = 0x%llx, target id = 0x%x\n",
+ val, GC0310_ID);
+ return -ENODEV;
+ }
+
+ dev_dbg(&client->dev, "detect gc0310 success\n");
+
+ return 0;
+}
+
+static int gc0310_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(&client->dev);
+ if (ret)
+ return ret;
+
+ ret = regmap_multi_reg_write(sensor->regmap,
+ gc0310_reset_register,
+ ARRAY_SIZE(gc0310_reset_register));
+ if (ret)
+ goto error_power_down;
+
+ ret = regmap_multi_reg_write(sensor->regmap,
+ gc0310_VGA_30fps,
+ ARRAY_SIZE(gc0310_VGA_30fps));
+ if (ret)
+ goto error_power_down;
+
+ /* restore value of all ctrls */
+ ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+
+ /* enable per frame MIPI and sensor ctrl reset */
+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, 0x30, &ret);
+
+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
+ GC0310_REGISTER_PAGE_3, &ret);
+ cci_write(sensor->regmap, GC0310_SW_STREAM_REG,
+ GC0310_START_STREAMING, &ret);
+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
+ GC0310_REGISTER_PAGE_0, &ret);
+
+error_power_down:
+ if (ret)
+ pm_runtime_put(&client->dev);
+
+ return ret;
+}
+
+static int gc0310_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = 0;
+
+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
+ GC0310_REGISTER_PAGE_3, &ret);
+ cci_write(sensor->regmap, GC0310_SW_STREAM_REG,
+ GC0310_STOP_STREAMING, &ret);
+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
+ GC0310_REGISTER_PAGE_0, &ret);
+
+ pm_runtime_put(&client->dev);
+ return ret;
+}
+
+static int gc0310_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ /* We support only a single format */
+ if (code->index)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_SGRBG8_1X8;
+ return 0;
+}
+
+static int gc0310_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ /* We support only a single resolution */
+ if (fse->index)
+ return -EINVAL;
+
+ fse->min_width = GC0310_NATIVE_WIDTH;
+ fse->max_width = GC0310_NATIVE_WIDTH;
+ fse->min_height = GC0310_NATIVE_HEIGHT;
+ fse->max_height = GC0310_NATIVE_HEIGHT;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops gc0310_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops gc0310_pad_ops = {
+ .enum_mbus_code = gc0310_enum_mbus_code,
+ .enum_frame_size = gc0310_enum_frame_size,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = v4l2_subdev_get_fmt, /* Only 1 fixed mode supported */
+ .get_selection = gc0310_get_selection,
+ .set_selection = gc0310_get_selection,
+ .enable_streams = gc0310_enable_streams,
+ .disable_streams = gc0310_disable_streams,
+};
+
+static const struct v4l2_subdev_ops gc0310_ops = {
+ .video = &gc0310_video_ops,
+ .pad = &gc0310_pad_ops,
+};
+
+static int gc0310_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+{
+ gc0310_fill_format(v4l2_subdev_state_get_format(sd_state, 0));
+ return 0;
+}
+
+static const struct v4l2_subdev_internal_ops gc0310_internal_ops = {
+ .init_state = gc0310_init_state,
+};
+
+static int gc0310_init_controls(struct gc0310_device *sensor)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
+ struct v4l2_ctrl_handler *hdl = &sensor->ctrls.handler;
+ struct v4l2_fwnode_device_properties props;
+ int exp_max, ret;
+
+ v4l2_ctrl_handler_init(hdl, 8);
+
+ /* Use the same lock for controls as for everything else */
+ sensor->sd.ctrl_handler = hdl;
+
+ exp_max = GC0310_NATIVE_HEIGHT + GC0310_V_BLANK_DEFAULT;
+ sensor->ctrls.exposure =
+ v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0,
+ exp_max, 1, exp_max);
+
+ /* 32 steps at base gain 1 + 64 half steps at base gain 2 */
+ sensor->ctrls.gain =
+ v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 0, 95, 1, 31);
+
+ sensor->ctrls.link_freq =
+ v4l2_ctrl_new_int_menu(hdl, NULL, V4L2_CID_LINK_FREQ,
+ 0, 0, link_freq_menu_items);
+ sensor->ctrls.pixel_rate =
+ v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_PIXEL_RATE, 0,
+ GC0310_PIXELRATE, 1, GC0310_PIXELRATE);
+
+ sensor->ctrls.vblank =
+ v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_VBLANK,
+ GC0310_V_BLANK_MIN,
+ GC0310_V_BLANK_MAX, 1,
+ GC0310_V_BLANK_DEFAULT);
+
+ sensor->ctrls.hblank =
+ v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_HBLANK,
+ GC0310_H_BLANK_DEFAULT,
+ GC0310_H_BLANK_DEFAULT, 1,
+ GC0310_H_BLANK_DEFAULT);
+
+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ if (ret)
+ return ret;
+
+ v4l2_ctrl_new_fwnode_properties(hdl, &ctrl_ops, &props);
+
+ if (hdl->error)
+ return hdl->error;
+
+ sensor->ctrls.pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ sensor->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ sensor->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ return 0;
+}
+
+static void gc0310_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
+ media_entity_cleanup(&sensor->sd.entity);
+ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+ pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev)) {
+ gc0310_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ }
+}
+
+static int gc0310_check_hwcfg(struct device *dev)
+{
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY,
+ };
+ struct fwnode_handle *ep_fwnode;
+ unsigned long link_freq_bitmap;
+ u32 mclk;
+ int ret;
+
+ /*
+ * Sometimes the fwnode graph is initialized by the bridge driver.
+ * Bridge drivers doing this may also add GPIO mappings, wait for this.
+ */
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
+ if (!ep_fwnode)
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "waiting for fwnode graph endpoint\n");
+
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+ &mclk);
+ if (ret) {
+ fwnode_handle_put(ep_fwnode);
+ return dev_err_probe(dev, ret,
+ "reading clock-frequency property\n");
+ }
+
+ if (mclk != GC0310_MCLK_FREQ) {
+ fwnode_handle_put(ep_fwnode);
+ return dev_err_probe(dev, -EINVAL,
+ "external clock %u is not supported\n",
+ mclk);
+ }
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg);
+ fwnode_handle_put(ep_fwnode);
+ if (ret)
+ return dev_err_probe(dev, ret, "parsing endpoint failed\n");
+
+ ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq_menu_items,
+ ARRAY_SIZE(link_freq_menu_items),
+ &link_freq_bitmap);
+
+ if (ret == 0 && bus_cfg.bus.mipi_csi2.num_data_lanes != 1)
+ ret = dev_err_probe(dev, -EINVAL,
+ "number of CSI2 data lanes %u is not supported\n",
+ bus_cfg.bus.mipi_csi2.num_data_lanes);
+
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+ return ret;
+}
+
+static int gc0310_probe(struct i2c_client *client)
+{
+ struct gc0310_device *sensor;
+ int ret;
+
+ ret = gc0310_check_hwcfg(&client->dev);
+ if (ret)
+ return ret;
+
+ sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+ return -ENOMEM;
+
+ sensor->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(sensor->reset)) {
+ return dev_err_probe(&client->dev, PTR_ERR(sensor->reset),
+ "getting reset GPIO\n");
+ }
+
+ sensor->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(sensor->powerdown)) {
+ return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown),
+ "getting powerdown GPIO\n");
+ }
+
+ v4l2_i2c_subdev_init(&sensor->sd, client, &gc0310_ops);
+
+ sensor->regmap = devm_cci_regmap_init_i2c(client, 8);
+ if (IS_ERR(sensor->regmap))
+ return PTR_ERR(sensor->regmap);
+
+ gc0310_power_on(&client->dev);
+
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_get_noresume(&client->dev);
+ pm_runtime_enable(&client->dev);
+
+ ret = gc0310_detect(sensor);
+ if (ret)
+ goto err_power_down;
+
+ sensor->sd.internal_ops = &gc0310_internal_ops;
+ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
+ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+ ret = gc0310_init_controls(sensor);
+ if (ret)
+ goto err_power_down;
+
+ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
+ if (ret)
+ goto err_power_down;
+
+ sensor->sd.state_lock = sensor->ctrls.handler.lock;
+ ret = v4l2_subdev_init_finalize(&sensor->sd);
+ if (ret)
+ goto err_power_down;
+
+ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
+ if (ret)
+ goto err_power_down;
+
+ pm_runtime_set_autosuspend_delay(&client->dev, 1000);
+ pm_runtime_use_autosuspend(&client->dev);
+ pm_runtime_put_autosuspend(&client->dev);
+
+ return 0;
+
+err_power_down:
+ pm_runtime_put_noidle(&client->dev);
+ gc0310_remove(client);
+ return ret;
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops,
+ gc0310_power_off, gc0310_power_on, NULL);
+
+static const struct acpi_device_id gc0310_acpi_match[] = {
+ {"INT0310"},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, gc0310_acpi_match);
+
+static struct i2c_driver gc0310_driver = {
+ .driver = {
+ .name = "gc0310",
+ .pm = pm_sleep_ptr(&gc0310_pm_ops),
+ .acpi_match_table = gc0310_acpi_match,
+ },
+ .probe = gc0310_probe,
+ .remove = gc0310_remove,
+};
+module_i2c_driver(gc0310_driver);
+
+MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>");
+MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>");
+MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/gc05a2.c b/drivers/media/i2c/gc05a2.c
index 3f7f3d5abeeb..8ba17f80fffe 100644
--- a/drivers/media/i2c/gc05a2.c
+++ b/drivers/media/i2c/gc05a2.c
@@ -1235,16 +1235,12 @@ static int gc05a2_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
"failed to init CCI\n");
- gc05a2->xclk = devm_clk_get(dev, NULL);
+ gc05a2->xclk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, true,
+ GC05A2_DEFAULT_CLK_FREQ);
if (IS_ERR(gc05a2->xclk))
return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
"failed to get xclk\n");
- ret = clk_set_rate(gc05a2->xclk, GC05A2_DEFAULT_CLK_FREQ);
- if (ret)
- return dev_err_probe(dev, ret,
- "failed to set xclk frequency\n");
-
ret = gc05a2_get_regulators(dev, gc05a2);
if (ret < 0)
return dev_err_probe(dev, ret,
diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
index 938709a677b6..11fd936db9c3 100644
--- a/drivers/media/i2c/gc08a3.c
+++ b/drivers/media/i2c/gc08a3.c
@@ -1199,16 +1199,12 @@ static int gc08a3_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
"failed to init CCI\n");
- gc08a3->xclk = devm_clk_get(dev, NULL);
+ gc08a3->xclk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, true,
+ GC08A3_DEFAULT_CLK_FREQ);
if (IS_ERR(gc08a3->xclk))
return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
"failed to get xclk\n");
- ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
- if (ret)
- return dev_err_probe(dev, ret,
- "failed to set xclk frequency\n");
-
ret = gc08a3_get_regulators(dev, gc08a3);
if (ret < 0)
return dev_err_probe(dev, ret,
diff --git a/drivers/media/i2c/gc2145.c b/drivers/media/i2c/gc2145.c
index 559a851669aa..b215963a2648 100644
--- a/drivers/media/i2c/gc2145.c
+++ b/drivers/media/i2c/gc2145.c
@@ -1331,7 +1331,7 @@ static int gc2145_probe(struct i2c_client *client)
return -EINVAL;
/* Get system clock (xclk) */
- gc2145->xclk = devm_clk_get(dev, NULL);
+ gc2145->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(gc2145->xclk))
return dev_err_probe(dev, PTR_ERR(gc2145->xclk),
"failed to get xclk\n");
diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c
index 076c19fcf99c..de573cee4451 100644
--- a/drivers/media/i2c/hi556.c
+++ b/drivers/media/i2c/hi556.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -10,6 +9,8 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -631,6 +632,8 @@ static const char * const hi556_supply_names[] = {
};
struct hi556 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -715,7 +718,6 @@ static int hi556_write_reg(struct hi556 *hi556, u16 reg, u16 len, u32 val)
static int hi556_write_reg_list(struct hi556 *hi556,
const struct hi556_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
unsigned int i;
int ret;
@@ -724,7 +726,7 @@ static int hi556_write_reg_list(struct hi556 *hi556,
HI556_REG_VALUE_16BIT,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(hi556->dev,
"failed to write reg 0x%4.4x. error = %d\n",
r_list->regs[i].address, ret);
return ret;
@@ -785,7 +787,6 @@ static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct hi556 *hi556 = container_of(ctrl->handler,
struct hi556, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
s64 exposure_max;
int ret = 0;
@@ -801,7 +802,7 @@ static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(hi556->dev))
return 0;
switch (ctrl->id) {
@@ -835,7 +836,7 @@ static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(hi556->dev);
return ret;
}
@@ -921,7 +922,6 @@ static void hi556_assign_pad_format(const struct hi556_mode *mode,
static int hi556_identify_module(struct hi556 *hi556)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
int ret;
u32 val;
@@ -934,7 +934,7 @@ static int hi556_identify_module(struct hi556 *hi556)
return ret;
if (val != HI556_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(hi556->dev, "chip id mismatch: %x!=%x\n",
HI556_CHIP_ID, val);
return -ENXIO;
}
@@ -998,7 +998,6 @@ static int hi556_get_selection(struct v4l2_subdev *sd,
static int hi556_start_streaming(struct hi556 *hi556)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
const struct hi556_reg_list *reg_list;
int link_freq_index, ret;
@@ -1010,14 +1009,14 @@ static int hi556_start_streaming(struct hi556 *hi556)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = hi556_write_reg_list(hi556, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls\n");
+ dev_err(hi556->dev, "failed to set plls\n");
return ret;
}
reg_list = &hi556->cur_mode->reg_list;
ret = hi556_write_reg_list(hi556, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode\n");
+ dev_err(hi556->dev, "failed to set mode\n");
return ret;
}
@@ -1029,7 +1028,7 @@ static int hi556_start_streaming(struct hi556 *hi556)
HI556_REG_VALUE_16BIT, HI556_MODE_STREAMING);
if (ret) {
- dev_err(&client->dev, "failed to set stream\n");
+ dev_err(hi556->dev, "failed to set stream\n");
return ret;
}
@@ -1038,22 +1037,19 @@ static int hi556_start_streaming(struct hi556 *hi556)
static void hi556_stop_streaming(struct hi556 *hi556)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
-
if (hi556_write_reg(hi556, HI556_REG_MODE_SELECT,
HI556_REG_VALUE_16BIT, HI556_MODE_STANDBY))
- dev_err(&client->dev, "failed to set stream\n");
+ dev_err(hi556->dev, "failed to set stream\n");
}
static int hi556_set_stream(struct v4l2_subdev *sd, int enable)
{
struct hi556 *hi556 = to_hi556(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&hi556->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(hi556->dev);
if (ret < 0) {
mutex_unlock(&hi556->mutex);
return ret;
@@ -1062,11 +1058,11 @@ static int hi556_set_stream(struct v4l2_subdev *sd, int enable)
ret = hi556_start_streaming(hi556);
if (ret) {
hi556_stop_streaming(hi556);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(hi556->dev);
}
} else {
hi556_stop_streaming(hi556);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(hi556->dev);
}
mutex_unlock(&hi556->mutex);
@@ -1217,7 +1213,6 @@ static int hi556_check_hwcfg(struct device *dev)
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
- u32 mclk;
int ret = 0;
unsigned int i, j;
@@ -1235,18 +1230,6 @@ static int hi556_check_hwcfg(struct device *dev)
if (ret)
return dev_err_probe(dev, ret, "parsing endpoint failed\n");
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
- if (ret) {
- dev_err(dev, "can't get clock frequency\n");
- goto check_hwcfg_error;
- }
-
- if (mclk != HI556_MCLK) {
- dev_err(dev, "external clock %d is not supported\n", mclk);
- ret = -EINVAL;
- goto check_hwcfg_error;
- }
-
if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
dev_err(dev, "number of CSI2 data lanes %d is not supported\n",
bus_cfg.bus.mipi_csi2.num_data_lanes);
@@ -1289,7 +1272,7 @@ static void hi556_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(hi556->dev);
mutex_destroy(&hi556->mutex);
}
@@ -1336,6 +1319,7 @@ static int hi556_resume(struct device *dev)
static int hi556_probe(struct i2c_client *client)
{
struct hi556 *hi556;
+ unsigned long freq;
bool full_power;
int i, ret;
@@ -1347,40 +1331,48 @@ static int hi556_probe(struct i2c_client *client)
if (!hi556)
return -ENOMEM;
+ hi556->dev = &client->dev;
+
v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops);
- hi556->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ hi556->reset_gpio = devm_gpiod_get_optional(hi556->dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(hi556->reset_gpio))
- return dev_err_probe(&client->dev, PTR_ERR(hi556->reset_gpio),
+ return dev_err_probe(hi556->dev, PTR_ERR(hi556->reset_gpio),
"failed to get reset GPIO\n");
- hi556->clk = devm_clk_get_optional(&client->dev, "clk");
+ hi556->clk = devm_v4l2_sensor_clk_get(hi556->dev, "clk");
if (IS_ERR(hi556->clk))
- return dev_err_probe(&client->dev, PTR_ERR(hi556->clk),
+ return dev_err_probe(hi556->dev, PTR_ERR(hi556->clk),
"failed to get clock\n");
+ freq = clk_get_rate(hi556->clk);
+ if (freq != HI556_MCLK)
+ return dev_err_probe(hi556->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
for (i = 0; i < ARRAY_SIZE(hi556_supply_names); i++)
hi556->supplies[i].supply = hi556_supply_names[i];
- ret = devm_regulator_bulk_get(&client->dev,
+ ret = devm_regulator_bulk_get(hi556->dev,
ARRAY_SIZE(hi556_supply_names),
hi556->supplies);
if (ret)
- return dev_err_probe(&client->dev, ret,
+ return dev_err_probe(hi556->dev, ret,
"failed to get regulators\n");
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(hi556->dev);
if (full_power) {
/* Ensure non ACPI managed resources are enabled */
- ret = hi556_resume(&client->dev);
+ ret = hi556_resume(hi556->dev);
if (ret)
- return dev_err_probe(&client->dev, ret,
+ return dev_err_probe(hi556->dev, ret,
"failed to power on sensor\n");
ret = hi556_identify_module(hi556);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ dev_err(hi556->dev, "failed to find sensor: %d\n", ret);
goto probe_error_power_off;
}
}
@@ -1389,7 +1381,7 @@ static int hi556_probe(struct i2c_client *client)
hi556->cur_mode = &supported_modes[0];
ret = hi556_init_controls(hi556);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d\n", ret);
+ dev_err(hi556->dev, "failed to init controls: %d\n", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -1400,22 +1392,22 @@ static int hi556_probe(struct i2c_client *client)
hi556->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&hi556->sd.entity, 1, &hi556->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d\n", ret);
+ dev_err(hi556->dev, "failed to init entity pads: %d\n", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&hi556->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d\n",
+ dev_err(hi556->dev, "failed to register V4L2 subdev: %d\n",
ret);
goto probe_error_media_entity_cleanup;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(hi556->dev);
+ pm_runtime_enable(hi556->dev);
+ pm_runtime_idle(hi556->dev);
return 0;
@@ -1428,7 +1420,7 @@ probe_error_v4l2_ctrl_handler_free:
probe_error_power_off:
if (full_power)
- hi556_suspend(&client->dev);
+ hi556_suspend(hi556->dev);
return ret;
}
diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
index 172772decd3d..a3f77b8434ca 100644
--- a/drivers/media/i2c/hi846.c
+++ b/drivers/media/i2c/hi846.c
@@ -2052,12 +2052,11 @@ static int hi846_probe(struct i2c_client *client)
return ret;
}
- hi846->clock = devm_clk_get(&client->dev, NULL);
- if (IS_ERR(hi846->clock)) {
- dev_err(&client->dev, "failed to get clock: %pe\n",
- hi846->clock);
- return PTR_ERR(hi846->clock);
- }
+ hi846->clock = devm_v4l2_sensor_clk_get(&client->dev, NULL);
+ if (IS_ERR(hi846->clock))
+ return dev_err_probe(&client->dev, PTR_ERR(hi846->clock),
+ "failed to get clock: %pe\n",
+ hi846->clock);
mclk_freq = clk_get_rate(hi846->clock);
if (mclk_freq != 25000000)
diff --git a/drivers/media/i2c/hi847.c b/drivers/media/i2c/hi847.c
index 546833f5b5f5..def01aa07b2f 100644
--- a/drivers/media/i2c/hi847.c
+++ b/drivers/media/i2c/hi847.c
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -2166,6 +2168,9 @@ static const struct hi847_mode supported_modes[] = {
};
struct hi847 {
+ struct device *dev;
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -2244,7 +2249,6 @@ static int hi847_write_reg(struct hi847 *hi847, u16 reg, u16 len, u32 val)
static int hi847_write_reg_list(struct hi847 *hi847,
const struct hi847_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
unsigned int i;
int ret;
@@ -2253,7 +2257,7 @@ static int hi847_write_reg_list(struct hi847 *hi847,
HI847_REG_VALUE_16BIT,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(hi847->dev,
"failed to write reg 0x%4.4x. error = %d",
r_list->regs[i].address, ret);
return ret;
@@ -2408,7 +2412,6 @@ static int hi847_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct hi847 *hi847 = container_of(ctrl->handler,
struct hi847, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
s64 exposure_max;
int ret = 0;
@@ -2424,7 +2427,7 @@ static int hi847_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(hi847->dev))
return 0;
switch (ctrl->id) {
@@ -2466,7 +2469,7 @@ static int hi847_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(hi847->dev);
return ret;
}
@@ -2557,7 +2560,6 @@ static void hi847_assign_pad_format(const struct hi847_mode *mode,
static int hi847_start_streaming(struct hi847 *hi847)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
const struct hi847_reg_list *reg_list;
int link_freq_index, ret;
@@ -2565,14 +2567,14 @@ static int hi847_start_streaming(struct hi847 *hi847)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = hi847_write_reg_list(hi847, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls");
+ dev_err(hi847->dev, "failed to set plls");
return ret;
}
reg_list = &hi847->cur_mode->reg_list;
ret = hi847_write_reg_list(hi847, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(hi847->dev, "failed to set mode");
return ret;
}
@@ -2587,7 +2589,7 @@ static int hi847_start_streaming(struct hi847 *hi847)
HI847_REG_VALUE_16BIT, HI847_MODE_STREAMING);
if (ret) {
- dev_err(&client->dev, "failed to set stream");
+ dev_err(hi847->dev, "failed to set stream");
return ret;
}
@@ -2596,28 +2598,25 @@ static int hi847_start_streaming(struct hi847 *hi847)
static void hi847_stop_streaming(struct hi847 *hi847)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
-
if (hi847_write_reg(hi847, HI847_REG_MODE_TG,
HI847_REG_VALUE_16BIT, HI847_REG_MODE_TG_DISABLE))
- dev_err(&client->dev, "failed to set stream 0x%x",
+ dev_err(hi847->dev, "failed to set stream 0x%x",
HI847_REG_MODE_TG);
if (hi847_write_reg(hi847, HI847_REG_MODE_SELECT,
HI847_REG_VALUE_16BIT, HI847_MODE_STANDBY))
- dev_err(&client->dev, "failed to set stream 0x%x",
+ dev_err(hi847->dev, "failed to set stream 0x%x",
HI847_REG_MODE_SELECT);
}
static int hi847_set_stream(struct v4l2_subdev *sd, int enable)
{
struct hi847 *hi847 = to_hi847(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&hi847->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(hi847->dev);
if (ret) {
mutex_unlock(&hi847->mutex);
return ret;
@@ -2627,11 +2626,11 @@ static int hi847_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
hi847_stop_streaming(hi847);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(hi847->dev);
}
} else {
hi847_stop_streaming(hi847);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(hi847->dev);
}
mutex_unlock(&hi847->mutex);
@@ -2768,7 +2767,6 @@ static const struct v4l2_subdev_internal_ops hi847_internal_ops = {
static int hi847_identify_module(struct hi847 *hi847)
{
- struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
int ret;
u32 val;
@@ -2778,7 +2776,7 @@ static int hi847_identify_module(struct hi847 *hi847)
return ret;
if (val != HI847_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(hi847->dev, "chip id mismatch: %x!=%x",
HI847_CHIP_ID, val);
return -ENXIO;
}
@@ -2793,24 +2791,12 @@ static int hi847_check_hwcfg(struct device *dev)
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
- u32 mclk;
int ret;
unsigned int i, j;
if (!fwnode)
return -ENXIO;
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
- if (ret) {
- dev_err(dev, "can't get clock frequency");
- return ret;
- }
-
- if (mclk != HI847_MCLK) {
- dev_err(dev, "external clock %d is not supported", mclk);
- return -EINVAL;
- }
-
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
return -ENXIO;
@@ -2862,22 +2848,36 @@ static void hi847_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(hi847->dev);
mutex_destroy(&hi847->mutex);
}
static int hi847_probe(struct i2c_client *client)
{
struct hi847 *hi847;
+ unsigned long freq;
int ret;
hi847 = devm_kzalloc(&client->dev, sizeof(*hi847), GFP_KERNEL);
if (!hi847)
return -ENOMEM;
- ret = hi847_check_hwcfg(&client->dev);
+ hi847->dev = &client->dev;
+
+ hi847->clk = devm_v4l2_sensor_clk_get(hi847->dev, NULL);
+ if (IS_ERR(hi847->clk))
+ return dev_err_probe(hi847->dev, PTR_ERR(hi847->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(hi847->clk);
+ if (freq != HI847_MCLK)
+ return dev_err_probe(hi847->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
+ ret = hi847_check_hwcfg(hi847->dev);
if (ret) {
- dev_err(&client->dev, "failed to get HW configuration: %d",
+ dev_err(hi847->dev, "failed to get HW configuration: %d",
ret);
return ret;
}
@@ -2885,7 +2885,7 @@ static int hi847_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&hi847->sd, client, &hi847_subdev_ops);
ret = hi847_identify_module(hi847);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(hi847->dev, "failed to find sensor: %d", ret);
return ret;
}
@@ -2893,7 +2893,7 @@ static int hi847_probe(struct i2c_client *client)
hi847->cur_mode = &supported_modes[0];
ret = hi847_init_controls(hi847);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(hi847->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -2904,20 +2904,20 @@ static int hi847_probe(struct i2c_client *client)
hi847->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&hi847->sd.entity, 1, &hi847->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(hi847->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&hi847->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(hi847->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_media_entity_cleanup;
}
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(hi847->dev);
+ pm_runtime_enable(hi847->dev);
+ pm_runtime_idle(hi847->dev);
return 0;
diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c
index 2b5a6ce7b1ae..d5350bb46f14 100644
--- a/drivers/media/i2c/imx208.c
+++ b/drivers/media/i2c/imx208.c
@@ -2,13 +2,15 @@
// Copyright (C) 2021 Intel Corporation
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <linux/unaligned.h>
#define IMX208_REG_MODE_SELECT 0x0100
#define IMX208_MODE_STANDBY 0x00
@@ -268,6 +270,9 @@ static const struct imx208_mode supported_modes[] = {
};
struct imx208 {
+ struct device *dev;
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -372,7 +377,6 @@ static int imx208_write_reg(struct imx208 *imx208, u16 reg, u32 len, u32 val)
static int imx208_write_regs(struct imx208 *imx208,
const struct imx208_reg *regs, u32 len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
unsigned int i;
int ret;
@@ -380,7 +384,7 @@ static int imx208_write_regs(struct imx208 *imx208,
ret = imx208_write_reg(imx208, regs[i].address, 1,
regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(imx208->dev,
"Failed to write reg 0x%4.4x. error = %d\n",
regs[i].address, ret);
@@ -431,14 +435,13 @@ static int imx208_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct imx208 *imx208 =
container_of(ctrl->handler, struct imx208, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
int ret;
/*
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(imx208->dev))
return 0;
switch (ctrl->id) {
@@ -471,13 +474,13 @@ static int imx208_set_ctrl(struct v4l2_ctrl *ctrl)
break;
default:
ret = -EINVAL;
- dev_err(&client->dev,
+ dev_err(imx208->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx208->dev);
return ret;
}
@@ -620,7 +623,6 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd,
static int imx208_identify_module(struct imx208 *imx208)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
int ret;
u32 val;
@@ -630,13 +632,13 @@ static int imx208_identify_module(struct imx208 *imx208)
ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
2, &val);
if (ret) {
- dev_err(&client->dev, "failed to read chip id %x\n",
+ dev_err(imx208->dev, "failed to read chip id %x\n",
IMX208_CHIP_ID);
return ret;
}
if (val != IMX208_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(imx208->dev, "chip id mismatch: %x!=%x\n",
IMX208_CHIP_ID, val);
return -EIO;
}
@@ -649,7 +651,6 @@ static int imx208_identify_module(struct imx208 *imx208)
/* Start streaming */
static int imx208_start_streaming(struct imx208 *imx208)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
const struct imx208_reg_list *reg_list;
int ret, link_freq_index;
@@ -662,7 +663,7 @@ static int imx208_start_streaming(struct imx208 *imx208)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs);
if (ret) {
- dev_err(&client->dev, "%s failed to set plls\n", __func__);
+ dev_err(imx208->dev, "%s failed to set plls\n", __func__);
return ret;
}
@@ -670,7 +671,7 @@ static int imx208_start_streaming(struct imx208 *imx208)
reg_list = &imx208->cur_mode->reg_list;
ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(imx208->dev, "%s failed to set mode\n", __func__);
return ret;
}
@@ -687,14 +688,13 @@ static int imx208_start_streaming(struct imx208 *imx208)
/* Stop streaming */
static int imx208_stop_streaming(struct imx208 *imx208)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
int ret;
/* set stream off register */
ret = imx208_write_reg(imx208, IMX208_REG_MODE_SELECT,
1, IMX208_MODE_STANDBY);
if (ret)
- dev_err(&client->dev, "%s failed to set stream\n", __func__);
+ dev_err(imx208->dev, "%s failed to set stream\n", __func__);
/*
* Return success even if it was an error, as there is nothing the
@@ -706,13 +706,12 @@ static int imx208_stop_streaming(struct imx208 *imx208)
static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
{
struct imx208 *imx208 = to_imx208(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&imx208->imx208_mx);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(imx208->dev);
if (ret) {
mutex_unlock(&imx208->imx208_mx);
return ret;
@@ -727,7 +726,7 @@ static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
imx208_stop_streaming(imx208);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx208->dev);
}
mutex_unlock(&imx208->imx208_mx);
@@ -739,7 +738,7 @@ static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx208->dev);
mutex_unlock(&imx208->imx208_mx);
return ret;
@@ -778,7 +777,7 @@ static int imx208_read_otp(struct imx208 *imx208)
if (imx208->otp_read)
goto out_unlock;
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(imx208->dev);
if (ret)
goto out_unlock;
@@ -805,7 +804,7 @@ static int imx208_read_otp(struct imx208 *imx208)
}
out_pm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx208->dev);
out_unlock:
mutex_unlock(&imx208->imx208_mx);
@@ -835,7 +834,6 @@ static const BIN_ATTR_RO(otp, IMX208_OTP_SIZE);
/* Initialize control handlers */
static int imx208_init_controls(struct imx208 *imx208)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
struct v4l2_ctrl_handler *ctrl_hdlr = &imx208->ctrl_handler;
s64 exposure_max;
s64 vblank_def;
@@ -914,7 +912,7 @@ static int imx208_init_controls(struct imx208 *imx208)
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "%s control init failed (%d)\n",
+ dev_err(imx208->dev, "%s control init failed (%d)\n",
__func__, ret);
goto error;
}
@@ -938,31 +936,36 @@ static void imx208_free_controls(struct imx208 *imx208)
static int imx208_probe(struct i2c_client *client)
{
struct imx208 *imx208;
+ unsigned long freq;
int ret;
bool full_power;
- u32 val = 0;
-
- device_property_read_u32(&client->dev, "clock-frequency", &val);
- if (val != 19200000) {
- dev_err(&client->dev,
- "Unsupported clock-frequency %u. Expected 19200000.\n",
- val);
- return -EINVAL;
- }
imx208 = devm_kzalloc(&client->dev, sizeof(*imx208), GFP_KERNEL);
if (!imx208)
return -ENOMEM;
+ imx208->dev = &client->dev;
+
+ imx208->clk = devm_v4l2_sensor_clk_get(imx208->dev, NULL);
+ if (IS_ERR(imx208->clk))
+ return dev_err_probe(imx208->dev, PTR_ERR(imx208->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(imx208->clk);
+ if (freq != 19200000)
+ return dev_err_probe(imx208->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops);
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(imx208->dev);
if (full_power) {
/* Check module identity */
ret = imx208_identify_module(imx208);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(imx208->dev, "failed to find sensor: %d", ret);
goto error_probe;
}
}
@@ -972,7 +975,7 @@ static int imx208_probe(struct i2c_client *client)
ret = imx208_init_controls(imx208);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(imx208->dev, "failed to init controls: %d", ret);
goto error_probe;
}
@@ -985,7 +988,7 @@ static int imx208_probe(struct i2c_client *client)
imx208->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&imx208->sd.entity, 1, &imx208->pad);
if (ret) {
- dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
+ dev_err(imx208->dev, "%s failed:%d\n", __func__, ret);
goto error_handler_free;
}
@@ -993,17 +996,17 @@ static int imx208_probe(struct i2c_client *client)
if (ret < 0)
goto error_media_entity;
- ret = device_create_bin_file(&client->dev, &bin_attr_otp);
+ ret = device_create_bin_file(imx208->dev, &bin_attr_otp);
if (ret) {
- dev_err(&client->dev, "sysfs otp creation failed\n");
+ dev_err(imx208->dev, "sysfs otp creation failed\n");
goto error_async_subdev;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(imx208->dev);
+ pm_runtime_enable(imx208->dev);
+ pm_runtime_idle(imx208->dev);
return 0;
@@ -1027,13 +1030,13 @@ static void imx208_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct imx208 *imx208 = to_imx208(sd);
- device_remove_bin_file(&client->dev, &bin_attr_otp);
+ device_remove_bin_file(imx208->dev, &bin_attr_otp);
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
imx208_free_controls(imx208);
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(imx208->dev);
+ pm_runtime_set_suspended(imx208->dev);
mutex_destroy(&imx208->imx208_mx);
}
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
index a0cef9e61b41..94ebe625c9e6 100644
--- a/drivers/media/i2c/imx214.c
+++ b/drivers/media/i2c/imx214.c
@@ -881,6 +881,109 @@ static const struct v4l2_ctrl_ops imx214_ctrl_ops = {
.s_ctrl = imx214_set_ctrl,
};
+static int imx214_pll_calculate(struct imx214 *imx214, struct ccs_pll *pll,
+ unsigned int link_freq)
+{
+ struct ccs_pll_limits limits = {
+ .min_ext_clk_freq_hz = 6000000,
+ .max_ext_clk_freq_hz = 27000000,
+
+ .vt_fr = {
+ .min_pre_pll_clk_div = 1,
+ .max_pre_pll_clk_div = 15,
+ /* Value is educated guess as we don't have a spec */
+ .min_pll_ip_clk_freq_hz = 6000000,
+ /* Value is educated guess as we don't have a spec */
+ .max_pll_ip_clk_freq_hz = 12000000,
+ .min_pll_multiplier = 12,
+ .max_pll_multiplier = 1200,
+ .min_pll_op_clk_freq_hz = 338000000,
+ .max_pll_op_clk_freq_hz = 1200000000,
+ },
+ .vt_bk = {
+ .min_sys_clk_div = 2,
+ .max_sys_clk_div = 4,
+ .min_pix_clk_div = 5,
+ .max_pix_clk_div = 10,
+ .min_pix_clk_freq_hz = 30000000,
+ .max_pix_clk_freq_hz = 120000000,
+ },
+ .op_bk = {
+ .min_sys_clk_div = 1,
+ .max_sys_clk_div = 2,
+ .min_pix_clk_div = 6,
+ .max_pix_clk_div = 10,
+ .min_pix_clk_freq_hz = 30000000,
+ .max_pix_clk_freq_hz = 120000000,
+ },
+
+ .min_line_length_pck_bin = IMX214_PPL_DEFAULT,
+ .min_line_length_pck = IMX214_PPL_DEFAULT,
+ };
+ unsigned int num_lanes = imx214->bus_cfg.bus.mipi_csi2.num_data_lanes;
+
+ /*
+ * There are no documented constraints on the sys clock frequency, for
+ * either branch. Recover them based on the PLL output clock frequency
+ * and sys_clk_div limits on one hand, and the pix clock frequency and
+ * the pix_clk_div limits on the other hand.
+ */
+ limits.vt_bk.min_sys_clk_freq_hz =
+ max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.vt_bk.max_sys_clk_div,
+ limits.vt_bk.min_pix_clk_freq_hz * limits.vt_bk.min_pix_clk_div);
+ limits.vt_bk.max_sys_clk_freq_hz =
+ min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.vt_bk.min_sys_clk_div,
+ limits.vt_bk.max_pix_clk_freq_hz * limits.vt_bk.max_pix_clk_div);
+
+ limits.op_bk.min_sys_clk_freq_hz =
+ max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.op_bk.max_sys_clk_div,
+ limits.op_bk.min_pix_clk_freq_hz * limits.op_bk.min_pix_clk_div);
+ limits.op_bk.max_sys_clk_freq_hz =
+ min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.op_bk.min_sys_clk_div,
+ limits.op_bk.max_pix_clk_freq_hz * limits.op_bk.max_pix_clk_div);
+
+ memset(pll, 0, sizeof(*pll));
+
+ pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
+ pll->op_lanes = num_lanes;
+ pll->vt_lanes = num_lanes;
+ pll->csi2.lanes = num_lanes;
+
+ pll->binning_horizontal = 1;
+ pll->binning_vertical = 1;
+ pll->scale_m = 1;
+ pll->scale_n = 1;
+ pll->bits_per_pixel =
+ IMX214_CSI_DATA_FORMAT_RAW10 & IMX214_BITS_PER_PIXEL_MASK;
+ pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
+ pll->link_freq = link_freq;
+ pll->ext_clk_freq_hz = clk_get_rate(imx214->xclk);
+
+ return ccs_pll_calculate(imx214->dev, &limits, pll);
+}
+
+static int imx214_pll_update(struct imx214 *imx214)
+{
+ u64 link_freq;
+ int ret;
+
+ link_freq = imx214->bus_cfg.link_frequencies[imx214->link_freq->val];
+ ret = imx214_pll_calculate(imx214, &imx214->pll, link_freq);
+ if (ret) {
+ dev_err(imx214->dev, "PLL calculations failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = v4l2_ctrl_s_ctrl_int64(imx214->pixel_rate,
+ imx214->pll.pixel_rate_pixel_array);
+ if (ret) {
+ dev_err(imx214->dev, "failed to set pixel rate\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int imx214_ctrls_init(struct imx214 *imx214)
{
static const struct v4l2_area unit_size = {
@@ -1003,6 +1106,13 @@ static int imx214_ctrls_init(struct imx214 *imx214)
return ret;
}
+ ret = imx214_pll_update(imx214);
+ if (ret < 0) {
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+ dev_err(imx214->dev, "failed to update PLL\n");
+ return ret;
+ }
+
imx214->sd.ctrl_handler = ctrl_hdlr;
return 0;
@@ -1029,8 +1139,8 @@ static int imx214_start_streaming(struct imx214 *imx214)
return ret;
}
- bit_rate_mbps = (imx214->pll.pixel_rate_csi / 1000000)
- * imx214->pll.bits_per_pixel;
+ bit_rate_mbps = imx214->pll.pixel_rate_csi / 1000000
+ * imx214->pll.bits_per_pixel;
ret = cci_write(imx214->regmap, IMX214_REG_REQ_LINK_BIT_RATE,
IMX214_LINK_BIT_RATE_MBPS(bit_rate_mbps), NULL);
if (ret) {
@@ -1115,109 +1225,6 @@ err_rpm_put:
return ret;
}
-static int imx214_pll_calculate(struct imx214 *imx214, struct ccs_pll *pll,
- unsigned int link_freq)
-{
- struct ccs_pll_limits limits = {
- .min_ext_clk_freq_hz = 6000000,
- .max_ext_clk_freq_hz = 27000000,
-
- .vt_fr = {
- .min_pre_pll_clk_div = 1,
- .max_pre_pll_clk_div = 15,
- /* Value is educated guess as we don't have a spec */
- .min_pll_ip_clk_freq_hz = 6000000,
- /* Value is educated guess as we don't have a spec */
- .max_pll_ip_clk_freq_hz = 12000000,
- .min_pll_multiplier = 12,
- .max_pll_multiplier = 1200,
- .min_pll_op_clk_freq_hz = 338000000,
- .max_pll_op_clk_freq_hz = 1200000000,
- },
- .vt_bk = {
- .min_sys_clk_div = 2,
- .max_sys_clk_div = 4,
- .min_pix_clk_div = 5,
- .max_pix_clk_div = 10,
- .min_pix_clk_freq_hz = 30000000,
- .max_pix_clk_freq_hz = 120000000,
- },
- .op_bk = {
- .min_sys_clk_div = 1,
- .max_sys_clk_div = 2,
- .min_pix_clk_div = 6,
- .max_pix_clk_div = 10,
- .min_pix_clk_freq_hz = 30000000,
- .max_pix_clk_freq_hz = 120000000,
- },
-
- .min_line_length_pck_bin = IMX214_PPL_DEFAULT,
- .min_line_length_pck = IMX214_PPL_DEFAULT,
- };
- unsigned int num_lanes = imx214->bus_cfg.bus.mipi_csi2.num_data_lanes;
-
- /*
- * There are no documented constraints on the sys clock frequency, for
- * either branch. Recover them based on the PLL output clock frequency
- * and sys_clk_div limits on one hand, and the pix clock frequency and
- * the pix_clk_div limits on the other hand.
- */
- limits.vt_bk.min_sys_clk_freq_hz =
- max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.vt_bk.max_sys_clk_div,
- limits.vt_bk.min_pix_clk_freq_hz * limits.vt_bk.min_pix_clk_div);
- limits.vt_bk.max_sys_clk_freq_hz =
- min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.vt_bk.min_sys_clk_div,
- limits.vt_bk.max_pix_clk_freq_hz * limits.vt_bk.max_pix_clk_div);
-
- limits.op_bk.min_sys_clk_freq_hz =
- max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.op_bk.max_sys_clk_div,
- limits.op_bk.min_pix_clk_freq_hz * limits.op_bk.min_pix_clk_div);
- limits.op_bk.max_sys_clk_freq_hz =
- min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.op_bk.min_sys_clk_div,
- limits.op_bk.max_pix_clk_freq_hz * limits.op_bk.max_pix_clk_div);
-
- memset(pll, 0, sizeof(*pll));
-
- pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
- pll->op_lanes = num_lanes;
- pll->vt_lanes = num_lanes;
- pll->csi2.lanes = num_lanes;
-
- pll->binning_horizontal = 1;
- pll->binning_vertical = 1;
- pll->scale_m = 1;
- pll->scale_n = 1;
- pll->bits_per_pixel =
- IMX214_CSI_DATA_FORMAT_RAW10 & IMX214_BITS_PER_PIXEL_MASK;
- pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
- pll->link_freq = link_freq;
- pll->ext_clk_freq_hz = clk_get_rate(imx214->xclk);
-
- return ccs_pll_calculate(imx214->dev, &limits, pll);
-}
-
-static int imx214_pll_update(struct imx214 *imx214)
-{
- u64 link_freq;
- int ret;
-
- link_freq = imx214->bus_cfg.link_frequencies[imx214->link_freq->val];
- ret = imx214_pll_calculate(imx214, &imx214->pll, link_freq);
- if (ret) {
- dev_err(imx214->dev, "PLL calculations failed: %d\n", ret);
- return ret;
- }
-
- ret = v4l2_ctrl_s_ctrl_int64(imx214->pixel_rate,
- imx214->pll.pixel_rate_pixel_array);
- if (ret) {
- dev_err(imx214->dev, "failed to set pixel rate\n");
- return ret;
- }
-
- return 0;
-}
-
static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fival)
@@ -1324,10 +1331,11 @@ static int imx214_identify_module(struct imx214 *imx214)
return 0;
}
-static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
+static int imx214_parse_fwnode(struct imx214 *imx214)
{
+ struct fwnode_handle *endpoint __free(fwnode_handle) = NULL;
struct v4l2_fwnode_endpoint *bus_cfg = &imx214->bus_cfg;
- struct fwnode_handle *endpoint;
+ struct device *dev = imx214->dev;
unsigned int i;
int ret;
@@ -1337,11 +1345,8 @@ static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
bus_cfg->bus_type = V4L2_MBUS_CSI2_DPHY;
ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, bus_cfg);
- fwnode_handle_put(endpoint);
- if (ret) {
- dev_err_probe(dev, ret, "parsing endpoint node failed\n");
- goto error;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "parsing endpoint node failed\n");
/* Check the number of MIPI CSI2 data lanes */
if (bus_cfg->bus.mipi_csi2.num_data_lanes != 4) {
@@ -1357,18 +1362,16 @@ static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
u64 freq = bus_cfg->link_frequencies[i];
struct ccs_pll pll;
- if (!imx214_pll_calculate(imx214, &pll, freq))
- break;
if (freq == IMX214_DEFAULT_LINK_FREQ_LEGACY) {
dev_warn(dev,
"link-frequencies %d not supported, please review your DT. Continuing anyway\n",
IMX214_DEFAULT_LINK_FREQ);
freq = IMX214_DEFAULT_LINK_FREQ;
- if (imx214_pll_calculate(imx214, &pll, freq))
- continue;
bus_cfg->link_frequencies[i] = freq;
- break;
}
+
+ if (!imx214_pll_calculate(imx214, &pll, freq))
+ break;
}
if (i == bus_cfg->nr_of_link_frequencies)
@@ -1396,7 +1399,7 @@ static int imx214_probe(struct i2c_client *client)
imx214->dev = dev;
- imx214->xclk = devm_clk_get(dev, NULL);
+ imx214->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(imx214->xclk))
return dev_err_probe(dev, PTR_ERR(imx214->xclk),
"failed to get xclk\n");
@@ -1415,7 +1418,7 @@ static int imx214_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(imx214->regmap),
"failed to initialize CCI\n");
- ret = imx214_parse_fwnode(dev, imx214);
+ ret = imx214_parse_fwnode(imx214);
if (ret)
return ret;
@@ -1459,12 +1462,6 @@ static int imx214_probe(struct i2c_client *client)
pm_runtime_set_active(imx214->dev);
pm_runtime_enable(imx214->dev);
- ret = imx214_pll_update(imx214);
- if (ret < 0) {
- dev_err_probe(dev, ret, "failed to update PLL\n");
- goto error_subdev_cleanup;
- }
-
ret = v4l2_async_register_subdev_sensor(&imx214->sd);
if (ret < 0) {
dev_err_probe(dev, ret,
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 3faf48f34af4..c680aa6c3a55 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -1032,6 +1032,10 @@ static int imx219_power_on(struct device *dev)
goto reg_off;
}
+ /*
+ * Note: Misinterpretation of reset assertion - do not re-use this code.
+ * XCLR pin is using incorrect (for reset signal) logical level.
+ */
gpiod_set_value_cansleep(imx219->reset_gpio, 1);
usleep_range(IMX219_XCLR_MIN_DELAY_US,
IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
@@ -1186,7 +1190,7 @@ static int imx219_probe(struct i2c_client *client)
"failed to initialize CCI\n");
/* Get system clock (xclk) */
- imx219->xclk = devm_clk_get(dev, NULL);
+ imx219->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(imx219->xclk))
return dev_err_probe(dev, PTR_ERR(imx219->xclk),
"failed to get xclk\n");
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 9e30fce1f223..e50dcfd830f5 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -8,11 +8,12 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
-#include <linux/unaligned.h>
#define IMX258_REG_MODE_SELECT CCI_REG8(0x0100)
#define IMX258_MODE_STANDBY 0x00
@@ -645,6 +646,8 @@ static const struct imx258_mode supported_modes[] = {
};
struct imx258 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct regmap *regmap;
@@ -751,7 +754,6 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct imx258 *imx258 =
container_of(ctrl->handler, struct imx258, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
int ret = 0;
/*
@@ -765,7 +767,7 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (pm_runtime_get_if_in_use(&client->dev) == 0)
+ if (pm_runtime_get_if_in_use(imx258->dev) == 0)
return 0;
switch (ctrl->id) {
@@ -811,14 +813,14 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
NULL);
break;
default:
- dev_info(&client->dev,
+ dev_info(imx258->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
ctrl->id, ctrl->val);
ret = -EINVAL;
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx258->dev);
return ret;
}
@@ -1013,14 +1015,13 @@ static int imx258_get_selection(struct v4l2_subdev *sd,
/* Start streaming */
static int imx258_start_streaming(struct imx258 *imx258)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
const struct imx258_reg_list *reg_list;
const struct imx258_link_freq_config *link_freq_cfg;
int ret, link_freq_index;
ret = cci_write(imx258->regmap, IMX258_REG_RESET, 0x01, NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to reset sensor\n", __func__);
+ dev_err(imx258->dev, "%s failed to reset sensor\n", __func__);
return ret;
}
@@ -1034,21 +1035,21 @@ static int imx258_start_streaming(struct imx258 *imx258)
reg_list = &link_freq_cfg->link_cfg[imx258->lane_mode_idx].reg_list;
ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set plls\n", __func__);
+ dev_err(imx258->dev, "%s failed to set plls\n", __func__);
return ret;
}
ret = cci_multi_reg_write(imx258->regmap, mode_common_regs,
ARRAY_SIZE(mode_common_regs), NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set common regs\n", __func__);
+ dev_err(imx258->dev, "%s failed to set common regs\n", __func__);
return ret;
}
ret = cci_multi_reg_write(imx258->regmap, imx258->variant_cfg->regs,
imx258->variant_cfg->num_regs, NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set variant config\n",
+ dev_err(imx258->dev, "%s failed to set variant config\n",
__func__);
return ret;
}
@@ -1057,7 +1058,7 @@ static int imx258_start_streaming(struct imx258 *imx258)
!!(imx258->csi2_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK),
NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set clock lane mode\n", __func__);
+ dev_err(imx258->dev, "%s failed to set clock lane mode\n", __func__);
return ret;
}
@@ -1065,7 +1066,7 @@ static int imx258_start_streaming(struct imx258 *imx258)
reg_list = &imx258->cur_mode->reg_list;
ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(imx258->dev, "%s failed to set mode\n", __func__);
return ret;
}
@@ -1082,14 +1083,13 @@ static int imx258_start_streaming(struct imx258 *imx258)
/* Stop streaming */
static int imx258_stop_streaming(struct imx258 *imx258)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
int ret;
/* set stream off register */
ret = cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,
IMX258_MODE_STANDBY, NULL);
if (ret)
- dev_err(&client->dev, "%s failed to set stream\n", __func__);
+ dev_err(imx258->dev, "%s failed to set stream\n", __func__);
/*
* Return success even if it was an error, as there is nothing the
@@ -1135,13 +1135,12 @@ static int imx258_power_off(struct device *dev)
static int imx258_set_stream(struct v4l2_subdev *sd, int enable)
{
struct imx258 *imx258 = to_imx258(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&imx258->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(imx258->dev);
if (ret < 0)
goto err_unlock;
@@ -1154,7 +1153,7 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
imx258_stop_streaming(imx258);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx258->dev);
}
mutex_unlock(&imx258->mutex);
@@ -1162,7 +1161,7 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx258->dev);
err_unlock:
mutex_unlock(&imx258->mutex);
@@ -1172,20 +1171,19 @@ err_unlock:
/* Verify chip ID */
static int imx258_identify_module(struct imx258 *imx258)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
int ret;
u64 val;
ret = cci_read(imx258->regmap, IMX258_REG_CHIP_ID,
&val, NULL);
if (ret) {
- dev_err(&client->dev, "failed to read chip id %x\n",
+ dev_err(imx258->dev, "failed to read chip id %x\n",
IMX258_CHIP_ID);
return ret;
}
if (val != IMX258_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",
+ dev_err(imx258->dev, "chip id mismatch: %x!=%llx\n",
IMX258_CHIP_ID, val);
return -EIO;
}
@@ -1217,7 +1215,6 @@ static const struct v4l2_subdev_internal_ops imx258_internal_ops = {
/* Initialize control handlers */
static int imx258_init_controls(struct imx258 *imx258)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
const struct imx258_link_freq_config *link_freq_cfgs;
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
@@ -1308,12 +1305,12 @@ static int imx258_init_controls(struct imx258 *imx258)
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "%s control init failed (%d)\n",
+ dev_err(imx258->dev, "%s control init failed (%d)\n",
__func__, ret);
goto error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(imx258->dev, &props);
if (ret)
goto error;
@@ -1339,15 +1336,14 @@ static void imx258_free_controls(struct imx258 *imx258)
mutex_destroy(&imx258->mutex);
}
-static int imx258_get_regulators(struct imx258 *imx258,
- struct i2c_client *client)
+static int imx258_get_regulators(struct imx258 *imx258)
{
unsigned int i;
for (i = 0; i < IMX258_NUM_SUPPLIES; i++)
imx258->supplies[i].supply = imx258_supply_name[i];
- return devm_regulator_bulk_get(&client->dev,
+ return devm_regulator_bulk_get(imx258->dev,
IMX258_NUM_SUPPLIES, imx258->supplies);
}
@@ -1365,30 +1361,27 @@ static int imx258_probe(struct i2c_client *client)
if (!imx258)
return -ENOMEM;
+ imx258->dev = &client->dev;
+
imx258->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(imx258->regmap)) {
ret = PTR_ERR(imx258->regmap);
- dev_err(&client->dev, "failed to initialize CCI: %d\n", ret);
+ dev_err(imx258->dev, "failed to initialize CCI: %d\n", ret);
return ret;
}
- ret = imx258_get_regulators(imx258, client);
+ ret = imx258_get_regulators(imx258);
if (ret)
- return dev_err_probe(&client->dev, ret,
+ return dev_err_probe(imx258->dev, ret,
"failed to get regulators\n");
- imx258->clk = devm_clk_get_optional(&client->dev, NULL);
+ imx258->clk = devm_v4l2_sensor_clk_get_legacy(imx258->dev, NULL, false,
+ 0);
if (IS_ERR(imx258->clk))
- return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
+ return dev_err_probe(imx258->dev, PTR_ERR(imx258->clk),
"error getting clock\n");
- if (!imx258->clk) {
- dev_dbg(&client->dev,
- "no clock provided, using clock-frequency property\n");
- device_property_read_u32(&client->dev, "clock-frequency", &val);
- } else {
- val = clk_get_rate(imx258->clk);
- }
+ val = clk_get_rate(imx258->clk);
switch (val) {
case 19200000:
@@ -1400,32 +1393,32 @@ static int imx258_probe(struct i2c_client *client)
imx258->link_freq_menu_items = link_freq_menu_items_24;
break;
default:
- dev_err(&client->dev, "input clock frequency of %u not supported\n",
+ dev_err(imx258->dev, "input clock frequency of %u not supported\n",
val);
return -EINVAL;
}
- endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx258->dev), NULL);
if (!endpoint) {
- dev_err(&client->dev, "Endpoint node not found\n");
+ dev_err(imx258->dev, "Endpoint node not found\n");
return -EINVAL;
}
ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
fwnode_handle_put(endpoint);
if (ret) {
- dev_err(&client->dev, "Parsing endpoint node failed\n");
+ dev_err(imx258->dev, "Parsing endpoint node failed\n");
return ret;
}
- ret = v4l2_link_freq_to_bitmap(&client->dev,
+ ret = v4l2_link_freq_to_bitmap(imx258->dev,
ep.link_frequencies,
ep.nr_of_link_frequencies,
imx258->link_freq_menu_items,
ARRAY_SIZE(link_freq_menu_items_19_2),
&imx258->link_freq_bitmap);
if (ret) {
- dev_err(&client->dev, "Link frequency not supported\n");
+ dev_err(imx258->dev, "Link frequency not supported\n");
goto error_endpoint_free;
}
@@ -1438,7 +1431,7 @@ static int imx258_probe(struct i2c_client *client)
imx258->lane_mode_idx = IMX258_4_LANE_MODE;
break;
default:
- dev_err(&client->dev, "Invalid data lanes: %u\n",
+ dev_err(imx258->dev, "Invalid data lanes: %u\n",
ep.bus.mipi_csi2.num_data_lanes);
ret = -EINVAL;
goto error_endpoint_free;
@@ -1446,7 +1439,7 @@ static int imx258_probe(struct i2c_client *client)
imx258->csi2_flags = ep.bus.mipi_csi2.flags;
- imx258->variant_cfg = device_get_match_data(&client->dev);
+ imx258->variant_cfg = device_get_match_data(imx258->dev);
if (!imx258->variant_cfg)
imx258->variant_cfg = &imx258_cfg;
@@ -1454,7 +1447,7 @@ static int imx258_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
/* Will be powered off via pm_runtime_idle */
- ret = imx258_power_on(&client->dev);
+ ret = imx258_power_on(imx258->dev);
if (ret)
goto error_endpoint_free;
@@ -1486,9 +1479,9 @@ static int imx258_probe(struct i2c_client *client)
if (ret < 0)
goto error_media_entity;
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(imx258->dev);
+ pm_runtime_enable(imx258->dev);
+ pm_runtime_idle(imx258->dev);
v4l2_fwnode_endpoint_free(&ep);
return 0;
@@ -1500,7 +1493,7 @@ error_handler_free:
imx258_free_controls(imx258);
error_identify:
- imx258_power_off(&client->dev);
+ imx258_power_off(imx258->dev);
error_endpoint_free:
v4l2_fwnode_endpoint_free(&ep);
@@ -1517,10 +1510,10 @@ static void imx258_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
imx258_free_controls(imx258);
- pm_runtime_disable(&client->dev);
- if (!pm_runtime_status_suspended(&client->dev))
- imx258_power_off(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(imx258->dev);
+ if (!pm_runtime_status_suspended(imx258->dev))
+ imx258_power_off(imx258->dev);
+ pm_runtime_set_suspended(imx258->dev);
}
static const struct dev_pm_ops imx258_pm_ops = {
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index a2b824986027..d86d08c29174 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -826,6 +826,8 @@ static int imx274_start_stream(struct stimx274 *priv)
* if rst = 0, keep it in reset;
* if rst = 1, bring it out of reset.
*
+ * Note: Misinterpretation of reset assertion - do not re-use this code.
+ * XCLR pin is using incorrect (for reset signal) logical level.
*/
static void imx274_reset(struct stimx274 *priv, int rst)
{
diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
index 67e8bb432d10..8ab63ad8f385 100644
--- a/drivers/media/i2c/imx283.c
+++ b/drivers/media/i2c/imx283.c
@@ -1460,11 +1460,10 @@ static int imx283_probe(struct i2c_client *client)
}
/* Get system clock (xclk) */
- imx283->xclk = devm_clk_get(imx283->dev, NULL);
- if (IS_ERR(imx283->xclk)) {
+ imx283->xclk = devm_v4l2_sensor_clk_get(imx283->dev, NULL);
+ if (IS_ERR(imx283->xclk))
return dev_err_probe(imx283->dev, PTR_ERR(imx283->xclk),
"failed to get xclk\n");
- }
xclk_freq = clk_get_rate(imx283->xclk);
for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
index ec172556612e..21cbc81cb2ed 100644
--- a/drivers/media/i2c/imx290.c
+++ b/drivers/media/i2c/imx290.c
@@ -1422,14 +1422,14 @@ static int imx290_get_regulators(struct device *dev, struct imx290 *imx290)
static int imx290_init_clk(struct imx290 *imx290)
{
u32 xclk_freq;
- int ret;
- ret = device_property_read_u32(imx290->dev, "clock-frequency",
- &xclk_freq);
- if (ret) {
- dev_err(imx290->dev, "Could not get xclk frequency\n");
- return ret;
- }
+ imx290->xclk = devm_v4l2_sensor_clk_get_legacy(imx290->dev, "xclk",
+ false, 0);
+ if (IS_ERR(imx290->xclk))
+ return dev_err_probe(imx290->dev, PTR_ERR(imx290->xclk),
+ "Could not get xclk\n");
+
+ xclk_freq = clk_get_rate(imx290->xclk);
/* external clock must be 37.125 MHz or 74.25MHz */
switch (xclk_freq) {
@@ -1445,12 +1445,6 @@ static int imx290_init_clk(struct imx290 *imx290)
return -EINVAL;
}
- ret = clk_set_rate(imx290->xclk, xclk_freq);
- if (ret) {
- dev_err(imx290->dev, "Could not set xclk frequency\n");
- return ret;
- }
-
return 0;
}
@@ -1596,11 +1590,6 @@ static int imx290_probe(struct i2c_client *client)
return ret;
/* Acquire resources. */
- imx290->xclk = devm_clk_get(dev, "xclk");
- if (IS_ERR(imx290->xclk))
- return dev_err_probe(dev, PTR_ERR(imx290->xclk),
- "Could not get xclk\n");
-
ret = imx290_get_regulators(dev, imx290);
if (ret < 0)
return dev_err_probe(dev, ret, "Cannot get regulators\n");
@@ -1611,7 +1600,7 @@ static int imx290_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(imx290->rst_gpio),
"Cannot get reset gpio\n");
- /* Initialize external clock frequency. */
+ /* Initialize external clock. */
ret = imx290_init_clk(imx290);
if (ret)
return ret;
diff --git a/drivers/media/i2c/imx296.c b/drivers/media/i2c/imx296.c
index 61116f4e3f76..69636db11a2b 100644
--- a/drivers/media/i2c/imx296.c
+++ b/drivers/media/i2c/imx296.c
@@ -921,7 +921,7 @@ static int imx296_read_temperature(struct imx296 *sensor, int *temp)
tmdout &= IMX296_TMDOUT_MASK;
- /* T(°C) = 246.312 - 0.304 * TMDOUT */;
+ /* T(°C) = 246.312 - 0.304 * TMDOUT */
*temp = 246312 - 304 * tmdout;
return imx296_write(sensor, IMX296_TMDCTRL, 0, NULL);
@@ -1043,7 +1043,7 @@ static int imx296_probe(struct i2c_client *client)
return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
"failed to get reset GPIO\n");
- sensor->clk = devm_clk_get(sensor->dev, "inck");
+ sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, "inck");
if (IS_ERR(sensor->clk))
return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
"failed to get clock\n");
diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c
index 701840f4a5cc..953310ef3046 100644
--- a/drivers/media/i2c/imx319.c
+++ b/drivers/media/i2c/imx319.c
@@ -1,11 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 Intel Corporation
-#include <linux/unaligned.h>
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
@@ -106,11 +108,12 @@ struct imx319_mode {
};
struct imx319_hwcfg {
- u32 ext_clk; /* sensor external clk */
unsigned long link_freq_bitmap;
};
struct imx319 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -1839,14 +1842,13 @@ static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
static int imx319_write_regs(struct imx319 *imx319,
const struct imx319_reg *regs, u32 len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
int ret;
u32 i;
for (i = 0; i < len; i++) {
ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(imx319->dev,
"write reg 0x%4.4x return err %d",
regs[i].address, ret);
return ret;
@@ -1880,7 +1882,6 @@ static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct imx319 *imx319 = container_of(ctrl->handler,
struct imx319, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
s64 max;
int ret;
@@ -1899,7 +1900,7 @@ static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(imx319->dev))
return 0;
switch (ctrl->id) {
@@ -1933,12 +1934,12 @@ static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
break;
default:
ret = -EINVAL;
- dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
+ dev_info(imx319->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx319->dev);
return ret;
}
@@ -2087,7 +2088,6 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
/* Verify chip ID */
static int imx319_identify_module(struct imx319 *imx319)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
int ret;
u32 val;
@@ -2099,7 +2099,7 @@ static int imx319_identify_module(struct imx319 *imx319)
return ret;
if (val != IMX319_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(imx319->dev, "chip id mismatch: %x!=%x",
IMX319_CHIP_ID, val);
return -EIO;
}
@@ -2112,7 +2112,6 @@ static int imx319_identify_module(struct imx319 *imx319)
/* Start streaming */
static int imx319_start_streaming(struct imx319 *imx319)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
const struct imx319_reg_list *reg_list;
int ret;
@@ -2124,7 +2123,7 @@ static int imx319_start_streaming(struct imx319 *imx319)
reg_list = &imx319_global_setting;
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
if (ret) {
- dev_err(&client->dev, "failed to set global settings");
+ dev_err(imx319->dev, "failed to set global settings");
return ret;
}
@@ -2132,7 +2131,7 @@ static int imx319_start_streaming(struct imx319 *imx319)
reg_list = &imx319->cur_mode->reg_list;
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(imx319->dev, "failed to set mode");
return ret;
}
@@ -2160,13 +2159,12 @@ static int imx319_stop_streaming(struct imx319 *imx319)
static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
{
struct imx319 *imx319 = to_imx319(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&imx319->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(imx319->dev);
if (ret < 0)
goto err_unlock;
@@ -2179,7 +2177,7 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
imx319_stop_streaming(imx319);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx319->dev);
}
/* vflip and hflip cannot change during streaming */
@@ -2191,7 +2189,7 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx319->dev);
err_unlock:
mutex_unlock(&imx319->mutex);
@@ -2231,7 +2229,6 @@ static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
/* Initialize control handlers */
static int imx319_init_controls(struct imx319 *imx319)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max;
s64 vblank_def;
@@ -2311,7 +2308,7 @@ static int imx319_init_controls(struct imx319 *imx319)
0, 0, imx319_test_pattern_menu);
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "control init failed: %d", ret);
+ dev_err(imx319->dev, "control init failed: %d", ret);
goto error;
}
@@ -2350,20 +2347,6 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
if (!cfg)
goto out_err;
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &cfg->ext_clk);
- if (ret) {
- dev_err(dev, "can't get clock frequency");
- goto out_err;
- }
-
- dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
- if (cfg->ext_clk != IMX319_EXT_CLK) {
- dev_err(dev, "external clock %d is not supported",
- cfg->ext_clk);
- goto out_err;
- }
-
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_freq_menu_items,
@@ -2385,6 +2368,8 @@ out_err:
static int imx319_probe(struct i2c_client *client)
{
struct imx319 *imx319;
+ unsigned long freq;
+ struct clk *clk;
bool full_power;
int ret;
@@ -2392,24 +2377,37 @@ static int imx319_probe(struct i2c_client *client)
if (!imx319)
return -ENOMEM;
+ imx319->dev = &client->dev;
+
mutex_init(&imx319->mutex);
+ clk = devm_v4l2_sensor_clk_get(imx319->dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(imx319->dev, PTR_ERR(clk),
+ "failed to acquire clock\n");
+
+ freq = clk_get_rate(clk);
+ if (freq != IMX319_EXT_CLK)
+ return dev_err_probe(imx319->dev, -EINVAL,
+ "external clock %lu is not supported",
+ freq);
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(imx319->dev);
if (full_power) {
/* Check module identity */
ret = imx319_identify_module(imx319);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(imx319->dev, "failed to find sensor: %d", ret);
goto error_probe;
}
}
- imx319->hwcfg = imx319_get_hwcfg(&client->dev);
+ imx319->hwcfg = imx319_get_hwcfg(imx319->dev);
if (!imx319->hwcfg) {
- dev_err(&client->dev, "failed to get hwcfg");
+ dev_err(imx319->dev, "failed to get hwcfg");
ret = -ENODEV;
goto error_probe;
}
@@ -2419,7 +2417,7 @@ static int imx319_probe(struct i2c_client *client)
ret = imx319_init_controls(imx319);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(imx319->dev, "failed to init controls: %d", ret);
goto error_probe;
}
@@ -2434,27 +2432,27 @@ static int imx319_probe(struct i2c_client *client)
imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(imx319->dev, "failed to init entity pads: %d", ret);
goto error_handler_free;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
+ pm_runtime_set_active(imx319->dev);
+ pm_runtime_enable(imx319->dev);
ret = v4l2_async_register_subdev_sensor(&imx319->sd);
if (ret < 0)
goto error_media_entity_pm;
- pm_runtime_idle(&client->dev);
+ pm_runtime_idle(imx319->dev);
return 0;
error_media_entity_pm:
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(imx319->dev);
if (full_power)
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_set_suspended(imx319->dev);
media_entity_cleanup(&imx319->sd.entity);
error_handler_free:
@@ -2475,9 +2473,9 @@ static void imx319_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
- if (!pm_runtime_status_suspended(&client->dev))
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(imx319->dev);
+ if (!pm_runtime_status_suspended(imx319->dev))
+ pm_runtime_set_suspended(imx319->dev);
mutex_destroy(&imx319->mutex);
}
diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c
index 846b9928d4e8..9654f9268056 100644
--- a/drivers/media/i2c/imx334.c
+++ b/drivers/media/i2c/imx334.c
@@ -118,6 +118,9 @@
#define IMX334_REG_TP CCI_REG8(0x329e)
#define IMX334_TP_COLOR_HBARS 0xa
#define IMX334_TP_COLOR_VBARS 0xb
+#define IMX334_TP_BLACK 0x0
+#define IMX334_TP_WHITE 0x1
+#define IMX334_TP_BLACK_GREY 0xc
#define IMX334_TPG_EN_DOUT CCI_REG8(0x329c)
#define IMX334_TP_ENABLE 0x1
@@ -398,12 +401,18 @@ static const char * const imx334_test_pattern_menu[] = {
"Disabled",
"Vertical Color Bars",
"Horizontal Color Bars",
+ "Black and Grey Bars",
+ "Black Color",
+ "White Color",
};
static const int imx334_test_pattern_val[] = {
IMX334_TP_DISABLE,
IMX334_TP_COLOR_HBARS,
IMX334_TP_COLOR_VBARS,
+ IMX334_TP_BLACK_GREY,
+ IMX334_TP_BLACK,
+ IMX334_TP_WHITE,
};
static const struct cci_reg_sequence raw10_framefmt_regs[] = {
@@ -997,7 +1006,7 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
"failed to get reset gpio\n");
/* Get sensor input clock */
- imx334->inclk = devm_clk_get(imx334->dev, NULL);
+ imx334->inclk = devm_v4l2_sensor_clk_get(imx334->dev, NULL);
if (IS_ERR(imx334->inclk))
return dev_err_probe(imx334->dev, PTR_ERR(imx334->inclk),
"could not get inclk\n");
@@ -1070,6 +1079,10 @@ static int imx334_power_on(struct device *dev)
struct imx334 *imx334 = to_imx334(sd);
int ret;
+ /*
+ * Note: Misinterpretation of reset assertion - do not re-use this code.
+ * XCLR pin is using incorrect (for reset signal) logical level.
+ */
gpiod_set_value_cansleep(imx334->reset_gpio, 1);
ret = clk_prepare_enable(imx334->inclk);
diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c
index 9b4db4cd4929..c043df2f15fb 100644
--- a/drivers/media/i2c/imx335.c
+++ b/drivers/media/i2c/imx335.c
@@ -1026,11 +1026,10 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
}
/* Get sensor input clock */
- imx335->inclk = devm_clk_get(imx335->dev, NULL);
- if (IS_ERR(imx335->inclk)) {
- dev_err(imx335->dev, "could not get inclk\n");
- return PTR_ERR(imx335->inclk);
- }
+ imx335->inclk = devm_v4l2_sensor_clk_get(imx335->dev, NULL);
+ if (IS_ERR(imx335->inclk))
+ return dev_err_probe(imx335->dev, PTR_ERR(imx335->inclk),
+ "could not get inclk\n");
rate = clk_get_rate(imx335->inclk);
if (rate != IMX335_INCLK_RATE) {
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index b2dce67c0b6b..776107efe386 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -1,11 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 Intel Corporation
-#include <linux/unaligned.h>
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
@@ -92,11 +94,13 @@ struct imx355_mode {
};
struct imx355_hwcfg {
- u32 ext_clk; /* sensor external clk */
unsigned long link_freq_bitmap;
};
struct imx355 {
+ struct device *dev;
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -1136,14 +1140,13 @@ static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
static int imx355_write_regs(struct imx355 *imx355,
const struct imx355_reg *regs, u32 len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
int ret;
u32 i;
for (i = 0; i < len; i++) {
ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(imx355->dev,
"write reg 0x%4.4x return err %d",
regs[i].address, ret);
@@ -1178,7 +1181,6 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct imx355 *imx355 = container_of(ctrl->handler,
struct imx355, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
s64 max;
int ret;
@@ -1197,7 +1199,7 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(imx355->dev))
return 0;
switch (ctrl->id) {
@@ -1231,12 +1233,12 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
break;
default:
ret = -EINVAL;
- dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
+ dev_info(imx355->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx355->dev);
return ret;
}
@@ -1385,7 +1387,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
/* Start streaming */
static int imx355_start_streaming(struct imx355 *imx355)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
const struct imx355_reg_list *reg_list;
int ret;
@@ -1393,7 +1394,7 @@ static int imx355_start_streaming(struct imx355 *imx355)
reg_list = &imx355_global_setting;
ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
if (ret) {
- dev_err(&client->dev, "failed to set global settings");
+ dev_err(imx355->dev, "failed to set global settings");
return ret;
}
@@ -1401,7 +1402,7 @@ static int imx355_start_streaming(struct imx355 *imx355)
reg_list = &imx355->cur_mode->reg_list;
ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(imx355->dev, "failed to set mode");
return ret;
}
@@ -1429,13 +1430,12 @@ static int imx355_stop_streaming(struct imx355 *imx355)
static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
{
struct imx355 *imx355 = to_imx355(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&imx355->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(imx355->dev);
if (ret < 0)
goto err_unlock;
@@ -1448,7 +1448,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
imx355_stop_streaming(imx355);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx355->dev);
}
/* vflip and hflip cannot change during streaming */
@@ -1460,7 +1460,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(imx355->dev);
err_unlock:
mutex_unlock(&imx355->mutex);
@@ -1470,7 +1470,6 @@ err_unlock:
/* Verify chip ID */
static int imx355_identify_module(struct imx355 *imx355)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
int ret;
u32 val;
@@ -1479,7 +1478,7 @@ static int imx355_identify_module(struct imx355 *imx355)
return ret;
if (val != IMX355_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(imx355->dev, "chip id mismatch: %x!=%x",
IMX355_CHIP_ID, val);
return -EIO;
}
@@ -1519,7 +1518,6 @@ static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
/* Initialize control handlers */
static int imx355_init_controls(struct imx355 *imx355)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max;
@@ -1600,11 +1598,11 @@ static int imx355_init_controls(struct imx355 *imx355)
0, 0, imx355_test_pattern_menu);
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "control init failed: %d", ret);
+ dev_err(imx355->dev, "control init failed: %d", ret);
goto error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(imx355->dev, &props);
if (ret)
goto error;
@@ -1648,20 +1646,6 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
if (!cfg)
goto out_err;
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &cfg->ext_clk);
- if (ret) {
- dev_err(dev, "can't get clock frequency");
- goto out_err;
- }
-
- dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
- if (cfg->ext_clk != IMX355_EXT_CLK) {
- dev_err(dev, "external clock %d is not supported",
- cfg->ext_clk);
- goto out_err;
- }
-
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_freq_menu_items,
@@ -1683,27 +1667,41 @@ out_err:
static int imx355_probe(struct i2c_client *client)
{
struct imx355 *imx355;
+ unsigned long freq;
int ret;
imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
if (!imx355)
return -ENOMEM;
+ imx355->dev = &client->dev;
+
mutex_init(&imx355->mutex);
+ imx355->clk = devm_v4l2_sensor_clk_get(imx355->dev, NULL);
+ if (IS_ERR(imx355->clk))
+ return dev_err_probe(imx355->dev, PTR_ERR(imx355->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(imx355->clk);
+ if (freq != IMX355_EXT_CLK)
+ return dev_err_probe(imx355->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
/* Check module identity */
ret = imx355_identify_module(imx355);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(imx355->dev, "failed to find sensor: %d", ret);
goto error_probe;
}
- imx355->hwcfg = imx355_get_hwcfg(&client->dev);
+ imx355->hwcfg = imx355_get_hwcfg(imx355->dev);
if (!imx355->hwcfg) {
- dev_err(&client->dev, "failed to get hwcfg");
+ dev_err(imx355->dev, "failed to get hwcfg");
ret = -ENODEV;
goto error_probe;
}
@@ -1713,7 +1711,7 @@ static int imx355_probe(struct i2c_client *client)
ret = imx355_init_controls(imx355);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(imx355->dev, "failed to init controls: %d", ret);
goto error_probe;
}
@@ -1728,7 +1726,7 @@ static int imx355_probe(struct i2c_client *client)
imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(imx355->dev, "failed to init entity pads: %d", ret);
goto error_handler_free;
}
@@ -1736,9 +1734,9 @@ static int imx355_probe(struct i2c_client *client)
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(imx355->dev);
+ pm_runtime_enable(imx355->dev);
+ pm_runtime_idle(imx355->dev);
ret = v4l2_async_register_subdev_sensor(&imx355->sd);
if (ret < 0)
@@ -1747,8 +1745,8 @@ static int imx355_probe(struct i2c_client *client)
return 0;
error_media_entity_runtime_pm:
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(imx355->dev);
+ pm_runtime_set_suspended(imx355->dev);
media_entity_cleanup(&imx355->sd.entity);
error_handler_free:
@@ -1769,8 +1767,8 @@ static void imx355_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(imx355->dev);
+ pm_runtime_set_suspended(imx355->dev);
mutex_destroy(&imx355->mutex);
}
diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c
index c74097a59c42..7bbd639a9ddf 100644
--- a/drivers/media/i2c/imx412.c
+++ b/drivers/media/i2c/imx412.c
@@ -933,11 +933,10 @@ static int imx412_parse_hw_config(struct imx412 *imx412)
}
/* Get sensor input clock */
- imx412->inclk = devm_clk_get(imx412->dev, NULL);
- if (IS_ERR(imx412->inclk)) {
- dev_err(imx412->dev, "could not get inclk\n");
- return PTR_ERR(imx412->inclk);
- }
+ imx412->inclk = devm_v4l2_sensor_clk_get(imx412->dev, NULL);
+ if (IS_ERR(imx412->inclk))
+ return dev_err_probe(imx412->dev, PTR_ERR(imx412->inclk),
+ "could not get inclk\n");
rate = clk_get_rate(imx412->inclk);
if (rate != IMX412_INCLK_RATE) {
diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c
index 276bf4d6f39d..0b424c17e880 100644
--- a/drivers/media/i2c/imx415.c
+++ b/drivers/media/i2c/imx415.c
@@ -1250,7 +1250,7 @@ static int imx415_parse_hw_config(struct imx415 *sensor)
return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
"failed to get reset GPIO\n");
- sensor->clk = devm_clk_get(sensor->dev, NULL);
+ sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, NULL);
if (IS_ERR(sensor->clk))
return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
"failed to get clock\n");
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index c84e1e0e6109..5588cdd7ec20 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -321,9 +321,9 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
static int ir_key_poll(struct IR_i2c *ir)
{
- enum rc_proto protocol;
- u32 scancode;
- u8 toggle;
+ enum rc_proto protocol = 0;
+ u32 scancode = 0;
+ u8 toggle = 0;
int rc;
dev_dbg(&ir->rc->dev, "%s\n", __func__);
diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c
index 12d3e86bdc0f..7a6114d18dfc 100644
--- a/drivers/media/i2c/mt9m001.c
+++ b/drivers/media/i2c/mt9m001.c
@@ -743,9 +743,10 @@ static int mt9m001_probe(struct i2c_client *client)
if (!mt9m001)
return -ENOMEM;
- mt9m001->clk = devm_clk_get(&client->dev, NULL);
+ mt9m001->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
if (IS_ERR(mt9m001->clk))
- return PTR_ERR(mt9m001->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(mt9m001->clk),
+ "failed to get the clock\n");
mt9m001->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby",
GPIOD_OUT_LOW);
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index 9aa5dcda3805..05dcf37c6f01 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -1279,9 +1279,10 @@ static int mt9m111_probe(struct i2c_client *client)
return ret;
}
- mt9m111->clk = devm_clk_get(&client->dev, "mclk");
+ mt9m111->clk = devm_v4l2_sensor_clk_get(&client->dev, "mclk");
if (IS_ERR(mt9m111->clk))
- return PTR_ERR(mt9m111->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(mt9m111->clk),
+ "failed to get mclk\n");
mt9m111->regulator = devm_regulator_get(&client->dev, "vdd");
if (IS_ERR(mt9m111->regulator)) {
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index aa3fd6c6c76c..51ebbe7ae996 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
@@ -42,6 +43,9 @@
#define MT9M114_RESET_AND_MISC_CONTROL CCI_REG16(0x001a)
#define MT9M114_RESET_SOC BIT(0)
#define MT9M114_PAD_SLEW CCI_REG16(0x001e)
+#define MT9M114_PAD_SLEW_MIN 0
+#define MT9M114_PAD_SLEW_MAX 7
+#define MT9M114_PAD_SLEW_DEFAULT 7
#define MT9M114_PAD_CONTROL CCI_REG16(0x0032)
/* XDMA registers */
@@ -388,6 +392,7 @@ struct mt9m114 {
unsigned int pixrate;
bool streaming;
+ u32 pad_slew_rate;
/* Pixel Array */
struct {
@@ -645,9 +650,6 @@ static const struct cci_reg_sequence mt9m114_init[] = {
{ MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX, 1459 },
{ MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION, 96 },
{ MT9M114_CAM_SENSOR_CFG_REG_0_DATA, 32 },
-
- /* Miscellaneous settings */
- { MT9M114_PAD_SLEW, 0x0777 },
};
/* -----------------------------------------------------------------------------
@@ -779,6 +781,13 @@ static int mt9m114_initialize(struct mt9m114 *sensor)
if (ret < 0)
return ret;
+ value = sensor->pad_slew_rate
+ | sensor->pad_slew_rate << 4
+ | sensor->pad_slew_rate << 8;
+ cci_write(sensor->regmap, MT9M114_PAD_SLEW, value, &ret);
+ if (ret < 0)
+ return ret;
+
ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
if (ret < 0)
return ret;
@@ -1283,6 +1292,7 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
struct mt9m114 *sensor = pa_to_mt9m114(sd);
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
+ int ret = 0;
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
@@ -1298,25 +1308,41 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
* binning, but binning is configured after setting the selection, so
* we can't know tell here if it will be used.
*/
- crop->left = ALIGN(sel->r.left, 4);
- crop->top = ALIGN(sel->r.top, 2);
- crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 4),
- MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH,
- MT9M114_PIXEL_ARRAY_WIDTH - crop->left);
- crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
- MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT,
- MT9M114_PIXEL_ARRAY_HEIGHT - crop->top);
-
- sel->r = *crop;
+ sel->r.left = ALIGN(sel->r.left, 4);
+ sel->r.top = ALIGN(sel->r.top, 2);
+ sel->r.width = clamp_t(unsigned int, ALIGN(sel->r.width, 4),
+ MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH,
+ MT9M114_PIXEL_ARRAY_WIDTH - sel->r.left);
+ sel->r.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
+ MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT,
+ MT9M114_PIXEL_ARRAY_HEIGHT - sel->r.top);
+
+ /* Changing the selection size is not allowed in streaming state. */
+ if (sensor->streaming &&
+ (sel->r.height != crop->height || sel->r.width != crop->width))
+ return -EBUSY;
+
+ *crop = sel->r;
/* Reset the format. */
format->width = crop->width;
format->height = crop->height;
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- mt9m114_pa_ctrl_update_blanking(sensor, format);
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ret;
- return 0;
+ mt9m114_pa_ctrl_update_blanking(sensor, format);
+
+ /* Apply values immediately if streaming. */
+ if (sensor->streaming) {
+ ret = mt9m114_configure_pa(sensor, state);
+ if (ret)
+ return ret;
+ /* Changing the cropping config requires a CONFIG_CHANGE. */
+ ret = mt9m114_set_state(sensor,
+ MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
+ }
+ return ret;
}
static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = {
@@ -2360,6 +2386,17 @@ static int mt9m114_parse_dt(struct mt9m114 *sensor)
goto error;
}
+ sensor->pad_slew_rate = MT9M114_PAD_SLEW_DEFAULT;
+ device_property_read_u32(&sensor->client->dev, "slew-rate",
+ &sensor->pad_slew_rate);
+
+ if (sensor->pad_slew_rate < MT9M114_PAD_SLEW_MIN ||
+ sensor->pad_slew_rate > MT9M114_PAD_SLEW_MAX) {
+ dev_err(&sensor->client->dev, "Invalid slew-rate %u\n",
+ sensor->pad_slew_rate);
+ return -EINVAL;
+ }
+
return 0;
error:
@@ -2390,10 +2427,10 @@ static int mt9m114_probe(struct i2c_client *client)
return ret;
/* Acquire clocks, GPIOs and regulators. */
- sensor->clk = devm_clk_get(dev, NULL);
+ sensor->clk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(sensor->clk)) {
- ret = PTR_ERR(sensor->clk);
- dev_err_probe(dev, ret, "Failed to get clock\n");
+ ret = dev_err_probe(dev, PTR_ERR(sensor->clk),
+ "Failed to get clock\n");
goto error_ep_free;
}
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 4ef5fb06131d..1500ee4db47e 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -233,9 +233,10 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
unsigned long ext_freq;
int ret;
- mt9p031->clk = devm_clk_get(&client->dev, NULL);
+ mt9p031->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
if (IS_ERR(mt9p031->clk))
- return PTR_ERR(mt9p031->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(mt9p031->clk),
+ "failed to get the clock\n");
ret = clk_set_rate(mt9p031->clk, mt9p031->ext_freq);
if (ret < 0)
@@ -1092,6 +1093,7 @@ static int mt9p031_parse_properties(struct mt9p031 *mt9p031, struct device *dev)
static int mt9p031_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
+ const struct mt9p031_model_info *info;
struct mt9p031 *mt9p031;
unsigned int i;
int ret;
@@ -1112,7 +1114,8 @@ static int mt9p031_probe(struct i2c_client *client)
mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
- mt9p031->code = (uintptr_t)device_get_match_data(&client->dev);
+ info = device_get_match_data(&client->dev);
+ mt9p031->code = info->code;
mt9p031->regulators[0].supply = "vdd";
mt9p031->regulators[1].supply = "vdd_io";
diff --git a/drivers/media/i2c/mt9t112.c b/drivers/media/i2c/mt9t112.c
index 878dff9b7577..2d2c840fc002 100644
--- a/drivers/media/i2c/mt9t112.c
+++ b/drivers/media/i2c/mt9t112.c
@@ -1078,13 +1078,12 @@ static int mt9t112_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
- priv->clk = devm_clk_get(&client->dev, "extclk");
- if (PTR_ERR(priv->clk) == -ENOENT) {
+ priv->clk = devm_v4l2_sensor_clk_get(&client->dev, "extclk");
+ if (PTR_ERR(priv->clk) == -ENOENT)
priv->clk = NULL;
- } else if (IS_ERR(priv->clk)) {
- dev_err(&client->dev, "Unable to get clock \"extclk\"\n");
- return PTR_ERR(priv->clk);
- }
+ else if (IS_ERR(priv->clk))
+ return dev_err_probe(&client->dev, PTR_ERR(priv->clk),
+ "Unable to get clock \"extclk\"\n");
priv->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby",
GPIOD_OUT_HIGH);
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 302120ff125e..d4359d5b92bb 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -15,16 +15,15 @@
#include <linux/i2c.h>
#include <linux/log2.h>
#include <linux/mod_devicetable.h>
+#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/regmap.h>
#include <linux/slab.h>
-#include <linux/videodev2.h>
#include <linux/v4l2-mediabus.h>
-#include <linux/module.h>
+#include <linux/videodev2.h>
-#include <media/i2c/mt9v032.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -182,7 +181,16 @@ static const struct mt9v032_model_version mt9v032_versions[] = {
{ MT9V034_CHIP_ID_REV1, "MT9V024/MT9V034 rev1" },
};
+struct mt9v032_platform_data {
+ unsigned int clk_pol:1;
+
+ const s64 *link_freqs;
+ s64 link_def_freq;
+};
+
struct mt9v032 {
+ struct device *dev;
+
struct v4l2_subdev subdev;
struct media_pad pad;
@@ -205,7 +213,7 @@ struct mt9v032 {
struct gpio_desc *reset_gpio;
struct gpio_desc *standby_gpio;
- struct mt9v032_platform_data *pdata;
+ struct mt9v032_platform_data pdata;
const struct mt9v032_model_info *model;
const struct mt9v032_model_version *version;
@@ -330,7 +338,7 @@ static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
return ret;
/* Configure the pixel clock polarity */
- if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
+ if (mt9v032->pdata.clk_pol) {
ret = regmap_write(map, mt9v032->model->data->pclk_reg,
MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
if (ret < 0)
@@ -473,13 +481,12 @@ static int mt9v032_get_format(struct v4l2_subdev *subdev,
static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032)
{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
int ret;
ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate,
mt9v032->sysclk / mt9v032->hratio);
if (ret < 0)
- dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret);
+ dev_warn(mt9v032->dev, "failed to set pixel rate (%d)\n", ret);
}
static unsigned int mt9v032_calc_ratio(unsigned int input, unsigned int output)
@@ -682,7 +689,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
if (mt9v032->link_freq == NULL)
break;
- freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
+ freq = mt9v032->pdata.link_freqs[mt9v032->link_freq->val];
*mt9v032->pixel_rate->p_new.p_s64 = freq;
mt9v032->sysclk = freq;
break;
@@ -883,12 +890,12 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
u32 version;
int ret;
- dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
+ dev_info(mt9v032->dev, "Probing MT9V032 at address 0x%02x\n",
client->addr);
ret = mt9v032_power_on(mt9v032);
if (ret < 0) {
- dev_err(&client->dev, "MT9V032 power up failed\n");
+ dev_err(mt9v032->dev, "MT9V032 power up failed\n");
return ret;
}
@@ -898,7 +905,7 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
mt9v032_power_off(mt9v032);
if (ret < 0) {
- dev_err(&client->dev, "Failed reading chip version\n");
+ dev_err(mt9v032->dev, "Failed reading chip version\n");
return ret;
}
@@ -910,12 +917,12 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
}
if (mt9v032->version == NULL) {
- dev_err(&client->dev, "Unsupported chip version 0x%04x\n",
+ dev_err(mt9v032->dev, "Unsupported chip version 0x%04x\n",
version);
return -ENODEV;
}
- dev_info(&client->dev, "%s detected at address 0x%02x\n",
+ dev_info(mt9v032->dev, "%s detected at address 0x%02x\n",
mt9v032->version->name, client->addr);
mt9v032_configure_pixel_rate(mt9v032);
@@ -995,41 +1002,33 @@ static const struct regmap_config mt9v032_regmap_config = {
* Driver initialization and probing
*/
-static struct mt9v032_platform_data *
-mt9v032_get_pdata(struct i2c_client *client)
+static int mt9v032_get_pdata(struct mt9v032 *mt9v032)
{
- struct mt9v032_platform_data *pdata = NULL;
+ struct mt9v032_platform_data *pdata = &mt9v032->pdata;
struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
- struct device_node *np;
+ struct device_node *np __free(device_node) = NULL;
struct property *prop;
- if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
- return client->dev.platform_data;
-
- np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
+ np = of_graph_get_endpoint_by_regs(mt9v032->dev->of_node, 0, -1);
if (!np)
- return NULL;
+ return -EINVAL;
if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &endpoint) < 0)
- goto done;
-
- pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- goto done;
+ return -EINVAL;
prop = of_find_property(np, "link-frequencies", NULL);
if (prop) {
u64 *link_freqs;
size_t size = prop->length / sizeof(*link_freqs);
- link_freqs = devm_kcalloc(&client->dev, size,
+ link_freqs = devm_kcalloc(mt9v032->dev, size,
sizeof(*link_freqs), GFP_KERNEL);
if (!link_freqs)
- goto done;
+ return -EINVAL;
if (of_property_read_u64_array(np, "link-frequencies",
link_freqs, size) < 0)
- goto done;
+ return -EINVAL;
pdata->link_freqs = link_freqs;
pdata->link_def_freq = link_freqs[0];
@@ -1038,14 +1037,11 @@ mt9v032_get_pdata(struct i2c_client *client)
pdata->clk_pol = !!(endpoint.bus.parallel.flags &
V4L2_MBUS_PCLK_SAMPLE_RISING);
-done:
- of_node_put(np);
- return pdata;
+ return 0;
}
static int mt9v032_probe(struct i2c_client *client)
{
- struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client);
struct mt9v032 *mt9v032;
unsigned int i;
int ret;
@@ -1054,27 +1050,35 @@ static int mt9v032_probe(struct i2c_client *client)
if (!mt9v032)
return -ENOMEM;
+ mt9v032->dev = &client->dev;
+
mt9v032->regmap = devm_regmap_init_i2c(client, &mt9v032_regmap_config);
if (IS_ERR(mt9v032->regmap))
return PTR_ERR(mt9v032->regmap);
- mt9v032->clk = devm_clk_get(&client->dev, NULL);
+ mt9v032->clk = devm_v4l2_sensor_clk_get(mt9v032->dev, NULL);
if (IS_ERR(mt9v032->clk))
- return PTR_ERR(mt9v032->clk);
+ return dev_err_probe(mt9v032->dev, PTR_ERR(mt9v032->clk),
+ "failed to get the clock\n");
- mt9v032->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ mt9v032->reset_gpio = devm_gpiod_get_optional(mt9v032->dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(mt9v032->reset_gpio))
return PTR_ERR(mt9v032->reset_gpio);
- mt9v032->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby",
+ mt9v032->standby_gpio = devm_gpiod_get_optional(mt9v032->dev, "standby",
GPIOD_OUT_LOW);
if (IS_ERR(mt9v032->standby_gpio))
return PTR_ERR(mt9v032->standby_gpio);
mutex_init(&mt9v032->power_lock);
- mt9v032->pdata = pdata;
- mt9v032->model = i2c_get_match_data(client);
+
+ ret = mt9v032_get_pdata(mt9v032);
+ if (ret)
+ return dev_err_probe(mt9v032->dev, -EINVAL,
+ "Failed to parse DT properties\n");
+
+ mt9v032->model = device_get_match_data(mt9v032->dev);
v4l2_ctrl_handler_init(&mt9v032->ctrls, 11 +
ARRAY_SIZE(mt9v032_aegc_controls));
@@ -1119,7 +1123,8 @@ static int mt9v032_probe(struct i2c_client *client)
v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
- if (pdata && pdata->link_freqs) {
+ if (mt9v032->pdata.link_freqs) {
+ const struct mt9v032_platform_data *pdata = &mt9v032->pdata;
unsigned int def = 0;
for (i = 0; pdata->link_freqs[i]; ++i) {
@@ -1139,7 +1144,7 @@ static int mt9v032_probe(struct i2c_client *client)
mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
if (mt9v032->ctrls.error) {
- dev_err(&client->dev, "control initialization error %d\n",
+ dev_err(mt9v032->dev, "control initialization error %d\n",
mt9v032->ctrls.error);
ret = mt9v032->ctrls.error;
goto err;
@@ -1177,7 +1182,7 @@ static int mt9v032_probe(struct i2c_client *client)
if (ret < 0)
goto err;
- mt9v032->subdev.dev = &client->dev;
+ mt9v032->subdev.dev = mt9v032->dev;
ret = v4l2_async_register_subdev(&mt9v032->subdev);
if (ret < 0)
goto err;
@@ -1261,19 +1266,6 @@ static const struct mt9v032_model_info mt9v032_models[] = {
},
};
-static const struct i2c_device_id mt9v032_id[] = {
- { "mt9v022", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_COLOR] },
- { "mt9v022m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_MONO] },
- { "mt9v024", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_COLOR] },
- { "mt9v024m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_MONO] },
- { "mt9v032", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_COLOR] },
- { "mt9v032m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_MONO] },
- { "mt9v034", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_COLOR] },
- { "mt9v034m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_MONO] },
- { /* Sentinel */ }
-};
-MODULE_DEVICE_TABLE(i2c, mt9v032_id);
-
static const struct of_device_id mt9v032_of_match[] = {
{ .compatible = "aptina,mt9v022", .data = &mt9v032_models[MT9V032_MODEL_V022_COLOR] },
{ .compatible = "aptina,mt9v022m", .data = &mt9v032_models[MT9V032_MODEL_V022_MONO] },
@@ -1294,7 +1286,6 @@ static struct i2c_driver mt9v032_driver = {
},
.probe = mt9v032_probe,
.remove = mt9v032_remove,
- .id_table = mt9v032_id,
};
module_i2c_driver(mt9v032_driver);
diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c
index 723fe138e7bc..b4f2703faa18 100644
--- a/drivers/media/i2c/mt9v111.c
+++ b/drivers/media/i2c/mt9v111.c
@@ -365,8 +365,6 @@ static int __mt9v111_power_on(struct v4l2_subdev *sd)
if (ret)
return ret;
- clk_set_rate(mt9v111->clk, mt9v111->sysclk);
-
gpiod_set_value(mt9v111->standby, 0);
usleep_range(500, 1000);
@@ -532,8 +530,8 @@ static int mt9v111_calc_frame_rate(struct mt9v111_dev *mt9v111,
static int mt9v111_hw_config(struct mt9v111_dev *mt9v111)
{
struct i2c_client *c = mt9v111->client;
- unsigned int ret;
u16 outfmtctrl2;
+ int ret;
/* Force device reset. */
ret = __mt9v111_hw_reset(mt9v111);
@@ -1129,9 +1127,10 @@ static int mt9v111_probe(struct i2c_client *client)
mt9v111->dev = &client->dev;
mt9v111->client = client;
- mt9v111->clk = devm_clk_get(&client->dev, NULL);
+ mt9v111->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
if (IS_ERR(mt9v111->clk))
- return PTR_ERR(mt9v111->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(mt9v111->clk),
+ "failed to get the clock\n");
mt9v111->sysclk = clk_get_rate(mt9v111->clk);
if (mt9v111->sysclk > MT9V111_MAX_CLKIN)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 78d5d406e4b7..c7184de6251a 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -10,6 +9,8 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -421,6 +422,7 @@ static const struct og01a1b_mode supported_modes[] = {
};
struct og01a1b {
+ struct device *dev;
struct clk *xvclk;
struct gpio_desc *reset_gpio;
struct regulator *avdd;
@@ -512,7 +514,6 @@ static int og01a1b_write_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 val)
static int og01a1b_write_reg_list(struct og01a1b *og01a1b,
const struct og01a1b_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
unsigned int i;
int ret;
@@ -520,7 +521,7 @@ static int og01a1b_write_reg_list(struct og01a1b *og01a1b,
ret = og01a1b_write_reg(og01a1b, r_list->regs[i].address, 1,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(og01a1b->dev,
"failed to write reg 0x%4.4x. error = %d",
r_list->regs[i].address, ret);
return ret;
@@ -544,7 +545,6 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct og01a1b *og01a1b = container_of(ctrl->handler,
struct og01a1b, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
s64 exposure_max;
int ret = 0;
@@ -560,7 +560,7 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(og01a1b->dev))
return 0;
switch (ctrl->id) {
@@ -596,7 +596,7 @@ static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(og01a1b->dev);
return ret;
}
@@ -682,13 +682,12 @@ static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,
{
fmt->width = mode->width;
fmt->height = mode->height;
- fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ fmt->code = MEDIA_BUS_FMT_Y10_1X10;
fmt->field = V4L2_FIELD_NONE;
}
static int og01a1b_start_streaming(struct og01a1b *og01a1b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
const struct og01a1b_reg_list *reg_list;
int link_freq_index, ret;
@@ -697,14 +696,14 @@ static int og01a1b_start_streaming(struct og01a1b *og01a1b)
ret = og01a1b_write_reg_list(og01a1b, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls");
+ dev_err(og01a1b->dev, "failed to set plls");
return ret;
}
reg_list = &og01a1b->cur_mode->reg_list;
ret = og01a1b_write_reg_list(og01a1b, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(og01a1b->dev, "failed to set mode");
return ret;
}
@@ -716,7 +715,7 @@ static int og01a1b_start_streaming(struct og01a1b *og01a1b)
OG01A1B_REG_VALUE_08BIT,
OG01A1B_MODE_STREAMING);
if (ret) {
- dev_err(&client->dev, "failed to set stream");
+ dev_err(og01a1b->dev, "failed to set stream");
return ret;
}
@@ -725,22 +724,19 @@ static int og01a1b_start_streaming(struct og01a1b *og01a1b)
static void og01a1b_stop_streaming(struct og01a1b *og01a1b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
-
if (og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY))
- dev_err(&client->dev, "failed to set stream");
+ dev_err(og01a1b->dev, "failed to set stream");
}
static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)
{
struct og01a1b *og01a1b = to_og01a1b(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&og01a1b->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(og01a1b->dev);
if (ret) {
mutex_unlock(&og01a1b->mutex);
return ret;
@@ -750,11 +746,11 @@ static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
og01a1b_stop_streaming(og01a1b);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(og01a1b->dev);
}
} else {
og01a1b_stop_streaming(og01a1b);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(og01a1b->dev);
}
mutex_unlock(&og01a1b->mutex);
@@ -828,7 +824,7 @@ static int og01a1b_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index > 0)
return -EINVAL;
- code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ code->code = MEDIA_BUS_FMT_Y10_1X10;
return 0;
}
@@ -840,7 +836,7 @@ static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,
if (fse->index >= ARRAY_SIZE(supported_modes))
return -EINVAL;
- if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+ if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
return -EINVAL;
fse->min_width = supported_modes[fse->index].width;
@@ -889,7 +885,6 @@ static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = {
static int og01a1b_identify_module(struct og01a1b *og01a1b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
int ret;
u32 val;
@@ -899,7 +894,7 @@ static int og01a1b_identify_module(struct og01a1b *og01a1b)
return ret;
if (val != OG01A1B_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(og01a1b->dev, "chip id mismatch: %x!=%x",
OG01A1B_CHIP_ID, val);
return -ENXIO;
}
@@ -909,35 +904,18 @@ static int og01a1b_identify_module(struct og01a1b *og01a1b)
static int og01a1b_check_hwcfg(struct og01a1b *og01a1b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
- struct device *dev = &client->dev;
+ struct device *dev = og01a1b->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
- u32 mclk;
int ret;
unsigned int i, j;
if (!fwnode)
return -ENXIO;
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
- if (ret) {
- if (!og01a1b->xvclk) {
- dev_err(dev, "can't get clock frequency");
- return ret;
- }
-
- mclk = clk_get_rate(og01a1b->xvclk);
- }
-
- if (mclk != OG01A1B_MCLK) {
- dev_err(dev, "external clock %d is not supported", mclk);
- return -EINVAL;
- }
-
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
return -ENXIO;
@@ -1066,47 +1044,54 @@ static void og01a1b_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(og01a1b->dev);
mutex_destroy(&og01a1b->mutex);
}
static int og01a1b_probe(struct i2c_client *client)
{
struct og01a1b *og01a1b;
+ unsigned long freq;
int ret;
og01a1b = devm_kzalloc(&client->dev, sizeof(*og01a1b), GFP_KERNEL);
if (!og01a1b)
return -ENOMEM;
+ og01a1b->dev = &client->dev;
+
v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops);
- og01a1b->xvclk = devm_clk_get_optional(&client->dev, NULL);
- if (IS_ERR(og01a1b->xvclk)) {
- ret = PTR_ERR(og01a1b->xvclk);
- dev_err(&client->dev, "failed to get xvclk clock: %d\n", ret);
- return ret;
- }
+ og01a1b->xvclk = devm_v4l2_sensor_clk_get(og01a1b->dev, NULL);
+ if (IS_ERR(og01a1b->xvclk))
+ return dev_err_probe(og01a1b->dev, PTR_ERR(og01a1b->xvclk),
+ "failed to get xvclk clock\n");
+
+ freq = clk_get_rate(og01a1b->xvclk);
+ if (freq != OG01A1B_MCLK)
+ return dev_err_probe(og01a1b->dev, -EINVAL,
+ "external clock %lu is not supported",
+ freq);
ret = og01a1b_check_hwcfg(og01a1b);
if (ret) {
- dev_err(&client->dev, "failed to check HW configuration: %d",
+ dev_err(og01a1b->dev, "failed to check HW configuration: %d",
ret);
return ret;
}
- og01a1b->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ og01a1b->reset_gpio = devm_gpiod_get_optional(og01a1b->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(og01a1b->reset_gpio)) {
- dev_err(&client->dev, "cannot get reset GPIO\n");
+ dev_err(og01a1b->dev, "cannot get reset GPIO\n");
return PTR_ERR(og01a1b->reset_gpio);
}
- og01a1b->avdd = devm_regulator_get_optional(&client->dev, "avdd");
+ og01a1b->avdd = devm_regulator_get_optional(og01a1b->dev, "avdd");
if (IS_ERR(og01a1b->avdd)) {
ret = PTR_ERR(og01a1b->avdd);
if (ret != -ENODEV) {
- dev_err_probe(&client->dev, ret,
+ dev_err_probe(og01a1b->dev, ret,
"Failed to get 'avdd' regulator\n");
return ret;
}
@@ -1114,11 +1099,11 @@ static int og01a1b_probe(struct i2c_client *client)
og01a1b->avdd = NULL;
}
- og01a1b->dovdd = devm_regulator_get_optional(&client->dev, "dovdd");
+ og01a1b->dovdd = devm_regulator_get_optional(og01a1b->dev, "dovdd");
if (IS_ERR(og01a1b->dovdd)) {
ret = PTR_ERR(og01a1b->dovdd);
if (ret != -ENODEV) {
- dev_err_probe(&client->dev, ret,
+ dev_err_probe(og01a1b->dev, ret,
"Failed to get 'dovdd' regulator\n");
return ret;
}
@@ -1126,11 +1111,11 @@ static int og01a1b_probe(struct i2c_client *client)
og01a1b->dovdd = NULL;
}
- og01a1b->dvdd = devm_regulator_get_optional(&client->dev, "dvdd");
+ og01a1b->dvdd = devm_regulator_get_optional(og01a1b->dev, "dvdd");
if (IS_ERR(og01a1b->dvdd)) {
ret = PTR_ERR(og01a1b->dvdd);
if (ret != -ENODEV) {
- dev_err_probe(&client->dev, ret,
+ dev_err_probe(og01a1b->dev, ret,
"Failed to get 'dvdd' regulator\n");
return ret;
}
@@ -1139,13 +1124,13 @@ static int og01a1b_probe(struct i2c_client *client)
}
/* The sensor must be powered on to read the CHIP_ID register */
- ret = og01a1b_power_on(&client->dev);
+ ret = og01a1b_power_on(og01a1b->dev);
if (ret)
return ret;
ret = og01a1b_identify_module(og01a1b);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(og01a1b->dev, "failed to find sensor: %d", ret);
goto power_off;
}
@@ -1153,7 +1138,7 @@ static int og01a1b_probe(struct i2c_client *client)
og01a1b->cur_mode = &supported_modes[0];
ret = og01a1b_init_controls(og01a1b);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(og01a1b->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -1164,21 +1149,21 @@ static int og01a1b_probe(struct i2c_client *client)
og01a1b->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&og01a1b->sd.entity, 1, &og01a1b->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(og01a1b->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&og01a1b->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(og01a1b->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_media_entity_cleanup;
}
/* Enable runtime PM and turn off the device */
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(og01a1b->dev);
+ pm_runtime_enable(og01a1b->dev);
+ pm_runtime_idle(og01a1b->dev);
return 0;
@@ -1190,7 +1175,7 @@ probe_error_v4l2_ctrl_handler_free:
mutex_destroy(&og01a1b->mutex);
power_off:
- og01a1b_power_off(&client->dev);
+ og01a1b_power_off(og01a1b->dev);
return ret;
}
diff --git a/drivers/media/i2c/og0ve1b.c b/drivers/media/i2c/og0ve1b.c
new file mode 100644
index 000000000000..262d9df766fe
--- /dev/null
+++ b/drivers/media/i2c/og0ve1b.c
@@ -0,0 +1,816 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2024-2025 Linaro Ltd
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/units.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define OG0VE1B_LINK_FREQ_500MHZ (500 * HZ_PER_MHZ)
+#define OG0VE1B_MCLK_FREQ_24MHZ (24 * HZ_PER_MHZ)
+
+#define OG0VE1B_REG_CHIP_ID CCI_REG24(0x300a)
+#define OG0VE1B_CHIP_ID 0xc75645
+
+#define OG0VE1B_REG_MODE_SELECT CCI_REG8(0x0100)
+#define OG0VE1B_MODE_STANDBY 0x00
+#define OG0VE1B_MODE_STREAMING BIT(0)
+
+#define OG0VE1B_REG_SOFTWARE_RST CCI_REG8(0x0103)
+#define OG0VE1B_SOFTWARE_RST BIT(0)
+
+/* Exposure controls from sensor */
+#define OG0VE1B_REG_EXPOSURE CCI_REG24(0x3500)
+#define OG0VE1B_EXPOSURE_MIN 1
+#define OG0VE1B_EXPOSURE_MAX_MARGIN 14
+#define OG0VE1B_EXPOSURE_STEP 1
+#define OG0VE1B_EXPOSURE_DEFAULT 554
+
+/* Analogue gain controls from sensor */
+#define OG0VE1B_REG_ANALOGUE_GAIN CCI_REG16(0x350a)
+#define OG0VE1B_ANALOGUE_GAIN_MIN 1
+#define OG0VE1B_ANALOGUE_GAIN_MAX 0x1ff
+#define OG0VE1B_ANALOGUE_GAIN_STEP 1
+#define OG0VE1B_ANALOGUE_GAIN_DEFAULT 16
+
+/* Test pattern */
+#define OG0VE1B_REG_PRE_ISP CCI_REG8(0x5e00)
+#define OG0VE1B_TEST_PATTERN_ENABLE BIT(7)
+
+#define to_og0ve1b(_sd) container_of(_sd, struct og0ve1b, sd)
+
+static const s64 og0ve1b_link_freq_menu[] = {
+ OG0VE1B_LINK_FREQ_500MHZ,
+};
+
+struct og0ve1b_reg_list {
+ const struct cci_reg_sequence *regs;
+ unsigned int num_regs;
+};
+
+struct og0ve1b_mode {
+ u32 width; /* Frame width in pixels */
+ u32 height; /* Frame height in pixels */
+ u32 hts; /* Horizontal timing size */
+ u32 vts; /* Default vertical timing size */
+ u32 bpp; /* Bits per pixel */
+
+ const struct og0ve1b_reg_list reg_list; /* Sensor register setting */
+};
+
+static const char * const og0ve1b_test_pattern_menu[] = {
+ "Disabled",
+ "Vertical Colour Bars",
+};
+
+static const char * const og0ve1b_supply_names[] = {
+ "avdd", /* Analog power */
+ "dovdd", /* Digital I/O power */
+ "dvdd", /* Digital core power */
+};
+
+#define OG0VE1B_NUM_SUPPLIES ARRAY_SIZE(og0ve1b_supply_names)
+
+struct og0ve1b {
+ struct device *dev;
+ struct regmap *regmap;
+ struct clk *xvclk;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[OG0VE1B_NUM_SUPPLIES];
+
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ /* Saved register value */
+ u64 pre_isp;
+};
+
+static const struct cci_reg_sequence og0ve1b_640x480_120fps_mode[] = {
+ { CCI_REG8(0x30a0), 0x02 },
+ { CCI_REG8(0x30a1), 0x00 },
+ { CCI_REG8(0x30a2), 0x48 },
+ { CCI_REG8(0x30a3), 0x34 },
+ { CCI_REG8(0x30a4), 0xf7 },
+ { CCI_REG8(0x30a5), 0x00 },
+ { CCI_REG8(0x3082), 0x32 },
+ { CCI_REG8(0x3083), 0x01 },
+ { CCI_REG8(0x301c), 0xf0 },
+ { CCI_REG8(0x301e), 0x0b },
+ { CCI_REG8(0x3106), 0x10 },
+ { CCI_REG8(0x3708), 0x77 },
+ { CCI_REG8(0x3709), 0xf8 },
+ { CCI_REG8(0x3717), 0x00 },
+ { CCI_REG8(0x3782), 0x00 },
+ { CCI_REG8(0x3783), 0x47 },
+ { CCI_REG8(0x37a2), 0x00 },
+ { CCI_REG8(0x3503), 0x07 },
+ { CCI_REG8(0x3509), 0x10 },
+ { CCI_REG8(0x3600), 0x83 },
+ { CCI_REG8(0x3601), 0x21 },
+ { CCI_REG8(0x3602), 0xf1 },
+ { CCI_REG8(0x360a), 0x18 },
+ { CCI_REG8(0x360e), 0xb3 },
+ { CCI_REG8(0x3613), 0x20 },
+ { CCI_REG8(0x366a), 0x78 },
+ { CCI_REG8(0x3706), 0x63 },
+ { CCI_REG8(0x3713), 0x00 },
+ { CCI_REG8(0x3716), 0xb0 },
+ { CCI_REG8(0x37a1), 0x38 },
+ { CCI_REG8(0x3800), 0x00 },
+ { CCI_REG8(0x3801), 0x04 },
+ { CCI_REG8(0x3802), 0x00 },
+ { CCI_REG8(0x3803), 0x04 },
+ { CCI_REG8(0x3804), 0x02 },
+ { CCI_REG8(0x3805), 0x8b },
+ { CCI_REG8(0x3806), 0x01 },
+ { CCI_REG8(0x3807), 0xeb },
+ { CCI_REG8(0x3808), 0x02 }, /* output width */
+ { CCI_REG8(0x3809), 0x80 },
+ { CCI_REG8(0x380a), 0x01 }, /* output height */
+ { CCI_REG8(0x380b), 0xe0 },
+ { CCI_REG8(0x380c), 0x03 }, /* horizontal timing size */
+ { CCI_REG8(0x380d), 0x18 },
+ { CCI_REG8(0x380e), 0x02 }, /* vertical timing size */
+ { CCI_REG8(0x380f), 0x38 },
+ { CCI_REG8(0x3811), 0x04 },
+ { CCI_REG8(0x3813), 0x04 },
+ { CCI_REG8(0x3814), 0x11 },
+ { CCI_REG8(0x3815), 0x11 },
+ { CCI_REG8(0x3820), 0x00 },
+ { CCI_REG8(0x3821), 0x00 },
+ { CCI_REG8(0x3823), 0x04 },
+ { CCI_REG8(0x382a), 0x00 },
+ { CCI_REG8(0x382b), 0x03 },
+ { CCI_REG8(0x3840), 0x00 },
+ { CCI_REG8(0x389e), 0x00 },
+ { CCI_REG8(0x3c05), 0x08 },
+ { CCI_REG8(0x3c26), 0x02 },
+ { CCI_REG8(0x3c27), 0xc0 },
+ { CCI_REG8(0x3c28), 0x00 },
+ { CCI_REG8(0x3c29), 0x40 },
+ { CCI_REG8(0x3c2c), 0x00 },
+ { CCI_REG8(0x3c2d), 0x50 },
+ { CCI_REG8(0x3c2e), 0x02 },
+ { CCI_REG8(0x3c2f), 0x66 },
+ { CCI_REG8(0x3c33), 0x08 },
+ { CCI_REG8(0x3c35), 0x00 },
+ { CCI_REG8(0x3c36), 0x00 },
+ { CCI_REG8(0x3c37), 0x00 },
+ { CCI_REG8(0x3f52), 0x9b },
+ { CCI_REG8(0x4001), 0x42 },
+ { CCI_REG8(0x4004), 0x08 },
+ { CCI_REG8(0x4005), 0x00 },
+ { CCI_REG8(0x4007), 0x28 },
+ { CCI_REG8(0x4009), 0x40 },
+ { CCI_REG8(0x4307), 0x30 },
+ { CCI_REG8(0x4500), 0x80 },
+ { CCI_REG8(0x4501), 0x02 },
+ { CCI_REG8(0x4502), 0x47 },
+ { CCI_REG8(0x4504), 0x7f },
+ { CCI_REG8(0x4601), 0x48 },
+ { CCI_REG8(0x4800), 0x64 },
+ { CCI_REG8(0x4801), 0x0f },
+ { CCI_REG8(0x4806), 0x2f },
+ { CCI_REG8(0x4819), 0xaa },
+ { CCI_REG8(0x4823), 0x3e },
+ { CCI_REG8(0x5000), 0x85 },
+ { CCI_REG8(0x5e00), 0x0c },
+ { CCI_REG8(0x3899), 0x09 },
+ { CCI_REG8(0x4f00), 0x64 },
+ { CCI_REG8(0x4f02), 0x0a },
+ { CCI_REG8(0x4f05), 0x0e },
+ { CCI_REG8(0x4f06), 0x11 },
+ { CCI_REG8(0x4f08), 0x0b },
+ { CCI_REG8(0x4f0a), 0xc4 },
+ { CCI_REG8(0x4f20), 0x1f },
+ { CCI_REG8(0x4f25), 0x10 },
+ { CCI_REG8(0x3016), 0x10 },
+ { CCI_REG8(0x3017), 0x00 },
+ { CCI_REG8(0x3018), 0x00 },
+ { CCI_REG8(0x3019), 0x00 },
+ { CCI_REG8(0x301a), 0x00 },
+ { CCI_REG8(0x301b), 0x00 },
+ { CCI_REG8(0x301c), 0x72 },
+ { CCI_REG8(0x3037), 0x40 },
+ { CCI_REG8(0x4f2c), 0x00 },
+ { CCI_REG8(0x4f21), 0x00 },
+ { CCI_REG8(0x4f23), 0x00 },
+ { CCI_REG8(0x4f2a), 0x00 },
+ { CCI_REG8(0x3665), 0xe7 },
+ { CCI_REG8(0x3668), 0x48 },
+ { CCI_REG8(0x3671), 0x3c },
+ { CCI_REG8(0x389a), 0x02 },
+ { CCI_REG8(0x389b), 0x00 },
+ { CCI_REG8(0x303c), 0xa0 },
+ { CCI_REG8(0x300f), 0xf0 },
+ { CCI_REG8(0x304b), 0x0f },
+ { CCI_REG8(0x3662), 0x24 },
+ { CCI_REG8(0x3006), 0x40 },
+ { CCI_REG8(0x4f26), 0x45 },
+ { CCI_REG8(0x3607), 0x34 },
+ { CCI_REG8(0x3608), 0x01 },
+ { CCI_REG8(0x360a), 0x0c },
+ { CCI_REG8(0x360b), 0x86 },
+ { CCI_REG8(0x360c), 0xcc },
+ { CCI_REG8(0x3013), 0x00 },
+ { CCI_REG8(0x3083), 0x02 },
+ { CCI_REG8(0x3084), 0x12 },
+ { CCI_REG8(0x4601), 0x38 },
+ { CCI_REG8(0x366f), 0x3a },
+ { CCI_REG8(0x3713), 0x19 },
+ { CCI_REG8(0x37a2), 0x00 },
+ { CCI_REG8(0x3f43), 0x27 },
+ { CCI_REG8(0x3f45), 0x27 },
+ { CCI_REG8(0x3f47), 0x32 },
+ { CCI_REG8(0x3f49), 0x3e },
+ { CCI_REG8(0x3f4b), 0x20 },
+ { CCI_REG8(0x3f4d), 0x30 },
+ { CCI_REG8(0x4300), 0x3f },
+ { CCI_REG8(0x4009), 0x10 },
+ { CCI_REG8(0x3f02), 0x68 },
+ { CCI_REG8(0x3700), 0x8c },
+ { CCI_REG8(0x370b), 0x7e },
+ { CCI_REG8(0x3f47), 0x35 },
+};
+
+static const struct og0ve1b_mode supported_modes[] = {
+ {
+ .width = 640,
+ .height = 480,
+ .hts = 792,
+ .vts = 568,
+ .bpp = 8,
+ .reg_list = {
+ .regs = og0ve1b_640x480_120fps_mode,
+ .num_regs = ARRAY_SIZE(og0ve1b_640x480_120fps_mode),
+ },
+ },
+};
+
+static int og0ve1b_enable_test_pattern(struct og0ve1b *og0ve1b, u32 pattern)
+{
+ u64 val = og0ve1b->pre_isp;
+
+ if (pattern)
+ val |= OG0VE1B_TEST_PATTERN_ENABLE;
+ else
+ val &= ~OG0VE1B_TEST_PATTERN_ENABLE;
+
+ return cci_write(og0ve1b->regmap, OG0VE1B_REG_PRE_ISP, val, NULL);
+}
+
+static int og0ve1b_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct og0ve1b *og0ve1b = container_of(ctrl->handler, struct og0ve1b,
+ ctrl_handler);
+ int ret;
+
+ /* V4L2 controls are applied, when sensor is powered up for streaming */
+ if (!pm_runtime_get_if_active(og0ve1b->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = cci_write(og0ve1b->regmap, OG0VE1B_REG_ANALOGUE_GAIN,
+ ctrl->val, NULL);
+ break;
+ case V4L2_CID_EXPOSURE:
+ ret = cci_write(og0ve1b->regmap, OG0VE1B_REG_EXPOSURE,
+ ctrl->val << 4, NULL);
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = og0ve1b_enable_test_pattern(og0ve1b, ctrl->val);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ pm_runtime_put(og0ve1b->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops og0ve1b_ctrl_ops = {
+ .s_ctrl = og0ve1b_set_ctrl,
+};
+
+static int og0ve1b_init_controls(struct og0ve1b *og0ve1b)
+{
+ struct v4l2_ctrl_handler *ctrl_hdlr = &og0ve1b->ctrl_handler;
+ const struct og0ve1b_mode *mode = &supported_modes[0];
+ struct v4l2_fwnode_device_properties props;
+ s64 exposure_max, pixel_rate, h_blank;
+ struct v4l2_ctrl *ctrl;
+ int ret;
+
+ v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+
+ ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, &og0ve1b_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+ ARRAY_SIZE(og0ve1b_link_freq_menu) - 1,
+ 0, og0ve1b_link_freq_menu);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ pixel_rate = og0ve1b_link_freq_menu[0] / mode->bpp;
+ v4l2_ctrl_new_std(ctrl_hdlr, &og0ve1b_ctrl_ops, V4L2_CID_PIXEL_RATE,
+ 0, pixel_rate, 1, pixel_rate);
+
+ h_blank = mode->hts - mode->width;
+ ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &og0ve1b_ctrl_ops, V4L2_CID_HBLANK,
+ h_blank, h_blank, 1, h_blank);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &og0ve1b_ctrl_ops, V4L2_CID_VBLANK,
+ mode->vts - mode->height,
+ mode->vts - mode->height, 1,
+ mode->vts - mode->height);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &og0ve1b_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+ OG0VE1B_ANALOGUE_GAIN_MIN, OG0VE1B_ANALOGUE_GAIN_MAX,
+ OG0VE1B_ANALOGUE_GAIN_STEP,
+ OG0VE1B_ANALOGUE_GAIN_DEFAULT);
+
+ exposure_max = (mode->vts - OG0VE1B_EXPOSURE_MAX_MARGIN);
+ v4l2_ctrl_new_std(ctrl_hdlr, &og0ve1b_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ OG0VE1B_EXPOSURE_MIN, exposure_max,
+ OG0VE1B_EXPOSURE_STEP,
+ OG0VE1B_EXPOSURE_DEFAULT);
+
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &og0ve1b_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(og0ve1b_test_pattern_menu) - 1,
+ 0, 0, og0ve1b_test_pattern_menu);
+
+ if (ctrl_hdlr->error)
+ return ctrl_hdlr->error;
+
+ ret = v4l2_fwnode_device_parse(og0ve1b->dev, &props);
+ if (ret)
+ goto error_free_hdlr;
+
+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &og0ve1b_ctrl_ops,
+ &props);
+ if (ret)
+ goto error_free_hdlr;
+
+ og0ve1b->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
+
+error_free_hdlr:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+
+ return ret;
+}
+
+static void og0ve1b_update_pad_format(const struct og0ve1b_mode *mode,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ fmt->code = MEDIA_BUS_FMT_Y8_1X8;
+ fmt->width = mode->width;
+ fmt->height = mode->height;
+ fmt->field = V4L2_FIELD_NONE;
+ fmt->colorspace = V4L2_COLORSPACE_RAW;
+ fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int og0ve1b_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ const struct og0ve1b_reg_list *reg_list = &supported_modes[0].reg_list;
+ struct og0ve1b *og0ve1b = to_og0ve1b(sd);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(og0ve1b->dev);
+ if (ret)
+ return ret;
+
+ /* Skip a step of explicit entering into the standby mode */
+ ret = cci_write(og0ve1b->regmap, OG0VE1B_REG_SOFTWARE_RST,
+ OG0VE1B_SOFTWARE_RST, NULL);
+ if (ret) {
+ dev_err(og0ve1b->dev, "failed to software reset: %d\n", ret);
+ goto error;
+ }
+
+ ret = cci_multi_reg_write(og0ve1b->regmap, reg_list->regs,
+ reg_list->num_regs, NULL);
+ if (ret) {
+ dev_err(og0ve1b->dev, "failed to set mode: %d\n", ret);
+ goto error;
+ }
+
+ ret = __v4l2_ctrl_handler_setup(og0ve1b->sd.ctrl_handler);
+ if (ret)
+ goto error;
+
+ ret = cci_write(og0ve1b->regmap, OG0VE1B_REG_MODE_SELECT,
+ OG0VE1B_MODE_STREAMING, NULL);
+ if (ret) {
+ dev_err(og0ve1b->dev, "failed to start streaming: %d\n", ret);
+ goto error;
+ }
+
+ return 0;
+
+error:
+ pm_runtime_put_autosuspend(og0ve1b->dev);
+
+ return ret;
+}
+
+static int og0ve1b_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct og0ve1b *og0ve1b = to_og0ve1b(sd);
+ int ret;
+
+ ret = cci_write(og0ve1b->regmap, OG0VE1B_REG_MODE_SELECT,
+ OG0VE1B_MODE_STANDBY, NULL);
+ if (ret)
+ dev_err(og0ve1b->dev, "failed to stop streaming: %d\n", ret);
+
+ pm_runtime_put_autosuspend(og0ve1b->dev);
+
+ return ret;
+}
+
+static int og0ve1b_set_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *fmt)
+{
+ struct v4l2_mbus_framefmt *format;
+ const struct og0ve1b_mode *mode;
+
+ format = v4l2_subdev_state_get_format(state, 0);
+
+ mode = v4l2_find_nearest_size(supported_modes,
+ ARRAY_SIZE(supported_modes),
+ width, height,
+ fmt->format.width,
+ fmt->format.height);
+
+ og0ve1b_update_pad_format(mode, &fmt->format);
+ *format = fmt->format;
+
+ return 0;
+}
+
+static int og0ve1b_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index > 0)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_Y8_1X8;
+
+ return 0;
+}
+
+static int og0ve1b_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ARRAY_SIZE(supported_modes))
+ return -EINVAL;
+
+ if (fse->code != MEDIA_BUS_FMT_Y8_1X8)
+ return -EINVAL;
+
+ fse->min_width = supported_modes[fse->index].width;
+ fse->max_width = fse->min_width;
+ fse->min_height = supported_modes[fse->index].height;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static int og0ve1b_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_TRY,
+ .pad = 0,
+ .format = {
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .width = supported_modes[0].width,
+ .height = supported_modes[0].height,
+ },
+ };
+
+ og0ve1b_set_pad_format(sd, state, &fmt);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops og0ve1b_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops og0ve1b_pad_ops = {
+ .set_fmt = og0ve1b_set_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .enum_mbus_code = og0ve1b_enum_mbus_code,
+ .enum_frame_size = og0ve1b_enum_frame_size,
+ .enable_streams = og0ve1b_enable_streams,
+ .disable_streams = og0ve1b_disable_streams,
+};
+
+static const struct v4l2_subdev_ops og0ve1b_subdev_ops = {
+ .video = &og0ve1b_video_ops,
+ .pad = &og0ve1b_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops og0ve1b_internal_ops = {
+ .init_state = og0ve1b_init_state,
+};
+
+static const struct media_entity_operations og0ve1b_subdev_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static int og0ve1b_identify_sensor(struct og0ve1b *og0ve1b)
+{
+ u64 val;
+ int ret;
+
+ ret = cci_read(og0ve1b->regmap, OG0VE1B_REG_CHIP_ID, &val, NULL);
+ if (ret) {
+ dev_err(og0ve1b->dev, "failed to read chip id: %d\n", ret);
+ return ret;
+ }
+
+ if (val != OG0VE1B_CHIP_ID) {
+ dev_err(og0ve1b->dev, "chip id mismatch: %x!=%llx\n",
+ OG0VE1B_CHIP_ID, val);
+ return -ENODEV;
+ }
+
+ ret = cci_read(og0ve1b->regmap, OG0VE1B_REG_PRE_ISP,
+ &og0ve1b->pre_isp, NULL);
+ if (ret)
+ dev_err(og0ve1b->dev, "failed to read pre_isp: %d\n", ret);
+
+ return ret;
+}
+
+static int og0ve1b_check_hwcfg(struct og0ve1b *og0ve1b)
+{
+ struct fwnode_handle *fwnode = dev_fwnode(og0ve1b->dev), *ep;
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY,
+ };
+ unsigned long freq_bitmap;
+ int ret;
+
+ if (!fwnode)
+ return -ENODEV;
+
+ ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+ if (!ep)
+ return -EINVAL;
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+ fwnode_handle_put(ep);
+ if (ret)
+ return ret;
+
+ ret = v4l2_link_freq_to_bitmap(og0ve1b->dev,
+ bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ og0ve1b_link_freq_menu,
+ ARRAY_SIZE(og0ve1b_link_freq_menu),
+ &freq_bitmap);
+
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+
+ return ret;
+}
+
+static int og0ve1b_power_on(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct og0ve1b *og0ve1b = to_og0ve1b(sd);
+ int ret;
+
+ ret = regulator_bulk_enable(OG0VE1B_NUM_SUPPLIES, og0ve1b->supplies);
+ if (ret)
+ return ret;
+
+ gpiod_set_value_cansleep(og0ve1b->reset_gpio, 0);
+ usleep_range(10 * USEC_PER_MSEC, 15 * USEC_PER_MSEC);
+
+ ret = clk_prepare_enable(og0ve1b->xvclk);
+ if (ret)
+ goto reset_gpio;
+
+ return 0;
+
+reset_gpio:
+ gpiod_set_value_cansleep(og0ve1b->reset_gpio, 1);
+
+ regulator_bulk_disable(OG0VE1B_NUM_SUPPLIES, og0ve1b->supplies);
+
+ return ret;
+}
+
+static int og0ve1b_power_off(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct og0ve1b *og0ve1b = to_og0ve1b(sd);
+
+ clk_disable_unprepare(og0ve1b->xvclk);
+
+ gpiod_set_value_cansleep(og0ve1b->reset_gpio, 1);
+
+ regulator_bulk_disable(OG0VE1B_NUM_SUPPLIES, og0ve1b->supplies);
+
+ return 0;
+}
+
+static int og0ve1b_probe(struct i2c_client *client)
+{
+ struct og0ve1b *og0ve1b;
+ unsigned long freq;
+ unsigned int i;
+ int ret;
+
+ og0ve1b = devm_kzalloc(&client->dev, sizeof(*og0ve1b), GFP_KERNEL);
+ if (!og0ve1b)
+ return -ENOMEM;
+
+ og0ve1b->dev = &client->dev;
+
+ v4l2_i2c_subdev_init(&og0ve1b->sd, client, &og0ve1b_subdev_ops);
+
+ og0ve1b->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(og0ve1b->regmap))
+ return dev_err_probe(og0ve1b->dev, PTR_ERR(og0ve1b->regmap),
+ "failed to init CCI\n");
+
+ og0ve1b->xvclk = devm_v4l2_sensor_clk_get(og0ve1b->dev, NULL);
+ if (IS_ERR(og0ve1b->xvclk))
+ return dev_err_probe(og0ve1b->dev, PTR_ERR(og0ve1b->xvclk),
+ "failed to get XVCLK clock\n");
+
+ freq = clk_get_rate(og0ve1b->xvclk);
+ if (freq && freq != OG0VE1B_MCLK_FREQ_24MHZ)
+ return dev_err_probe(og0ve1b->dev, -EINVAL,
+ "XVCLK clock frequency %lu is not supported\n",
+ freq);
+
+ ret = og0ve1b_check_hwcfg(og0ve1b);
+ if (ret)
+ return dev_err_probe(og0ve1b->dev, ret,
+ "failed to check HW configuration\n");
+
+ og0ve1b->reset_gpio = devm_gpiod_get_optional(og0ve1b->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(og0ve1b->reset_gpio))
+ return dev_err_probe(og0ve1b->dev, PTR_ERR(og0ve1b->reset_gpio),
+ "cannot get reset GPIO\n");
+
+ for (i = 0; i < OG0VE1B_NUM_SUPPLIES; i++)
+ og0ve1b->supplies[i].supply = og0ve1b_supply_names[i];
+
+ ret = devm_regulator_bulk_get(og0ve1b->dev, OG0VE1B_NUM_SUPPLIES,
+ og0ve1b->supplies);
+ if (ret)
+ return dev_err_probe(og0ve1b->dev, ret,
+ "failed to get supply regulators\n");
+
+ /* The sensor must be powered on to read the CHIP_ID register */
+ ret = og0ve1b_power_on(og0ve1b->dev);
+ if (ret)
+ return ret;
+
+ ret = og0ve1b_identify_sensor(og0ve1b);
+ if (ret) {
+ dev_err_probe(og0ve1b->dev, ret, "failed to find sensor\n");
+ goto power_off;
+ }
+
+ ret = og0ve1b_init_controls(og0ve1b);
+ if (ret) {
+ dev_err_probe(og0ve1b->dev, ret, "failed to init controls\n");
+ goto power_off;
+ }
+
+ og0ve1b->sd.state_lock = og0ve1b->ctrl_handler.lock;
+ og0ve1b->sd.internal_ops = &og0ve1b_internal_ops;
+ og0ve1b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ og0ve1b->sd.entity.ops = &og0ve1b_subdev_entity_ops;
+ og0ve1b->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ og0ve1b->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&og0ve1b->sd.entity, 1, &og0ve1b->pad);
+ if (ret) {
+ dev_err_probe(og0ve1b->dev, ret,
+ "failed to init media entity pads\n");
+ goto v4l2_ctrl_handler_free;
+ }
+
+ ret = v4l2_subdev_init_finalize(&og0ve1b->sd);
+ if (ret < 0) {
+ dev_err_probe(og0ve1b->dev, ret,
+ "failed to init media entity pads\n");
+ goto media_entity_cleanup;
+ }
+
+ pm_runtime_set_active(og0ve1b->dev);
+ pm_runtime_enable(og0ve1b->dev);
+
+ ret = v4l2_async_register_subdev_sensor(&og0ve1b->sd);
+ if (ret < 0) {
+ dev_err_probe(og0ve1b->dev, ret,
+ "failed to register V4L2 subdev\n");
+ goto subdev_cleanup;
+ }
+
+ /* Enable runtime PM and turn off the device */
+ pm_runtime_idle(og0ve1b->dev);
+ pm_runtime_set_autosuspend_delay(og0ve1b->dev, 1000);
+ pm_runtime_use_autosuspend(og0ve1b->dev);
+
+ return 0;
+
+subdev_cleanup:
+ v4l2_subdev_cleanup(&og0ve1b->sd);
+ pm_runtime_disable(og0ve1b->dev);
+ pm_runtime_set_suspended(og0ve1b->dev);
+
+media_entity_cleanup:
+ media_entity_cleanup(&og0ve1b->sd.entity);
+
+v4l2_ctrl_handler_free:
+ v4l2_ctrl_handler_free(og0ve1b->sd.ctrl_handler);
+
+power_off:
+ og0ve1b_power_off(og0ve1b->dev);
+
+ return ret;
+}
+
+static void og0ve1b_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct og0ve1b *og0ve1b = to_og0ve1b(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
+ pm_runtime_disable(og0ve1b->dev);
+
+ if (!pm_runtime_status_suspended(og0ve1b->dev)) {
+ og0ve1b_power_off(og0ve1b->dev);
+ pm_runtime_set_suspended(og0ve1b->dev);
+ }
+}
+
+static const struct dev_pm_ops og0ve1b_pm_ops = {
+ SET_RUNTIME_PM_OPS(og0ve1b_power_off, og0ve1b_power_on, NULL)
+};
+
+static const struct of_device_id og0ve1b_of_match[] = {
+ { .compatible = "ovti,og0ve1b" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, og0ve1b_of_match);
+
+static struct i2c_driver og0ve1b_i2c_driver = {
+ .driver = {
+ .name = "og0ve1b",
+ .pm = &og0ve1b_pm_ops,
+ .of_match_table = og0ve1b_of_match,
+ },
+ .probe = og0ve1b_probe,
+ .remove = og0ve1b_remove,
+};
+
+module_i2c_driver(og0ve1b_i2c_driver);
+
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>");
+MODULE_DESCRIPTION("OmniVision OG0VE1B sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c
index 6c30e1a0d814..70d9d7c43f18 100644
--- a/drivers/media/i2c/ov02a10.c
+++ b/drivers/media/i2c/ov02a10.c
@@ -100,7 +100,8 @@ struct ov02a10_mode {
};
struct ov02a10 {
- u32 eclk_freq;
+ struct device *dev;
+
/* Indication of MIPI transmission speed select */
u32 mipi_clock_voltage;
@@ -392,7 +393,7 @@ static int ov02a10_check_sensor_id(struct ov02a10 *ov02a10)
chip_id = le16_to_cpu((__force __le16)ret);
if ((chip_id & OV02A10_ID_MASK) != OV02A10_ID) {
- dev_err(&client->dev, "unexpected sensor id(0x%04x)\n", chip_id);
+ dev_err(ov02a10->dev, "unexpected sensor id(0x%04x)\n", chip_id);
return -EINVAL;
}
@@ -481,7 +482,7 @@ static int __ov02a10_start_stream(struct ov02a10 *ov02a10)
ret = i2c_smbus_write_byte_data(client, REG_MIRROR_FLIP_CONTROL,
REG_MIRROR_FLIP_ENABLE);
if (ret < 0) {
- dev_err(&client->dev, "failed to set orientation\n");
+ dev_err(ov02a10->dev, "failed to set orientation\n");
return ret;
}
ret = i2c_smbus_write_byte_data(client, REG_GLOBAL_EFFECTIVE,
@@ -530,7 +531,6 @@ static int ov02a10_init_state(struct v4l2_subdev *sd,
static int ov02a10_s_stream(struct v4l2_subdev *sd, int on)
{
struct ov02a10 *ov02a10 = to_ov02a10(sd);
- struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
int ret;
mutex_lock(&ov02a10->mutex);
@@ -541,7 +541,7 @@ static int ov02a10_s_stream(struct v4l2_subdev *sd, int on)
}
if (on) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov02a10->dev);
if (ret < 0)
goto unlock_and_return;
@@ -553,7 +553,7 @@ static int ov02a10_s_stream(struct v4l2_subdev *sd, int on)
}
} else {
__ov02a10_stop_stream(ov02a10);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02a10->dev);
}
ov02a10->streaming = on;
@@ -562,7 +562,7 @@ static int ov02a10_s_stream(struct v4l2_subdev *sd, int on)
return 0;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02a10->dev);
unlock_and_return:
mutex_unlock(&ov02a10->mutex);
@@ -662,7 +662,6 @@ static int ov02a10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov02a10 *ov02a10 = container_of(ctrl->handler,
struct ov02a10, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
s64 max_expo;
int ret;
@@ -678,7 +677,7 @@ static int ov02a10_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov02a10->dev))
return 0;
switch (ctrl->id) {
@@ -699,7 +698,7 @@ static int ov02a10_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02a10->dev);
return ret;
}
@@ -734,7 +733,6 @@ static const struct v4l2_ctrl_ops ov02a10_ctrl_ops = {
static int ov02a10_initialize_controls(struct ov02a10 *ov02a10)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
const struct ov02a10_mode *mode;
struct v4l2_ctrl_handler *handler;
struct v4l2_ctrl *ctrl;
@@ -790,7 +788,7 @@ static int ov02a10_initialize_controls(struct ov02a10 *ov02a10)
if (handler->error) {
ret = handler->error;
- dev_err(&client->dev, "failed to init controls(%d)\n", ret);
+ dev_err(ov02a10->dev, "failed to init controls(%d)\n", ret);
goto err_free_handler;
}
@@ -866,6 +864,8 @@ static int ov02a10_probe(struct i2c_client *client)
if (!ov02a10)
return -ENOMEM;
+ ov02a10->dev = dev;
+
ret = ov02a10_check_hwcfg(dev, ov02a10);
if (ret)
return dev_err_probe(dev, ret,
@@ -885,22 +885,11 @@ static int ov02a10_probe(struct i2c_client *client)
ov02a10->fmt.code = MEDIA_BUS_FMT_SRGGB10_1X10;
}
- ov02a10->eclk = devm_clk_get(dev, "eclk");
+ ov02a10->eclk = devm_v4l2_sensor_clk_get_legacy(dev, "eclk", false, 0);
if (IS_ERR(ov02a10->eclk))
return dev_err_probe(dev, PTR_ERR(ov02a10->eclk),
"failed to get eclk\n");
- ret = device_property_read_u32(dev, "clock-frequency",
- &ov02a10->eclk_freq);
- if (ret < 0)
- return dev_err_probe(dev, ret,
- "failed to get eclk frequency\n");
-
- ret = clk_set_rate(ov02a10->eclk, ov02a10->eclk_freq);
- if (ret < 0)
- return dev_err_probe(dev, ret,
- "failed to set eclk frequency (24MHz)\n");
-
if (clk_get_rate(ov02a10->eclk) != OV02A10_ECLK_FREQ)
dev_warn(dev, "eclk mismatched, mode is based on 24MHz\n");
@@ -985,10 +974,10 @@ static void ov02a10_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
- if (!pm_runtime_status_suspended(&client->dev))
- ov02a10_power_off(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov02a10->dev);
+ if (!pm_runtime_status_suspended(ov02a10->dev))
+ ov02a10_power_off(ov02a10->dev);
+ pm_runtime_set_suspended(ov02a10->dev);
mutex_destroy(&ov02a10->mutex);
}
diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
index 089a4fd9627c..8c4d85dc7922 100644
--- a/drivers/media/i2c/ov02c10.c
+++ b/drivers/media/i2c/ov02c10.c
@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
-#include <linux/version.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -373,6 +372,8 @@ static const char * const ov02c10_supply_names[] = {
};
struct ov02c10 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -418,7 +419,6 @@ static int ov02c10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov02c10 *ov02c10 = container_of(ctrl->handler,
struct ov02c10, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd);
const u32 height = supported_modes[0].height;
s64 exposure_max;
int ret = 0;
@@ -434,7 +434,7 @@ static int ov02c10_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov02c10->dev))
return 0;
switch (ctrl->id) {
@@ -467,7 +467,7 @@ static int ov02c10_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02c10->dev);
return ret;
}
@@ -478,7 +478,6 @@ static const struct v4l2_ctrl_ops ov02c10_ctrl_ops = {
static int ov02c10_init_controls(struct ov02c10 *ov02c10)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd);
struct v4l2_ctrl_handler *ctrl_hdlr = &ov02c10->ctrl_handler;
const struct ov02c10_mode *mode = &supported_modes[0];
u32 vblank_min, vblank_max, vblank_default, vts_def;
@@ -542,7 +541,7 @@ static int ov02c10_init_controls(struct ov02c10 *ov02c10)
ARRAY_SIZE(ov02c10_test_pattern_menu) - 1,
0, 0, ov02c10_test_pattern_menu);
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov02c10->dev, &props);
if (ret)
return ret;
@@ -570,12 +569,11 @@ static int ov02c10_enable_streams(struct v4l2_subdev *sd,
u32 pad, u64 streams_mask)
{
const struct ov02c10_mode *mode = &supported_modes[0];
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov02c10 *ov02c10 = to_ov02c10(sd);
const struct reg_sequence *reg_sequence;
int ret, sequence_length;
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov02c10->dev);
if (ret)
return ret;
@@ -584,7 +582,7 @@ static int ov02c10_enable_streams(struct v4l2_subdev *sd,
ret = regmap_multi_reg_write(ov02c10->regmap,
reg_sequence, sequence_length);
if (ret) {
- dev_err(&client->dev, "failed to set mode\n");
+ dev_err(ov02c10->dev, "failed to set mode\n");
goto out;
}
@@ -593,7 +591,7 @@ static int ov02c10_enable_streams(struct v4l2_subdev *sd,
ret = regmap_multi_reg_write(ov02c10->regmap,
reg_sequence, sequence_length);
if (ret) {
- dev_err(&client->dev, "failed to write lane settings\n");
+ dev_err(ov02c10->dev, "failed to write lane settings\n");
goto out;
}
@@ -604,7 +602,7 @@ static int ov02c10_enable_streams(struct v4l2_subdev *sd,
ret = cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 1, NULL);
out:
if (ret)
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02c10->dev);
return ret;
}
@@ -613,11 +611,10 @@ static int ov02c10_disable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov02c10 *ov02c10 = to_ov02c10(sd);
cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 0, NULL);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02c10->dev);
return 0;
}
@@ -778,7 +775,6 @@ static const struct v4l2_subdev_internal_ops ov02c10_internal_ops = {
static int ov02c10_identify_module(struct ov02c10 *ov02c10)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov02c10->sd);
u64 chip_id;
int ret;
@@ -787,7 +783,7 @@ static int ov02c10_identify_module(struct ov02c10 *ov02c10)
return ret;
if (chip_id != OV02C10_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%llx",
+ dev_err(ov02c10->dev, "chip id mismatch: %x!=%llx",
OV02C10_CHIP_ID, chip_id);
return -ENXIO;
}
@@ -795,14 +791,14 @@ static int ov02c10_identify_module(struct ov02c10 *ov02c10)
return 0;
}
-static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10)
+static int ov02c10_check_hwcfg(struct ov02c10 *ov02c10)
{
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
+ struct device *dev = ov02c10->dev;
struct fwnode_handle *ep, *fwnode = dev_fwnode(dev);
unsigned long link_freq_bitmap;
- u32 mclk;
int ret;
/*
@@ -814,31 +810,6 @@ static int ov02c10_check_hwcfg(struct device *dev, struct ov02c10 *ov02c10)
return dev_err_probe(dev, -EPROBE_DEFER,
"waiting for fwnode graph endpoint\n");
- ov02c10->img_clk = devm_clk_get_optional(dev, NULL);
- if (IS_ERR(ov02c10->img_clk)) {
- fwnode_handle_put(ep);
- return dev_err_probe(dev, PTR_ERR(ov02c10->img_clk),
- "failed to get imaging clock\n");
- }
-
- if (ov02c10->img_clk) {
- mclk = clk_get_rate(ov02c10->img_clk);
- } else {
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
- if (ret) {
- fwnode_handle_put(ep);
- return dev_err_probe(dev, ret,
- "reading clock-frequency property\n");
- }
- }
-
- if (mclk != OV02C10_MCLK) {
- fwnode_handle_put(ep);
- return dev_err_probe(dev, -EINVAL,
- "external clock %u is not supported\n",
- mclk);
- }
-
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
fwnode_handle_put(ep);
if (ret)
@@ -873,35 +844,50 @@ check_hwcfg_error:
static void ov02c10_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov02c10 *ov02c10 = to_ov02c10(sd);
v4l2_async_unregister_subdev(sd);
v4l2_subdev_cleanup(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
- if (!pm_runtime_status_suspended(&client->dev)) {
- ov02c10_power_off(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov02c10->dev);
+ if (!pm_runtime_status_suspended(ov02c10->dev)) {
+ ov02c10_power_off(ov02c10->dev);
+ pm_runtime_set_suspended(ov02c10->dev);
}
}
static int ov02c10_probe(struct i2c_client *client)
{
struct ov02c10 *ov02c10;
+ unsigned long freq;
int ret;
ov02c10 = devm_kzalloc(&client->dev, sizeof(*ov02c10), GFP_KERNEL);
if (!ov02c10)
return -ENOMEM;
+ ov02c10->dev = &client->dev;
+
+ ov02c10->img_clk = devm_v4l2_sensor_clk_get(ov02c10->dev, NULL);
+ if (IS_ERR(ov02c10->img_clk))
+ return dev_err_probe(ov02c10->dev, PTR_ERR(ov02c10->img_clk),
+ "failed to get imaging clock\n");
+
+ freq = clk_get_rate(ov02c10->img_clk);
+ if (freq != OV02C10_MCLK)
+ return dev_err_probe(ov02c10->dev, -EINVAL,
+ "external clock %lu is not supported",
+ freq);
+
v4l2_i2c_subdev_init(&ov02c10->sd, client, &ov02c10_subdev_ops);
/* Check HW config */
- ret = ov02c10_check_hwcfg(&client->dev, ov02c10);
+ ret = ov02c10_check_hwcfg(ov02c10);
if (ret)
return ret;
- ret = ov02c10_get_pm_resources(&client->dev);
+ ret = ov02c10_get_pm_resources(ov02c10->dev);
if (ret)
return ret;
@@ -909,21 +895,21 @@ static int ov02c10_probe(struct i2c_client *client)
if (IS_ERR(ov02c10->regmap))
return PTR_ERR(ov02c10->regmap);
- ret = ov02c10_power_on(&client->dev);
+ ret = ov02c10_power_on(ov02c10->dev);
if (ret) {
- dev_err_probe(&client->dev, ret, "failed to power on\n");
+ dev_err_probe(ov02c10->dev, ret, "failed to power on\n");
return ret;
}
ret = ov02c10_identify_module(ov02c10);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(ov02c10->dev, "failed to find sensor: %d", ret);
goto probe_error_power_off;
}
ret = ov02c10_init_controls(ov02c10);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(ov02c10->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -934,33 +920,33 @@ static int ov02c10_probe(struct i2c_client *client)
ov02c10->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov02c10->sd.entity, 1, &ov02c10->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(ov02c10->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ov02c10->sd.state_lock = ov02c10->ctrl_handler.lock;
ret = v4l2_subdev_init_finalize(&ov02c10->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to init subdev: %d", ret);
+ dev_err(ov02c10->dev, "failed to init subdev: %d", ret);
goto probe_error_media_entity_cleanup;
}
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
+ pm_runtime_set_active(ov02c10->dev);
+ pm_runtime_enable(ov02c10->dev);
ret = v4l2_async_register_subdev_sensor(&ov02c10->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(ov02c10->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_v4l2_subdev_cleanup;
}
- pm_runtime_idle(&client->dev);
+ pm_runtime_idle(ov02c10->dev);
return 0;
probe_error_v4l2_subdev_cleanup:
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov02c10->dev);
+ pm_runtime_set_suspended(ov02c10->dev);
v4l2_subdev_cleanup(&ov02c10->sd);
probe_error_media_entity_cleanup:
@@ -970,7 +956,7 @@ probe_error_v4l2_ctrl_handler_free:
v4l2_ctrl_handler_free(ov02c10->sd.ctrl_handler);
probe_error_power_off:
- ov02c10_power_off(&client->dev);
+ ov02c10_power_off(ov02c10->dev);
return ret;
}
diff --git a/drivers/media/i2c/ov02e10.c b/drivers/media/i2c/ov02e10.c
index d74dc62e189d..4a64cba99991 100644
--- a/drivers/media/i2c/ov02e10.c
+++ b/drivers/media/i2c/ov02e10.c
@@ -226,6 +226,8 @@ static const char * const ov02e10_supply_names[] = {
};
struct ov02e10 {
+ struct device *dev;
+
struct regmap *regmap;
struct v4l2_subdev sd;
struct media_pad pad;
@@ -288,7 +290,6 @@ static int ov02e10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov02e10 *ov02e10 = container_of(ctrl->handler,
struct ov02e10, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov02e10->sd);
s64 exposure_max;
int ret;
@@ -307,7 +308,7 @@ static int ov02e10_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov02e10->dev))
return 0;
ret = cci_write(ov02e10->regmap, OV02E10_REG_COMMAND_UPDATE,
@@ -363,7 +364,7 @@ static int ov02e10_set_ctrl(struct v4l2_ctrl *ctrl)
cci_write(ov02e10->regmap, OV02E10_REG_COMMAND_UPDATE,
OV02E10_COMMAND_UPDATE, &ret);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02e10->dev);
return ret;
}
@@ -374,7 +375,6 @@ static const struct v4l2_ctrl_ops ov02e10_ctrl_ops = {
static int ov02e10_init_controls(struct ov02e10 *ov02e10)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov02e10->sd);
struct v4l2_ctrl_handler *ctrl_hdlr = &ov02e10->ctrl_handler;
const struct ov02e10_mode *mode = ov02e10->cur_mode;
u32 vblank_min, vblank_max, vblank_def;
@@ -442,7 +442,7 @@ static int ov02e10_init_controls(struct ov02e10 *ov02e10)
ARRAY_SIZE(ov02e10_test_pattern_menu) - 1,
0, 0, ov02e10_test_pattern_menu);
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov02e10->dev, &props);
if (ret)
return ret;
@@ -481,12 +481,11 @@ static int ov02e10_enable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov02e10 *ov02e10 = to_ov02e10(sd);
const struct reg_sequence_list *reg_list;
int ret;
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov02e10->dev);
if (ret)
return ret;
@@ -494,7 +493,7 @@ static int ov02e10_enable_streams(struct v4l2_subdev *sd,
ret = regmap_multi_reg_write(ov02e10->regmap, reg_list->regs,
reg_list->num_regs);
if (ret) {
- dev_err(&client->dev, "failed to set mode\n");
+ dev_err(ov02e10->dev, "failed to set mode\n");
goto out;
}
@@ -506,7 +505,7 @@ static int ov02e10_enable_streams(struct v4l2_subdev *sd,
out:
if (ret)
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02e10->dev);
return ret;
}
@@ -515,11 +514,10 @@ static int ov02e10_disable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov02e10 *ov02e10 = to_ov02e10(sd);
ov02e10_set_stream_mode(ov02e10, 0);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov02e10->dev);
return 0;
}
@@ -724,7 +722,6 @@ static const struct v4l2_subdev_internal_ops ov02e10_internal_ops = {
static int ov02e10_identify_module(struct ov02e10 *ov02e10)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov02e10->sd);
int ret;
u64 val;
@@ -735,7 +732,7 @@ static int ov02e10_identify_module(struct ov02e10 *ov02e10)
return ret;
if (val != OV02E10_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(ov02e10->dev, "chip id mismatch: %x!=%x\n",
OV02E10_CHIP_ID, (u32)val);
return -ENXIO;
}
@@ -743,15 +740,15 @@ static int ov02e10_identify_module(struct ov02e10 *ov02e10)
return 0;
}
-static int ov02e10_check_hwcfg(struct device *dev, struct ov02e10 *ov02e10)
+static int ov02e10_check_hwcfg(struct ov02e10 *ov02e10)
{
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
+ struct device *dev = ov02e10->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
unsigned long link_freq_bitmap;
- u32 ext_clk;
int ret;
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
@@ -764,31 +761,6 @@ static int ov02e10_check_hwcfg(struct device *dev, struct ov02e10 *ov02e10)
if (ret)
return dev_err_probe(dev, ret, "parsing endpoint failed\n");
- ov02e10->img_clk = devm_clk_get_optional(dev, NULL);
- if (IS_ERR(ov02e10->img_clk)) {
- ret = dev_err_probe(dev, PTR_ERR(ov02e10->img_clk),
- "failed to get imaging clock\n");
- goto out_err;
- }
-
- if (ov02e10->img_clk) {
- ext_clk = clk_get_rate(ov02e10->img_clk);
- } else {
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &ext_clk);
- if (ret) {
- dev_err(dev, "can't get clock frequency\n");
- goto out_err;
- }
- }
-
- if (ext_clk != OV02E10_MCLK) {
- dev_err(dev, "external clock %d is not supported\n",
- ext_clk);
- ret = -EINVAL;
- goto out_err;
- }
-
if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV02E10_DATA_LANES) {
dev_err(dev, "number of CSI2 data lanes %d is not supported\n",
bus_cfg.bus.mipi_csi2.num_data_lanes);
@@ -823,32 +795,47 @@ out_err:
static void ov02e10_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov02e10 *ov02e10 = to_ov02e10(sd);
v4l2_async_unregister_subdev(sd);
v4l2_subdev_cleanup(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov02e10->dev);
- if (!pm_runtime_status_suspended(&client->dev)) {
- ov02e10_power_off(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ if (!pm_runtime_status_suspended(ov02e10->dev)) {
+ ov02e10_power_off(ov02e10->dev);
+ pm_runtime_set_suspended(ov02e10->dev);
}
}
static int ov02e10_probe(struct i2c_client *client)
{
struct ov02e10 *ov02e10;
+ unsigned long freq;
int ret;
ov02e10 = devm_kzalloc(&client->dev, sizeof(*ov02e10), GFP_KERNEL);
if (!ov02e10)
return -ENOMEM;
+ ov02e10->dev = &client->dev;
+
+ ov02e10->img_clk = devm_v4l2_sensor_clk_get(ov02e10->dev, NULL);
+ if (IS_ERR(ov02e10->img_clk))
+ return dev_err_probe(ov02e10->dev, PTR_ERR(ov02e10->img_clk),
+ "failed to get imaging clock\n");
+
+ freq = clk_get_rate(ov02e10->img_clk);
+ if (freq != OV02E10_MCLK)
+ return dev_err_probe(ov02e10->dev, -EINVAL,
+ "external clock %lu is not supported",
+ freq);
+
v4l2_i2c_subdev_init(&ov02e10->sd, client, &ov02e10_subdev_ops);
/* Check HW config */
- ret = ov02e10_check_hwcfg(&client->dev, ov02e10);
+ ret = ov02e10_check_hwcfg(ov02e10);
if (ret)
return ret;
@@ -857,27 +844,27 @@ static int ov02e10_probe(struct i2c_client *client)
if (IS_ERR(ov02e10->regmap))
return PTR_ERR(ov02e10->regmap);
- ret = ov02e10_get_pm_resources(&client->dev);
+ ret = ov02e10_get_pm_resources(ov02e10->dev);
if (ret)
return ret;
- ret = ov02e10_power_on(&client->dev);
+ ret = ov02e10_power_on(ov02e10->dev);
if (ret) {
- dev_err_probe(&client->dev, ret, "failed to power on\n");
+ dev_err_probe(ov02e10->dev, ret, "failed to power on\n");
return ret;
}
/* Check module identity */
ret = ov02e10_identify_module(ov02e10);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ dev_err(ov02e10->dev, "failed to find sensor: %d\n", ret);
goto probe_error_power_off;
}
ov02e10->cur_mode = &supported_modes[0];
ret = ov02e10_init_controls(ov02e10);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d\n", ret);
+ dev_err(ov02e10->dev, "failed to init controls: %d\n", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -891,33 +878,33 @@ static int ov02e10_probe(struct i2c_client *client)
ov02e10->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov02e10->sd.entity, 1, &ov02e10->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(ov02e10->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ov02e10->sd.state_lock = ov02e10->ctrl_handler.lock;
ret = v4l2_subdev_init_finalize(&ov02e10->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to init subdev: %d", ret);
+ dev_err(ov02e10->dev, "failed to init subdev: %d", ret);
goto probe_error_media_entity_cleanup;
}
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
+ pm_runtime_set_active(ov02e10->dev);
+ pm_runtime_enable(ov02e10->dev);
ret = v4l2_async_register_subdev_sensor(&ov02e10->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(ov02e10->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_v4l2_subdev_cleanup;
}
- pm_runtime_idle(&client->dev);
+ pm_runtime_idle(ov02e10->dev);
return 0;
probe_error_v4l2_subdev_cleanup:
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov02e10->dev);
+ pm_runtime_set_suspended(ov02e10->dev);
v4l2_subdev_cleanup(&ov02e10->sd);
probe_error_media_entity_cleanup:
@@ -927,7 +914,7 @@ probe_error_v4l2_ctrl_handler_free:
v4l2_ctrl_handler_free(ov02e10->sd.ctrl_handler);
probe_error_power_off:
- ov02e10_power_off(&client->dev);
+ ov02e10_power_off(ov02e10->dev);
return ret;
}
@@ -961,7 +948,7 @@ static struct i2c_driver ov02e10_i2c_driver = {
module_i2c_driver(ov02e10_i2c_driver);
-MODULE_AUTHOR("Jingjing Xiong <jingjing.xiong@intel.com>");
+MODULE_AUTHOR("Jingjing Xiong");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_AUTHOR("Alan Stern <stern@rowland.harvard.edu>");
MODULE_AUTHOR("Bryan O'Donoghue <bryan.odonoghue@linaro.org>");
diff --git a/drivers/media/i2c/ov08d10.c b/drivers/media/i2c/ov08d10.c
index 1bacbdfa4298..43ec2a1f2fcf 100644
--- a/drivers/media/i2c/ov08d10.c
+++ b/drivers/media/i2c/ov08d10.c
@@ -515,12 +515,13 @@ static const char * const ov08d10_test_pattern_menu[] = {
};
struct ov08d10 {
+ struct device *dev;
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
- struct clk *xvclk;
-
/* V4L2 Controls */
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *pixel_rate;
@@ -663,7 +664,7 @@ static int ov08d10_write_reg_list(struct ov08d10 *ov08d10,
ret = i2c_smbus_write_byte_data(client, r_list->regs[i].address,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov08d10->dev,
"failed to write reg 0x%2.2x. error = %d",
r_list->regs[i].address, ret);
return ret;
@@ -849,7 +850,6 @@ static int ov08d10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov08d10 *ov08d10 = container_of(ctrl->handler,
struct ov08d10, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov08d10->sd);
s64 exposure_max;
int ret;
@@ -865,7 +865,7 @@ static int ov08d10_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov08d10->dev))
return 0;
switch (ctrl->id) {
@@ -901,7 +901,7 @@ static int ov08d10_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov08d10->dev);
return ret;
}
@@ -1025,32 +1025,32 @@ static int ov08d10_start_streaming(struct ov08d10 *ov08d10)
/* soft reset */
ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
if (ret < 0) {
- dev_err(&client->dev, "failed to reset sensor");
+ dev_err(ov08d10->dev, "failed to reset sensor");
return ret;
}
ret = i2c_smbus_write_byte_data(client, 0x20, 0x0e);
if (ret < 0) {
- dev_err(&client->dev, "failed to reset sensor");
+ dev_err(ov08d10->dev, "failed to reset sensor");
return ret;
}
usleep_range(3000, 4000);
ret = i2c_smbus_write_byte_data(client, 0x20, 0x0b);
if (ret < 0) {
- dev_err(&client->dev, "failed to reset sensor");
+ dev_err(ov08d10->dev, "failed to reset sensor");
return ret;
}
/* update sensor setting */
ret = ov08d10_write_reg_list(ov08d10, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls");
+ dev_err(ov08d10->dev, "failed to set plls");
return ret;
}
reg_list = &ov08d10->cur_mode->reg_list;
ret = ov08d10_write_reg_list(ov08d10, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(ov08d10->dev, "failed to set mode");
return ret;
}
@@ -1077,19 +1077,19 @@ static void ov08d10_stop_streaming(struct ov08d10 *ov08d10)
ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x00);
if (ret < 0) {
- dev_err(&client->dev, "failed to stop streaming");
+ dev_err(ov08d10->dev, "failed to stop streaming");
return;
}
ret = i2c_smbus_write_byte_data(client, OV08D10_REG_MODE_SELECT,
OV08D10_MODE_STANDBY);
if (ret < 0) {
- dev_err(&client->dev, "failed to stop streaming");
+ dev_err(ov08d10->dev, "failed to stop streaming");
return;
}
ret = i2c_smbus_write_byte_data(client, OV08D10_REG_PAGE, 0x01);
if (ret < 0) {
- dev_err(&client->dev, "failed to stop streaming");
+ dev_err(ov08d10->dev, "failed to stop streaming");
return;
}
}
@@ -1097,12 +1097,11 @@ static void ov08d10_stop_streaming(struct ov08d10 *ov08d10)
static int ov08d10_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov08d10 *ov08d10 = to_ov08d10(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov08d10->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov08d10->dev);
if (ret < 0) {
mutex_unlock(&ov08d10->mutex);
return ret;
@@ -1112,11 +1111,11 @@ static int ov08d10_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
ov08d10_stop_streaming(ov08d10);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov08d10->dev);
}
} else {
ov08d10_stop_streaming(ov08d10);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov08d10->dev);
}
/* vflip and hflip cannot change during streaming */
@@ -1293,7 +1292,7 @@ static int ov08d10_identify_module(struct ov08d10 *ov08d10)
chip_id = val | ret;
if ((chip_id & OV08D10_ID_MASK) != OV08D10_CHIP_ID) {
- dev_err(&client->dev, "unexpected sensor id(0x%04x)\n",
+ dev_err(ov08d10->dev, "unexpected sensor id(0x%04x)\n",
chip_id);
return -EINVAL;
}
@@ -1301,28 +1300,20 @@ static int ov08d10_identify_module(struct ov08d10 *ov08d10)
return 0;
}
-static int ov08d10_get_hwcfg(struct ov08d10 *ov08d10, struct device *dev)
+static int ov08d10_get_hwcfg(struct ov08d10 *ov08d10)
{
+ struct device *dev = ov08d10->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
- u32 xvclk_rate;
unsigned int i, j;
int ret;
if (!fwnode)
return -ENXIO;
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &xvclk_rate);
- if (ret)
- return ret;
-
- if (xvclk_rate != OV08D10_XVCLK_19_2)
- dev_warn(dev, "external clock rate %u is unsupported",
- xvclk_rate);
-
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
return -ENXIO;
@@ -1380,22 +1371,35 @@ static void ov08d10_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov08d10->dev);
mutex_destroy(&ov08d10->mutex);
}
static int ov08d10_probe(struct i2c_client *client)
{
struct ov08d10 *ov08d10;
+ unsigned long freq;
int ret;
ov08d10 = devm_kzalloc(&client->dev, sizeof(*ov08d10), GFP_KERNEL);
if (!ov08d10)
return -ENOMEM;
- ret = ov08d10_get_hwcfg(ov08d10, &client->dev);
+ ov08d10->dev = &client->dev;
+
+ ov08d10->clk = devm_v4l2_sensor_clk_get(ov08d10->dev, NULL);
+ if (IS_ERR(ov08d10->clk))
+ return dev_err_probe(ov08d10->dev, PTR_ERR(ov08d10->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(ov08d10->clk);
+ if (freq != OV08D10_XVCLK_19_2)
+ dev_warn(ov08d10->dev,
+ "external clock rate %lu is not supported\n", freq);
+
+ ret = ov08d10_get_hwcfg(ov08d10);
if (ret) {
- dev_err(&client->dev, "failed to get HW configuration: %d",
+ dev_err(ov08d10->dev, "failed to get HW configuration: %d",
ret);
return ret;
}
@@ -1404,7 +1408,7 @@ static int ov08d10_probe(struct i2c_client *client)
ret = ov08d10_identify_module(ov08d10);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(ov08d10->dev, "failed to find sensor: %d", ret);
return ret;
}
@@ -1412,7 +1416,7 @@ static int ov08d10_probe(struct i2c_client *client)
ov08d10->cur_mode = &ov08d10->priv_lane->sp_modes[0];
ret = ov08d10_init_controls(ov08d10);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(ov08d10->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -1422,13 +1426,13 @@ static int ov08d10_probe(struct i2c_client *client)
ov08d10->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov08d10->sd.entity, 1, &ov08d10->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(ov08d10->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&ov08d10->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(ov08d10->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_media_entity_cleanup;
}
@@ -1437,9 +1441,9 @@ static int ov08d10_probe(struct i2c_client *client)
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov08d10->dev);
+ pm_runtime_enable(ov08d10->dev);
+ pm_runtime_idle(ov08d10->dev);
return 0;
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index e0094305ca2a..5eaf454f4763 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -1,15 +1,16 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
-#include <linux/i2c.h>
+#include <linux/delay.h>
#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
#include <linux/module.h>
-#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -1305,6 +1306,8 @@ static const char * const ov08x40_supply_names[] = {
};
struct ov08x40 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -1513,7 +1516,6 @@ static int ov08x40_write_reg(struct ov08x40 *ov08x,
static int ov08x40_write_regs(struct ov08x40 *ov08x,
const struct ov08x40_reg *regs, u32 len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
int ret;
u32 i;
@@ -1522,7 +1524,7 @@ static int ov08x40_write_regs(struct ov08x40 *ov08x,
regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov08x->dev,
"Failed to write reg 0x%4.4x. error = %d\n",
regs[i].address, ret);
@@ -1648,7 +1650,7 @@ static int ov08x40_set_ctrl_hflip(struct ov08x40 *ov08x, u32 ctrl_val)
return ov08x40_write_reg(ov08x, OV08X40_REG_MIRROR,
OV08X40_REG_VALUE_08BIT,
- ctrl_val ? val | BIT(2) : val & ~BIT(2));
+ ctrl_val ? val & ~BIT(2) : val | BIT(2));
}
static int ov08x40_set_ctrl_vflip(struct ov08x40 *ov08x, u32 ctrl_val)
@@ -1670,7 +1672,6 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov08x40 *ov08x = container_of(ctrl->handler,
struct ov08x40, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
s64 max;
int exp;
int fll;
@@ -1699,7 +1700,7 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl)
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov08x->dev))
return 0;
switch (ctrl->id) {
@@ -1737,13 +1738,13 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl)
ov08x40_set_ctrl_vflip(ov08x, ctrl->val);
break;
default:
- dev_info(&client->dev,
+ dev_info(ov08x->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov08x->dev);
return ret;
}
@@ -1912,7 +1913,6 @@ ov08x40_set_pad_format(struct v4l2_subdev *sd,
static int ov08x40_start_streaming(struct ov08x40 *ov08x)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
const struct ov08x40_reg_list *reg_list;
int ret, link_freq_index;
@@ -1920,7 +1920,7 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x)
ret = ov08x40_write_reg(ov08x, OV08X40_REG_SOFTWARE_RST,
OV08X40_REG_VALUE_08BIT, OV08X40_SOFTWARE_RST);
if (ret) {
- dev_err(&client->dev, "%s failed to set powerup registers\n",
+ dev_err(ov08x->dev, "%s failed to set powerup registers\n",
__func__);
return ret;
}
@@ -1930,14 +1930,14 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x)
ret = ov08x40_write_reg_list(ov08x, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set plls\n", __func__);
+ dev_err(ov08x->dev, "%s failed to set plls\n", __func__);
return ret;
}
reg_list = &ov08x40_global_setting;
ret = ov08x40_write_reg_list(ov08x, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set global setting\n",
+ dev_err(ov08x->dev, "%s failed to set global setting\n",
__func__);
return ret;
}
@@ -1946,7 +1946,7 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x)
reg_list = &ov08x->cur_mode->reg_list;
ret = ov08x40_write_reg_list(ov08x, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(ov08x->dev, "%s failed to set mode\n", __func__);
return ret;
}
@@ -1962,7 +1962,7 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x)
}
if (ret) {
- dev_err(&client->dev, "%s failed to set regs\n", __func__);
+ dev_err(ov08x->dev, "%s failed to set regs\n", __func__);
return ret;
}
@@ -1986,7 +1986,6 @@ static int ov08x40_stop_streaming(struct ov08x40 *ov08x)
/* Verify chip ID */
static int ov08x40_identify_module(struct ov08x40 *ov08x)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
int ret;
u32 val;
@@ -1996,17 +1995,17 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x)
ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
OV08X40_REG_VALUE_24BIT, &val);
if (ret) {
- dev_err(&client->dev, "error reading chip-id register: %d\n", ret);
+ dev_err(ov08x->dev, "error reading chip-id register: %d\n", ret);
return ret;
}
if (val != OV08X40_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(ov08x->dev, "chip id mismatch: %x!=%x\n",
OV08X40_CHIP_ID, val);
return -ENXIO;
}
- dev_dbg(&client->dev, "chip id 0x%x\n", val);
+ dev_dbg(ov08x->dev, "chip id 0x%x\n", val);
ov08x->identified = true;
return 0;
@@ -2015,13 +2014,12 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x)
static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov08x40 *ov08x = to_ov08x40(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov08x->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov08x->dev);
if (ret < 0)
goto err_unlock;
@@ -2038,7 +2036,7 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
ov08x40_stop_streaming(ov08x);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov08x->dev);
}
mutex_unlock(&ov08x->mutex);
@@ -2046,7 +2044,7 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov08x->dev);
err_unlock:
mutex_unlock(&ov08x->mutex);
@@ -2079,7 +2077,6 @@ static const struct v4l2_subdev_internal_ops ov08x40_internal_ops = {
static int ov08x40_init_controls(struct ov08x40 *ov08x)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max;
@@ -2160,12 +2157,12 @@ static int ov08x40_init_controls(struct ov08x40 *ov08x)
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "%s control init failed (%d)\n",
+ dev_err(ov08x->dev, "%s control init failed (%d)\n",
__func__, ret);
goto error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov08x->dev, &props);
if (ret)
goto error;
@@ -2191,11 +2188,12 @@ static void ov08x40_free_controls(struct ov08x40 *ov08x)
mutex_destroy(&ov08x->mutex);
}
-static int ov08x40_check_hwcfg(struct ov08x40 *ov08x, struct device *dev)
+static int ov08x40_check_hwcfg(struct ov08x40 *ov08x)
{
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
+ struct device *dev = ov08x->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
unsigned int i;
@@ -2232,23 +2230,14 @@ static int ov08x40_check_hwcfg(struct ov08x40 *ov08x, struct device *dev)
if (ret)
goto out_err;
- ov08x->xvclk = devm_clk_get_optional(dev, NULL);
+ ov08x->xvclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(ov08x->xvclk)) {
ret = dev_err_probe(dev, PTR_ERR(ov08x->xvclk),
"getting xvclk\n");
goto out_err;
}
- if (ov08x->xvclk) {
- xvclk_rate = clk_get_rate(ov08x->xvclk);
- } else {
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &xvclk_rate);
- if (ret) {
- dev_err(dev, "can't get clock frequency\n");
- goto out_err;
- }
- }
+ xvclk_rate = clk_get_rate(ov08x->xvclk);
if (xvclk_rate != OV08X40_XVCLK) {
dev_err(dev, "external clock %d is not supported\n",
xvclk_rate);
@@ -2294,19 +2283,21 @@ static int ov08x40_probe(struct i2c_client *client)
if (!ov08x)
return -ENOMEM;
+ ov08x->dev = &client->dev;
+
/* Check HW config */
- ret = ov08x40_check_hwcfg(ov08x, &client->dev);
+ ret = ov08x40_check_hwcfg(ov08x);
if (ret)
return ret;
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov08x->sd, client, &ov08x40_subdev_ops);
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(ov08x->dev);
if (full_power) {
- ret = ov08x40_power_on(&client->dev);
+ ret = ov08x40_power_on(ov08x->dev);
if (ret) {
- dev_err(&client->dev, "failed to power on\n");
+ dev_err(ov08x->dev, "failed to power on\n");
return ret;
}
@@ -2333,7 +2324,7 @@ static int ov08x40_probe(struct i2c_client *client)
ov08x->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov08x->sd.entity, 1, &ov08x->pad);
if (ret) {
- dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
+ dev_err(ov08x->dev, "%s failed:%d\n", __func__, ret);
goto error_handler_free;
}
@@ -2342,9 +2333,9 @@ static int ov08x40_probe(struct i2c_client *client)
goto error_media_entity;
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov08x->dev);
+ pm_runtime_enable(ov08x->dev);
+ pm_runtime_idle(ov08x->dev);
return 0;
@@ -2355,7 +2346,7 @@ error_handler_free:
ov08x40_free_controls(ov08x);
probe_power_off:
- ov08x40_power_off(&client->dev);
+ ov08x40_power_off(ov08x->dev);
return ret;
}
@@ -2369,10 +2360,10 @@ static void ov08x40_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
ov08x40_free_controls(ov08x);
- pm_runtime_disable(&client->dev);
- if (!pm_runtime_status_suspended(&client->dev))
- ov08x40_power_off(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov08x->dev);
+ if (!pm_runtime_status_suspended(ov08x->dev))
+ ov08x40_power_off(ov08x->dev);
+ pm_runtime_set_suspended(ov08x->dev);
}
static DEFINE_RUNTIME_DEV_PM_OPS(ov08x40_pm_ops, ov08x40_power_off,
diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
index 7a3fc1d28514..162b49046990 100644
--- a/drivers/media/i2c/ov13858.c
+++ b/drivers/media/i2c/ov13858.c
@@ -2,6 +2,7 @@
// Copyright (c) 2017 Intel Corporation.
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
@@ -1028,6 +1029,9 @@ static const struct ov13858_mode supported_modes[] = {
};
struct ov13858 {
+ struct device *dev;
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -1117,7 +1121,6 @@ static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len,
static int ov13858_write_regs(struct ov13858 *ov13858,
const struct ov13858_reg *regs, u32 len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
int ret;
u32 i;
@@ -1126,7 +1129,7 @@ static int ov13858_write_regs(struct ov13858 *ov13858,
regs[i].val);
if (ret) {
dev_err_ratelimited(
- &client->dev,
+ ov13858->dev,
"Failed to write reg 0x%4.4x. error = %d\n",
regs[i].address, ret);
@@ -1209,7 +1212,6 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov13858 *ov13858 = container_of(ctrl->handler,
struct ov13858, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
s64 max;
int ret;
@@ -1228,7 +1230,7 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov13858->dev))
return 0;
ret = 0;
@@ -1256,13 +1258,13 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
ret = ov13858_enable_test_pattern(ov13858, ctrl->val);
break;
default:
- dev_info(&client->dev,
+ dev_info(ov13858->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov13858->dev);
return ret;
}
@@ -1408,7 +1410,6 @@ static int ov13858_get_skip_frames(struct v4l2_subdev *sd, u32 *frames)
/* Start streaming */
static int ov13858_start_streaming(struct ov13858 *ov13858)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
const struct ov13858_reg_list *reg_list;
int ret, link_freq_index;
@@ -1416,7 +1417,7 @@ static int ov13858_start_streaming(struct ov13858 *ov13858)
ret = ov13858_write_reg(ov13858, OV13858_REG_SOFTWARE_RST,
OV13858_REG_VALUE_08BIT, OV13858_SOFTWARE_RST);
if (ret) {
- dev_err(&client->dev, "%s failed to set powerup registers\n",
+ dev_err(ov13858->dev, "%s failed to set powerup registers\n",
__func__);
return ret;
}
@@ -1426,7 +1427,7 @@ static int ov13858_start_streaming(struct ov13858 *ov13858)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov13858_write_reg_list(ov13858, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set plls\n", __func__);
+ dev_err(ov13858->dev, "%s failed to set plls\n", __func__);
return ret;
}
@@ -1434,7 +1435,7 @@ static int ov13858_start_streaming(struct ov13858 *ov13858)
reg_list = &ov13858->cur_mode->reg_list;
ret = ov13858_write_reg_list(ov13858, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(ov13858->dev, "%s failed to set mode\n", __func__);
return ret;
}
@@ -1458,13 +1459,12 @@ static int ov13858_stop_streaming(struct ov13858 *ov13858)
static int ov13858_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov13858 *ov13858 = to_ov13858(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov13858->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov13858->dev);
if (ret < 0)
goto err_unlock;
@@ -1477,7 +1477,7 @@ static int ov13858_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
ov13858_stop_streaming(ov13858);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov13858->dev);
}
mutex_unlock(&ov13858->mutex);
@@ -1485,7 +1485,7 @@ static int ov13858_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov13858->dev);
err_unlock:
mutex_unlock(&ov13858->mutex);
@@ -1495,7 +1495,6 @@ err_unlock:
/* Verify chip ID */
static int ov13858_identify_module(struct ov13858 *ov13858)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
int ret;
u32 val;
@@ -1505,7 +1504,7 @@ static int ov13858_identify_module(struct ov13858 *ov13858)
return ret;
if (val != OV13858_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(ov13858->dev, "chip id mismatch: %x!=%x\n",
OV13858_CHIP_ID, val);
return -EIO;
}
@@ -1552,7 +1551,6 @@ static const struct v4l2_subdev_internal_ops ov13858_internal_ops = {
/* Initialize control handlers */
static int ov13858_init_controls(struct ov13858 *ov13858)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd);
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max;
@@ -1626,12 +1624,12 @@ static int ov13858_init_controls(struct ov13858 *ov13858)
0, 0, ov13858_test_pattern_menu);
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "%s control init failed (%d)\n",
+ dev_err(ov13858->dev, "%s control init failed (%d)\n",
__func__, ret);
goto error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov13858->dev, &props);
if (ret)
goto error;
@@ -1660,24 +1658,33 @@ static void ov13858_free_controls(struct ov13858 *ov13858)
static int ov13858_probe(struct i2c_client *client)
{
struct ov13858 *ov13858;
+ unsigned long freq;
int ret;
- u32 val = 0;
-
- device_property_read_u32(&client->dev, "clock-frequency", &val);
- if (val != 19200000)
- return -EINVAL;
ov13858 = devm_kzalloc(&client->dev, sizeof(*ov13858), GFP_KERNEL);
if (!ov13858)
return -ENOMEM;
+ ov13858->dev = &client->dev;
+
+ ov13858->clk = devm_v4l2_sensor_clk_get(ov13858->dev, NULL);
+ if (IS_ERR(ov13858->clk))
+ return dev_err_probe(ov13858->dev, PTR_ERR(ov13858->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(ov13858->clk);
+ if (freq != 19200000)
+ return dev_err_probe(ov13858->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops);
/* Check module identity */
ret = ov13858_identify_module(ov13858);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ dev_err(ov13858->dev, "failed to find sensor: %d\n", ret);
return ret;
}
@@ -1699,7 +1706,7 @@ static int ov13858_probe(struct i2c_client *client)
ov13858->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov13858->sd.entity, 1, &ov13858->pad);
if (ret) {
- dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
+ dev_err(ov13858->dev, "%s failed:%d\n", __func__, ret);
goto error_handler_free;
}
@@ -1711,9 +1718,9 @@ static int ov13858_probe(struct i2c_client *client)
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov13858->dev);
+ pm_runtime_enable(ov13858->dev);
+ pm_runtime_idle(ov13858->dev);
return 0;
@@ -1722,7 +1729,7 @@ error_media_entity:
error_handler_free:
ov13858_free_controls(ov13858);
- dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
+ dev_err(ov13858->dev, "%s failed:%d\n", __func__, ret);
return ret;
}
@@ -1736,7 +1743,7 @@ static void ov13858_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
ov13858_free_controls(ov13858);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov13858->dev);
}
static const struct i2c_device_id ov13858_id_table[] = {
diff --git a/drivers/media/i2c/ov13b10.c b/drivers/media/i2c/ov13b10.c
index e85c7d33a670..869bc78ed792 100644
--- a/drivers/media/i2c/ov13b10.c
+++ b/drivers/media/i2c/ov13b10.c
@@ -700,6 +700,8 @@ static const struct ov13b10_mode supported_2_lanes_modes[] = {
};
struct ov13b10 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -805,7 +807,6 @@ static int ov13b10_write_reg(struct ov13b10 *ov13b,
static int ov13b10_write_regs(struct ov13b10 *ov13b,
const struct ov13b10_reg *regs, u32 len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
int ret;
u32 i;
@@ -813,7 +814,7 @@ static int ov13b10_write_regs(struct ov13b10 *ov13b,
ret = ov13b10_write_reg(ov13b, regs[i].address, 1,
regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov13b->dev,
"Failed to write reg 0x%4.4x. error = %d\n",
regs[i].address, ret);
@@ -968,7 +969,6 @@ static int ov13b10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov13b10 *ov13b = container_of(ctrl->handler,
struct ov13b10, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
s64 max;
int ret;
@@ -987,7 +987,7 @@ static int ov13b10_set_ctrl(struct v4l2_ctrl *ctrl)
* Applying V4L2 control value only happens
* when power is up for streaming
*/
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov13b->dev))
return 0;
ret = 0;
@@ -1021,13 +1021,13 @@ static int ov13b10_set_ctrl(struct v4l2_ctrl *ctrl)
ov13b10_set_ctrl_vflip(ov13b, ctrl->val);
break;
default:
- dev_info(&client->dev,
+ dev_info(ov13b->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov13b->dev);
return ret;
}
@@ -1166,7 +1166,6 @@ ov13b10_set_pad_format(struct v4l2_subdev *sd,
/* Verify chip ID */
static int ov13b10_identify_module(struct ov13b10 *ov13b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
int ret;
u32 val;
@@ -1179,7 +1178,7 @@ static int ov13b10_identify_module(struct ov13b10 *ov13b)
return ret;
if (val != OV13B10_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(ov13b->dev, "chip id mismatch: %x!=%x\n",
OV13B10_CHIP_ID, val);
return -EIO;
}
@@ -1234,7 +1233,6 @@ static int ov13b10_power_on(struct device *dev)
static int ov13b10_start_streaming(struct ov13b10 *ov13b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
const struct ov13b10_reg_list *reg_list;
int ret, link_freq_index;
@@ -1246,7 +1244,7 @@ static int ov13b10_start_streaming(struct ov13b10 *ov13b)
ret = ov13b10_write_reg(ov13b, OV13B10_REG_SOFTWARE_RST,
OV13B10_REG_VALUE_08BIT, OV13B10_SOFTWARE_RST);
if (ret) {
- dev_err(&client->dev, "%s failed to set powerup registers\n",
+ dev_err(ov13b->dev, "%s failed to set powerup registers\n",
__func__);
return ret;
}
@@ -1255,7 +1253,7 @@ static int ov13b10_start_streaming(struct ov13b10 *ov13b)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov13b10_write_reg_list(ov13b, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set plls\n", __func__);
+ dev_err(ov13b->dev, "%s failed to set plls\n", __func__);
return ret;
}
@@ -1263,7 +1261,7 @@ static int ov13b10_start_streaming(struct ov13b10 *ov13b)
reg_list = &ov13b->cur_mode->reg_list;
ret = ov13b10_write_reg_list(ov13b, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(ov13b->dev, "%s failed to set mode\n", __func__);
return ret;
}
@@ -1287,13 +1285,12 @@ static int ov13b10_stop_streaming(struct ov13b10 *ov13b)
static int ov13b10_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov13b10 *ov13b = to_ov13b10(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov13b->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov13b->dev);
if (ret < 0)
goto err_unlock;
@@ -1306,7 +1303,7 @@ static int ov13b10_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
ov13b10_stop_streaming(ov13b);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov13b->dev);
}
mutex_unlock(&ov13b->mutex);
@@ -1314,7 +1311,7 @@ static int ov13b10_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov13b->dev);
err_unlock:
mutex_unlock(&ov13b->mutex);
@@ -1360,7 +1357,6 @@ static const struct v4l2_subdev_internal_ops ov13b10_internal_ops = {
/* Initialize control handlers */
static int ov13b10_init_controls(struct ov13b10 *ov13b)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov13b->sd);
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max;
@@ -1443,12 +1439,12 @@ static int ov13b10_init_controls(struct ov13b10 *ov13b)
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
- dev_err(&client->dev, "%s control init failed (%d)\n",
+ dev_err(ov13b->dev, "%s control init failed (%d)\n",
__func__, ret);
goto error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov13b->dev, &props);
if (ret)
goto error;
@@ -1474,44 +1470,49 @@ static void ov13b10_free_controls(struct ov13b10 *ov13b)
mutex_destroy(&ov13b->mutex);
}
-static int ov13b10_get_pm_resources(struct device *dev)
+static int ov13b10_get_pm_resources(struct ov13b10 *ov13b)
{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct ov13b10 *ov13b = to_ov13b10(sd);
+ unsigned long freq;
int ret;
- ov13b->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ ov13b->reset = devm_gpiod_get_optional(ov13b->dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(ov13b->reset))
- return dev_err_probe(dev, PTR_ERR(ov13b->reset),
+ return dev_err_probe(ov13b->dev, PTR_ERR(ov13b->reset),
"failed to get reset gpio\n");
- ov13b->img_clk = devm_clk_get_optional(dev, NULL);
+ ov13b->img_clk = devm_v4l2_sensor_clk_get(ov13b->dev, NULL);
if (IS_ERR(ov13b->img_clk))
- return dev_err_probe(dev, PTR_ERR(ov13b->img_clk),
+ return dev_err_probe(ov13b->dev, PTR_ERR(ov13b->img_clk),
"failed to get imaging clock\n");
- ov13b->avdd = devm_regulator_get_optional(dev, "avdd");
+ freq = clk_get_rate(ov13b->img_clk);
+ if (freq != OV13B10_EXT_CLK)
+ return dev_err_probe(ov13b->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
+ ov13b->avdd = devm_regulator_get_optional(ov13b->dev, "avdd");
if (IS_ERR(ov13b->avdd)) {
ret = PTR_ERR(ov13b->avdd);
ov13b->avdd = NULL;
if (ret != -ENODEV)
- return dev_err_probe(dev, ret,
+ return dev_err_probe(ov13b->dev, ret,
"failed to get avdd regulator\n");
}
return 0;
}
-static int ov13b10_check_hwcfg(struct device *dev, struct ov13b10 *ov13b)
+static int ov13b10_check_hwcfg(struct ov13b10 *ov13b)
{
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
+ struct device *dev = ov13b->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
unsigned int i, j;
int ret;
- u32 ext_clk;
u8 dlane;
if (!fwnode)
@@ -1521,19 +1522,6 @@ static int ov13b10_check_hwcfg(struct device *dev, struct ov13b10 *ov13b)
if (!ep)
return -EPROBE_DEFER;
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &ext_clk);
- if (ret) {
- dev_err(dev, "can't get clock frequency");
- return ret;
- }
-
- if (ext_clk != OV13B10_EXT_CLK) {
- dev_err(dev, "external clock %d is not supported",
- ext_clk);
- return -EINVAL;
- }
-
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
fwnode_handle_put(ep);
if (ret)
@@ -1602,32 +1590,34 @@ static int ov13b10_probe(struct i2c_client *client)
if (!ov13b)
return -ENOMEM;
+ ov13b->dev = &client->dev;
+
/* Check HW config */
- ret = ov13b10_check_hwcfg(&client->dev, ov13b);
+ ret = ov13b10_check_hwcfg(ov13b);
if (ret) {
- dev_err(&client->dev, "failed to check hwcfg: %d", ret);
+ dev_err(ov13b->dev, "failed to check hwcfg: %d", ret);
return ret;
}
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov13b->sd, client, &ov13b10_subdev_ops);
- ret = ov13b10_get_pm_resources(&client->dev);
+ ret = ov13b10_get_pm_resources(ov13b);
if (ret)
return ret;
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(ov13b->dev);
if (full_power) {
- ret = ov13b10_power_on(&client->dev);
+ ret = ov13b10_power_on(ov13b->dev);
if (ret) {
- dev_err(&client->dev, "failed to power on\n");
+ dev_err(ov13b->dev, "failed to power on\n");
return ret;
}
/* Check module identity */
ret = ov13b10_identify_module(ov13b);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ dev_err(ov13b->dev, "failed to find sensor: %d\n", ret);
goto error_power_off;
}
}
@@ -1646,7 +1636,7 @@ static int ov13b10_probe(struct i2c_client *client)
ov13b->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov13b->sd.entity, 1, &ov13b->pad);
if (ret) {
- dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
+ dev_err(ov13b->dev, "%s failed:%d\n", __func__, ret);
goto error_handler_free;
}
@@ -1657,9 +1647,9 @@ static int ov13b10_probe(struct i2c_client *client)
*/
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov13b->dev);
+ pm_runtime_enable(ov13b->dev);
+ pm_runtime_idle(ov13b->dev);
ret = v4l2_async_register_subdev_sensor(&ov13b->sd);
if (ret < 0)
@@ -1668,17 +1658,17 @@ static int ov13b10_probe(struct i2c_client *client)
return 0;
error_media_entity_runtime_pm:
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov13b->dev);
if (full_power)
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_set_suspended(ov13b->dev);
media_entity_cleanup(&ov13b->sd.entity);
error_handler_free:
ov13b10_free_controls(ov13b);
- dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
+ dev_err(ov13b->dev, "%s failed:%d\n", __func__, ret);
error_power_off:
- ov13b10_power_off(&client->dev);
+ ov13b10_power_off(ov13b->dev);
return ret;
}
@@ -1692,8 +1682,8 @@ static void ov13b10_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
ov13b10_free_controls(ov13b);
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov13b->dev);
+ pm_runtime_set_suspended(ov13b->dev);
}
static DEFINE_RUNTIME_DEV_PM_OPS(ov13b10_pm_ops, ov13b10_suspend,
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 586b31ba076b..061401b020fc 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1437,9 +1437,10 @@ static int ov2659_probe(struct i2c_client *client)
ov2659->pdata = pdata;
ov2659->client = client;
- ov2659->clk = devm_clk_get(&client->dev, "xvclk");
+ ov2659->clk = devm_v4l2_sensor_clk_get(&client->dev, "xvclk");
if (IS_ERR(ov2659->clk))
- return PTR_ERR(ov2659->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(ov2659->clk),
+ "failed to get xvclk\n");
ov2659->xvclk_frequency = clk_get_rate(ov2659->clk);
if (ov2659->xvclk_frequency < 6000000 ||
diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
index 7237fb27ecd0..78e63bd1b35b 100644
--- a/drivers/media/i2c/ov2680.c
+++ b/drivers/media/i2c/ov2680.c
@@ -1079,7 +1079,6 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
struct device *dev = sensor->dev;
struct fwnode_handle *ep_fwnode;
struct gpio_desc *gpio;
- unsigned int rate = 0;
int i, ret;
/*
@@ -1114,38 +1113,14 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
sensor->pwdn_gpio = gpio;
- sensor->xvclk = devm_clk_get_optional(dev, "xvclk");
+ sensor->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
if (IS_ERR(sensor->xvclk)) {
ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk),
"xvclk clock missing or invalid\n");
goto out_free_bus_cfg;
}
- /*
- * We could have either a 24MHz or 19.2MHz clock rate from either DT or
- * ACPI... but we also need to support the weird IPU3 case which will
- * have an external clock AND a clock-frequency property. Check for the
- * clock-frequency property and if found, set that rate if we managed
- * to acquire a clock. This should cover the ACPI case. If the system
- * uses devicetree then the configured rate should already be set, so
- * we can just read it.
- */
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &rate);
- if (ret && !sensor->xvclk) {
- dev_err_probe(dev, ret, "invalid clock config\n");
- goto out_free_bus_cfg;
- }
-
- if (!ret && sensor->xvclk) {
- ret = clk_set_rate(sensor->xvclk, rate);
- if (ret) {
- dev_err_probe(dev, ret, "failed to set clock rate\n");
- goto out_free_bus_cfg;
- }
- }
-
- sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk);
+ sensor->xvclk_freq = clk_get_rate(sensor->xvclk);
for (i = 0; i < ARRAY_SIZE(ov2680_xvclk_freqs); i++) {
if (sensor->xvclk_freq == ov2680_xvclk_freqs[i])
diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c
index 9b8481b8dcd4..4911a4eea126 100644
--- a/drivers/media/i2c/ov2685.c
+++ b/drivers/media/i2c/ov2685.c
@@ -783,16 +783,12 @@ static int ov2685_probe(struct i2c_client *client)
ov2685->client = client;
ov2685->cur_mode = &supported_modes[0];
- ov2685->xvclk = devm_clk_get(dev, "xvclk");
- if (IS_ERR(ov2685->xvclk)) {
- dev_err(dev, "Failed to get xvclk\n");
- return -EINVAL;
- }
- ret = clk_set_rate(ov2685->xvclk, OV2685_XVCLK_FREQ);
- if (ret < 0) {
- dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
- return ret;
- }
+ ov2685->xvclk = devm_v4l2_sensor_clk_get_legacy(dev, "xvclk", true,
+ OV2685_XVCLK_FREQ);
+ if (IS_ERR(ov2685->xvclk))
+ return dev_err_probe(dev, PTR_ERR(ov2685->xvclk),
+ "Failed to get xvclk\n");
+
if (clk_get_rate(ov2685->xvclk) != OV2685_XVCLK_FREQ)
dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
diff --git a/drivers/media/i2c/ov2735.c b/drivers/media/i2c/ov2735.c
new file mode 100644
index 000000000000..b96600204141
--- /dev/null
+++ b/drivers/media/i2c/ov2735.c
@@ -0,0 +1,1109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 Support for the OV2735
+ *
+ * Copyright (C) 2025 Silicon Signals Pvt. Ltd.
+ *
+ * Based on Rockchip ov2735 Camera Driver
+ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ *
+ * Inspired from ov8858, imx219, imx283 camera drivers.
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitops.h>
+#include <linux/cleanup.h>
+#include <linux/clk.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/device/devres.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/units.h>
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mediabus.h>
+
+#define OV2735_XCLK_FREQ (24 * HZ_PER_MHZ)
+
+/* Add page number in CCI private bits [31:28] of the register address */
+#define OV2735_PAGE_REG8(p, x) (((p) << CCI_REG_PRIVATE_SHIFT) | CCI_REG8(x))
+#define OV2735_PAGE_REG16(p, x) (((p) << CCI_REG_PRIVATE_SHIFT) | CCI_REG16(x))
+
+#define OV2735_REG_PAGE_SELECT CCI_REG8(0xfd)
+
+/* Page 0 */
+#define OV2735_REG_CHIPID OV2735_PAGE_REG16(0x00, 0x02)
+#define OV2735_CHIPID 0x2735
+
+#define OV2735_REG_SOFT_RESET OV2735_PAGE_REG8(0x00, 0x20)
+
+/* Clock Settings */
+#define OV2735_REG_PLL_CTRL OV2735_PAGE_REG8(0x00, 0x2f)
+#define OV2735_PLL_CTRL_ENABLE 0x7f
+#define OV2735_REG_PLL_OUTDIV OV2735_PAGE_REG8(0x00, 0x34)
+#define OV2735_REG_CLK_MODE OV2735_PAGE_REG8(0x00, 0x30)
+#define OV2735_REG_CLOCK_REG1 OV2735_PAGE_REG8(0x00, 0x33)
+#define OV2735_REG_CLOCK_REG2 OV2735_PAGE_REG8(0x00, 0x35)
+
+/* Page 1 */
+#define OV2735_REG_STREAM_CTRL OV2735_PAGE_REG8(0x01, 0xa0)
+#define OV2735_STREAM_CTRL_ON 0x01
+#define OV2735_STREAM_CTRL_OFF 0x00
+
+#define OV2735_REG_UPDOWN_MIRROR OV2735_PAGE_REG8(0x01, 0x3f)
+#define OV2735_REG_BINNING_DAC_CODE_MODE OV2735_PAGE_REG8(0x01, 0x30)
+#define OV2735_REG_FRAME_LENGTH OV2735_PAGE_REG16(0x01, 0x0e)
+#define OV2735_FRAME_LENGTH_MAX 0x0fff
+#define OV2735_REG_FRAME_EXP_SEPERATE_EN OV2735_PAGE_REG8(0x01, 0x0d)
+#define OV2735_FRAME_EXP_SEPERATE_EN 0x10
+#define OV2735_REG_FRAME_SYNC OV2735_PAGE_REG8(0x01, 0x01)
+
+#define OV2735_REG_HBLANK OV2735_PAGE_REG16(0x01, 0x09)
+
+#define OV2735_REG_HS_MIPI OV2735_PAGE_REG8(0x01, 0xb1)
+#define OV2735_REG_MIPI_CTRL1 OV2735_PAGE_REG8(0x01, 0x92)
+#define OV2735_REG_MIPI_CTRL2 OV2735_PAGE_REG8(0x01, 0x94)
+#define OV2735_REG_MIPI_CTRL3 OV2735_PAGE_REG8(0x01, 0xa1)
+#define OV2735_REG_MIPI_CTRL4 OV2735_PAGE_REG8(0x01, 0xb2)
+#define OV2735_REG_MIPI_CTRL5 OV2735_PAGE_REG8(0x01, 0xb3)
+#define OV2735_REG_MIPI_CTRL6 OV2735_PAGE_REG8(0x01, 0xb4)
+#define OV2735_REG_MIPI_CTRL7 OV2735_PAGE_REG8(0x01, 0xb5)
+#define OV2735_REG_HIGH_SPEED OV2735_PAGE_REG8(0x01, 0x9d)
+#define OV2735_REG_PREPARE OV2735_PAGE_REG8(0x01, 0x95)
+#define OV2735_REG_R_HS_ZERO OV2735_PAGE_REG8(0x01, 0x96)
+#define OV2735_REG_TRAIL OV2735_PAGE_REG8(0x01, 0x98)
+#define OV2735_REG_R_CLK_ZERO OV2735_PAGE_REG8(0x01, 0x9c)
+#define OV2735_REG_MIPI_COLOMN_NUMBER OV2735_PAGE_REG16(0x01, 0x8e)
+#define OV2735_REG_MIPI_LINE_NUMBER OV2735_PAGE_REG16(0x01, 0x90)
+
+/* Timing control registers */
+#define OV2735_REG_TIMING_CTRL2 OV2735_PAGE_REG8(0x01, 0x1a)
+#define OV2735_REG_TIMING_CTRL3 OV2735_PAGE_REG8(0x01, 0x1c)
+#define OV2735_REG_TIMING_CTRL1 OV2735_PAGE_REG8(0x01, 0x16)
+#define OV2735_REG_RST_NUM OV2735_PAGE_REG16(0x01, 0x10)
+#define OV2735_REG_RST_NUM2 OV2735_PAGE_REG16(0x01, 0x32)
+#define OV2735_REG_BOOST_EN OV2735_PAGE_REG8(0x01, 0xd0)
+#define OV2735_REG_B2_NUM OV2735_PAGE_REG16(0x01, 0xd1)
+#define OV2735_REG_B4_NUM OV2735_PAGE_REG16(0x01, 0xd3)
+#define OV2735_REG_PIXEL_CYCLE_P0 OV2735_PAGE_REG8(0x01, 0x50)
+#define OV2735_REG_PIXEL_CYCLE_P1 OV2735_PAGE_REG8(0x01, 0x51)
+#define OV2735_REG_PIXEL_CYCLE_P2 OV2735_PAGE_REG8(0x01, 0x52)
+#define OV2735_REG_PIXEL_CYCLE_P3 OV2735_PAGE_REG8(0x01, 0x53)
+#define OV2735_REG_PIXEL_CYCLE_P5 OV2735_PAGE_REG8(0x01, 0x55)
+#define OV2735_REG_PIXEL_CYCLE_P7 OV2735_PAGE_REG16(0x01, 0x57)
+#define OV2735_REG_PIXEL_CYCLE_P9 OV2735_PAGE_REG8(0x01, 0x5a)
+#define OV2735_REG_PIXEL_CYCLE_P10 OV2735_PAGE_REG8(0x01, 0x5b)
+#define OV2735_REG_PIXEL_CYCLE_P12 OV2735_PAGE_REG8(0x01, 0x5d)
+#define OV2735_REG_PIXEL_CYCLE_P18 OV2735_PAGE_REG8(0x01, 0x64)
+#define OV2735_REG_PIXEL_CYCLE_P20 OV2735_PAGE_REG8(0x01, 0x66)
+#define OV2735_REG_PIXEL_CYCLE_P22 OV2735_PAGE_REG8(0x01, 0x68)
+#define OV2735_REG_PIXEL_CYCLE_P33 OV2735_PAGE_REG16(0x01, 0x74)
+#define OV2735_REG_PIXEL_CYCLE_P34 OV2735_PAGE_REG8(0x01, 0x76)
+#define OV2735_REG_PIXEL_CYCLE_P35_P36 OV2735_PAGE_REG8(0x01, 0x77)
+#define OV2735_REG_PIXEL_CYCLE_P37_P38 OV2735_PAGE_REG8(0x01, 0x78)
+#define OV2735_REG_PIXEL_CYCLE_P31 OV2735_PAGE_REG8(0x01, 0x72)
+#define OV2735_REG_PIXEL_CYCLE_P32 OV2735_PAGE_REG8(0x01, 0x73)
+#define OV2735_REG_PIXEL_CYCLE_P44 OV2735_PAGE_REG8(0x01, 0x7d)
+#define OV2735_REG_PIXEL_CYCLE_P45 OV2735_PAGE_REG8(0x01, 0x7e)
+#define OV2735_REG_PIXEL_BIAS_CTRL_RH_RL OV2735_PAGE_REG8(0x01, 0x8a)
+#define OV2735_REG_PIXEL_BIAS_CTRL_SH_SL OV2735_PAGE_REG8(0x01, 0x8b)
+
+/* Analog Control registers */
+#define OV2735_REG_ICOMP OV2735_PAGE_REG8(0x01, 0x19)
+#define OV2735_REG_PCP_RST_SEL OV2735_PAGE_REG8(0x01, 0x21)
+#define OV2735_REG_VNCP OV2735_PAGE_REG8(0x01, 0x20)
+#define OV2735_REG_ANALOG_CTRL3 OV2735_PAGE_REG8(0x01, 0x25)
+#define OV2735_REG_ANALOG_CTRL4 OV2735_PAGE_REG8(0x01, 0x26)
+#define OV2735_REG_ANALOG_CTRL5 OV2735_PAGE_REG8(0x01, 0x29)
+#define OV2735_REG_ANALOG_CTRL6 OV2735_PAGE_REG8(0x01, 0x2a)
+#define OV2735_REG_ANALOG_CTRL8 OV2735_PAGE_REG8(0x01, 0x2c)
+
+/* BLC registers */
+#define OV2735_REG_BLC_GAIN_BLUE OV2735_PAGE_REG8(0x01, 0x86)
+#define OV2735_REG_BLC_GAIN_RED OV2735_PAGE_REG8(0x01, 0x87)
+#define OV2735_REG_BLC_GAIN_GR OV2735_PAGE_REG8(0x01, 0x88)
+#define OV2735_REG_BLC_GAIN_GB OV2735_PAGE_REG8(0x01, 0x89)
+#define OV2735_REG_GB_SUBOFFSET OV2735_PAGE_REG8(0x01, 0xf0)
+#define OV2735_REG_BLUE_SUBOFFSET OV2735_PAGE_REG8(0x01, 0xf1)
+#define OV2735_REG_RED_SUBOFFSET OV2735_PAGE_REG8(0x01, 0xf2)
+#define OV2735_REG_GR_SUBOFFSET OV2735_PAGE_REG8(0x01, 0xf3)
+#define OV2735_REG_BLC_BPC_TH_P OV2735_PAGE_REG8(0x01, 0xfc)
+#define OV2735_REG_BLC_BPC_TH_N OV2735_PAGE_REG8(0x01, 0xfe)
+#define OV2735_REG_ABL OV2735_PAGE_REG8(0x01, 0xfb)
+
+#define OV2735_REG_TEST_PATTERN OV2735_PAGE_REG8(0x01, 0xb2)
+#define OV2735_TEST_PATTERN_ENABLE 0x01
+#define OV2735_TEST_PATTERN_DISABLE 0xfe
+
+#define OV2735_REG_LONG_EXPOSURE OV2735_PAGE_REG16(0x01, 0x03)
+#define OV2735_EXPOSURE_MIN 4
+#define OV2735_EXPOSURE_STEP 1
+#define OV2735_EXPOSURE_MARGIN 4
+
+#define OV2735_REG_ANALOG_GAIN OV2735_PAGE_REG8(0x01, 0x24)
+#define OV2735_ANALOG_GAIN_MIN 0x10
+#define OV2735_ANALOG_GAIN_MAX 0xff
+#define OV2735_ANALOG_GAIN_STEP 1
+#define OV2735_ANALOG_GAIN_DEFAULT 0x10
+
+/* Page 2 */
+#define OV2735_REG_V_START OV2735_PAGE_REG16(0x02, 0xa0)
+#define OV2735_REG_V_SIZE OV2735_PAGE_REG16(0x02, 0xa2)
+#define OV2735_REG_H_START OV2735_PAGE_REG16(0x02, 0xa4)
+#define OV2735_REG_H_SIZE OV2735_PAGE_REG16(0x02, 0xa6)
+
+#define OV2735_LINK_FREQ_420MHZ (420 * HZ_PER_MHZ)
+#define OV2735_PIXEL_RATE (168 * HZ_PER_MHZ)
+
+/* OV2735 native and active pixel array size */
+static const struct v4l2_rect ov2735_native_area = {
+ .top = 0,
+ .left = 0,
+ .width = 1936,
+ .height = 1096,
+};
+
+static const struct v4l2_rect ov2735_active_area = {
+ .top = 8,
+ .left = 8,
+ .width = 1920,
+ .height = 1080,
+};
+
+static const char * const ov2735_supply_name[] = {
+ "avdd", /* Analog power */
+ "dovdd", /* Digital I/O power */
+ "dvdd", /* Digital core power */
+};
+
+/* PLL_OUT = [PLL_IN * (pll_nc +3)] / [(pll_mc + 1) * (pll_outdiv + 1)] */
+struct ov2735_pll_parameters {
+ u8 pll_nc;
+ u8 pll_mc;
+ u8 pll_outdiv;
+};
+
+struct ov2735 {
+ struct device *dev;
+ struct regmap *cci;
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct clk *xclk;
+ struct gpio_desc *reset_gpio;
+ struct gpio_desc *enable_gpio;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(ov2735_supply_name)];
+
+ /* V4L2 Controls */
+ struct v4l2_ctrl_handler handler;
+ struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *gain;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *test_pattern;
+
+ u32 link_freq_index;
+
+ u8 current_page;
+ struct mutex page_lock;
+};
+
+struct ov2735_mode {
+ u32 width;
+ u32 height;
+ u32 hts_def;
+ u32 vts_def;
+ u32 exp_def;
+ struct v4l2_rect crop;
+};
+
+static const struct cci_reg_sequence ov2735_common_regs[] = {
+ { OV2735_REG_CLK_MODE, 0x15 },
+ { OV2735_REG_CLOCK_REG1, 0x01 },
+ { OV2735_REG_CLOCK_REG2, 0x20 },
+ { OV2735_REG_BINNING_DAC_CODE_MODE, 0x00 },
+ { OV2735_REG_ABL, 0x73 },
+ { OV2735_REG_FRAME_SYNC, 0x01 },
+
+ /* Timing ctrl */
+ { OV2735_REG_TIMING_CTRL2, 0x6b },
+ { OV2735_REG_TIMING_CTRL3, 0xea },
+ { OV2735_REG_TIMING_CTRL1, 0x0c },
+ { OV2735_REG_RST_NUM, 0x0063 },
+ { OV2735_REG_RST_NUM2, 0x006f },
+ { OV2735_REG_BOOST_EN, 0x02 },
+ { OV2735_REG_B2_NUM, 0x0120 },
+ { OV2735_REG_B4_NUM, 0x042a },
+ { OV2735_REG_PIXEL_CYCLE_P0, 0x00 },
+ { OV2735_REG_PIXEL_CYCLE_P1, 0x2c },
+ { OV2735_REG_PIXEL_CYCLE_P2, 0x29 },
+ { OV2735_REG_PIXEL_CYCLE_P3, 0x00 },
+ { OV2735_REG_PIXEL_CYCLE_P5, 0x44 },
+ { OV2735_REG_PIXEL_CYCLE_P7, 0x0029 },
+ { OV2735_REG_PIXEL_CYCLE_P9, 0x00 },
+ { OV2735_REG_PIXEL_CYCLE_P10, 0x00 },
+ { OV2735_REG_PIXEL_CYCLE_P12, 0x00 },
+ { OV2735_REG_PIXEL_CYCLE_P18, 0x2f },
+ { OV2735_REG_PIXEL_CYCLE_P20, 0x62 },
+ { OV2735_REG_PIXEL_CYCLE_P22, 0x5b },
+ { OV2735_REG_PIXEL_CYCLE_P33, 0x0046 },
+ { OV2735_REG_PIXEL_CYCLE_P34, 0x36 },
+ { OV2735_REG_PIXEL_CYCLE_P35_P36, 0x4f },
+ { OV2735_REG_PIXEL_CYCLE_P37_P38, 0xef },
+ { OV2735_REG_PIXEL_CYCLE_P31, 0xcf },
+ { OV2735_REG_PIXEL_CYCLE_P32, 0x36 },
+ { OV2735_REG_PIXEL_CYCLE_P44, 0x0d },
+ { OV2735_REG_PIXEL_CYCLE_P45, 0x0d },
+ { OV2735_REG_PIXEL_BIAS_CTRL_RH_RL, 0x77 },
+ { OV2735_REG_PIXEL_BIAS_CTRL_SH_SL, 0x77 },
+
+ /* Analog ctrl */
+ { OV2735_REG_ANALOG_CTRL4, 0x5a },
+ { OV2735_REG_ANALOG_CTRL5, 0x01 },
+ { OV2735_REG_ANALOG_CTRL6, 0xd2 },
+ { OV2735_REG_ANALOG_CTRL8, 0x40 },
+ { OV2735_REG_PCP_RST_SEL, 0x00 },
+ { OV2735_REG_ICOMP, 0xc3 },
+
+ { OV2735_REG_HS_MIPI, 0x83 },
+ { OV2735_REG_MIPI_CTRL5, 0x0b },
+ { OV2735_REG_MIPI_CTRL6, 0x14 },
+ { OV2735_REG_HIGH_SPEED, 0x40 },
+ { OV2735_REG_MIPI_CTRL3, 0x05 },
+ { OV2735_REG_MIPI_CTRL2, 0x44 },
+ { OV2735_REG_PREPARE, 0x33 },
+ { OV2735_REG_R_HS_ZERO, 0x1f },
+ { OV2735_REG_TRAIL, 0x45 },
+ { OV2735_REG_R_CLK_ZERO, 0x10 },
+ { OV2735_REG_MIPI_CTRL7, 0x70 },
+ { OV2735_REG_ANALOG_CTRL3, 0xe0 },
+ { OV2735_REG_VNCP, 0x7b },
+
+ /* BLC */
+ { OV2735_REG_BLC_GAIN_BLUE, 0x77 },
+ { OV2735_REG_BLC_GAIN_GB, 0x77 },
+ { OV2735_REG_BLC_GAIN_RED, 0x74 },
+ { OV2735_REG_BLC_GAIN_GR, 0x74 },
+ { OV2735_REG_BLC_BPC_TH_P, 0xe0 },
+ { OV2735_REG_BLC_BPC_TH_N, 0xe0 },
+ { OV2735_REG_GB_SUBOFFSET, 0x40 },
+ { OV2735_REG_BLUE_SUBOFFSET, 0x40 },
+ { OV2735_REG_RED_SUBOFFSET, 0x40 },
+ { OV2735_REG_GR_SUBOFFSET, 0x40 },
+};
+
+static const struct ov2735_mode supported_modes[] = {
+ {
+ .width = 1920,
+ .height = 1080,
+ .exp_def = 399,
+ .hts_def = 2200,
+ .vts_def = 2545,
+ .crop = {
+ .top = 8,
+ .left = 8,
+ .width = 1920,
+ .height = 1080,
+ },
+ },
+};
+
+static const s64 link_freq_menu_items[] = {
+ OV2735_LINK_FREQ_420MHZ,
+};
+
+static const struct ov2735_pll_parameters pll_configs[] = {
+ /* For 420MHz pll_configs */
+ {
+ .pll_nc = 4,
+ .pll_mc = 0,
+ .pll_outdiv = 1,
+ },
+};
+
+static const char * const ov2735_test_pattern_menu[] = {
+ "Disabled",
+ "Vertical Color",
+};
+
+static int ov2735_page_access(struct ov2735 *ov2735, u32 reg, int *err)
+{
+ u8 page = reg >> CCI_REG_PRIVATE_SHIFT;
+ int ret = 0;
+
+ if (err && *err)
+ return *err;
+
+ guard(mutex)(&ov2735->page_lock);
+
+ /* Perform page access before read/write */
+ if (ov2735->current_page == page)
+ return ret;
+
+ ret = cci_write(ov2735->cci, OV2735_REG_PAGE_SELECT, page, err);
+ if (!ret)
+ ov2735->current_page = page;
+
+ return ret;
+}
+
+static int ov2735_read(struct ov2735 *ov2735, u32 reg, u64 *val, int *err)
+{
+ u32 addr = reg & ~CCI_REG_PRIVATE_MASK;
+ int ret;
+
+ ret = ov2735_page_access(ov2735, reg, err);
+ if (ret)
+ return ret;
+
+ return cci_read(ov2735->cci, addr, val, err);
+}
+
+static int ov2735_write(struct ov2735 *ov2735, u32 reg, u64 val, int *err)
+{
+ u32 addr = reg & ~CCI_REG_PRIVATE_MASK;
+ int ret;
+
+ ret = ov2735_page_access(ov2735, reg, err);
+ if (ret)
+ return ret;
+
+ return cci_write(ov2735->cci, addr, val, err);
+}
+
+static int ov2735_multi_reg_write(struct ov2735 *ov2735,
+ const struct cci_reg_sequence *regs,
+ unsigned int num_regs, int *err)
+{
+ unsigned int i;
+ int ret;
+
+ for (i = 0; i < num_regs; i++) {
+ ret = ov2735_write(ov2735, regs[i].reg, regs[i].val, err);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static inline struct ov2735 *to_ov2735(struct v4l2_subdev *_sd)
+{
+ return container_of_const(_sd, struct ov2735, sd);
+}
+
+static int ov2735_enable_test_pattern(struct ov2735 *ov2735, u32 pattern)
+{
+ int ret;
+ u64 val;
+
+ ret = ov2735_read(ov2735, OV2735_REG_TEST_PATTERN, &val, NULL);
+ if (ret)
+ return ret;
+
+ switch (pattern) {
+ case 0:
+ val &= ~OV2735_TEST_PATTERN_ENABLE;
+ break;
+ case 1:
+ val |= OV2735_TEST_PATTERN_ENABLE;
+ break;
+ }
+
+ return ov2735_write(ov2735, OV2735_REG_TEST_PATTERN, val, NULL);
+}
+
+static int ov2735_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov2735 *ov2735 =
+ container_of_const(ctrl->handler, struct ov2735, handler);
+ struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_subdev_state *state;
+ u64 vts;
+ int ret = 0;
+
+ state = v4l2_subdev_get_locked_active_state(&ov2735->sd);
+ fmt = v4l2_subdev_state_get_format(state, 0);
+
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ /* Honour the VBLANK limits when setting exposure */
+ s64 max = fmt->height + ctrl->val - OV2735_EXPOSURE_MARGIN;
+
+ ret = __v4l2_ctrl_modify_range(ov2735->exposure,
+ ov2735->exposure->minimum, max,
+ ov2735->exposure->step,
+ ov2735->exposure->default_value);
+ if (ret)
+ return ret;
+ }
+
+ if (pm_runtime_get_if_in_use(ov2735->dev) == 0)
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ ov2735_write(ov2735, OV2735_REG_LONG_EXPOSURE, ctrl->val, &ret);
+ break;
+ case V4L2_CID_ANALOGUE_GAIN:
+ ov2735_write(ov2735, OV2735_REG_ANALOG_GAIN, ctrl->val, &ret);
+ break;
+ case V4L2_CID_HBLANK:
+ ov2735_write(ov2735, OV2735_REG_HBLANK, ctrl->val, &ret);
+ break;
+ case V4L2_CID_VBLANK:
+ vts = ctrl->val + fmt->height;
+ ov2735_write(ov2735, OV2735_REG_FRAME_EXP_SEPERATE_EN,
+ OV2735_FRAME_EXP_SEPERATE_EN, &ret);
+ ov2735_write(ov2735, OV2735_REG_FRAME_LENGTH, vts, &ret);
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = ov2735_enable_test_pattern(ov2735, ctrl->val);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ ov2735_write(ov2735, OV2735_REG_FRAME_SYNC, 0x01, &ret);
+
+ pm_runtime_put(ov2735->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops ov2735_ctrl_ops = {
+ .s_ctrl = ov2735_set_ctrl,
+};
+
+static int ov2735_init_controls(struct ov2735 *ov2735)
+{
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ struct v4l2_fwnode_device_properties props;
+ const struct ov2735_mode *mode = &supported_modes[0];
+ u64 hblank_def, vblank_def, exp_max;
+ int ret;
+
+ ctrl_hdlr = &ov2735->handler;
+ v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+
+ ov2735->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, 0,
+ OV2735_PIXEL_RATE, 1,
+ OV2735_PIXEL_RATE);
+
+ ov2735->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+ ov2735->link_freq_index,
+ 0, link_freq_menu_items);
+ if (ov2735->link_freq)
+ ov2735->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ hblank_def = mode->hts_def - mode->width;
+ ov2735->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_HBLANK, hblank_def,
+ hblank_def, 1, hblank_def);
+
+ vblank_def = mode->vts_def - mode->height;
+ ov2735->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_VBLANK, vblank_def,
+ OV2735_FRAME_LENGTH_MAX - mode->height,
+ 1, vblank_def);
+
+ exp_max = mode->vts_def - OV2735_EXPOSURE_MARGIN;
+ ov2735->exposure =
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ OV2735_EXPOSURE_MIN, exp_max,
+ OV2735_EXPOSURE_STEP, mode->exp_def);
+
+ ov2735->gain =
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_ANALOGUE_GAIN, OV2735_ANALOG_GAIN_MIN,
+ OV2735_ANALOG_GAIN_MAX, OV2735_ANALOG_GAIN_STEP,
+ OV2735_ANALOG_GAIN_DEFAULT);
+
+ ov2735->test_pattern =
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov2735_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(ov2735_test_pattern_menu) - 1,
+ 0, 0, ov2735_test_pattern_menu);
+
+ if (ctrl_hdlr->error) {
+ ret = ctrl_hdlr->error;
+ dev_err(ov2735->dev, "control init failed (%d)\n", ret);
+ goto err_handler_free;
+ }
+
+ ret = v4l2_fwnode_device_parse(ov2735->dev, &props);
+ if (ret)
+ goto err_handler_free;
+
+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr,
+ &ov2735_ctrl_ops, &props);
+ if (ret)
+ goto err_handler_free;
+
+ ov2735->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
+
+err_handler_free:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+
+ return ret;
+}
+
+static int ov2735_set_pll_ctrl(struct ov2735 *ov2735)
+{
+ const struct ov2735_pll_parameters *pll_parameters;
+ u8 pll_ctrl;
+ u8 pll_outdiv;
+ int ret = 0;
+
+ pll_parameters = &pll_configs[ov2735->link_freq_index];
+
+ /* BIT[7]: pll_clk_sel, BIT[6:2]: pll_nc, BIT[1:0]: pll_mc */
+ pll_ctrl = ((pll_parameters->pll_nc << 2) | (pll_parameters->pll_mc << 0)) &
+ OV2735_PLL_CTRL_ENABLE;
+
+ pll_outdiv = pll_parameters->pll_outdiv;
+
+ ov2735_write(ov2735, OV2735_REG_PLL_CTRL, pll_ctrl, &ret);
+ ov2735_write(ov2735, OV2735_REG_PLL_OUTDIV, pll_outdiv, &ret);
+
+ return ret;
+}
+
+static int ov2735_set_framefmt(struct ov2735 *ov2735,
+ struct v4l2_subdev_state *state)
+{
+ const struct v4l2_mbus_framefmt *format;
+ const struct v4l2_rect *crop;
+ int ret = 0;
+
+ format = v4l2_subdev_state_get_format(state, 0);
+ crop = v4l2_subdev_state_get_crop(state, 0);
+
+ ov2735_write(ov2735, OV2735_REG_V_START, crop->top, &ret);
+ ov2735_write(ov2735, OV2735_REG_V_SIZE, format->height, &ret);
+ ov2735_write(ov2735, OV2735_REG_MIPI_LINE_NUMBER, format->height, &ret);
+ ov2735_write(ov2735, OV2735_REG_H_START, crop->left, &ret);
+ /* OV2735_REG_H_SIZE: Image half horizontal size */
+ ov2735_write(ov2735, OV2735_REG_H_SIZE, (format->width / 2), &ret);
+ ov2735_write(ov2735, OV2735_REG_MIPI_COLOMN_NUMBER, format->width, &ret);
+
+ return ret;
+}
+
+static int ov2735_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct ov2735 *ov2735 = to_ov2735(sd);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(ov2735->dev);
+ if (ret < 0)
+ return ret;
+
+ /* Apply pll settings */
+ ret = ov2735_set_pll_ctrl(ov2735);
+ if (ret) {
+ dev_err(ov2735->dev, "failed to set frame format: %d\n", ret);
+ goto err_rpm_put;
+ }
+
+ ret = ov2735_multi_reg_write(ov2735, ov2735_common_regs,
+ ARRAY_SIZE(ov2735_common_regs), NULL);
+ if (ret) {
+ dev_err(ov2735->dev, "failed to write common registers\n");
+ goto err_rpm_put;
+ }
+
+ /* Apply format settings */
+ ret = ov2735_set_framefmt(ov2735, state);
+ if (ret) {
+ dev_err(ov2735->dev, "failed to set frame format: %d\n", ret);
+ goto err_rpm_put;
+ }
+
+ /* Apply customized values from user */
+ ret = __v4l2_ctrl_handler_setup(ov2735->sd.ctrl_handler);
+ if (ret)
+ goto err_rpm_put;
+
+ ret = ov2735_write(ov2735, OV2735_REG_STREAM_CTRL,
+ OV2735_STREAM_CTRL_ON, NULL);
+ if (ret)
+ goto err_rpm_put;
+
+ return 0;
+
+err_rpm_put:
+ pm_runtime_put(ov2735->dev);
+ return ret;
+}
+
+static int ov2735_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct ov2735 *ov2735 = to_ov2735(sd);
+ int ret;
+
+ ret = ov2735_write(ov2735, OV2735_REG_STREAM_CTRL,
+ OV2735_STREAM_CTRL_OFF, NULL);
+ if (ret)
+ dev_err(ov2735->dev, "%s failed to set stream\n", __func__);
+
+ pm_runtime_put(ov2735->dev);
+
+ return ret;
+}
+
+static int ov2735_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
+ return 0;
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r = ov2735_native_area;
+ return 0;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r = ov2735_active_area;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int ov2735_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+
+ return 0;
+}
+
+static int ov2735_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ARRAY_SIZE(supported_modes))
+ return -EINVAL;
+
+ if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+ return -EINVAL;
+
+ fse->min_width = supported_modes[fse->index].width;
+ fse->max_width = fse->min_width;
+ fse->min_height = supported_modes[fse->index].height;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static int ov2735_set_framing_limits(struct ov2735 *ov2735,
+ const struct ov2735_mode *mode)
+{
+ u32 hblank, vblank_def;
+ int ret;
+
+ hblank = mode->hts_def - mode->width;
+ ret = __v4l2_ctrl_modify_range(ov2735->hblank, hblank, hblank, 1,
+ hblank);
+ if (ret)
+ return ret;
+
+ vblank_def = mode->vts_def - mode->height;
+ return __v4l2_ctrl_modify_range(ov2735->vblank, vblank_def,
+ OV2735_FRAME_LENGTH_MAX - mode->height,
+ 1, vblank_def);
+}
+
+static int ov2735_set_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *fmt)
+{
+ struct v4l2_mbus_framefmt *format;
+ const struct ov2735_mode *mode;
+ struct v4l2_rect *crop;
+ struct ov2735 *ov2735 = to_ov2735(sd);
+ int ret;
+
+ format = v4l2_subdev_state_get_format(sd_state, 0);
+
+ mode = v4l2_find_nearest_size(supported_modes,
+ ARRAY_SIZE(supported_modes),
+ width, height,
+ fmt->format.width, fmt->format.height);
+
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+ fmt->format.field = V4L2_FIELD_NONE;
+ fmt->format.colorspace = V4L2_COLORSPACE_RAW;
+ fmt->format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+ ret = ov2735_set_framing_limits(ov2735, mode);
+ if (ret)
+ return ret;
+ }
+
+ *format = fmt->format;
+
+ /* Initialize crop rectangle */
+ crop = v4l2_subdev_state_get_crop(sd_state, 0);
+ *crop = mode->crop;
+
+ return 0;
+}
+
+static int ov2735_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_TRY,
+ .format = {
+ .code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .width = supported_modes[0].width,
+ .height = supported_modes[0].height,
+ },
+ };
+
+ ov2735_set_pad_format(sd, state, &fmt);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov2735_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops ov2735_pad_ops = {
+ .enum_mbus_code = ov2735_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = ov2735_set_pad_format,
+ .get_selection = ov2735_get_selection,
+ .enum_frame_size = ov2735_enum_frame_size,
+ .enable_streams = ov2735_enable_streams,
+ .disable_streams = ov2735_disable_streams,
+};
+
+static const struct v4l2_subdev_ops ov2735_subdev_ops = {
+ .video = &ov2735_video_ops,
+ .pad = &ov2735_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops ov2735_internal_ops = {
+ .init_state = ov2735_init_state,
+};
+
+static int ov2735_power_on(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov2735 *ov2735 = to_ov2735(sd);
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ov2735_supply_name),
+ ov2735->supplies);
+ if (ret) {
+ dev_err(ov2735->dev, "failed to enable regulators\n");
+ return ret;
+ }
+
+ gpiod_set_value_cansleep(ov2735->enable_gpio, 1);
+ /* T4: delay from PWDN pulling low to RSTB pulling high */
+ fsleep(4 * USEC_PER_MSEC);
+
+ ret = clk_prepare_enable(ov2735->xclk);
+ if (ret) {
+ dev_err(ov2735->dev, "failed to enable clock\n");
+ goto err_regulator_off;
+ }
+
+ gpiod_set_value_cansleep(ov2735->reset_gpio, 0);
+ /* T5: delay from RSTB pulling high to first I2C command */
+ fsleep(5 * USEC_PER_MSEC);
+
+ return 0;
+
+err_regulator_off:
+ regulator_bulk_disable(ARRAY_SIZE(ov2735_supply_name), ov2735->supplies);
+ return ret;
+}
+
+static int ov2735_power_off(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov2735 *ov2735 = to_ov2735(sd);
+
+ gpiod_set_value_cansleep(ov2735->enable_gpio, 0);
+ clk_disable_unprepare(ov2735->xclk);
+ gpiod_set_value_cansleep(ov2735->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(ov2735_supply_name), ov2735->supplies);
+
+ return 0;
+}
+
+static int ov2735_get_regulators(struct ov2735 *ov2735)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ov2735_supply_name); i++)
+ ov2735->supplies[i].supply = ov2735_supply_name[i];
+
+ return devm_regulator_bulk_get(ov2735->dev,
+ ARRAY_SIZE(ov2735_supply_name),
+ ov2735->supplies);
+}
+
+static int ov2735_identify_module(struct ov2735 *ov2735)
+{
+ u64 chip_id;
+ int ret;
+
+ ret = ov2735_read(ov2735, OV2735_REG_CHIPID, &chip_id, NULL);
+ if (ret)
+ return dev_err_probe(ov2735->dev, ret,
+ "failed to read chip id %x\n",
+ OV2735_CHIPID);
+
+ if (chip_id != OV2735_CHIPID)
+ return dev_err_probe(ov2735->dev, -EIO,
+ "chip id mismatch: %x!=%llx\n",
+ OV2735_CHIPID, chip_id);
+
+ return 0;
+}
+
+static int ov2735_parse_endpoint(struct ov2735 *ov2735)
+{
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY,
+ };
+ struct fwnode_handle *ep;
+ unsigned long link_freq_bitmap;
+ int ret;
+
+ ep = fwnode_graph_get_next_endpoint(dev_fwnode(ov2735->dev), NULL);
+ if (!ep)
+ return dev_err_probe(ov2735->dev, -ENXIO,
+ "Failed to get next endpoint\n");
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+ fwnode_handle_put(ep);
+ if (ret)
+ return ret;
+
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
+ ret = dev_err_probe(ov2735->dev, -EINVAL,
+ "only 2 data lanes are supported\n");
+ goto error_out;
+ }
+
+ ret = v4l2_link_freq_to_bitmap(ov2735->dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq_menu_items,
+ ARRAY_SIZE(link_freq_menu_items),
+ &link_freq_bitmap);
+ if (ret) {
+ ret = dev_err_probe(ov2735->dev, -EINVAL,
+ "only 420MHz frequency is available\n");
+ goto error_out;
+ }
+
+ ov2735->link_freq_index = __ffs(link_freq_bitmap);
+
+error_out:
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+
+ return ret;
+};
+
+static int ov2735_probe(struct i2c_client *client)
+{
+ struct ov2735 *ov2735;
+ unsigned int xclk_freq;
+ int ret;
+
+ ov2735 = devm_kzalloc(&client->dev, sizeof(*ov2735), GFP_KERNEL);
+ if (!ov2735)
+ return -ENOMEM;
+
+ ov2735->dev = &client->dev;
+
+ v4l2_i2c_subdev_init(&ov2735->sd, client, &ov2735_subdev_ops);
+ ov2735->sd.internal_ops = &ov2735_internal_ops;
+
+ ov2735->cci = devm_cci_regmap_init_i2c(client, 8);
+ if (IS_ERR(ov2735->cci))
+ return dev_err_probe(ov2735->dev, PTR_ERR(ov2735->cci),
+ "failed to initialize CCI\n");
+
+ /* Set Current page to 0 */
+ ov2735->current_page = 0;
+
+ ret = devm_mutex_init(ov2735->dev, &ov2735->page_lock);
+ if (ret)
+ return dev_err_probe(ov2735->dev, ret,
+ "Failed to initialize lock\n");
+
+ /* Get system clock (xvclk) */
+ ov2735->xclk = devm_v4l2_sensor_clk_get(ov2735->dev, NULL);
+ if (IS_ERR(ov2735->xclk))
+ return dev_err_probe(ov2735->dev, PTR_ERR(ov2735->xclk),
+ "failed to get xclk\n");
+
+ xclk_freq = clk_get_rate(ov2735->xclk);
+ if (xclk_freq != OV2735_XCLK_FREQ)
+ return dev_err_probe(ov2735->dev, -EINVAL,
+ "xclk frequency not supported: %u Hz\n",
+ xclk_freq);
+
+ ret = ov2735_get_regulators(ov2735);
+ if (ret)
+ return dev_err_probe(ov2735->dev, ret,
+ "failed to get regulators\n");
+
+ ret = ov2735_parse_endpoint(ov2735);
+ if (ret)
+ return dev_err_probe(ov2735->dev, ret,
+ "failed to parse endpoint configuration\n");
+
+ ov2735->reset_gpio = devm_gpiod_get_optional(ov2735->dev,
+ "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ov2735->reset_gpio))
+ return dev_err_probe(ov2735->dev, PTR_ERR(ov2735->reset_gpio),
+ "failed to get reset GPIO\n");
+
+ ov2735->enable_gpio = devm_gpiod_get_optional(ov2735->dev,
+ "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(ov2735->enable_gpio))
+ return dev_err_probe(ov2735->dev, PTR_ERR(ov2735->enable_gpio),
+ "failed to get enable GPIO\n");
+
+ ret = ov2735_power_on(ov2735->dev);
+ if (ret)
+ return ret;
+
+ ret = ov2735_identify_module(ov2735);
+ if (ret)
+ goto error_power_off;
+
+ ret = ov2735_init_controls(ov2735);
+ if (ret)
+ goto error_power_off;
+
+ /* Initialize subdev */
+ ov2735->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ ov2735->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ov2735->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&ov2735->sd.entity, 1, &ov2735->pad);
+ if (ret) {
+ dev_err_probe(ov2735->dev, ret, "failed to init entity pads\n");
+ goto error_handler_free;
+ }
+
+ ov2735->sd.state_lock = ov2735->handler.lock;
+ ret = v4l2_subdev_init_finalize(&ov2735->sd);
+ if (ret) {
+ dev_err_probe(ov2735->dev, ret, "subdev init error\n");
+ goto error_media_entity;
+ }
+
+ ret = devm_pm_runtime_get_noresume(ov2735->dev);
+ if (ret) {
+ dev_err_probe(ov2735->dev, ret,
+ "failed to get runtime PM noresume\n");
+ goto error_subdev_cleanup;
+ }
+
+ ret = devm_pm_runtime_set_active_enabled(ov2735->dev);
+ if (ret) {
+ dev_err_probe(ov2735->dev, ret,
+ "failed to set runtime PM active+enabled\n");
+ goto error_subdev_cleanup;
+ }
+
+ ret = v4l2_async_register_subdev_sensor(&ov2735->sd);
+ if (ret) {
+ dev_err_probe(ov2735->dev, ret,
+ "failed to register ov2735 sub-device\n");
+ goto error_subdev_cleanup;
+ }
+
+ return 0;
+
+error_subdev_cleanup:
+ v4l2_subdev_cleanup(&ov2735->sd);
+
+error_media_entity:
+ media_entity_cleanup(&ov2735->sd.entity);
+
+error_handler_free:
+ v4l2_ctrl_handler_free(ov2735->sd.ctrl_handler);
+
+error_power_off:
+ ov2735_power_off(ov2735->dev);
+
+ return ret;
+}
+
+static void ov2735_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov2735 *ov2735 = to_ov2735(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(&ov2735->sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(ov2735->sd.ctrl_handler);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(ov2735_pm_ops,
+ ov2735_power_off, ov2735_power_on, NULL);
+
+static const struct of_device_id ov2735_id[] = {
+ { .compatible = "ovti,ov2735" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ov2735_id);
+
+static struct i2c_driver ov2735_driver = {
+ .driver = {
+ .name = "ov2735",
+ .pm = pm_ptr(&ov2735_pm_ops),
+ .of_match_table = ov2735_id,
+ },
+ .probe = ov2735_probe,
+ .remove = ov2735_remove,
+};
+module_i2c_driver(ov2735_driver);
+
+MODULE_DESCRIPTION("OV2735 Camera Sensor Driver");
+MODULE_AUTHOR("Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>");
+MODULE_AUTHOR("Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index 4e959534e6e7..fb590dfadda1 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -1,17 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
-#include <linux/pm_runtime.h>
#include <linux/nvmem-provider.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -519,6 +519,8 @@ static const struct ov2740_mode supported_modes_180mhz[] = {
};
struct ov2740 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -616,7 +618,6 @@ static int ov2740_write_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 val)
static int ov2740_write_reg_list(struct ov2740 *ov2740,
const struct ov2740_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
unsigned int i;
int ret;
@@ -624,7 +625,7 @@ static int ov2740_write_reg_list(struct ov2740 *ov2740,
ret = ov2740_write_reg(ov2740, r_list->regs[i].address, 1,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov2740->dev,
"write reg 0x%4.4x return err = %d\n",
r_list->regs[i].address, ret);
return ret;
@@ -636,7 +637,6 @@ static int ov2740_write_reg_list(struct ov2740 *ov2740,
static int ov2740_identify_module(struct ov2740 *ov2740)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
int ret;
u32 val;
@@ -648,12 +648,12 @@ static int ov2740_identify_module(struct ov2740 *ov2740)
return ret;
if (val != OV2740_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x != %x\n",
+ dev_err(ov2740->dev, "chip id mismatch: %x != %x\n",
OV2740_CHIP_ID, val);
return -ENXIO;
}
- dev_dbg(&client->dev, "chip id: 0x%x\n", val);
+ dev_dbg(ov2740->dev, "chip id: 0x%x\n", val);
ov2740->identified = true;
@@ -704,7 +704,6 @@ static int ov2740_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov2740 *ov2740 = container_of(ctrl->handler,
struct ov2740, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
s64 exposure_max;
int ret;
@@ -720,7 +719,7 @@ static int ov2740_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov2740->dev))
return 0;
switch (ctrl->id) {
@@ -753,7 +752,7 @@ static int ov2740_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov2740->dev);
return ret;
}
@@ -764,7 +763,6 @@ static const struct v4l2_ctrl_ops ov2740_ctrl_ops = {
static int ov2740_init_controls(struct ov2740 *ov2740)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max, h_blank, pixel_rate;
u32 vblank_min, vblank_max, vblank_default;
@@ -821,7 +819,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740)
ARRAY_SIZE(ov2740_test_pattern_menu) - 1,
0, 0, ov2740_test_pattern_menu);
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov2740->dev, &props);
if (ret) {
v4l2_ctrl_handler_free(ctrl_hdlr);
return ret;
@@ -940,7 +938,6 @@ err:
static int ov2740_start_streaming(struct ov2740 *ov2740)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
const struct ov2740_reg_list *reg_list;
int link_freq_index;
int ret;
@@ -955,7 +952,7 @@ static int ov2740_start_streaming(struct ov2740 *ov2740)
/* Reset the sensor */
ret = ov2740_write_reg(ov2740, 0x0103, 1, 0x01);
if (ret) {
- dev_err(&client->dev, "failed to reset\n");
+ dev_err(ov2740->dev, "failed to reset\n");
return ret;
}
@@ -965,14 +962,14 @@ static int ov2740_start_streaming(struct ov2740 *ov2740)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov2740_write_reg_list(ov2740, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls\n");
+ dev_err(ov2740->dev, "failed to set plls\n");
return ret;
}
reg_list = &ov2740->cur_mode->reg_list;
ret = ov2740_write_reg_list(ov2740, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode\n");
+ dev_err(ov2740->dev, "failed to set mode\n");
return ret;
}
@@ -983,31 +980,28 @@ static int ov2740_start_streaming(struct ov2740 *ov2740)
ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
OV2740_MODE_STREAMING);
if (ret)
- dev_err(&client->dev, "failed to start streaming\n");
+ dev_err(ov2740->dev, "failed to start streaming\n");
return ret;
}
static void ov2740_stop_streaming(struct ov2740 *ov2740)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
-
if (ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
OV2740_MODE_STANDBY))
- dev_err(&client->dev, "failed to stop streaming\n");
+ dev_err(ov2740->dev, "failed to stop streaming\n");
}
static int ov2740_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov2740 *ov2740 = to_ov2740(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct v4l2_subdev_state *sd_state;
int ret = 0;
sd_state = v4l2_subdev_lock_and_get_active_state(&ov2740->sd);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov2740->dev);
if (ret < 0)
goto out_unlock;
@@ -1015,11 +1009,11 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
ov2740_stop_streaming(ov2740);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov2740->dev);
}
} else {
ov2740_stop_streaming(ov2740);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov2740->dev);
}
out_unlock:
@@ -1131,16 +1125,14 @@ static const struct media_entity_operations ov2740_subdev_entity_ops = {
.link_validate = v4l2_subdev_link_validate,
};
-static int ov2740_check_hwcfg(struct device *dev)
+static int ov2740_check_hwcfg(struct ov2740 *ov2740)
{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct ov2740 *ov2740 = to_ov2740(sd);
+ struct device *dev = ov2740->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
- u32 mclk;
int ret;
unsigned int i, j;
@@ -1153,20 +1145,6 @@ static int ov2740_check_hwcfg(struct device *dev)
return dev_err_probe(dev, -EPROBE_DEFER,
"waiting for fwnode graph endpoint\n");
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
- if (ret) {
- fwnode_handle_put(ep);
- return dev_err_probe(dev, ret,
- "reading clock-frequency property\n");
- }
-
- if (mclk != OV2740_MCLK) {
- fwnode_handle_put(ep);
- return dev_err_probe(dev, -EINVAL,
- "external clock %d is not supported\n",
- mclk);
- }
-
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
fwnode_handle_put(ep);
if (ret)
@@ -1270,7 +1248,7 @@ static int ov2740_register_nvmem(struct i2c_client *client,
struct regmap_config regmap_config = { };
struct nvmem_config nvmem_config = { };
struct regmap *regmap;
- struct device *dev = &client->dev;
+ struct device *dev = ov2740->dev;
nvm = devm_kzalloc(dev, sizeof(*nvm), GFP_KERNEL);
if (!nvm)
@@ -1349,6 +1327,7 @@ static int ov2740_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct ov2740 *ov2740;
+ unsigned long freq;
bool full_power;
unsigned int i;
int ret;
@@ -1357,10 +1336,12 @@ static int ov2740_probe(struct i2c_client *client)
if (!ov2740)
return -ENOMEM;
+ ov2740->dev = &client->dev;
+
v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops);
ov2740->sd.internal_ops = &ov2740_internal_ops;
- ret = ov2740_check_hwcfg(dev);
+ ret = ov2740_check_hwcfg(ov2740);
if (ret)
return ret;
@@ -1384,11 +1365,17 @@ static int ov2740_probe(struct i2c_client *client)
msleep(20);
}
- ov2740->clk = devm_clk_get_optional(dev, "clk");
+ ov2740->clk = devm_v4l2_sensor_clk_get(dev, "clk");
if (IS_ERR(ov2740->clk))
return dev_err_probe(dev, PTR_ERR(ov2740->clk),
"failed to get clock\n");
+ freq = clk_get_rate(ov2740->clk);
+ if (freq != OV2740_MCLK)
+ return dev_err_probe(dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ freq);
+
for (i = 0; i < ARRAY_SIZE(ov2740_supply_name); i++)
ov2740->supplies[i].supply = ov2740_supply_name[i];
@@ -1397,7 +1384,7 @@ static int ov2740_probe(struct i2c_client *client)
if (ret)
return dev_err_probe(dev, ret, "failed to get regulators\n");
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(ov2740->dev);
if (full_power) {
/* ACPI does not always clear the reset GPIO / enable the clock */
ret = ov2740_resume(dev);
@@ -1435,9 +1422,9 @@ static int ov2740_probe(struct i2c_client *client)
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov2740->dev);
+ pm_runtime_enable(ov2740->dev);
+ pm_runtime_idle(ov2740->dev);
ret = v4l2_async_register_subdev_sensor(&ov2740->sd);
if (ret < 0) {
@@ -1447,13 +1434,13 @@ static int ov2740_probe(struct i2c_client *client)
ret = ov2740_register_nvmem(client, ov2740);
if (ret)
- dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret);
+ dev_warn(ov2740->dev, "register nvmem failed, ret %d\n", ret);
return 0;
probe_error_v4l2_subdev_cleanup:
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov2740->dev);
+ pm_runtime_set_suspended(ov2740->dev);
v4l2_subdev_cleanup(&ov2740->sd);
probe_error_media_entity_cleanup:
diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c
index 7d740ad3926f..a59d25b09b5b 100644
--- a/drivers/media/i2c/ov4689.c
+++ b/drivers/media/i2c/ov4689.c
@@ -907,20 +907,12 @@ static int ov4689_probe(struct i2c_client *client)
ov4689->cur_mode = &supported_modes[OV4689_MODE_2688_1520];
- ov4689->xvclk = devm_clk_get_optional(dev, NULL);
+ ov4689->xvclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(ov4689->xvclk))
return dev_err_probe(dev, PTR_ERR(ov4689->xvclk),
"Failed to get external clock\n");
- if (!ov4689->xvclk) {
- dev_dbg(dev,
- "No clock provided, using clock-frequency property\n");
- device_property_read_u32(dev, "clock-frequency",
- &ov4689->clock_rate);
- } else {
- ov4689->clock_rate = clk_get_rate(ov4689->xvclk);
- }
-
+ ov4689->clock_rate = clk_get_rate(ov4689->xvclk);
if (ov4689->clock_rate != OV4689_XVCLK_FREQ) {
dev_err(dev,
"External clock rate mismatch: got %d Hz, expected %d Hz\n",
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 84198613381d..85ecc23b3587 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -3895,11 +3895,10 @@ static int ov5640_probe(struct i2c_client *client)
ov5640_dvp_default_fmt;
/* get system clock (xclk) */
- sensor->xclk = devm_clk_get(dev, "xclk");
- if (IS_ERR(sensor->xclk)) {
- dev_err(dev, "failed to get xclk\n");
- return PTR_ERR(sensor->xclk);
- }
+ sensor->xclk = devm_v4l2_sensor_clk_get(dev, "xclk");
+ if (IS_ERR(sensor->xclk))
+ return dev_err_probe(dev, PTR_ERR(sensor->xclk),
+ "failed to get xclk\n");
sensor->xclk_freq = clk_get_rate(sensor->xclk);
if (sensor->xclk_freq < OV5640_XCLK_MIN ||
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index 58c846a44376..b10d408034a1 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -1042,27 +1042,18 @@ static int ov5645_probe(struct i2c_client *client)
"invalid bus type, must be CSI2\n");
/* get system clock (xclk) */
- ov5645->xclk = devm_clk_get(dev, NULL);
+ ov5645->xclk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, false, 0);
if (IS_ERR(ov5645->xclk))
return dev_err_probe(dev, PTR_ERR(ov5645->xclk),
"could not get xclk");
- ret = of_property_read_u32(dev->of_node, "clock-frequency", &xclk_freq);
- if (ret)
- return dev_err_probe(dev, ret,
- "could not get xclk frequency\n");
-
/* external clock must be 24MHz, allow 1% tolerance */
+ xclk_freq = clk_get_rate(ov5645->xclk);
if (xclk_freq < 23760000 || xclk_freq > 24240000)
return dev_err_probe(dev, -EINVAL,
"unsupported xclk frequency %u\n",
xclk_freq);
- ret = clk_set_rate(ov5645->xclk, xclk_freq);
- if (ret)
- return dev_err_probe(dev, ret,
- "could not set xclk frequency\n");
-
for (i = 0; i < OV5645_NUM_SUPPLIES; i++)
ov5645->supplies[i].supply = ov5645_supply_name[i];
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index a727beb9d57e..e193fef4fced 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1398,11 +1398,10 @@ static int ov5647_probe(struct i2c_client *client)
}
}
- sensor->xclk = devm_clk_get(dev, NULL);
- if (IS_ERR(sensor->xclk)) {
- dev_err(dev, "could not get xclk");
- return PTR_ERR(sensor->xclk);
- }
+ sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
+ if (IS_ERR(sensor->xclk))
+ return dev_err_probe(dev, PTR_ERR(sensor->xclk),
+ "could not get xclk\n");
xclk_freq = clk_get_rate(sensor->xclk);
if (xclk_freq != 25000000) {
diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c
index 4b86d2631bd1..f0b839cd65f1 100644
--- a/drivers/media/i2c/ov5648.c
+++ b/drivers/media/i2c/ov5648.c
@@ -1061,8 +1061,8 @@ static int ov5648_sw_standby(struct ov5648_sensor *sensor, int standby)
static int ov5648_chip_id_check(struct ov5648_sensor *sensor)
{
- u16 regs[] = { OV5648_CHIP_ID_H_REG, OV5648_CHIP_ID_L_REG };
- u8 values[] = { OV5648_CHIP_ID_H_VALUE, OV5648_CHIP_ID_L_VALUE };
+ static const u16 regs[] = { OV5648_CHIP_ID_H_REG, OV5648_CHIP_ID_L_REG };
+ static const u8 values[] = { OV5648_CHIP_ID_H_VALUE, OV5648_CHIP_ID_L_VALUE };
unsigned int i;
u8 value;
int ret;
@@ -2521,10 +2521,10 @@ static int ov5648_probe(struct i2c_client *client)
/* External Clock */
- sensor->xvclk = devm_clk_get(dev, NULL);
+ sensor->xvclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(sensor->xvclk)) {
- dev_err(dev, "failed to get external clock\n");
- ret = PTR_ERR(sensor->xvclk);
+ ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk),
+ "failed to get external clock\n");
goto error_endpoint;
}
diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index b9efb2d2276a..04b3183b7bcb 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -12,6 +11,8 @@
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
@@ -1854,6 +1855,8 @@ static const struct ov5670_mode supported_modes[] = {
};
struct ov5670 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_fwnode_endpoint endpoint;
@@ -1959,7 +1962,6 @@ static int ov5670_write_reg(struct ov5670 *ov5670, u16 reg, unsigned int len,
static int ov5670_write_regs(struct ov5670 *ov5670,
const struct ov5670_reg *regs, unsigned int len)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
unsigned int i;
int ret;
@@ -1967,7 +1969,7 @@ static int ov5670_write_regs(struct ov5670 *ov5670,
ret = ov5670_write_reg(ov5670, regs[i].address, 1, regs[i].val);
if (ret) {
dev_err_ratelimited(
- &client->dev,
+ ov5670->dev,
"Failed to write reg 0x%4.4x. error = %d\n",
regs[i].address, ret);
@@ -2032,7 +2034,6 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov5670 *ov5670 = container_of(ctrl->handler,
struct ov5670, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
s64 max;
int ret;
@@ -2048,7 +2049,7 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov5670->dev))
return 0;
switch (ctrl->id) {
@@ -2080,12 +2081,12 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
break;
default:
ret = -EINVAL;
- dev_info(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+ dev_info(ov5670->dev, "%s Unhandled id:0x%x, val:0x%x\n",
__func__, ctrl->id, ctrl->val);
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov5670->dev);
return ret;
}
@@ -2099,7 +2100,6 @@ static int ov5670_init_controls(struct ov5670 *ov5670)
{
struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =
&ov5670->endpoint.bus.mipi_csi2;
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
unsigned int lanes_count;
@@ -2177,7 +2177,7 @@ static int ov5670_init_controls(struct ov5670 *ov5670)
goto error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov5670->dev, &props);
if (ret)
goto error;
@@ -2350,7 +2350,6 @@ static int ov5670_get_skip_frames(struct v4l2_subdev *sd, u32 *frames)
/* Verify chip ID */
static int ov5670_identify_module(struct ov5670 *ov5670)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
int ret;
u32 val;
@@ -2363,7 +2362,7 @@ static int ov5670_identify_module(struct ov5670 *ov5670)
return ret;
if (val != OV5670_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(ov5670->dev, "chip id mismatch: %x!=%x\n",
OV5670_CHIP_ID, val);
return -ENXIO;
}
@@ -2389,7 +2388,6 @@ static int ov5670_mipi_configure(struct ov5670 *ov5670)
/* Prepare streaming by writing default values and customized values */
static int ov5670_start_streaming(struct ov5670 *ov5670)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
const struct ov5670_reg_list *reg_list;
int link_freq_index;
int ret;
@@ -2402,7 +2400,7 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
ret = ov5670_write_reg(ov5670, OV5670_REG_SOFTWARE_RST,
OV5670_REG_VALUE_08BIT, OV5670_SOFTWARE_RST);
if (ret) {
- dev_err(&client->dev, "%s failed to set powerup registers\n",
+ dev_err(ov5670->dev, "%s failed to set powerup registers\n",
__func__);
return ret;
}
@@ -2412,7 +2410,7 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov5670_write_reg_list(ov5670, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set plls\n", __func__);
+ dev_err(ov5670->dev, "%s failed to set plls\n", __func__);
return ret;
}
@@ -2420,13 +2418,13 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
reg_list = &ov5670->cur_mode->reg_list;
ret = ov5670_write_reg_list(ov5670, reg_list);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(ov5670->dev, "%s failed to set mode\n", __func__);
return ret;
}
ret = ov5670_mipi_configure(ov5670);
if (ret) {
- dev_err(&client->dev, "%s failed to configure MIPI\n", __func__);
+ dev_err(ov5670->dev, "%s failed to configure MIPI\n", __func__);
return ret;
}
@@ -2438,7 +2436,7 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
ret = ov5670_write_reg(ov5670, OV5670_REG_MODE_SELECT,
OV5670_REG_VALUE_08BIT, OV5670_MODE_STREAMING);
if (ret) {
- dev_err(&client->dev, "%s failed to set stream\n", __func__);
+ dev_err(ov5670->dev, "%s failed to set stream\n", __func__);
return ret;
}
@@ -2447,13 +2445,12 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
static int ov5670_stop_streaming(struct ov5670 *ov5670)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
int ret;
ret = ov5670_write_reg(ov5670, OV5670_REG_MODE_SELECT,
OV5670_REG_VALUE_08BIT, OV5670_MODE_STANDBY);
if (ret)
- dev_err(&client->dev, "%s failed to set stream\n", __func__);
+ dev_err(ov5670->dev, "%s failed to set stream\n", __func__);
/* Return success even if it was an error, as there is nothing the
* caller can do about it.
@@ -2464,13 +2461,12 @@ static int ov5670_stop_streaming(struct ov5670 *ov5670)
static int ov5670_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov5670 *ov5670 = to_ov5670(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov5670->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov5670->dev);
if (ret < 0)
goto unlock_and_return;
@@ -2479,12 +2475,12 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable)
goto error;
} else {
ret = ov5670_stop_streaming(ov5670);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov5670->dev);
}
goto unlock_and_return;
error:
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov5670->dev);
unlock_and_return:
mutex_unlock(&ov5670->mutex);
@@ -2621,26 +2617,23 @@ static const struct media_entity_operations ov5670_subdev_entity_ops = {
static int ov5670_regulators_probe(struct ov5670 *ov5670)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
unsigned int i;
for (i = 0; i < OV5670_NUM_SUPPLIES; i++)
ov5670->supplies[i].supply = ov5670_supply_names[i];
- return devm_regulator_bulk_get(&client->dev, OV5670_NUM_SUPPLIES,
+ return devm_regulator_bulk_get(ov5670->dev, OV5670_NUM_SUPPLIES,
ov5670->supplies);
}
static int ov5670_gpio_probe(struct ov5670 *ov5670)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
-
- ov5670->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
+ ov5670->pwdn_gpio = devm_gpiod_get_optional(ov5670->dev, "powerdown",
GPIOD_OUT_LOW);
if (IS_ERR(ov5670->pwdn_gpio))
return PTR_ERR(ov5670->pwdn_gpio);
- ov5670->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ ov5670->reset_gpio = devm_gpiod_get_optional(ov5670->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(ov5670->reset_gpio))
return PTR_ERR(ov5670->reset_gpio);
@@ -2660,18 +2653,16 @@ static int ov5670_probe(struct i2c_client *client)
if (!ov5670)
return -ENOMEM;
- ov5670->xvclk = devm_clk_get_optional(&client->dev, NULL);
- if (!IS_ERR_OR_NULL(ov5670->xvclk))
- input_clk = clk_get_rate(ov5670->xvclk);
- else if (!ov5670->xvclk || PTR_ERR(ov5670->xvclk) == -ENOENT)
- device_property_read_u32(&client->dev, "clock-frequency",
- &input_clk);
- else
- return dev_err_probe(&client->dev, PTR_ERR(ov5670->xvclk),
+ ov5670->dev = &client->dev;
+
+ ov5670->xvclk = devm_v4l2_sensor_clk_get(ov5670->dev, NULL);
+ if (IS_ERR(ov5670->xvclk))
+ return dev_err_probe(ov5670->dev, PTR_ERR(ov5670->xvclk),
"error getting clock\n");
+ input_clk = clk_get_rate(ov5670->xvclk);
if (input_clk != OV5670_XVCLK_FREQ) {
- dev_err(&client->dev,
+ dev_err(ov5670->dev,
"Unsupported clock frequency %u\n", input_clk);
return -EINVAL;
}
@@ -2682,20 +2673,20 @@ static int ov5670_probe(struct i2c_client *client)
ret = ov5670_regulators_probe(ov5670);
if (ret)
- return dev_err_probe(&client->dev, ret, "Regulators probe failed\n");
+ return dev_err_probe(ov5670->dev, ret, "Regulators probe failed\n");
ret = ov5670_gpio_probe(ov5670);
if (ret)
- return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");
+ return dev_err_probe(ov5670->dev, ret, "GPIO probe failed\n");
/*
* Graph Endpoint. If it's missing we defer rather than fail, as this
* sensor is known to co-exist on systems with the IPU3 and so it might
* be created by the ipu-bridge.
*/
- handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
+ handle = fwnode_graph_get_next_endpoint(dev_fwnode(ov5670->dev), NULL);
if (!handle)
- return dev_err_probe(&client->dev, -EPROBE_DEFER,
+ return dev_err_probe(ov5670->dev, -EPROBE_DEFER,
"Endpoint for node get failed\n");
ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
@@ -2704,20 +2695,20 @@ static int ov5670_probe(struct i2c_client *client)
ret = v4l2_fwnode_endpoint_alloc_parse(handle, &ov5670->endpoint);
fwnode_handle_put(handle);
if (ret)
- return dev_err_probe(&client->dev, ret, "Endpoint parse failed\n");
+ return dev_err_probe(ov5670->dev, ret, "Endpoint parse failed\n");
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(ov5670->dev);
if (full_power) {
- ret = ov5670_runtime_resume(&client->dev);
+ ret = ov5670_runtime_resume(ov5670->dev);
if (ret) {
- dev_err_probe(&client->dev, ret, "Power up failed\n");
+ dev_err_probe(ov5670->dev, ret, "Power up failed\n");
goto error_endpoint;
}
/* Check module identity */
ret = ov5670_identify_module(ov5670);
if (ret) {
- dev_err_probe(&client->dev, ret, "ov5670_identify_module() error\n");
+ dev_err_probe(ov5670->dev, ret, "ov5670_identify_module() error\n");
goto error_power_off;
}
}
@@ -2729,7 +2720,7 @@ static int ov5670_probe(struct i2c_client *client)
ret = ov5670_init_controls(ov5670);
if (ret) {
- dev_err_probe(&client->dev, ret, "ov5670_init_controls() error\n");
+ dev_err_probe(ov5670->dev, ret, "ov5670_init_controls() error\n");
goto error_mutex_destroy;
}
@@ -2742,28 +2733,28 @@ static int ov5670_probe(struct i2c_client *client)
ov5670->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov5670->sd.entity, 1, &ov5670->pad);
if (ret) {
- dev_err_probe(&client->dev, ret, "media_entity_pads_init() error\n");
+ dev_err_probe(ov5670->dev, ret, "media_entity_pads_init() error\n");
goto error_handler_free;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
+ pm_runtime_set_active(ov5670->dev);
+ pm_runtime_enable(ov5670->dev);
/* Async register for subdev */
ret = v4l2_async_register_subdev_sensor(&ov5670->sd);
if (ret < 0) {
- dev_err_probe(&client->dev, ret, "v4l2_async_register_subdev() error\n");
+ dev_err_probe(ov5670->dev, ret, "v4l2_async_register_subdev() error\n");
goto error_pm_disable;
}
- pm_runtime_idle(&client->dev);
+ pm_runtime_idle(ov5670->dev);
return 0;
error_pm_disable:
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov5670->dev);
media_entity_cleanup(&ov5670->sd.entity);
@@ -2775,7 +2766,7 @@ error_mutex_destroy:
error_power_off:
if (full_power)
- ov5670_runtime_suspend(&client->dev);
+ ov5670_runtime_suspend(ov5670->dev);
error_endpoint:
v4l2_fwnode_endpoint_free(&ov5670->endpoint);
@@ -2793,8 +2784,8 @@ static void ov5670_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(sd->ctrl_handler);
mutex_destroy(&ov5670->mutex);
- pm_runtime_disable(&client->dev);
- ov5670_runtime_suspend(&client->dev);
+ pm_runtime_disable(ov5670->dev);
+ ov5670_runtime_suspend(ov5670->dev);
v4l2_fwnode_endpoint_free(&ov5670->endpoint);
}
diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
index e7aec281e9a4..30e27d39ee44 100644
--- a/drivers/media/i2c/ov5675.c
+++ b/drivers/media/i2c/ov5675.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -11,6 +10,8 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -493,6 +494,8 @@ static const struct ov5675_mode supported_modes[] = {
};
struct ov5675 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -584,7 +587,6 @@ static int ov5675_write_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 val)
static int ov5675_write_reg_list(struct ov5675 *ov5675,
const struct ov5675_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
unsigned int i;
int ret;
@@ -592,7 +594,7 @@ static int ov5675_write_reg_list(struct ov5675 *ov5675,
ret = ov5675_write_reg(ov5675, r_list->regs[i].address, 1,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov5675->dev,
"failed to write reg 0x%4.4x. error = %d",
r_list->regs[i].address, ret);
return ret;
@@ -700,7 +702,6 @@ static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov5675 *ov5675 = container_of(ctrl->handler,
struct ov5675, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
s64 exposure_max;
int ret = 0;
@@ -716,7 +717,7 @@ static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov5675->dev))
return 0;
switch (ctrl->id) {
@@ -765,7 +766,7 @@ static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov5675->dev);
return ret;
}
@@ -776,7 +777,6 @@ static const struct v4l2_ctrl_ops ov5675_ctrl_ops = {
static int ov5675_init_controls(struct ov5675 *ov5675)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max, h_blank;
@@ -839,7 +839,7 @@ static int ov5675_init_controls(struct ov5675 *ov5675)
return ctrl_hdlr->error;
}
- ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ ret = v4l2_fwnode_device_parse(ov5675->dev, &props);
if (ret)
goto error;
@@ -869,7 +869,6 @@ static void ov5675_update_pad_format(const struct ov5675_mode *mode,
static int ov5675_identify_module(struct ov5675 *ov5675)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
int ret;
u32 val;
@@ -882,7 +881,7 @@ static int ov5675_identify_module(struct ov5675 *ov5675)
return ret;
if (val != OV5675_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(ov5675->dev, "chip id mismatch: %x!=%x",
OV5675_CHIP_ID, val);
return -ENXIO;
}
@@ -894,7 +893,6 @@ static int ov5675_identify_module(struct ov5675 *ov5675)
static int ov5675_start_streaming(struct ov5675 *ov5675)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
const struct ov5675_reg_list *reg_list;
int link_freq_index, ret;
@@ -906,14 +904,14 @@ static int ov5675_start_streaming(struct ov5675 *ov5675)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov5675_write_reg_list(ov5675, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls");
+ dev_err(ov5675->dev, "failed to set plls");
return ret;
}
reg_list = &ov5675->cur_mode->reg_list;
ret = ov5675_write_reg_list(ov5675, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(ov5675->dev, "failed to set mode");
return ret;
}
@@ -924,7 +922,7 @@ static int ov5675_start_streaming(struct ov5675 *ov5675)
ret = ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
OV5675_REG_VALUE_08BIT, OV5675_MODE_STREAMING);
if (ret) {
- dev_err(&client->dev, "failed to set stream");
+ dev_err(ov5675->dev, "failed to set stream");
return ret;
}
@@ -933,22 +931,19 @@ static int ov5675_start_streaming(struct ov5675 *ov5675)
static void ov5675_stop_streaming(struct ov5675 *ov5675)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
-
if (ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
OV5675_REG_VALUE_08BIT, OV5675_MODE_STANDBY))
- dev_err(&client->dev, "failed to set stream");
+ dev_err(ov5675->dev, "failed to set stream");
}
static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov5675 *ov5675 = to_ov5675(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov5675->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov5675->dev);
if (ret < 0) {
mutex_unlock(&ov5675->mutex);
return ret;
@@ -958,11 +953,11 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
ov5675_stop_streaming(ov5675);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov5675->dev);
}
} else {
ov5675_stop_streaming(ov5675);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov5675->dev);
}
mutex_unlock(&ov5675->mutex);
@@ -1171,8 +1166,9 @@ static const struct v4l2_subdev_internal_ops ov5675_internal_ops = {
.open = ov5675_open,
};
-static int ov5675_get_hwcfg(struct ov5675 *ov5675, struct device *dev)
+static int ov5675_get_hwcfg(struct ov5675 *ov5675)
{
+ struct device *dev = ov5675->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct v4l2_fwnode_endpoint bus_cfg = {
@@ -1185,24 +1181,13 @@ static int ov5675_get_hwcfg(struct ov5675 *ov5675, struct device *dev)
if (!fwnode)
return -ENXIO;
- ov5675->xvclk = devm_clk_get_optional(dev, NULL);
+ ov5675->xvclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(ov5675->xvclk))
return dev_err_probe(dev, PTR_ERR(ov5675->xvclk),
"failed to get xvclk: %ld\n",
PTR_ERR(ov5675->xvclk));
- if (ov5675->xvclk) {
- xvclk_rate = clk_get_rate(ov5675->xvclk);
- } else {
- ret = fwnode_property_read_u32(fwnode, "clock-frequency",
- &xvclk_rate);
-
- if (ret) {
- dev_err(dev, "can't get clock frequency");
- return ret;
- }
- }
-
+ xvclk_rate = clk_get_rate(ov5675->xvclk);
if (xvclk_rate != OV5675_XVCLK_19_2) {
dev_err(dev, "external clock rate %u is unsupported",
xvclk_rate);
@@ -1276,12 +1261,12 @@ static void ov5675_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov5675->dev);
mutex_destroy(&ov5675->mutex);
- if (!pm_runtime_status_suspended(&client->dev))
- ov5675_power_off(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ if (!pm_runtime_status_suspended(ov5675->dev))
+ ov5675_power_off(ov5675->dev);
+ pm_runtime_set_suspended(ov5675->dev);
}
static int ov5675_probe(struct i2c_client *client)
@@ -1294,23 +1279,25 @@ static int ov5675_probe(struct i2c_client *client)
if (!ov5675)
return -ENOMEM;
- ret = ov5675_get_hwcfg(ov5675, &client->dev);
+ ov5675->dev = &client->dev;
+
+ ret = ov5675_get_hwcfg(ov5675);
if (ret)
return ret;
v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
- ret = ov5675_power_on(&client->dev);
+ ret = ov5675_power_on(ov5675->dev);
if (ret) {
- dev_err(&client->dev, "failed to power on: %d\n", ret);
+ dev_err(ov5675->dev, "failed to power on: %d\n", ret);
return ret;
}
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(ov5675->dev);
if (full_power) {
ret = ov5675_identify_module(ov5675);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(ov5675->dev, "failed to find sensor: %d", ret);
goto probe_power_off;
}
}
@@ -1319,7 +1306,7 @@ static int ov5675_probe(struct i2c_client *client)
ov5675->cur_mode = &supported_modes[0];
ret = ov5675_init_controls(ov5675);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(ov5675->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -1330,22 +1317,22 @@ static int ov5675_probe(struct i2c_client *client)
ov5675->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov5675->sd.entity, 1, &ov5675->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(ov5675->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&ov5675->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(ov5675->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_media_entity_cleanup;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov5675->dev);
+ pm_runtime_enable(ov5675->dev);
+ pm_runtime_idle(ov5675->dev);
return 0;
@@ -1356,7 +1343,7 @@ probe_error_v4l2_ctrl_handler_free:
v4l2_ctrl_handler_free(ov5675->sd.ctrl_handler);
mutex_destroy(&ov5675->mutex);
probe_power_off:
- ov5675_power_off(&client->dev);
+ ov5675_power_off(ov5675->dev);
return ret;
}
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
index 485efd15257e..d294477f9dd3 100644
--- a/drivers/media/i2c/ov5693.c
+++ b/drivers/media/i2c/ov5693.c
@@ -1289,25 +1289,13 @@ static int ov5693_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
- ov5693->xvclk = devm_clk_get_optional(&client->dev, "xvclk");
+ ov5693->xvclk = devm_v4l2_sensor_clk_get(&client->dev, "xvclk");
if (IS_ERR(ov5693->xvclk))
return dev_err_probe(&client->dev, PTR_ERR(ov5693->xvclk),
"failed to get xvclk: %ld\n",
PTR_ERR(ov5693->xvclk));
- if (ov5693->xvclk) {
- xvclk_rate = clk_get_rate(ov5693->xvclk);
- } else {
- ret = fwnode_property_read_u32(dev_fwnode(&client->dev),
- "clock-frequency",
- &xvclk_rate);
-
- if (ret) {
- dev_err(&client->dev, "can't get clock frequency");
- return ret;
- }
- }
-
+ xvclk_rate = clk_get_rate(ov5693->xvclk);
if (xvclk_rate != OV5693_XVCLK_FREQ)
dev_warn(&client->dev, "Found clk freq %u, expected %u\n",
xvclk_rate, OV5693_XVCLK_FREQ);
diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c
index 663eccdfea6a..5bb6ce7b3237 100644
--- a/drivers/media/i2c/ov5695.c
+++ b/drivers/media/i2c/ov5695.c
@@ -1264,16 +1264,12 @@ static int ov5695_probe(struct i2c_client *client)
ov5695->client = client;
ov5695->cur_mode = &supported_modes[0];
- ov5695->xvclk = devm_clk_get(dev, "xvclk");
- if (IS_ERR(ov5695->xvclk)) {
- dev_err(dev, "Failed to get xvclk\n");
- return -EINVAL;
- }
- ret = clk_set_rate(ov5695->xvclk, OV5695_XVCLK_FREQ);
- if (ret < 0) {
- dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
- return ret;
- }
+ ov5695->xvclk = devm_v4l2_sensor_clk_get_legacy(dev, "xvclk", true,
+ OV5695_XVCLK_FREQ);
+ if (IS_ERR(ov5695->xvclk))
+ return dev_err_probe(dev, PTR_ERR(ov5695->xvclk),
+ "Failed to get xvclk\n");
+
if (clk_get_rate(ov5695->xvclk) != OV5695_XVCLK_FREQ)
dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
diff --git a/drivers/media/i2c/ov6211.c b/drivers/media/i2c/ov6211.c
new file mode 100644
index 000000000000..e3ac5ecf27d1
--- /dev/null
+++ b/drivers/media/i2c/ov6211.c
@@ -0,0 +1,793 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2024-2025 Linaro Ltd
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/units.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define OV6211_LINK_FREQ_480MHZ (480 * HZ_PER_MHZ)
+#define OV6211_MCLK_FREQ_24MHZ (24 * HZ_PER_MHZ)
+
+#define OV6211_REG_CHIP_ID CCI_REG16(0x300a)
+#define OV6211_CHIP_ID 0x6710
+
+#define OV6211_REG_MODE_SELECT CCI_REG8(0x0100)
+#define OV6211_MODE_STANDBY 0x00
+#define OV6211_MODE_STREAMING BIT(0)
+
+#define OV6211_REG_SOFTWARE_RST CCI_REG8(0x0103)
+#define OV6211_SOFTWARE_RST BIT(0)
+
+/* Exposure controls from sensor */
+#define OV6211_REG_EXPOSURE CCI_REG24(0x3500)
+#define OV6211_EXPOSURE_MIN 1
+#define OV6211_EXPOSURE_MAX_MARGIN 4
+#define OV6211_EXPOSURE_STEP 1
+#define OV6211_EXPOSURE_DEFAULT 210
+
+/* Analogue gain controls from sensor */
+#define OV6211_REG_ANALOGUE_GAIN CCI_REG16(0x350a)
+#define OV6211_ANALOGUE_GAIN_MIN 1
+#define OV6211_ANALOGUE_GAIN_MAX 0x3ff
+#define OV6211_ANALOGUE_GAIN_STEP 1
+#define OV6211_ANALOGUE_GAIN_DEFAULT 160
+
+/* Test pattern */
+#define OV6211_REG_PRE_ISP CCI_REG8(0x5e00)
+#define OV6211_TEST_PATTERN_ENABLE BIT(7)
+
+#define to_ov6211(_sd) container_of(_sd, struct ov6211, sd)
+
+static const s64 ov6211_link_freq_menu[] = {
+ OV6211_LINK_FREQ_480MHZ,
+};
+
+struct ov6211_reg_list {
+ const struct cci_reg_sequence *regs;
+ unsigned int num_regs;
+};
+
+struct ov6211_mode {
+ u32 width; /* Frame width in pixels */
+ u32 height; /* Frame height in pixels */
+ u32 hts; /* Horizontal timing size */
+ u32 vts; /* Default vertical timing size */
+ u32 bpp; /* Bits per pixel */
+
+ const struct ov6211_reg_list reg_list; /* Sensor register setting */
+};
+
+static const char * const ov6211_test_pattern_menu[] = {
+ "Disabled",
+ "Vertical Colour Bars",
+};
+
+static const char * const ov6211_supply_names[] = {
+ "avdd", /* Analog power */
+ "dovdd", /* Digital I/O power */
+ "dvdd", /* Digital core power */
+};
+
+#define OV6211_NUM_SUPPLIES ARRAY_SIZE(ov6211_supply_names)
+
+struct ov6211 {
+ struct device *dev;
+ struct regmap *regmap;
+ struct clk *xvclk;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[OV6211_NUM_SUPPLIES];
+
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ /* Saved register values */
+ u64 pre_isp;
+};
+
+static const struct cci_reg_sequence ov6211_400x400_120fps_mode[] = {
+ { CCI_REG8(0x3005), 0x00 },
+ { CCI_REG8(0x3013), 0x12 },
+ { CCI_REG8(0x3014), 0x04 },
+ { CCI_REG8(0x3016), 0x10 },
+ { CCI_REG8(0x3017), 0x00 },
+ { CCI_REG8(0x3018), 0x00 },
+ { CCI_REG8(0x301a), 0x00 },
+ { CCI_REG8(0x301b), 0x00 },
+ { CCI_REG8(0x301c), 0x00 },
+ { CCI_REG8(0x3037), 0xf0 },
+ { CCI_REG8(0x3080), 0x01 },
+ { CCI_REG8(0x3081), 0x00 },
+ { CCI_REG8(0x3082), 0x01 },
+ { CCI_REG8(0x3098), 0x04 },
+ { CCI_REG8(0x3099), 0x28 },
+ { CCI_REG8(0x309a), 0x06 },
+ { CCI_REG8(0x309b), 0x04 },
+ { CCI_REG8(0x309c), 0x00 },
+ { CCI_REG8(0x309d), 0x00 },
+ { CCI_REG8(0x309e), 0x01 },
+ { CCI_REG8(0x309f), 0x00 },
+ { CCI_REG8(0x30b0), 0x08 },
+ { CCI_REG8(0x30b1), 0x02 },
+ { CCI_REG8(0x30b2), 0x00 },
+ { CCI_REG8(0x30b3), 0x28 },
+ { CCI_REG8(0x30b4), 0x02 },
+ { CCI_REG8(0x30b5), 0x00 },
+ { CCI_REG8(0x3106), 0xd9 },
+ { CCI_REG8(0x3503), 0x07 },
+ { CCI_REG8(0x3509), 0x10 },
+ { CCI_REG8(0x3600), 0xfc },
+ { CCI_REG8(0x3620), 0xb7 },
+ { CCI_REG8(0x3621), 0x05 },
+ { CCI_REG8(0x3626), 0x31 },
+ { CCI_REG8(0x3627), 0x40 },
+ { CCI_REG8(0x3632), 0xa3 },
+ { CCI_REG8(0x3633), 0x34 },
+ { CCI_REG8(0x3634), 0x40 },
+ { CCI_REG8(0x3636), 0x00 },
+ { CCI_REG8(0x3660), 0x80 },
+ { CCI_REG8(0x3662), 0x03 },
+ { CCI_REG8(0x3664), 0xf0 },
+ { CCI_REG8(0x366a), 0x10 },
+ { CCI_REG8(0x366b), 0x06 },
+ { CCI_REG8(0x3680), 0xf4 },
+ { CCI_REG8(0x3681), 0x50 },
+ { CCI_REG8(0x3682), 0x00 },
+ { CCI_REG8(0x3708), 0x20 },
+ { CCI_REG8(0x3709), 0x40 },
+ { CCI_REG8(0x370d), 0x03 },
+ { CCI_REG8(0x373b), 0x02 },
+ { CCI_REG8(0x373c), 0x08 },
+ { CCI_REG8(0x3742), 0x00 },
+ { CCI_REG8(0x3744), 0x16 },
+ { CCI_REG8(0x3745), 0x08 },
+ { CCI_REG8(0x3781), 0xfc },
+ { CCI_REG8(0x3788), 0x00 },
+ { CCI_REG8(0x3800), 0x00 },
+ { CCI_REG8(0x3801), 0x04 },
+ { CCI_REG8(0x3802), 0x00 },
+ { CCI_REG8(0x3803), 0x04 },
+ { CCI_REG8(0x3804), 0x01 },
+ { CCI_REG8(0x3805), 0x9b },
+ { CCI_REG8(0x3806), 0x01 },
+ { CCI_REG8(0x3807), 0x9b },
+ { CCI_REG8(0x3808), 0x01 }, /* output width */
+ { CCI_REG8(0x3809), 0x90 },
+ { CCI_REG8(0x380a), 0x01 }, /* output height */
+ { CCI_REG8(0x380b), 0x90 },
+ { CCI_REG8(0x380c), 0x05 }, /* horizontal timing size */
+ { CCI_REG8(0x380d), 0xf2 },
+ { CCI_REG8(0x380e), 0x01 }, /* vertical timing size */
+ { CCI_REG8(0x380f), 0xb6 },
+ { CCI_REG8(0x3810), 0x00 },
+ { CCI_REG8(0x3811), 0x04 },
+ { CCI_REG8(0x3812), 0x00 },
+ { CCI_REG8(0x3813), 0x04 },
+ { CCI_REG8(0x3814), 0x11 },
+ { CCI_REG8(0x3815), 0x11 },
+ { CCI_REG8(0x3820), 0x00 },
+ { CCI_REG8(0x3821), 0x00 },
+ { CCI_REG8(0x382b), 0xfa },
+ { CCI_REG8(0x382f), 0x04 },
+ { CCI_REG8(0x3832), 0x00 },
+ { CCI_REG8(0x3833), 0x05 },
+ { CCI_REG8(0x3834), 0x00 },
+ { CCI_REG8(0x3835), 0x05 },
+ { CCI_REG8(0x3882), 0x04 },
+ { CCI_REG8(0x3883), 0x00 },
+ { CCI_REG8(0x38a4), 0x10 },
+ { CCI_REG8(0x38a5), 0x00 },
+ { CCI_REG8(0x38b1), 0x03 },
+ { CCI_REG8(0x3b80), 0x00 },
+ { CCI_REG8(0x3b81), 0xff },
+ { CCI_REG8(0x3b82), 0x10 },
+ { CCI_REG8(0x3b83), 0x00 },
+ { CCI_REG8(0x3b84), 0x08 },
+ { CCI_REG8(0x3b85), 0x00 },
+ { CCI_REG8(0x3b86), 0x01 },
+ { CCI_REG8(0x3b87), 0x00 },
+ { CCI_REG8(0x3b88), 0x00 },
+ { CCI_REG8(0x3b89), 0x00 },
+ { CCI_REG8(0x3b8a), 0x00 },
+ { CCI_REG8(0x3b8b), 0x05 },
+ { CCI_REG8(0x3b8c), 0x00 },
+ { CCI_REG8(0x3b8d), 0x00 },
+ { CCI_REG8(0x3b8e), 0x01 },
+ { CCI_REG8(0x3b8f), 0xb2 },
+ { CCI_REG8(0x3b94), 0x05 },
+ { CCI_REG8(0x3b95), 0xf2 },
+ { CCI_REG8(0x3b96), 0xc0 },
+ { CCI_REG8(0x4004), 0x04 },
+ { CCI_REG8(0x404e), 0x01 },
+ { CCI_REG8(0x4801), 0x0f },
+ { CCI_REG8(0x4806), 0x0f },
+ { CCI_REG8(0x4837), 0x43 },
+ { CCI_REG8(0x5a08), 0x00 },
+ { CCI_REG8(0x5a01), 0x00 },
+ { CCI_REG8(0x5a03), 0x00 },
+ { CCI_REG8(0x5a04), 0x10 },
+ { CCI_REG8(0x5a05), 0xa0 },
+ { CCI_REG8(0x5a06), 0x0c },
+ { CCI_REG8(0x5a07), 0x78 },
+};
+
+static const struct ov6211_mode supported_modes[] = {
+ {
+ .width = 400,
+ .height = 400,
+ .hts = 1522,
+ .vts = 438,
+ .bpp = 8,
+ .reg_list = {
+ .regs = ov6211_400x400_120fps_mode,
+ .num_regs = ARRAY_SIZE(ov6211_400x400_120fps_mode),
+ },
+ },
+};
+
+static int ov6211_set_test_pattern(struct ov6211 *ov6211, u32 pattern)
+{
+ u64 val = ov6211->pre_isp;
+
+ if (pattern)
+ val |= OV6211_TEST_PATTERN_ENABLE;
+ else
+ val &= ~OV6211_TEST_PATTERN_ENABLE;
+
+ return cci_write(ov6211->regmap, OV6211_REG_PRE_ISP, val, NULL);
+}
+
+static int ov6211_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov6211 *ov6211 = container_of(ctrl->handler, struct ov6211,
+ ctrl_handler);
+ int ret;
+
+ /* V4L2 controls are applied, when sensor is powered up for streaming */
+ if (!pm_runtime_get_if_active(ov6211->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = cci_write(ov6211->regmap, OV6211_REG_ANALOGUE_GAIN,
+ ctrl->val, NULL);
+ break;
+ case V4L2_CID_EXPOSURE:
+ ret = cci_write(ov6211->regmap, OV6211_REG_EXPOSURE,
+ ctrl->val << 4, NULL);
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = ov6211_set_test_pattern(ov6211, ctrl->val);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ pm_runtime_put(ov6211->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops ov6211_ctrl_ops = {
+ .s_ctrl = ov6211_set_ctrl,
+};
+
+static int ov6211_init_controls(struct ov6211 *ov6211)
+{
+ struct v4l2_ctrl_handler *ctrl_hdlr = &ov6211->ctrl_handler;
+ const struct ov6211_mode *mode = &supported_modes[0];
+ struct v4l2_fwnode_device_properties props;
+ s64 exposure_max, pixel_rate, h_blank;
+ struct v4l2_ctrl *ctrl;
+ int ret;
+
+ v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+
+ ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov6211_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+ ARRAY_SIZE(ov6211_link_freq_menu) - 1,
+ 0, ov6211_link_freq_menu);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ pixel_rate = ov6211_link_freq_menu[0] / mode->bpp;
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops, V4L2_CID_PIXEL_RATE,
+ 0, pixel_rate, 1, pixel_rate);
+
+ h_blank = mode->hts - mode->width;
+ ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops, V4L2_CID_HBLANK,
+ h_blank, h_blank, 1, h_blank);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops, V4L2_CID_VBLANK,
+ mode->vts - mode->height,
+ mode->vts - mode->height, 1,
+ mode->vts - mode->height);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+ OV6211_ANALOGUE_GAIN_MIN, OV6211_ANALOGUE_GAIN_MAX,
+ OV6211_ANALOGUE_GAIN_STEP,
+ OV6211_ANALOGUE_GAIN_DEFAULT);
+
+ exposure_max = (mode->vts - OV6211_EXPOSURE_MAX_MARGIN);
+ v4l2_ctrl_new_std(ctrl_hdlr, &ov6211_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ OV6211_EXPOSURE_MIN, exposure_max,
+ OV6211_EXPOSURE_STEP,
+ OV6211_EXPOSURE_DEFAULT);
+
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov6211_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(ov6211_test_pattern_menu) - 1,
+ 0, 0, ov6211_test_pattern_menu);
+
+ if (ctrl_hdlr->error)
+ return ctrl_hdlr->error;
+
+ ret = v4l2_fwnode_device_parse(ov6211->dev, &props);
+ if (ret)
+ goto error_free_hdlr;
+
+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov6211_ctrl_ops,
+ &props);
+ if (ret)
+ goto error_free_hdlr;
+
+ ov6211->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
+
+error_free_hdlr:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+
+ return ret;
+}
+
+static void ov6211_update_pad_format(const struct ov6211_mode *mode,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ fmt->code = MEDIA_BUS_FMT_Y8_1X8;
+ fmt->width = mode->width;
+ fmt->height = mode->height;
+ fmt->field = V4L2_FIELD_NONE;
+ fmt->colorspace = V4L2_COLORSPACE_RAW;
+ fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int ov6211_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ const struct ov6211_reg_list *reg_list = &supported_modes[0].reg_list;
+ struct ov6211 *ov6211 = to_ov6211(sd);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(ov6211->dev);
+ if (ret)
+ return ret;
+
+ /* Skip a step of explicit entering into the standby mode */
+ ret = cci_write(ov6211->regmap, OV6211_REG_SOFTWARE_RST,
+ OV6211_SOFTWARE_RST, NULL);
+ if (ret) {
+ dev_err(ov6211->dev, "failed to software reset: %d\n", ret);
+ goto error;
+ }
+
+ ret = cci_multi_reg_write(ov6211->regmap, reg_list->regs,
+ reg_list->num_regs, NULL);
+ if (ret) {
+ dev_err(ov6211->dev, "failed to set mode: %d\n", ret);
+ goto error;
+ }
+
+ ret = __v4l2_ctrl_handler_setup(ov6211->sd.ctrl_handler);
+ if (ret)
+ goto error;
+
+ ret = cci_write(ov6211->regmap, OV6211_REG_MODE_SELECT,
+ OV6211_MODE_STREAMING, NULL);
+ if (ret) {
+ dev_err(ov6211->dev, "failed to start streaming: %d\n", ret);
+ goto error;
+ }
+
+ return 0;
+
+error:
+ pm_runtime_put_autosuspend(ov6211->dev);
+
+ return ret;
+}
+
+static int ov6211_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct ov6211 *ov6211 = to_ov6211(sd);
+ int ret;
+
+ ret = cci_write(ov6211->regmap, OV6211_REG_MODE_SELECT,
+ OV6211_MODE_STANDBY, NULL);
+ if (ret)
+ dev_err(ov6211->dev, "failed to stop streaming: %d\n", ret);
+
+ pm_runtime_put_autosuspend(ov6211->dev);
+
+ return ret;
+}
+
+static int ov6211_set_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *fmt)
+{
+ struct v4l2_mbus_framefmt *format;
+ const struct ov6211_mode *mode;
+
+ format = v4l2_subdev_state_get_format(state, 0);
+
+ mode = v4l2_find_nearest_size(supported_modes,
+ ARRAY_SIZE(supported_modes),
+ width, height,
+ fmt->format.width,
+ fmt->format.height);
+
+ ov6211_update_pad_format(mode, &fmt->format);
+ *format = fmt->format;
+
+ return 0;
+}
+
+static int ov6211_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index > 0)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_Y8_1X8;
+
+ return 0;
+}
+
+static int ov6211_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ARRAY_SIZE(supported_modes))
+ return -EINVAL;
+
+ if (fse->code != MEDIA_BUS_FMT_Y8_1X8)
+ return -EINVAL;
+
+ fse->min_width = supported_modes[fse->index].width;
+ fse->max_width = fse->min_width;
+ fse->min_height = supported_modes[fse->index].height;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static int ov6211_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_TRY,
+ .pad = 0,
+ .format = {
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .width = supported_modes[0].width,
+ .height = supported_modes[0].height,
+ },
+ };
+
+ ov6211_set_pad_format(sd, state, &fmt);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov6211_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops ov6211_pad_ops = {
+ .set_fmt = ov6211_set_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .enum_mbus_code = ov6211_enum_mbus_code,
+ .enum_frame_size = ov6211_enum_frame_size,
+ .enable_streams = ov6211_enable_streams,
+ .disable_streams = ov6211_disable_streams,
+};
+
+static const struct v4l2_subdev_ops ov6211_subdev_ops = {
+ .video = &ov6211_video_ops,
+ .pad = &ov6211_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops ov6211_internal_ops = {
+ .init_state = ov6211_init_state,
+};
+
+static const struct media_entity_operations ov6211_subdev_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static int ov6211_identify_sensor(struct ov6211 *ov6211)
+{
+ u64 val;
+ int ret;
+
+ ret = cci_read(ov6211->regmap, OV6211_REG_CHIP_ID, &val, NULL);
+ if (ret) {
+ dev_err(ov6211->dev, "failed to read chip id: %d\n", ret);
+ return ret;
+ }
+
+ if (val != OV6211_CHIP_ID) {
+ dev_err(ov6211->dev, "chip id mismatch: %x!=%llx\n",
+ OV6211_CHIP_ID, val);
+ return -ENODEV;
+ }
+
+ ret = cci_read(ov6211->regmap, OV6211_REG_PRE_ISP,
+ &ov6211->pre_isp, NULL);
+ if (ret)
+ dev_err(ov6211->dev, "failed to read pre_isp: %d\n", ret);
+
+ return ret;
+}
+
+static int ov6211_check_hwcfg(struct ov6211 *ov6211)
+{
+ struct fwnode_handle *fwnode = dev_fwnode(ov6211->dev), *ep;
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY,
+ };
+ unsigned long freq_bitmap;
+ int ret;
+
+ if (!fwnode)
+ return -ENODEV;
+
+ ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+ if (!ep)
+ return -EINVAL;
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+ fwnode_handle_put(ep);
+ if (ret)
+ return ret;
+
+ ret = v4l2_link_freq_to_bitmap(ov6211->dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ ov6211_link_freq_menu,
+ ARRAY_SIZE(ov6211_link_freq_menu),
+ &freq_bitmap);
+
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+
+ return ret;
+}
+
+static int ov6211_power_on(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov6211 *ov6211 = to_ov6211(sd);
+ int ret;
+
+ ret = regulator_bulk_enable(OV6211_NUM_SUPPLIES, ov6211->supplies);
+ if (ret)
+ return ret;
+
+ gpiod_set_value_cansleep(ov6211->reset_gpio, 0);
+ usleep_range(10 * USEC_PER_MSEC, 15 * USEC_PER_MSEC);
+
+ ret = clk_prepare_enable(ov6211->xvclk);
+ if (ret)
+ goto reset_gpio;
+
+ return 0;
+
+reset_gpio:
+ gpiod_set_value_cansleep(ov6211->reset_gpio, 1);
+
+ regulator_bulk_disable(OV6211_NUM_SUPPLIES, ov6211->supplies);
+
+ return ret;
+}
+
+static int ov6211_power_off(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov6211 *ov6211 = to_ov6211(sd);
+
+ clk_disable_unprepare(ov6211->xvclk);
+
+ gpiod_set_value_cansleep(ov6211->reset_gpio, 1);
+
+ regulator_bulk_disable(OV6211_NUM_SUPPLIES, ov6211->supplies);
+
+ return 0;
+}
+
+static int ov6211_probe(struct i2c_client *client)
+{
+ struct ov6211 *ov6211;
+ unsigned long freq;
+ unsigned int i;
+ int ret;
+
+ ov6211 = devm_kzalloc(&client->dev, sizeof(*ov6211), GFP_KERNEL);
+ if (!ov6211)
+ return -ENOMEM;
+
+ ov6211->dev = &client->dev;
+
+ v4l2_i2c_subdev_init(&ov6211->sd, client, &ov6211_subdev_ops);
+
+ ov6211->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(ov6211->regmap))
+ return dev_err_probe(ov6211->dev, PTR_ERR(ov6211->regmap),
+ "failed to init CCI\n");
+
+ ov6211->xvclk = devm_v4l2_sensor_clk_get(ov6211->dev, NULL);
+ if (IS_ERR(ov6211->xvclk))
+ return dev_err_probe(ov6211->dev, PTR_ERR(ov6211->xvclk),
+ "failed to get XVCLK clock\n");
+
+ freq = clk_get_rate(ov6211->xvclk);
+ if (freq && freq != OV6211_MCLK_FREQ_24MHZ)
+ return dev_err_probe(ov6211->dev, -EINVAL,
+ "XVCLK clock frequency %lu is not supported\n",
+ freq);
+
+ ret = ov6211_check_hwcfg(ov6211);
+ if (ret)
+ return dev_err_probe(ov6211->dev, ret,
+ "failed to check HW configuration\n");
+
+ ov6211->reset_gpio = devm_gpiod_get_optional(ov6211->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(ov6211->reset_gpio))
+ return dev_err_probe(ov6211->dev, PTR_ERR(ov6211->reset_gpio),
+ "cannot get reset GPIO\n");
+
+ for (i = 0; i < OV6211_NUM_SUPPLIES; i++)
+ ov6211->supplies[i].supply = ov6211_supply_names[i];
+
+ ret = devm_regulator_bulk_get(ov6211->dev, OV6211_NUM_SUPPLIES,
+ ov6211->supplies);
+ if (ret)
+ return dev_err_probe(ov6211->dev, ret,
+ "failed to get supply regulators\n");
+
+ /* The sensor must be powered on to read the CHIP_ID register */
+ ret = ov6211_power_on(ov6211->dev);
+ if (ret)
+ return ret;
+
+ ret = ov6211_identify_sensor(ov6211);
+ if (ret) {
+ dev_err_probe(ov6211->dev, ret, "failed to find sensor\n");
+ goto power_off;
+ }
+
+ ret = ov6211_init_controls(ov6211);
+ if (ret) {
+ dev_err_probe(ov6211->dev, ret, "failed to init controls\n");
+ goto power_off;
+ }
+
+ ov6211->sd.state_lock = ov6211->ctrl_handler.lock;
+ ov6211->sd.internal_ops = &ov6211_internal_ops;
+ ov6211->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ ov6211->sd.entity.ops = &ov6211_subdev_entity_ops;
+ ov6211->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ov6211->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&ov6211->sd.entity, 1, &ov6211->pad);
+ if (ret) {
+ dev_err_probe(ov6211->dev, ret,
+ "failed to init media entity pads\n");
+ goto v4l2_ctrl_handler_free;
+ }
+
+ ret = v4l2_subdev_init_finalize(&ov6211->sd);
+ if (ret < 0) {
+ dev_err_probe(ov6211->dev, ret,
+ "failed to init media entity pads\n");
+ goto media_entity_cleanup;
+ }
+
+ pm_runtime_set_active(ov6211->dev);
+ pm_runtime_enable(ov6211->dev);
+
+ ret = v4l2_async_register_subdev_sensor(&ov6211->sd);
+ if (ret < 0) {
+ dev_err_probe(ov6211->dev, ret,
+ "failed to register V4L2 subdev\n");
+ goto subdev_cleanup;
+ }
+
+ /* Enable runtime PM and turn off the device */
+ pm_runtime_idle(ov6211->dev);
+ pm_runtime_set_autosuspend_delay(ov6211->dev, 1000);
+ pm_runtime_use_autosuspend(ov6211->dev);
+
+ return 0;
+
+subdev_cleanup:
+ v4l2_subdev_cleanup(&ov6211->sd);
+ pm_runtime_disable(ov6211->dev);
+ pm_runtime_set_suspended(ov6211->dev);
+
+media_entity_cleanup:
+ media_entity_cleanup(&ov6211->sd.entity);
+
+v4l2_ctrl_handler_free:
+ v4l2_ctrl_handler_free(ov6211->sd.ctrl_handler);
+
+power_off:
+ ov6211_power_off(ov6211->dev);
+
+ return ret;
+}
+
+static void ov6211_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov6211 *ov6211 = to_ov6211(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
+ pm_runtime_disable(ov6211->dev);
+
+ if (!pm_runtime_status_suspended(ov6211->dev)) {
+ ov6211_power_off(ov6211->dev);
+ pm_runtime_set_suspended(ov6211->dev);
+ }
+}
+
+static const struct dev_pm_ops ov6211_pm_ops = {
+ SET_RUNTIME_PM_OPS(ov6211_power_off, ov6211_power_on, NULL)
+};
+
+static const struct of_device_id ov6211_of_match[] = {
+ { .compatible = "ovti,ov6211" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ov6211_of_match);
+
+static struct i2c_driver ov6211_i2c_driver = {
+ .driver = {
+ .name = "ov6211",
+ .pm = &ov6211_pm_ops,
+ .of_match_table = ov6211_of_match,
+ },
+ .probe = ov6211_probe,
+ .remove = ov6211_remove,
+};
+
+module_i2c_driver(ov6211_i2c_driver);
+
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>");
+MODULE_DESCRIPTION("OmniVision OV6211 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov64a40.c b/drivers/media/i2c/ov64a40.c
index 2031cbd05c26..78b62c169b99 100644
--- a/drivers/media/i2c/ov64a40.c
+++ b/drivers/media/i2c/ov64a40.c
@@ -3546,7 +3546,7 @@ static int ov64a40_probe(struct i2c_client *client)
return PTR_ERR(ov64a40->cci);
}
- ov64a40->xclk = devm_clk_get(&client->dev, NULL);
+ ov64a40->xclk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
if (IS_ERR(ov64a40->xclk))
return dev_err_probe(&client->dev, PTR_ERR(ov64a40->xclk),
"Failed to get clock\n");
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c
deleted file mode 100644
index 9c7627161142..000000000000
--- a/drivers/media/i2c/ov6650.c
+++ /dev/null
@@ -1,1149 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * V4L2 subdevice driver for OmniVision OV6650 Camera Sensor
- *
- * Copyright (C) 2010 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
- *
- * Based on OmniVision OV96xx Camera Driver
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
- *
- * Based on ov772x camera driver:
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ov7670 and soc_camera_platform driver,
- * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
- * Copyright (C) 2008 Magnus Damm
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * Hardware specific bits initially based on former work by Matt Callow
- * drivers/media/video/omap/sensor_ov6650.c
- * Copyright (C) 2006 Matt Callow
- */
-
-#include <linux/bitops.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/module.h>
-
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-
-/* Register definitions */
-#define REG_GAIN 0x00 /* range 00 - 3F */
-#define REG_BLUE 0x01
-#define REG_RED 0x02
-#define REG_SAT 0x03 /* [7:4] saturation [0:3] reserved */
-#define REG_HUE 0x04 /* [7:6] rsrvd [5] hue en [4:0] hue */
-
-#define REG_BRT 0x06
-
-#define REG_PIDH 0x0a
-#define REG_PIDL 0x0b
-
-#define REG_AECH 0x10
-#define REG_CLKRC 0x11 /* Data Format and Internal Clock */
- /* [7:6] Input system clock (MHz)*/
- /* 00=8, 01=12, 10=16, 11=24 */
- /* [5:0]: Internal Clock Pre-Scaler */
-#define REG_COMA 0x12 /* [7] Reset */
-#define REG_COMB 0x13
-#define REG_COMC 0x14
-#define REG_COMD 0x15
-#define REG_COML 0x16
-#define REG_HSTRT 0x17
-#define REG_HSTOP 0x18
-#define REG_VSTRT 0x19
-#define REG_VSTOP 0x1a
-#define REG_PSHFT 0x1b
-#define REG_MIDH 0x1c
-#define REG_MIDL 0x1d
-#define REG_HSYNS 0x1e
-#define REG_HSYNE 0x1f
-#define REG_COME 0x20
-#define REG_YOFF 0x21
-#define REG_UOFF 0x22
-#define REG_VOFF 0x23
-#define REG_AEW 0x24
-#define REG_AEB 0x25
-#define REG_COMF 0x26
-#define REG_COMG 0x27
-#define REG_COMH 0x28
-#define REG_COMI 0x29
-
-#define REG_FRARL 0x2b
-#define REG_COMJ 0x2c
-#define REG_COMK 0x2d
-#define REG_AVGY 0x2e
-#define REG_REF0 0x2f
-#define REG_REF1 0x30
-#define REG_REF2 0x31
-#define REG_FRAJH 0x32
-#define REG_FRAJL 0x33
-#define REG_FACT 0x34
-#define REG_L1AEC 0x35
-#define REG_AVGU 0x36
-#define REG_AVGV 0x37
-
-#define REG_SPCB 0x60
-#define REG_SPCC 0x61
-#define REG_GAM1 0x62
-#define REG_GAM2 0x63
-#define REG_GAM3 0x64
-#define REG_SPCD 0x65
-
-#define REG_SPCE 0x68
-#define REG_ADCL 0x69
-
-#define REG_RMCO 0x6c
-#define REG_GMCO 0x6d
-#define REG_BMCO 0x6e
-
-
-/* Register bits, values, etc. */
-#define OV6650_PIDH 0x66 /* high byte of product ID number */
-#define OV6650_PIDL 0x50 /* low byte of product ID number */
-#define OV6650_MIDH 0x7F /* high byte of mfg ID */
-#define OV6650_MIDL 0xA2 /* low byte of mfg ID */
-
-#define DEF_GAIN 0x00
-#define DEF_BLUE 0x80
-#define DEF_RED 0x80
-
-#define SAT_SHIFT 4
-#define SAT_MASK (0xf << SAT_SHIFT)
-#define SET_SAT(x) (((x) << SAT_SHIFT) & SAT_MASK)
-
-#define HUE_EN BIT(5)
-#define HUE_MASK 0x1f
-#define DEF_HUE 0x10
-#define SET_HUE(x) (HUE_EN | ((x) & HUE_MASK))
-
-#define DEF_AECH 0x4D
-
-#define CLKRC_8MHz 0x00
-#define CLKRC_12MHz 0x40
-#define CLKRC_16MHz 0x80
-#define CLKRC_24MHz 0xc0
-#define CLKRC_DIV_MASK 0x3f
-#define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1)
-#define DEF_CLKRC 0x00
-
-#define COMA_RESET BIT(7)
-#define COMA_QCIF BIT(5)
-#define COMA_RAW_RGB BIT(4)
-#define COMA_RGB BIT(3)
-#define COMA_BW BIT(2)
-#define COMA_WORD_SWAP BIT(1)
-#define COMA_BYTE_SWAP BIT(0)
-#define DEF_COMA 0x00
-
-#define COMB_FLIP_V BIT(7)
-#define COMB_FLIP_H BIT(5)
-#define COMB_BAND_FILTER BIT(4)
-#define COMB_AWB BIT(2)
-#define COMB_AGC BIT(1)
-#define COMB_AEC BIT(0)
-#define DEF_COMB 0x5f
-
-#define COML_ONE_CHANNEL BIT(7)
-
-#define DEF_HSTRT 0x24
-#define DEF_HSTOP 0xd4
-#define DEF_VSTRT 0x04
-#define DEF_VSTOP 0x94
-
-#define COMF_HREF_LOW BIT(4)
-
-#define COMJ_PCLK_RISING BIT(4)
-#define COMJ_VSYNC_HIGH BIT(0)
-
-/* supported resolutions */
-#define W_QCIF (DEF_HSTOP - DEF_HSTRT)
-#define W_CIF (W_QCIF << 1)
-#define H_QCIF (DEF_VSTOP - DEF_VSTRT)
-#define H_CIF (H_QCIF << 1)
-
-#define FRAME_RATE_MAX 30
-
-
-struct ov6650_reg {
- u8 reg;
- u8 val;
-};
-
-struct ov6650 {
- struct v4l2_subdev subdev;
- struct v4l2_ctrl_handler hdl;
- struct {
- /* exposure/autoexposure cluster */
- struct v4l2_ctrl *autoexposure;
- struct v4l2_ctrl *exposure;
- };
- struct {
- /* gain/autogain cluster */
- struct v4l2_ctrl *autogain;
- struct v4l2_ctrl *gain;
- };
- struct {
- /* blue/red/autowhitebalance cluster */
- struct v4l2_ctrl *autowb;
- struct v4l2_ctrl *blue;
- struct v4l2_ctrl *red;
- };
- struct clk *clk;
- bool half_scale; /* scale down output by 2 */
- struct v4l2_rect rect; /* sensor cropping window */
- struct v4l2_fract tpf; /* as requested with set_frame_interval */
- u32 code;
-};
-
-struct ov6650_xclk {
- unsigned long rate;
- u8 clkrc;
-};
-
-static const struct ov6650_xclk ov6650_xclk[] = {
-{
- .rate = 8000000,
- .clkrc = CLKRC_8MHz,
-},
-{
- .rate = 12000000,
- .clkrc = CLKRC_12MHz,
-},
-{
- .rate = 16000000,
- .clkrc = CLKRC_16MHz,
-},
-{
- .rate = 24000000,
- .clkrc = CLKRC_24MHz,
-},
-};
-
-static u32 ov6650_codes[] = {
- MEDIA_BUS_FMT_YUYV8_2X8,
- MEDIA_BUS_FMT_UYVY8_2X8,
- MEDIA_BUS_FMT_YVYU8_2X8,
- MEDIA_BUS_FMT_VYUY8_2X8,
- MEDIA_BUS_FMT_SBGGR8_1X8,
- MEDIA_BUS_FMT_Y8_1X8,
-};
-
-static const struct v4l2_mbus_framefmt ov6650_def_fmt = {
- .width = W_CIF,
- .height = H_CIF,
- .code = MEDIA_BUS_FMT_SBGGR8_1X8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .field = V4L2_FIELD_NONE,
- .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
- .quantization = V4L2_QUANTIZATION_DEFAULT,
- .xfer_func = V4L2_XFER_FUNC_DEFAULT,
-};
-
-/* read a register */
-static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val)
-{
- int ret;
- u8 data = reg;
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = &data,
- };
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0)
- goto err;
-
- msg.flags = I2C_M_RD;
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0)
- goto err;
-
- *val = data;
- return 0;
-
-err:
- dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg);
- return ret;
-}
-
-/* write a register */
-static int ov6650_reg_write(struct i2c_client *client, u8 reg, u8 val)
-{
- int ret;
- unsigned char data[2] = { reg, val };
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = data,
- };
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- udelay(100);
-
- if (ret < 0) {
- dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg);
- return ret;
- }
- return 0;
-}
-
-
-/* Read a register, alter its bits, write it back */
-static int ov6650_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 mask)
-{
- u8 val;
- int ret;
-
- ret = ov6650_reg_read(client, reg, &val);
- if (ret) {
- dev_err(&client->dev,
- "[Read]-Modify-Write of register 0x%02x failed!\n",
- reg);
- return ret;
- }
-
- val &= ~mask;
- val |= set;
-
- ret = ov6650_reg_write(client, reg, val);
- if (ret)
- dev_err(&client->dev,
- "Read-Modify-[Write] of register 0x%02x failed!\n",
- reg);
-
- return ret;
-}
-
-static struct ov6650 *to_ov6650(const struct i2c_client *client)
-{
- return container_of(i2c_get_clientdata(client), struct ov6650, subdev);
-}
-
-/* Start/Stop streaming from the device */
-static int ov6650_s_stream(struct v4l2_subdev *sd, int enable)
-{
- return 0;
-}
-
-/* Get status of additional camera capabilities */
-static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
- struct v4l2_subdev *sd = &priv->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- uint8_t reg, reg2;
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- ret = ov6650_reg_read(client, REG_GAIN, &reg);
- if (!ret)
- priv->gain->val = reg;
- return ret;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = ov6650_reg_read(client, REG_BLUE, &reg);
- if (!ret)
- ret = ov6650_reg_read(client, REG_RED, &reg2);
- if (!ret) {
- priv->blue->val = reg;
- priv->red->val = reg2;
- }
- return ret;
- case V4L2_CID_EXPOSURE_AUTO:
- ret = ov6650_reg_read(client, REG_AECH, &reg);
- if (!ret)
- priv->exposure->val = reg;
- return ret;
- }
- return -EINVAL;
-}
-
-/* Set status of additional camera capabilities */
-static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
- struct v4l2_subdev *sd = &priv->subdev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_AUTOGAIN:
- ret = ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_AGC : 0, COMB_AGC);
- if (!ret && !ctrl->val)
- ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val);
- return ret;
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ret = ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_AWB : 0, COMB_AWB);
- if (!ret && !ctrl->val) {
- ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val);
- if (!ret)
- ret = ov6650_reg_write(client, REG_RED,
- priv->red->val);
- }
- return ret;
- case V4L2_CID_SATURATION:
- return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val),
- SAT_MASK);
- case V4L2_CID_HUE:
- return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val),
- HUE_MASK);
- case V4L2_CID_BRIGHTNESS:
- return ov6650_reg_write(client, REG_BRT, ctrl->val);
- case V4L2_CID_EXPOSURE_AUTO:
- ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val ==
- V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC);
- if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL)
- ret = ov6650_reg_write(client, REG_AECH,
- priv->exposure->val);
- return ret;
- case V4L2_CID_GAMMA:
- return ov6650_reg_write(client, REG_GAM1, ctrl->val);
- case V4L2_CID_VFLIP:
- return ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V);
- case V4L2_CID_HFLIP:
- return ov6650_reg_rmw(client, REG_COMB,
- ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H);
- }
-
- return -EINVAL;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov6650_get_register(struct v4l2_subdev *sd,
- struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret;
- u8 val;
-
- if (reg->reg & ~0xff)
- return -EINVAL;
-
- reg->size = 1;
-
- ret = ov6650_reg_read(client, reg->reg, &val);
- if (!ret)
- reg->val = (__u64)val;
-
- return ret;
-}
-
-static int ov6650_set_register(struct v4l2_subdev *sd,
- const struct v4l2_dbg_register *reg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (reg->reg & ~0xff || reg->val & ~0xff)
- return -EINVAL;
-
- return ov6650_reg_write(client, reg->reg, reg->val);
-}
-#endif
-
-static int ov6650_s_power(struct v4l2_subdev *sd, int on)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- int ret = 0;
-
- if (on)
- ret = clk_prepare_enable(priv->clk);
- else
- clk_disable_unprepare(priv->clk);
-
- return ret;
-}
-
-static int ov6650_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_selection *sel)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- struct v4l2_rect *rect;
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- /* pre-select try crop rectangle */
- rect = v4l2_subdev_state_get_crop(sd_state, 0);
-
- } else {
- /* pre-select active crop rectangle */
- rect = &priv->rect;
- }
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- sel->r.left = DEF_HSTRT << 1;
- sel->r.top = DEF_VSTRT << 1;
- sel->r.width = W_CIF;
- sel->r.height = H_CIF;
- return 0;
-
- case V4L2_SEL_TGT_CROP:
- /* use selected crop rectangle */
- sel->r = *rect;
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect)
-{
- return width > rect->width >> 1 || height > rect->height >> 1;
-}
-
-static void ov6650_bind_align_crop_rectangle(struct v4l2_rect *rect)
-{
- v4l_bound_align_image(&rect->width, 2, W_CIF, 1,
- &rect->height, 2, H_CIF, 1, 0);
- v4l_bound_align_image(&rect->left, DEF_HSTRT << 1,
- (DEF_HSTRT << 1) + W_CIF - (__s32)rect->width, 1,
- &rect->top, DEF_VSTRT << 1,
- (DEF_VSTRT << 1) + H_CIF - (__s32)rect->height,
- 1, 0);
-}
-
-static int ov6650_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_selection *sel)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- int ret;
-
- if (sel->target != V4L2_SEL_TGT_CROP)
- return -EINVAL;
-
- ov6650_bind_align_crop_rectangle(&sel->r);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- struct v4l2_rect *crop =
- v4l2_subdev_state_get_crop(sd_state, 0);
- struct v4l2_mbus_framefmt *mf =
- v4l2_subdev_state_get_format(sd_state, 0);
- /* detect current pad config scaling factor */
- bool half_scale = !is_unscaled_ok(mf->width, mf->height, crop);
-
- /* store new crop rectangle */
- *crop = sel->r;
-
- /* adjust frame size */
- mf->width = crop->width >> half_scale;
- mf->height = crop->height >> half_scale;
-
- return 0;
- }
-
- /* V4L2_SUBDEV_FORMAT_ACTIVE */
-
- /* apply new crop rectangle */
- ret = ov6650_reg_write(client, REG_HSTRT, sel->r.left >> 1);
- if (!ret) {
- priv->rect.width += priv->rect.left - sel->r.left;
- priv->rect.left = sel->r.left;
- ret = ov6650_reg_write(client, REG_HSTOP,
- (sel->r.left + sel->r.width) >> 1);
- }
- if (!ret) {
- priv->rect.width = sel->r.width;
- ret = ov6650_reg_write(client, REG_VSTRT, sel->r.top >> 1);
- }
- if (!ret) {
- priv->rect.height += priv->rect.top - sel->r.top;
- priv->rect.top = sel->r.top;
- ret = ov6650_reg_write(client, REG_VSTOP,
- (sel->r.top + sel->r.height) >> 1);
- }
- if (!ret)
- priv->rect.height = sel->r.height;
-
- return ret;
-}
-
-static int ov6650_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct v4l2_mbus_framefmt *mf = &format->format;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
-
- if (format->pad)
- return -EINVAL;
-
- /* initialize response with default media bus frame format */
- *mf = ov6650_def_fmt;
-
- /* update media bus format code and frame size */
- if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- struct v4l2_mbus_framefmt *try_fmt =
- v4l2_subdev_state_get_format(sd_state, 0);
-
- mf->width = try_fmt->width;
- mf->height = try_fmt->height;
- mf->code = try_fmt->code;
-
- } else {
- mf->width = priv->rect.width >> priv->half_scale;
- mf->height = priv->rect.height >> priv->half_scale;
- mf->code = priv->code;
- }
- return 0;
-}
-
-#define to_clkrc(div) ((div) - 1)
-
-/* set the format we will capture in */
-static int ov6650_s_fmt(struct v4l2_subdev *sd, u32 code, bool half_scale)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask;
- int ret;
-
- /* select color matrix configuration for given color encoding */
- switch (code) {
- case MEDIA_BUS_FMT_Y8_1X8:
- dev_dbg(&client->dev, "pixel format GREY8_1X8\n");
- coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP;
- coma_set |= COMA_BW;
- break;
- case MEDIA_BUS_FMT_YUYV8_2X8:
- dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n");
- coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP;
- coma_set |= COMA_WORD_SWAP;
- break;
- case MEDIA_BUS_FMT_YVYU8_2X8:
- dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n");
- coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP |
- COMA_BYTE_SWAP;
- break;
- case MEDIA_BUS_FMT_UYVY8_2X8:
- dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n");
- if (half_scale) {
- coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP;
- coma_set |= COMA_BYTE_SWAP;
- } else {
- coma_mask |= COMA_RGB | COMA_BW;
- coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP;
- }
- break;
- case MEDIA_BUS_FMT_VYUY8_2X8:
- dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n");
- if (half_scale) {
- coma_mask |= COMA_RGB | COMA_BW;
- coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP;
- } else {
- coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP;
- coma_set |= COMA_BYTE_SWAP;
- }
- break;
- case MEDIA_BUS_FMT_SBGGR8_1X8:
- dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n");
- coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP;
- coma_set |= COMA_RAW_RGB | COMA_RGB;
- break;
- default:
- dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code);
- return -EINVAL;
- }
-
- if (code == MEDIA_BUS_FMT_Y8_1X8 ||
- code == MEDIA_BUS_FMT_SBGGR8_1X8) {
- coml_mask = COML_ONE_CHANNEL;
- coml_set = 0;
- } else {
- coml_mask = 0;
- coml_set = COML_ONE_CHANNEL;
- }
-
- if (half_scale) {
- dev_dbg(&client->dev, "max resolution: QCIF\n");
- coma_set |= COMA_QCIF;
- } else {
- dev_dbg(&client->dev, "max resolution: CIF\n");
- coma_mask |= COMA_QCIF;
- }
-
- ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask);
- if (!ret) {
- priv->half_scale = half_scale;
-
- ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask);
- }
- if (!ret)
- priv->code = code;
-
- return ret;
-}
-
-static int ov6650_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct v4l2_mbus_framefmt *mf = &format->format;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- struct v4l2_rect *crop;
- bool half_scale;
-
- if (format->pad)
- return -EINVAL;
-
- switch (mf->code) {
- case MEDIA_BUS_FMT_Y10_1X10:
- mf->code = MEDIA_BUS_FMT_Y8_1X8;
- fallthrough;
- case MEDIA_BUS_FMT_Y8_1X8:
- case MEDIA_BUS_FMT_YVYU8_2X8:
- case MEDIA_BUS_FMT_YUYV8_2X8:
- case MEDIA_BUS_FMT_VYUY8_2X8:
- case MEDIA_BUS_FMT_UYVY8_2X8:
- break;
- default:
- mf->code = MEDIA_BUS_FMT_SBGGR8_1X8;
- fallthrough;
- case MEDIA_BUS_FMT_SBGGR8_1X8:
- break;
- }
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- crop = v4l2_subdev_state_get_crop(sd_state, 0);
- else
- crop = &priv->rect;
-
- half_scale = !is_unscaled_ok(mf->width, mf->height, crop);
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- struct v4l2_mbus_framefmt *try_fmt =
- v4l2_subdev_state_get_format(sd_state, 0);
-
- /* store new mbus frame format code and size in pad config */
- try_fmt->width = crop->width >> half_scale;
- try_fmt->height = crop->height >> half_scale;
- try_fmt->code = mf->code;
-
- /* return default mbus frame format updated with pad config */
- *mf = ov6650_def_fmt;
- mf->width = try_fmt->width;
- mf->height = try_fmt->height;
- mf->code = try_fmt->code;
-
- } else {
- int ret = 0;
-
- /* apply new media bus frame format and scaling if changed */
- if (mf->code != priv->code || half_scale != priv->half_scale)
- ret = ov6650_s_fmt(sd, mf->code, half_scale);
- if (ret)
- return ret;
-
- /* return default format updated with active size and code */
- *mf = ov6650_def_fmt;
- mf->width = priv->rect.width >> priv->half_scale;
- mf->height = priv->rect.height >> priv->half_scale;
- mf->code = priv->code;
- }
- return 0;
-}
-
-static int ov6650_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->pad || code->index >= ARRAY_SIZE(ov6650_codes))
- return -EINVAL;
-
- code->code = ov6650_codes[code->index];
- return 0;
-}
-
-static int ov6650_enum_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_frame_interval_enum *fie)
-{
- int i;
-
- /* enumerate supported frame intervals not exceeding 1 second */
- if (fie->index > CLKRC_DIV_MASK ||
- GET_CLKRC_DIV(fie->index) > FRAME_RATE_MAX)
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(ov6650_codes); i++)
- if (fie->code == ov6650_codes[i])
- break;
- if (i == ARRAY_SIZE(ov6650_codes))
- return -EINVAL;
-
- if (!fie->width || fie->width > W_CIF ||
- !fie->height || fie->height > H_CIF)
- return -EINVAL;
-
- fie->interval.numerator = GET_CLKRC_DIV(fie->index);
- fie->interval.denominator = FRAME_RATE_MAX;
-
- return 0;
-}
-
-static int ov6650_get_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_frame_interval *ival)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
-
- /*
- * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
- * subdev active state API.
- */
- if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- ival->interval = priv->tpf;
-
- dev_dbg(&client->dev, "Frame interval: %u/%u s\n",
- ival->interval.numerator, ival->interval.denominator);
-
- return 0;
-}
-
-static int ov6650_set_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_frame_interval *ival)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- struct v4l2_fract *tpf = &ival->interval;
- int div, ret;
-
- /*
- * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
- * subdev active state API.
- */
- if (ival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (tpf->numerator == 0 || tpf->denominator == 0)
- div = 1; /* Reset to full rate */
- else
- div = (tpf->numerator * FRAME_RATE_MAX) / tpf->denominator;
-
- if (div == 0)
- div = 1;
- else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK))
- div = GET_CLKRC_DIV(CLKRC_DIV_MASK);
-
- ret = ov6650_reg_rmw(client, REG_CLKRC, to_clkrc(div), CLKRC_DIV_MASK);
- if (!ret) {
- priv->tpf.numerator = div;
- priv->tpf.denominator = FRAME_RATE_MAX;
-
- *tpf = priv->tpf;
- }
-
- return ret;
-}
-
-/* Soft reset the camera. This has nothing to do with the RESET pin! */
-static int ov6650_reset(struct i2c_client *client)
-{
- int ret;
-
- dev_dbg(&client->dev, "reset\n");
-
- ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0);
- if (ret)
- dev_err(&client->dev,
- "An error occurred while entering soft reset!\n");
-
- return ret;
-}
-
-/* program default register values */
-static int ov6650_prog_dflt(struct i2c_client *client, u8 clkrc)
-{
- int ret;
-
- dev_dbg(&client->dev, "initializing\n");
-
- ret = ov6650_reg_write(client, REG_COMA, 0); /* ~COMA_RESET */
- if (!ret)
- ret = ov6650_reg_write(client, REG_CLKRC, clkrc);
- if (!ret)
- ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_BAND_FILTER);
-
- return ret;
-}
-
-static int ov6650_video_probe(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov6650 *priv = to_ov6650(client);
- const struct ov6650_xclk *xclk = NULL;
- unsigned long rate;
- u8 pidh, pidl, midh, midl;
- int i, ret = 0;
-
- priv->clk = devm_clk_get(&client->dev, NULL);
- if (IS_ERR(priv->clk)) {
- ret = PTR_ERR(priv->clk);
- dev_err(&client->dev, "clk request err: %d\n", ret);
- return ret;
- }
-
- rate = clk_get_rate(priv->clk);
- for (i = 0; rate && i < ARRAY_SIZE(ov6650_xclk); i++) {
- if (rate != ov6650_xclk[i].rate)
- continue;
-
- xclk = &ov6650_xclk[i];
- dev_info(&client->dev, "using host default clock rate %lukHz\n",
- rate / 1000);
- break;
- }
- for (i = 0; !xclk && i < ARRAY_SIZE(ov6650_xclk); i++) {
- ret = clk_set_rate(priv->clk, ov6650_xclk[i].rate);
- if (ret || clk_get_rate(priv->clk) != ov6650_xclk[i].rate)
- continue;
-
- xclk = &ov6650_xclk[i];
- dev_info(&client->dev, "using negotiated clock rate %lukHz\n",
- xclk->rate / 1000);
- break;
- }
- if (!xclk) {
- dev_err(&client->dev, "unable to get supported clock rate\n");
- if (!ret)
- ret = -EINVAL;
- return ret;
- }
-
- ret = ov6650_s_power(sd, 1);
- if (ret < 0)
- return ret;
-
- msleep(20);
-
- /*
- * check and show product ID and manufacturer ID
- */
- ret = ov6650_reg_read(client, REG_PIDH, &pidh);
- if (!ret)
- ret = ov6650_reg_read(client, REG_PIDL, &pidl);
- if (!ret)
- ret = ov6650_reg_read(client, REG_MIDH, &midh);
- if (!ret)
- ret = ov6650_reg_read(client, REG_MIDL, &midl);
-
- if (ret)
- goto done;
-
- if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) {
- dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n",
- pidh, pidl);
- ret = -ENODEV;
- goto done;
- }
-
- dev_info(&client->dev,
- "ov6650 Product ID 0x%02x:0x%02x Manufacturer ID 0x%02x:0x%02x\n",
- pidh, pidl, midh, midl);
-
- ret = ov6650_reset(client);
- if (!ret)
- ret = ov6650_prog_dflt(client, xclk->clkrc);
- if (!ret) {
- /* driver default frame format, no scaling */
- ret = ov6650_s_fmt(sd, ov6650_def_fmt.code, false);
- }
- if (!ret)
- ret = v4l2_ctrl_handler_setup(&priv->hdl);
-
-done:
- ov6650_s_power(sd, 0);
- return ret;
-}
-
-static const struct v4l2_ctrl_ops ov6550_ctrl_ops = {
- .g_volatile_ctrl = ov6550_g_volatile_ctrl,
- .s_ctrl = ov6550_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops ov6650_core_ops = {
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .g_register = ov6650_get_register,
- .s_register = ov6650_set_register,
-#endif
- .s_power = ov6650_s_power,
-};
-
-/* Request bus settings on camera side */
-static int ov6650_get_mbus_config(struct v4l2_subdev *sd,
- unsigned int pad,
- struct v4l2_mbus_config *cfg)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u8 comj, comf;
- int ret;
-
- ret = ov6650_reg_read(client, REG_COMJ, &comj);
- if (ret)
- return ret;
-
- ret = ov6650_reg_read(client, REG_COMF, &comf);
- if (ret)
- return ret;
-
- cfg->type = V4L2_MBUS_PARALLEL;
-
- cfg->bus.parallel.flags = V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH
- | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
- : V4L2_MBUS_VSYNC_ACTIVE_LOW)
- | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW
- : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
- | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
- : V4L2_MBUS_PCLK_SAMPLE_FALLING);
- return 0;
-}
-
-static const struct v4l2_subdev_video_ops ov6650_video_ops = {
- .s_stream = ov6650_s_stream,
-};
-
-static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
- .enum_mbus_code = ov6650_enum_mbus_code,
- .enum_frame_interval = ov6650_enum_frame_interval,
- .get_selection = ov6650_get_selection,
- .set_selection = ov6650_set_selection,
- .get_fmt = ov6650_get_fmt,
- .set_fmt = ov6650_set_fmt,
- .get_frame_interval = ov6650_get_frame_interval,
- .set_frame_interval = ov6650_set_frame_interval,
- .get_mbus_config = ov6650_get_mbus_config,
-};
-
-static const struct v4l2_subdev_ops ov6650_subdev_ops = {
- .core = &ov6650_core_ops,
- .video = &ov6650_video_ops,
- .pad = &ov6650_pad_ops,
-};
-
-static const struct v4l2_subdev_internal_ops ov6650_internal_ops = {
- .registered = ov6650_video_probe,
-};
-
-/*
- * i2c_driver function
- */
-static int ov6650_probe(struct i2c_client *client)
-{
- struct ov6650 *priv;
- int ret;
-
- priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
- v4l2_ctrl_handler_init(&priv->hdl, 13);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
- priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN);
- priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE);
- priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_SATURATION, 0, 0xf, 1, 0x8);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80);
- priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl,
- &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
- V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
- priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH);
- v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
- V4L2_CID_GAMMA, 0, 0xff, 1, 0x12);
-
- priv->subdev.ctrl_handler = &priv->hdl;
- if (priv->hdl.error) {
- ret = priv->hdl.error;
- goto ectlhdlfree;
- }
-
- v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true);
- v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true);
- v4l2_ctrl_auto_cluster(2, &priv->autoexposure,
- V4L2_EXPOSURE_MANUAL, true);
-
- priv->rect.left = DEF_HSTRT << 1;
- priv->rect.top = DEF_VSTRT << 1;
- priv->rect.width = W_CIF;
- priv->rect.height = H_CIF;
-
- /* Hardware default frame interval */
- priv->tpf.numerator = GET_CLKRC_DIV(DEF_CLKRC);
- priv->tpf.denominator = FRAME_RATE_MAX;
-
- priv->subdev.internal_ops = &ov6650_internal_ops;
-
- ret = v4l2_async_register_subdev(&priv->subdev);
- if (!ret)
- return 0;
-ectlhdlfree:
- v4l2_ctrl_handler_free(&priv->hdl);
-
- return ret;
-}
-
-static void ov6650_remove(struct i2c_client *client)
-{
- struct ov6650 *priv = to_ov6650(client);
-
- v4l2_async_unregister_subdev(&priv->subdev);
- v4l2_ctrl_handler_free(&priv->hdl);
-}
-
-static const struct i2c_device_id ov6650_id[] = {
- { "ov6650" },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ov6650_id);
-
-static struct i2c_driver ov6650_i2c_driver = {
- .driver = {
- .name = "ov6650",
- },
- .probe = ov6650_probe,
- .remove = ov6650_remove,
- .id_table = ov6650_id,
-};
-
-module_i2c_driver(ov6650_i2c_driver);
-
-MODULE_DESCRIPTION("V4L2 subdevice driver for OmniVision OV6650 camera sensor");
-MODULE_AUTHOR("Janusz Krzysztofik <jmkrzyszt@gmail.com");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c
index 31a42d81e970..27afc3fc0175 100644
--- a/drivers/media/i2c/ov7251.c
+++ b/drivers/media/i2c/ov7251.c
@@ -1630,7 +1630,6 @@ static int ov7251_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct ov7251 *ov7251;
- unsigned int rate = 0, clk_rate = 0;
int ret;
int i;
@@ -1646,33 +1645,12 @@ static int ov7251_probe(struct i2c_client *client)
return ret;
/* get system clock (xclk) */
- ov7251->xclk = devm_clk_get_optional(dev, NULL);
+ ov7251->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(ov7251->xclk))
return dev_err_probe(dev, PTR_ERR(ov7251->xclk),
"could not get xclk");
- /*
- * We could have either a 24MHz or 19.2MHz clock rate from either DT or
- * ACPI. We also need to support the IPU3 case which will have both an
- * external clock AND a clock-frequency property.
- */
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &rate);
- if (ret && !ov7251->xclk)
- return dev_err_probe(dev, ret, "invalid clock config\n");
-
- clk_rate = clk_get_rate(ov7251->xclk);
- ov7251->xclk_freq = clk_rate ? clk_rate : rate;
-
- if (ov7251->xclk_freq == 0)
- return dev_err_probe(dev, -EINVAL, "invalid clock frequency\n");
-
- if (!ret && ov7251->xclk) {
- ret = clk_set_rate(ov7251->xclk, rate);
- if (ret)
- return dev_err_probe(dev, ret,
- "failed to set clock rate\n");
- }
+ ov7251->xclk_freq = clk_get_rate(ov7251->xclk);
for (i = 0; i < ARRAY_SIZE(supported_xclk_rates); i++)
if (ov7251->xclk_freq == supported_xclk_rates[i])
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 1f1c0de8e510..632fb80469be 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1036,13 +1036,10 @@ static int ov7740_probe(struct i2c_client *client)
if (!ov7740)
return -ENOMEM;
- ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
- if (IS_ERR(ov7740->xvclk)) {
- ret = PTR_ERR(ov7740->xvclk);
- dev_err(&client->dev,
- "OV7740: fail to get xvclk: %d\n", ret);
- return ret;
- }
+ ov7740->xvclk = devm_v4l2_sensor_clk_get(&client->dev, "xvclk");
+ if (IS_ERR(ov7740->xvclk))
+ return dev_err_probe(&client->dev, PTR_ERR(ov7740->xvclk),
+ "OV7740: fail to get xvclk\n");
ret = ov7740_probe_dt(client, ov7740);
if (ret)
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
index 4b6874d2a104..e2998cfa0d18 100644
--- a/drivers/media/i2c/ov8856.c
+++ b/drivers/media/i2c/ov8856.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
@@ -10,6 +9,8 @@
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -1414,6 +1415,8 @@ static const struct ov8856_reg_list bayer_offset_configs[] = {
};
struct ov8856 {
+ struct device *dev;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -1668,7 +1671,6 @@ static int ov8856_write_reg(struct ov8856 *ov8856, u16 reg, u16 len, u32 val)
static int ov8856_write_reg_list(struct ov8856 *ov8856,
const struct ov8856_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
unsigned int i;
int ret;
@@ -1676,7 +1678,7 @@ static int ov8856_write_reg_list(struct ov8856 *ov8856,
ret = ov8856_write_reg(ov8856, r_list->regs[i].address, 1,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov8856->dev,
"failed to write reg 0x%4.4x. error = %d",
r_list->regs[i].address, ret);
return ret;
@@ -1688,7 +1690,6 @@ static int ov8856_write_reg_list(struct ov8856 *ov8856,
static int ov8856_identify_module(struct ov8856 *ov8856)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
int ret;
u32 val;
@@ -1701,7 +1702,7 @@ static int ov8856_identify_module(struct ov8856 *ov8856)
return ret;
if (val != OV8856_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(ov8856->dev, "chip id mismatch: %x!=%x",
OV8856_CHIP_ID, val);
return -ENXIO;
}
@@ -1818,7 +1819,6 @@ static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov8856 *ov8856 = container_of(ctrl->handler,
struct ov8856, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
s64 exposure_max;
int ret = 0;
@@ -1834,7 +1834,7 @@ static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov8856->dev))
return 0;
switch (ctrl->id) {
@@ -1876,7 +1876,7 @@ static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov8856->dev);
return ret;
}
@@ -1979,7 +1979,6 @@ static void ov8856_update_pad_format(struct ov8856 *ov8856,
static int ov8856_start_streaming(struct ov8856 *ov8856)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
const struct ov8856_reg_list *reg_list;
int link_freq_index, ret;
@@ -1992,21 +1991,21 @@ static int ov8856_start_streaming(struct ov8856 *ov8856)
ret = ov8856_write_reg_list(ov8856, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls");
+ dev_err(ov8856->dev, "failed to set plls");
return ret;
}
reg_list = &ov8856->cur_mode->reg_list;
ret = ov8856_write_reg_list(ov8856, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(ov8856->dev, "failed to set mode");
return ret;
}
reg_list = &bayer_offset_configs[ov8856->cur_mbus_index];
ret = ov8856_write_reg_list(ov8856, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mbus format");
+ dev_err(ov8856->dev, "failed to set mbus format");
return ret;
}
@@ -2017,7 +2016,7 @@ static int ov8856_start_streaming(struct ov8856 *ov8856)
ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
if (ret) {
- dev_err(&client->dev, "failed to set stream");
+ dev_err(ov8856->dev, "failed to set stream");
return ret;
}
@@ -2026,22 +2025,19 @@ static int ov8856_start_streaming(struct ov8856 *ov8856)
static void ov8856_stop_streaming(struct ov8856 *ov8856)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
-
if (ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY))
- dev_err(&client->dev, "failed to set stream");
+ dev_err(ov8856->dev, "failed to set stream");
}
static int ov8856_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov8856 *ov8856 = to_ov8856(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov8856->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov8856->dev);
if (ret < 0) {
mutex_unlock(&ov8856->mutex);
return ret;
@@ -2051,11 +2047,11 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
ov8856_stop_streaming(ov8856);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov8856->dev);
}
} else {
ov8856_stop_streaming(ov8856);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov8856->dev);
}
mutex_unlock(&ov8856->mutex);
@@ -2255,8 +2251,9 @@ static const struct v4l2_subdev_internal_ops ov8856_internal_ops = {
};
-static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
+static int ov8856_get_hwcfg(struct ov8856 *ov8856)
{
+ struct device *dev = ov8856->dev;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct v4l2_fwnode_endpoint bus_cfg = {
@@ -2269,21 +2266,17 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
if (!fwnode)
return -ENXIO;
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &xvclk_rate);
- if (ret)
- return ret;
-
- if (!is_acpi_node(fwnode)) {
- ov8856->xvclk = devm_clk_get(dev, "xvclk");
- if (IS_ERR(ov8856->xvclk)) {
- dev_err_probe(dev, PTR_ERR(ov8856->xvclk),
- "could not get xvclk clock\n");
- return PTR_ERR(ov8856->xvclk);
- }
+ ov8856->xvclk = devm_v4l2_sensor_clk_get_legacy(dev, "xvclk", false, 0);
+ if (IS_ERR(ov8856->xvclk))
+ return dev_err_probe(dev, PTR_ERR(ov8856->xvclk),
+ "could not get xvclk clock\n");
- clk_set_rate(ov8856->xvclk, xvclk_rate);
- xvclk_rate = clk_get_rate(ov8856->xvclk);
+ xvclk_rate = clk_get_rate(ov8856->xvclk);
+ if (xvclk_rate != OV8856_XVCLK_19_2)
+ dev_warn(dev, "external clock rate %u is unsupported",
+ xvclk_rate);
+ if (!is_acpi_node(fwnode)) {
ov8856->reset_gpio = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(ov8856->reset_gpio))
@@ -2299,10 +2292,6 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
return ret;
}
- if (xvclk_rate != OV8856_XVCLK_19_2)
- dev_warn(dev, "external clock rate %u is unsupported",
- xvclk_rate);
-
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
return -ENXIO;
@@ -2365,10 +2354,10 @@ static void ov8856_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
+ pm_runtime_disable(ov8856->dev);
mutex_destroy(&ov8856->mutex);
- ov8856_power_off(&client->dev);
+ ov8856_power_off(ov8856->dev);
}
static int ov8856_probe(struct i2c_client *client)
@@ -2381,23 +2370,25 @@ static int ov8856_probe(struct i2c_client *client)
if (!ov8856)
return -ENOMEM;
- ret = ov8856_get_hwcfg(ov8856, &client->dev);
+ ov8856->dev = &client->dev;
+
+ ret = ov8856_get_hwcfg(ov8856);
if (ret)
return ret;
v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
- full_power = acpi_dev_state_d0(&client->dev);
+ full_power = acpi_dev_state_d0(ov8856->dev);
if (full_power) {
- ret = ov8856_power_on(&client->dev);
+ ret = ov8856_power_on(ov8856->dev);
if (ret) {
- dev_err(&client->dev, "failed to power on\n");
+ dev_err(ov8856->dev, "failed to power on\n");
return ret;
}
ret = ov8856_identify_module(ov8856);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(ov8856->dev, "failed to find sensor: %d", ret);
goto probe_power_off;
}
}
@@ -2407,7 +2398,7 @@ static int ov8856_probe(struct i2c_client *client)
ov8856->cur_mbus_index = ov8856->cur_mode->default_mbus_index;
ret = ov8856_init_controls(ov8856);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(ov8856->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -2418,22 +2409,22 @@ static int ov8856_probe(struct i2c_client *client)
ov8856->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov8856->sd.entity, 1, &ov8856->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(ov8856->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&ov8856->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(ov8856->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_media_entity_cleanup;
}
/* Set the device's state to active if it's in D0 state. */
if (full_power)
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov8856->dev);
+ pm_runtime_enable(ov8856->dev);
+ pm_runtime_idle(ov8856->dev);
return 0;
@@ -2445,7 +2436,7 @@ probe_error_v4l2_ctrl_handler_free:
mutex_destroy(&ov8856->mutex);
probe_power_off:
- ov8856_power_off(&client->dev);
+ ov8856_power_off(ov8856->dev);
return ret;
}
diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c
index 6b7193eaea1f..3f45f7fab833 100644
--- a/drivers/media/i2c/ov8858.c
+++ b/drivers/media/i2c/ov8858.c
@@ -1876,7 +1876,7 @@ static int ov8858_probe(struct i2c_client *client)
if (!ov8858)
return -ENOMEM;
- ov8858->xvclk = devm_clk_get(dev, "xvclk");
+ ov8858->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
if (IS_ERR(ov8858->xvclk))
return dev_err_probe(dev, PTR_ERR(ov8858->xvclk),
"Failed to get xvclk\n");
diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index a2138f7988aa..a8586df14f77 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2304,14 +2304,6 @@ static int ov8865_state_configure(struct ov8865_sensor *sensor,
if (sensor->state.streaming)
return -EBUSY;
- /* State will be configured at first power on otherwise. */
- if (pm_runtime_enabled(sensor->dev) &&
- !pm_runtime_suspended(sensor->dev)) {
- ret = ov8865_mode_configure(sensor, mode, mbus_code);
- if (ret)
- return ret;
- }
-
ret = ov8865_state_mipi_configure(sensor, mode, mbus_code);
if (ret)
return ret;
@@ -2384,10 +2376,10 @@ static int ov8865_sensor_init(struct ov8865_sensor *sensor)
}
/* Configure current mode. */
- ret = ov8865_state_configure(sensor, sensor->state.mode,
- sensor->state.mbus_code);
+ ret = ov8865_mode_configure(sensor, sensor->state.mode,
+ sensor->state.mbus_code);
if (ret) {
- dev_err(sensor->dev, "failed to configure state\n");
+ dev_err(sensor->dev, "failed to configure mode\n");
return ret;
}
@@ -2956,7 +2948,6 @@ static int ov8865_probe(struct i2c_client *client)
struct ov8865_sensor *sensor;
struct v4l2_subdev *subdev;
struct media_pad *pad;
- unsigned int rate = 0;
unsigned int i;
int ret;
@@ -3020,39 +3011,14 @@ static int ov8865_probe(struct i2c_client *client)
/* External Clock */
- sensor->extclk = devm_clk_get(dev, NULL);
- if (PTR_ERR(sensor->extclk) == -ENOENT) {
- dev_info(dev, "no external clock found, continuing...\n");
- sensor->extclk = NULL;
- } else if (IS_ERR(sensor->extclk)) {
- dev_err(dev, "failed to get external clock\n");
- ret = PTR_ERR(sensor->extclk);
- goto error_endpoint;
- }
-
- /*
- * We could have either a 24MHz or 19.2MHz clock rate from either dt or
- * ACPI...but we also need to support the weird IPU3 case which will
- * have an external clock AND a clock-frequency property. Check for the
- * clock-frequency property and if found, set that rate if we managed
- * to acquire a clock. This should cover the ACPI case. If the system
- * uses devicetree then the configured rate should already be set, so
- * we can just read it.
- */
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &rate);
- if (!ret && sensor->extclk) {
- ret = clk_set_rate(sensor->extclk, rate);
- if (ret) {
- dev_err_probe(dev, ret, "failed to set clock rate\n");
- goto error_endpoint;
- }
- } else if (ret && !sensor->extclk) {
- dev_err_probe(dev, ret, "invalid clock config\n");
+ sensor->extclk = devm_v4l2_sensor_clk_get(dev, NULL);
+ if (IS_ERR(sensor->extclk)) {
+ ret = dev_err_probe(dev, PTR_ERR(sensor->extclk),
+ "failed to get external clock\n");
goto error_endpoint;
}
- sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+ sensor->extclk_rate = clk_get_rate(sensor->extclk);
for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
if (sensor->extclk_rate == supported_extclk_rates[i])
diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index c882a021cf18..a9f6176e9729 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -1135,11 +1135,10 @@ static int ov9282_parse_hw_config(struct ov9282 *ov9282)
}
/* Get sensor input clock */
- ov9282->inclk = devm_clk_get(ov9282->dev, NULL);
- if (IS_ERR(ov9282->inclk)) {
- dev_err(ov9282->dev, "could not get inclk");
- return PTR_ERR(ov9282->inclk);
- }
+ ov9282->inclk = devm_v4l2_sensor_clk_get(ov9282->dev, NULL);
+ if (IS_ERR(ov9282->inclk))
+ return dev_err_probe(ov9282->dev, PTR_ERR(ov9282->inclk),
+ "could not get inclk\n");
ret = ov9282_configure_regulators(ov9282);
if (ret)
diff --git a/drivers/media/i2c/ov9640.c b/drivers/media/i2c/ov9640.c
index 01dbc0ba89c8..2190c52b1433 100644
--- a/drivers/media/i2c/ov9640.c
+++ b/drivers/media/i2c/ov9640.c
@@ -718,9 +718,10 @@ static int ov9640_probe(struct i2c_client *client)
priv->subdev.ctrl_handler = &priv->hdl;
- priv->clk = devm_clk_get(&client->dev, "mclk");
+ priv->clk = devm_v4l2_sensor_clk_get(&client->dev, "mclk");
if (IS_ERR(priv->clk)) {
- ret = PTR_ERR(priv->clk);
+ ret = dev_err_probe(&client->dev, PTR_ERR(priv->clk),
+ "failed to get mclk\n");
goto ectrlinit;
}
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 026ea34d6291..c94e8fe29f22 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1494,9 +1494,10 @@ static int ov965x_probe(struct i2c_client *client)
}
if (dev_fwnode(&client->dev)) {
- ov965x->clk = devm_clk_get(&client->dev, NULL);
+ ov965x->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
if (IS_ERR(ov965x->clk))
- return PTR_ERR(ov965x->clk);
+ return dev_err_probe(&client->dev, PTR_ERR(ov965x->clk),
+ "failed to get the clock\n");
ov965x->mclk_frequency = clk_get_rate(ov965x->clk);
ret = ov965x_configure_gpios(ov965x);
diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c
index cae3aeefb616..0eaf33807fc9 100644
--- a/drivers/media/i2c/ov9734.c
+++ b/drivers/media/i2c/ov9734.c
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Intel Corporation.
-#include <linux/unaligned.h>
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/unaligned.h>
+
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -321,6 +323,9 @@ static const struct ov9734_mode supported_modes[] = {
};
struct ov9734 {
+ struct device *dev;
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
@@ -414,7 +419,6 @@ static int ov9734_write_reg(struct ov9734 *ov9734, u16 reg, u16 len, u32 val)
static int ov9734_write_reg_list(struct ov9734 *ov9734,
const struct ov9734_reg_list *r_list)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
unsigned int i;
int ret;
@@ -422,7 +426,7 @@ static int ov9734_write_reg_list(struct ov9734 *ov9734,
ret = ov9734_write_reg(ov9734, r_list->regs[i].address, 1,
r_list->regs[i].val);
if (ret) {
- dev_err_ratelimited(&client->dev,
+ dev_err_ratelimited(ov9734->dev,
"write reg 0x%4.4x return err = %d",
r_list->regs[i].address, ret);
return ret;
@@ -476,7 +480,6 @@ static int ov9734_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ov9734 *ov9734 = container_of(ctrl->handler,
struct ov9734, ctrl_handler);
- struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
s64 exposure_max;
int ret = 0;
@@ -492,7 +495,7 @@ static int ov9734_set_ctrl(struct v4l2_ctrl *ctrl)
}
/* V4L2 controls values will be applied only when power is already up */
- if (!pm_runtime_get_if_in_use(&client->dev))
+ if (!pm_runtime_get_if_in_use(ov9734->dev))
return 0;
switch (ctrl->id) {
@@ -525,7 +528,7 @@ static int ov9734_set_ctrl(struct v4l2_ctrl *ctrl)
break;
}
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov9734->dev);
return ret;
}
@@ -610,7 +613,6 @@ static void ov9734_update_pad_format(const struct ov9734_mode *mode,
static int ov9734_start_streaming(struct ov9734 *ov9734)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
const struct ov9734_reg_list *reg_list;
int link_freq_index, ret;
@@ -618,14 +620,14 @@ static int ov9734_start_streaming(struct ov9734 *ov9734)
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov9734_write_reg_list(ov9734, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set plls");
+ dev_err(ov9734->dev, "failed to set plls");
return ret;
}
reg_list = &ov9734->cur_mode->reg_list;
ret = ov9734_write_reg_list(ov9734, reg_list);
if (ret) {
- dev_err(&client->dev, "failed to set mode");
+ dev_err(ov9734->dev, "failed to set mode");
return ret;
}
@@ -636,30 +638,27 @@ static int ov9734_start_streaming(struct ov9734 *ov9734)
ret = ov9734_write_reg(ov9734, OV9734_REG_MODE_SELECT,
1, OV9734_MODE_STREAMING);
if (ret)
- dev_err(&client->dev, "failed to start stream");
+ dev_err(ov9734->dev, "failed to start stream");
return ret;
}
static void ov9734_stop_streaming(struct ov9734 *ov9734)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
-
if (ov9734_write_reg(ov9734, OV9734_REG_MODE_SELECT,
1, OV9734_MODE_STANDBY))
- dev_err(&client->dev, "failed to stop stream");
+ dev_err(ov9734->dev, "failed to stop stream");
}
static int ov9734_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov9734 *ov9734 = to_ov9734(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
mutex_lock(&ov9734->mutex);
if (enable) {
- ret = pm_runtime_resume_and_get(&client->dev);
+ ret = pm_runtime_resume_and_get(ov9734->dev);
if (ret < 0) {
mutex_unlock(&ov9734->mutex);
return ret;
@@ -669,11 +668,11 @@ static int ov9734_set_stream(struct v4l2_subdev *sd, int enable)
if (ret) {
enable = 0;
ov9734_stop_streaming(ov9734);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov9734->dev);
}
} else {
ov9734_stop_streaming(ov9734);
- pm_runtime_put(&client->dev);
+ pm_runtime_put(ov9734->dev);
}
mutex_unlock(&ov9734->mutex);
@@ -808,7 +807,6 @@ static const struct v4l2_subdev_internal_ops ov9734_internal_ops = {
static int ov9734_identify_module(struct ov9734 *ov9734)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov9734->sd);
int ret;
u32 val;
@@ -817,7 +815,7 @@ static int ov9734_identify_module(struct ov9734 *ov9734)
return ret;
if (val != OV9734_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ dev_err(ov9734->dev, "chip id mismatch: %x!=%x",
OV9734_CHIP_ID, val);
return -ENXIO;
}
@@ -832,22 +830,12 @@ static int ov9734_check_hwcfg(struct device *dev)
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
- u32 mclk;
int ret;
unsigned int i, j;
if (!fwnode)
return -ENXIO;
- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
- if (ret)
- return ret;
-
- if (mclk != OV9734_MCLK) {
- dev_err(dev, "external clock %d is not supported", mclk);
- return -EINVAL;
- }
-
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
return -ENXIO;
@@ -892,14 +880,15 @@ static void ov9734_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov9734->dev);
+ pm_runtime_set_suspended(ov9734->dev);
mutex_destroy(&ov9734->mutex);
}
static int ov9734_probe(struct i2c_client *client)
{
struct ov9734 *ov9734;
+ unsigned long freq;
int ret;
ret = ov9734_check_hwcfg(&client->dev);
@@ -913,10 +902,23 @@ static int ov9734_probe(struct i2c_client *client)
if (!ov9734)
return -ENOMEM;
+ ov9734->dev = &client->dev;
+
+ ov9734->clk = devm_v4l2_sensor_clk_get(ov9734->dev, NULL);
+ if (IS_ERR(ov9734->clk))
+ return dev_err_probe(ov9734->dev, PTR_ERR(ov9734->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(ov9734->clk);
+ if (freq != OV9734_MCLK)
+ return dev_err_probe(ov9734->dev, -EINVAL,
+ "external clock %lu is not supported",
+ freq);
+
v4l2_i2c_subdev_init(&ov9734->sd, client, &ov9734_subdev_ops);
ret = ov9734_identify_module(ov9734);
if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
+ dev_err(ov9734->dev, "failed to find sensor: %d", ret);
return ret;
}
@@ -924,7 +926,7 @@ static int ov9734_probe(struct i2c_client *client)
ov9734->cur_mode = &supported_modes[0];
ret = ov9734_init_controls(ov9734);
if (ret) {
- dev_err(&client->dev, "failed to init controls: %d", ret);
+ dev_err(ov9734->dev, "failed to init controls: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -935,7 +937,7 @@ static int ov9734_probe(struct i2c_client *client)
ov9734->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&ov9734->sd.entity, 1, &ov9734->pad);
if (ret) {
- dev_err(&client->dev, "failed to init entity pads: %d", ret);
+ dev_err(ov9734->dev, "failed to init entity pads: %d", ret);
goto probe_error_v4l2_ctrl_handler_free;
}
@@ -943,13 +945,13 @@ static int ov9734_probe(struct i2c_client *client)
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(ov9734->dev);
+ pm_runtime_enable(ov9734->dev);
+ pm_runtime_idle(ov9734->dev);
ret = v4l2_async_register_subdev_sensor(&ov9734->sd);
if (ret < 0) {
- dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ dev_err(ov9734->dev, "failed to register V4L2 subdev: %d",
ret);
goto probe_error_media_entity_cleanup_pm;
}
@@ -957,8 +959,8 @@ static int ov9734_probe(struct i2c_client *client)
return 0;
probe_error_media_entity_cleanup_pm:
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
+ pm_runtime_disable(ov9734->dev);
+ pm_runtime_set_suspended(ov9734->dev);
media_entity_cleanup(&ov9734->sd.entity);
probe_error_v4l2_ctrl_handler_free:
diff --git a/drivers/media/i2c/rj54n1cb0c.c b/drivers/media/i2c/rj54n1cb0c.c
index b7ca39f63dba..6dfc91216851 100644
--- a/drivers/media/i2c/rj54n1cb0c.c
+++ b/drivers/media/i2c/rj54n1cb0c.c
@@ -1329,10 +1329,13 @@ static int rj54n1_probe(struct i2c_client *client)
V4L2_CID_GAIN, 0, 127, 1, 66);
v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
- rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
- if (rj54n1->hdl.error)
- return rj54n1->hdl.error;
+ if (rj54n1->hdl.error) {
+ ret = rj54n1->hdl.error;
+ goto err_free_ctrl;
+ }
+
+ rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
rj54n1->clk_div = clk_div;
rj54n1->rect.left = RJ54N1_COLUMN_SKIP;
rj54n1->rect.top = RJ54N1_ROW_SKIP;
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 7716dfe2b8c9..ab31ee2b596b 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1368,10 +1368,6 @@ static int __s5c73m3_power_on(struct s5c73m3 *state)
goto err_reg_dis;
}
- ret = clk_set_rate(state->clock, state->mclk_frequency);
- if (ret < 0)
- goto err_reg_dis;
-
ret = clk_prepare_enable(state->clock);
if (ret < 0)
goto err_reg_dis;
@@ -1556,16 +1552,13 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
if (!node)
return -EINVAL;
- state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME);
+ state->clock = devm_v4l2_sensor_clk_get_legacy(dev, S5C73M3_CLK_NAME,
+ false,
+ S5C73M3_DEFAULT_MCLK_FREQ);
if (IS_ERR(state->clock))
- return PTR_ERR(state->clock);
-
- if (of_property_read_u32(node, "clock-frequency",
- &state->mclk_frequency)) {
- state->mclk_frequency = S5C73M3_DEFAULT_MCLK_FREQ;
- dev_info(dev, "using default %u Hz clock frequency\n",
- state->mclk_frequency);
- }
+ return dev_err_probe(dev, PTR_ERR(state->clock),
+ "Failed to get the clock %s\n",
+ S5C73M3_CLK_NAME);
/* Request GPIO lines asserted */
state->stby = devm_gpiod_get(dev, "standby", GPIOD_OUT_HIGH);
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h
index 627e80cf5b72..68a19c2c8db8 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3.h
+++ b/drivers/media/i2c/s5c73m3/s5c73m3.h
@@ -382,8 +382,6 @@ struct s5c73m3 {
struct clk *clock;
- /* External master clock frequency */
- u32 mclk_frequency;
/* Video bus type - MIPI-CSI2/parallel */
enum v4l2_mbus_type bus_type;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 24f399cd2124..d1d00eca8708 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -284,7 +284,6 @@ struct s5k5baf {
struct regulator_bulk_data supplies[S5K5BAF_NUM_SUPPLIES];
struct clk *clock;
- u32 mclk_frequency;
struct s5k5baf_fw *fw;
@@ -576,7 +575,7 @@ static void s5k5baf_hw_patch(struct s5k5baf *state)
static void s5k5baf_hw_set_clocks(struct s5k5baf *state)
{
- unsigned long mclk = state->mclk_frequency / 1000;
+ unsigned long mclk = clk_get_rate(state->clock) / 1000;
u16 status;
static const u16 nseq_clk_cfg[] = {
NSEQ(REG_I_USE_NPVI_CLOCKS,
@@ -946,10 +945,6 @@ static int s5k5baf_power_on(struct s5k5baf *state)
if (ret < 0)
goto err;
- ret = clk_set_rate(state->clock, state->mclk_frequency);
- if (ret < 0)
- goto err_reg_dis;
-
ret = clk_prepare_enable(state->clock);
if (ret < 0)
goto err_reg_dis;
@@ -1841,14 +1836,6 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
return -EINVAL;
}
- ret = of_property_read_u32(node, "clock-frequency",
- &state->mclk_frequency);
- if (ret < 0) {
- state->mclk_frequency = S5K5BAF_DEFAULT_MCLK_FREQ;
- dev_info(dev, "using default %u Hz clock frequency\n",
- state->mclk_frequency);
- }
-
node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!node_ep) {
dev_err(dev, "no endpoint defined at node %pOF\n", node);
@@ -1967,9 +1954,11 @@ static int s5k5baf_probe(struct i2c_client *c)
if (ret < 0)
goto err_me;
- state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
+ state->clock = devm_v4l2_sensor_clk_get_legacy(state->sd.dev,
+ S5K5BAF_CLK_NAME, false,
+ S5K5BAF_DEFAULT_MCLK_FREQ);
if (IS_ERR(state->clock)) {
- ret = -EPROBE_DEFER;
+ ret = PTR_ERR(state->clock);
goto err_me;
}
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index 0c2674115b7b..ba6477e88da3 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -51,7 +51,6 @@ enum {
* @lock: mutex protecting the structure's members below
* @format: media bus format at the sensor's source pad
* @clock: pointer to &struct clk.
- * @clock_frequency: clock frequency
* @power_count: stores state if device is powered
*/
struct s5k6a3 {
@@ -63,7 +62,6 @@ struct s5k6a3 {
struct mutex lock;
struct v4l2_mbus_framefmt format;
struct clk *clock;
- u32 clock_frequency;
int power_count;
};
@@ -192,10 +190,6 @@ static int __s5k6a3_power_on(struct s5k6a3 *sensor)
int i = S5K6A3_SUPP_VDDA;
int ret;
- ret = clk_set_rate(sensor->clock, sensor->clock_frequency);
- if (ret < 0)
- return ret;
-
ret = pm_runtime_get(sensor->dev);
if (ret < 0)
goto error_rpm_put;
@@ -292,22 +286,18 @@ static int s5k6a3_probe(struct i2c_client *client)
mutex_init(&sensor->lock);
sensor->dev = dev;
- sensor->clock = devm_clk_get(sensor->dev, S5K6A3_CLK_NAME);
+ sensor->clock = devm_v4l2_sensor_clk_get_legacy(sensor->dev,
+ S5K6A3_CLK_NAME, false,
+ S5K6A3_DEFAULT_CLK_FREQ);
if (IS_ERR(sensor->clock))
- return PTR_ERR(sensor->clock);
+ return dev_err_probe(sensor->dev, PTR_ERR(sensor->clock),
+ "failed to get extclk\n");
sensor->gpio_reset = devm_gpiod_get(dev, NULL, GPIOD_OUT_HIGH);
ret = PTR_ERR_OR_ZERO(sensor->gpio_reset);
if (ret)
return ret;
- if (of_property_read_u32(dev->of_node, "clock-frequency",
- &sensor->clock_frequency)) {
- sensor->clock_frequency = S5K6A3_DEFAULT_CLK_FREQ;
- dev_info(dev, "using default %u Hz clock frequency\n",
- sensor->clock_frequency);
- }
-
for (i = 0; i < S5K6A3_NUM_SUPPLIES; i++)
sensor->supplies[i].supply = s5k6a3_supply_names[i];
diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c
index 1ed8b5edb3fb..1c0031ba43b4 100644
--- a/drivers/media/i2c/saa6752hs.c
+++ b/drivers/media/i2c/saa6752hs.c
@@ -6,7 +6,7 @@
AC-3 support:
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2008 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index b8b8f206ec3a..48d6730d9271 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -18,7 +18,7 @@
// Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
// (2/17/2003)
//
-// VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
+// VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@kernel.org>
//
// Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org>
// SAA7111, SAA7113 and SAA7118 support
diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c
index 818ed19cf37b..a42a7ffe3768 100644
--- a/drivers/media/i2c/saa7127.c
+++ b/drivers/media/i2c/saa7127.c
@@ -25,7 +25,7 @@
* Copyright (C) 2004 Chris Kennedy <c@groovy.org>
*
* VBI additions & cleanup:
- * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@kernel.org>
*
* Note: the saa7126 is identical to the saa7127, and the saa7128 is
* identical to the saa7129, except that the saa7126 and saa7128 have
diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c
index b0793bb0c02a..713331be947c 100644
--- a/drivers/media/i2c/saa717x.c
+++ b/drivers/media/i2c/saa717x.c
@@ -10,7 +10,7 @@
* Changes by T.Adachi (tadachi@tadachi-net.com)
* - support audio, video scaler etc, and checked the initialize sequence.
*
- * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl>
+ * Cleaned up by Hans Verkuil <hverkuil@kernel.org>
*
* Note: this is a reversed engineered driver based on captures from
* the I2C bus under Windows. This chip is very similar to the saa7134,
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 1cc7636e446d..a0ca19359c43 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -38,7 +38,21 @@
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-3)");
+MODULE_PARM_DESC(debug, " debug level (0-3)");
+
+static int packet_type = 0x87;
+module_param(packet_type, int, 0644);
+MODULE_PARM_DESC(packet_type,
+ " Programmable Packet Type. Possible values:\n"
+ "\t\t 0x87: DRM InfoFrame (Default).\n"
+ "\t\t 0x01: Audio Clock Regeneration Packet\n"
+ "\t\t 0x02: Audio Sample Packet\n"
+ "\t\t 0x03: General Control Packet\n"
+ "\t\t 0x04: ACP Packet\n"
+ "\t\t 0x07: One Bit Audio Sample Packet\n"
+ "\t\t 0x08: DST Audio Packet\n"
+ "\t\t 0x09: High Bitrate Audio Stream Packet\n"
+ "\t\t 0x0a: Gamut Metadata Packet\n");
MODULE_DESCRIPTION("Toshiba TC358743 HDMI to CSI-2 bridge driver");
MODULE_AUTHOR("Ramakrishnan Muthukrishnan <ram@rkrishnan.org>");
@@ -466,10 +480,29 @@ tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
if (!is_hdmi(sd))
return 0;
- if (type != V4L2_DEBUGFS_IF_AVI)
+ switch (type) {
+ case V4L2_DEBUGFS_IF_AVI:
+ i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_AUDIO:
+ i2c_rd(sd, PK_AUD_0HEAD, buf, PK_AUD_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_SPD:
+ i2c_rd(sd, PK_SPD_0HEAD, buf, PK_SPD_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_HDMI:
+ i2c_rd(sd, PK_VS_0HEAD, buf, PK_VS_LEN);
+ break;
+ case V4L2_DEBUGFS_IF_DRM:
+ i2c_rd(sd, PK_ACP_0HEAD, buf, PK_ACP_LEN);
+ break;
+ default:
return 0;
+ }
+
+ if (!buf[2])
+ return -ENOENT;
- i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_16BYTE - PK_AVI_0HEAD + 1);
len = buf[2] + 4;
if (len > V4L2_DEBUGFS_IF_MAX_LEN)
len = -ENOENT;
@@ -478,26 +511,69 @@ tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
return len < 0 ? 0 : len;
}
-static void print_avi_infoframe(struct v4l2_subdev *sd)
+static void print_infoframes(struct v4l2_subdev *sd)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct device *dev = &client->dev;
union hdmi_infoframe frame;
- u8 buffer[HDMI_INFOFRAME_SIZE(AVI)] = {};
+ u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+
+ /*
+ * Updating the ACP TYPE here allows for dynamically
+ * changing the type you want to monitor, without having
+ * to reload the driver with a new packet_type module option value.
+ *
+ * Instead you can set it with the new value, then call
+ * VIDIOC_LOG_STATUS.
+ */
+ i2c_wr8(sd, TYP_ACP_SET, packet_type);
if (!is_hdmi(sd)) {
- v4l2_info(sd, "DVI-D signal - AVI infoframe not supported\n");
+ v4l2_info(sd, "DVI-D signal - InfoFrames not supported\n");
return;
}
- i2c_rd(sd, PK_AVI_0HEAD, buffer, HDMI_INFOFRAME_SIZE(AVI));
+ i2c_rd(sd, PK_AVI_0HEAD, buffer, PK_AVI_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
- if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) {
- v4l2_err(sd, "%s: unpack of AVI infoframe failed\n", __func__);
- return;
+ i2c_rd(sd, PK_VS_0HEAD, buffer, PK_VS_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+
+ i2c_rd(sd, PK_AUD_0HEAD, buffer, PK_AUD_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+
+ i2c_rd(sd, PK_SPD_0HEAD, buffer, PK_SPD_LEN);
+ if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+
+ i2c_rd(sd, PK_ACP_0HEAD, buffer, PK_ACP_LEN);
+ if (buffer[0] == packet_type) {
+ if (packet_type < 0x80)
+ v4l2_info(sd, "Packet: %*ph\n", PK_ACP_LEN, buffer);
+ else if (packet_type != 0x87)
+ v4l2_info(sd, "InfoFrame: %*ph\n", PK_ACP_LEN, buffer);
+ else if (hdmi_infoframe_unpack(&frame, buffer,
+ sizeof(buffer)) >= 0)
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
}
- hdmi_infoframe_log(KERN_INFO, dev, &frame);
+ i2c_rd(sd, PK_MS_0HEAD, buffer, PK_MS_LEN);
+ if (buffer[2] && buffer[2] + 3 <= PK_MS_LEN)
+ v4l2_info(sd, "MPEG Source InfoFrame: %*ph\n",
+ buffer[2] + 3, buffer);
+
+ i2c_rd(sd, PK_ISRC1_0HEAD, buffer, PK_ISRC1_LEN);
+ if (buffer[0] == 0x05)
+ v4l2_info(sd, "ISRC1 Packet: %*ph\n",
+ PK_ISRC1_LEN, buffer);
+
+ i2c_rd(sd, PK_ISRC2_0HEAD, buffer, PK_ISRC2_LEN);
+ if (buffer[0] == 0x06)
+ v4l2_info(sd, "ISRC2 Packet: %*ph\n",
+ PK_ISRC2_LEN, buffer);
}
/* --------------- CTRLS --------------- */
@@ -1375,7 +1451,7 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
v4l2_info(sd, "Deep color mode: %d-bits per channel\n",
deep_color_mode[(i2c_rd8(sd, VI_STATUS1) &
MASK_S_DEEPCOLOR) >> 2]);
- print_avi_infoframe(sd);
+ print_infoframes(sd);
return 0;
}
@@ -2232,10 +2308,15 @@ static int tc358743_probe(struct i2c_client *client)
if (err < 0)
goto err_work_queues;
+ i2c_wr8(sd, TYP_ACP_SET, packet_type);
+ i2c_wr8(sd, PK_AUTO_CLR, 0xff);
+ i2c_wr8(sd, NO_PKT_CLR, MASK_NO_ACP_CLR);
+
state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
- V4L2_DEBUGFS_IF_AVI, sd,
- tc358743_debugfs_if_read);
+ V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+ V4L2_DEBUGFS_IF_SPD | V4L2_DEBUGFS_IF_HDMI |
+ V4L2_DEBUGFS_IF_DRM, sd, tc358743_debugfs_if_read);
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
client->addr << 1, client->adapter->name);
@@ -2245,10 +2326,10 @@ static int tc358743_probe(struct i2c_client *client)
err_work_queues:
cec_unregister_adapter(state->cec_adap);
if (!state->i2c_client->irq) {
- timer_delete(&state->timer);
+ timer_delete_sync(&state->timer);
flush_work(&state->work_i2c_poll);
}
- cancel_delayed_work(&state->delayed_work_enable_hotplug);
+ cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
mutex_destroy(&state->confctl_mutex);
err_hdl:
media_entity_cleanup(&sd->entity);
diff --git a/drivers/media/i2c/tc358743_regs.h b/drivers/media/i2c/tc358743_regs.h
index 2495878dc358..aae288f8add3 100644
--- a/drivers/media/i2c/tc358743_regs.h
+++ b/drivers/media/i2c/tc358743_regs.h
@@ -692,6 +692,8 @@
#define MASK_NCO_F0_MOD_42MHZ 0x00
#define MASK_NCO_F0_MOD_27MHZ 0x01
+#define TYP_ACP_SET 0x8706
+
#define PK_INT_MODE 0x8709
#define MASK_ISRC2_INT_MODE 0x80
#define MASK_ISRC_INT_MODE 0x40
@@ -702,6 +704,8 @@
#define MASK_AUD_INT_MODE 0x02
#define MASK_AVI_INT_MODE 0x01
+#define PK_AUTO_CLR 0x870a
+
#define NO_PKT_LIMIT 0x870B
#define MASK_NO_ACP_LIMIT 0xf0
#define SET_NO_ACP_LIMIT_MS(milliseconds) ((((milliseconds) / 80) << 4) & \
@@ -720,25 +724,44 @@
#define ERR_PK_LIMIT 0x870D
#define NO_PKT_LIMIT2 0x870E
#define PK_AVI_0HEAD 0x8710
-#define PK_AVI_1HEAD 0x8711
-#define PK_AVI_2HEAD 0x8712
#define PK_AVI_0BYTE 0x8713
-#define PK_AVI_1BYTE 0x8714
-#define PK_AVI_2BYTE 0x8715
-#define PK_AVI_3BYTE 0x8716
-#define PK_AVI_4BYTE 0x8717
-#define PK_AVI_5BYTE 0x8718
-#define PK_AVI_6BYTE 0x8719
-#define PK_AVI_7BYTE 0x871A
-#define PK_AVI_8BYTE 0x871B
-#define PK_AVI_9BYTE 0x871C
-#define PK_AVI_10BYTE 0x871D
-#define PK_AVI_11BYTE 0x871E
-#define PK_AVI_12BYTE 0x871F
-#define PK_AVI_13BYTE 0x8720
-#define PK_AVI_14BYTE 0x8721
-#define PK_AVI_15BYTE 0x8722
#define PK_AVI_16BYTE 0x8723
+#define PK_AVI_LEN (PK_AVI_16BYTE - PK_AVI_0HEAD + 1)
+
+#define PK_AUD_0HEAD 0x8730
+#define PK_AUD_0BYTE 0x8733
+#define PK_AUD_10BYTE 0x873d
+#define PK_AUD_LEN (PK_AUD_10BYTE - PK_AUD_0HEAD + 1)
+
+#define PK_MS_0HEAD 0x8740
+#define PK_MS_0BYTE 0x8743
+#define PK_MS_10BYTE 0x874d
+#define PK_MS_LEN (PK_MS_10BYTE - PK_MS_0HEAD + 1)
+
+#define PK_SPD_0HEAD 0x8750
+#define PK_SPD_0BYTE 0x8753
+#define PK_SPD_27BYTE 0x876e
+#define PK_SPD_LEN (PK_SPD_27BYTE - PK_SPD_0HEAD + 1)
+
+#define PK_VS_0HEAD 0x8770
+#define PK_VS_0BYTE 0x8773
+#define PK_VS_27BYTE 0x878e
+#define PK_VS_LEN (PK_VS_27BYTE - PK_VS_0HEAD + 1)
+
+#define PK_ACP_0HEAD 0x8790
+#define PK_ACP_0BYTE 0x8793
+#define PK_ACP_27BYTE 0x87ae
+#define PK_ACP_LEN (PK_ACP_27BYTE - PK_ACP_0HEAD + 1)
+
+#define PK_ISRC1_0HEAD 0x87b0
+#define PK_ISRC1_0BYTE 0x87b3
+#define PK_ISRC1_27BYTE 0x87c2
+#define PK_ISRC1_LEN (PK_ISRC1_27BYTE - PK_ISRC1_0HEAD + 1)
+
+#define PK_ISRC2_0HEAD 0x87d0
+#define PK_ISRC2_0BYTE 0x87d3
+#define PK_ISRC2_27BYTE 0x87ee
+#define PK_ISRC2_LEN (PK_ISRC2_27BYTE - PK_ISRC2_0HEAD + 1)
#define BKSV 0x8800
diff --git a/drivers/media/i2c/tda9840.c b/drivers/media/i2c/tda9840.c
index d61da811c9da..e3b266db571f 100644
--- a/drivers/media/i2c/tda9840.c
+++ b/drivers/media/i2c/tda9840.c
@@ -3,7 +3,7 @@
tda9840 - i2c-driver for the tda9840 by SGS Thomson
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2008 Hans Verkuil <hverkuil@kernel.org>
The tda9840 is a stereo/dual sound processor with digital
identification. It can be found at address 0x84 on the i2c-bus.
diff --git a/drivers/media/i2c/tea6415c.c b/drivers/media/i2c/tea6415c.c
index 4aaf66353610..0cd2e6c52e20 100644
--- a/drivers/media/i2c/tea6415c.c
+++ b/drivers/media/i2c/tea6415c.c
@@ -3,7 +3,7 @@
tea6415c - i2c-driver for the tea6415c by SGS Thomson
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2008 Hans Verkuil <hverkuil@kernel.org>
The tea6415c is a bus controlled video-matrix-switch
with 8 inputs and 6 outputs.
diff --git a/drivers/media/i2c/tea6420.c b/drivers/media/i2c/tea6420.c
index 5c5ea3973251..400883fc0c0f 100644
--- a/drivers/media/i2c/tea6420.c
+++ b/drivers/media/i2c/tea6420.c
@@ -3,7 +3,7 @@
tea6420 - i2c-driver for the tea6420 by SGS Thomson
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2008 Hans Verkuil <hverkuil@kernel.org>
The tea6420 is a bus controlled audio-matrix with 5 stereo inputs,
4 stereo outputs and gain control for each output.
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c
index b7cedc5b3e8e..ff268ebeb4d9 100644
--- a/drivers/media/i2c/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -7,7 +7,7 @@
* Author: Chaithrika U S <chaithrika@ti.com>
*
* Contributors:
- * Hans Verkuil <hansverk@cisco.com>
+ * Hans Verkuil <hverkuil@kernel.org>
* Lad, Prabhakar <prabhakar.lad@ti.com>
* Martin Bugge <marbugge@cisco.com>
*
diff --git a/drivers/media/i2c/tlv320aic23b.c b/drivers/media/i2c/tlv320aic23b.c
index b7b31b6192af..6f6bc5236565 100644
--- a/drivers/media/i2c/tlv320aic23b.c
+++ b/drivers/media/i2c/tlv320aic23b.c
@@ -7,7 +7,7 @@
* Based on wm8775 driver
*
* Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
- * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/module.h>
diff --git a/drivers/media/i2c/upd64031a.c b/drivers/media/i2c/upd64031a.c
index 9d0b72a213be..a178af46e695 100644
--- a/drivers/media/i2c/upd64031a.c
+++ b/drivers/media/i2c/upd64031a.c
@@ -4,7 +4,7 @@
*
* 2003 by T.Adachi <tadachi@tadachi-net.com>
* 2003 by Takeru KOMORIYA <komoriya@paken.org>
- * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
+ * 2006 by Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/i2c/upd64083.c b/drivers/media/i2c/upd64083.c
index 2e99ed5da42c..5421dc5e32c9 100644
--- a/drivers/media/i2c/upd64083.c
+++ b/drivers/media/i2c/upd64083.c
@@ -4,7 +4,7 @@
*
* 2003 by T.Adachi (tadachi@tadachi-net.com)
* 2003 by Takeru KOMORIYA <komoriya@paken.org>
- * 2006 by Hans Verkuil <hverkuil@xs4all.nl>
+ * 2006 by Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/module.h>
diff --git a/drivers/media/i2c/vd55g1.c b/drivers/media/i2c/vd55g1.c
index 7c39183dd44b..f09d6bf32641 100644
--- a/drivers/media/i2c/vd55g1.c
+++ b/drivers/media/i2c/vd55g1.c
@@ -66,7 +66,7 @@
#define VD55G1_REG_READOUT_CTRL CCI_REG8(0x052e)
#define VD55G1_READOUT_CTRL_BIN_MODE_NORMAL 0
#define VD55G1_READOUT_CTRL_BIN_MODE_DIGITAL_X2 1
-#define VD55G1_REG_DUSTER_CTRL CCI_REG8(0x03ea)
+#define VD55G1_REG_DUSTER_CTRL CCI_REG8(0x03ae)
#define VD55G1_DUSTER_ENABLE BIT(0)
#define VD55G1_DUSTER_DISABLE 0
#define VD55G1_DUSTER_DYN_ENABLE BIT(1)
@@ -1860,7 +1860,7 @@ static int vd55g1_probe(struct i2c_client *client)
if (ret)
return dev_err_probe(dev, ret, "Failed to get regulators\n");
- sensor->xclk = devm_clk_get(dev, NULL);
+ sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(sensor->xclk))
return dev_err_probe(dev, PTR_ERR(sensor->xclk),
"Failed to get xclk\n");
diff --git a/drivers/media/i2c/vd56g3.c b/drivers/media/i2c/vd56g3.c
index d66e21ba4498..157acea9e286 100644
--- a/drivers/media/i2c/vd56g3.c
+++ b/drivers/media/i2c/vd56g3.c
@@ -1471,7 +1471,7 @@ static int vd56g3_probe(struct i2c_client *client)
if (ret)
return dev_err_probe(dev, ret, "Failed to get regulators\n");
- sensor->xclk = devm_clk_get(dev, NULL);
+ sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(sensor->xclk))
return dev_err_probe(dev, PTR_ERR(sensor->xclk),
"Failed to get xclk\n");
diff --git a/drivers/media/i2c/vgxy61.c b/drivers/media/i2c/vgxy61.c
index 5b0479f3a3c0..d64d0099e6fe 100644
--- a/drivers/media/i2c/vgxy61.c
+++ b/drivers/media/i2c/vgxy61.c
@@ -1181,6 +1181,21 @@ static int vgxy61_s_stream(struct v4l2_subdev *sd, int enable)
return ret;
}
+static int vgxy61_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
+ struct v4l2_mbus_frame_desc *fd)
+{
+ struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
+
+ fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2;
+ fd->num_entries = 1;
+ fd->entry[0].pixelcode = sensor->fmt.code;
+ fd->entry[0].stream = 0;
+ fd->entry[0].bus.csi2.vc = 0;
+ fd->entry[0].bus.csi2.dt = get_data_type_by_code(sensor->fmt.code);
+
+ return 0;
+}
+
static int vgxy61_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
@@ -1402,6 +1417,7 @@ static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = {
.set_fmt = vgxy61_set_fmt,
.get_selection = vgxy61_get_selection,
.enum_frame_size = vgxy61_enum_frame_size,
+ .get_frame_desc = vgxy61_get_frame_desc,
};
static const struct v4l2_subdev_ops vgxy61_subdev_ops = {
@@ -1761,11 +1777,11 @@ static int vgxy61_probe(struct i2c_client *client)
return ret;
}
- sensor->xclk = devm_clk_get(dev, NULL);
- if (IS_ERR(sensor->xclk)) {
- dev_err(dev, "failed to get xclk\n");
- return PTR_ERR(sensor->xclk);
- }
+ sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
+ if (IS_ERR(sensor->xclk))
+ return dev_err_probe(dev, PTR_ERR(sensor->xclk),
+ "failed to get xclk\n");
+
sensor->clk_freq = clk_get_rate(sensor->xclk);
if (sensor->clk_freq < 6 * HZ_PER_MHZ ||
sensor->clk_freq > 27 * HZ_PER_MHZ) {
diff --git a/drivers/media/i2c/vp27smpx.c b/drivers/media/i2c/vp27smpx.c
index 06fd46a63c72..df21950be24f 100644
--- a/drivers/media/i2c/vp27smpx.c
+++ b/drivers/media/i2c/vp27smpx.c
@@ -2,7 +2,7 @@
/*
* vp27smpx - driver version 0.0.1
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*
* Based on a tvaudio patch from Takahiro Adachi <tadachi@tadachi-net.com>
* and Kazuhiko Kawakami <kazz-0@mail.goo.ne.jp>
diff --git a/drivers/media/i2c/wm8739.c b/drivers/media/i2c/wm8739.c
index c091b78a5b41..72eb10339d06 100644
--- a/drivers/media/i2c/wm8739.c
+++ b/drivers/media/i2c/wm8739.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 2005 T. Adachi <tadachi@tadachi-net.com>
*
- * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@kernel.org>
* - Cleanup
*/
diff --git a/drivers/media/i2c/wm8775.c b/drivers/media/i2c/wm8775.c
index 619b2988577c..56778d3bc28a 100644
--- a/drivers/media/i2c/wm8775.c
+++ b/drivers/media/i2c/wm8775.c
@@ -6,7 +6,7 @@
*
* Based on saa7115 driver
*
- * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@kernel.org>
* - Cleanup
* - V4L2 API update
* - sound fixes
diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c
index 56444edaf136..6daa7aa99442 100644
--- a/drivers/media/mc/mc-devnode.c
+++ b/drivers/media/mc/mc-devnode.c
@@ -50,11 +50,6 @@ static void media_devnode_release(struct device *cd)
{
struct media_devnode *devnode = to_media_devnode(cd);
- mutex_lock(&media_devnode_lock);
- /* Mark device node number as free */
- clear_bit(devnode->minor, media_devnode_nums);
- mutex_unlock(&media_devnode_lock);
-
/* Release media_devnode and perform other cleanups as needed. */
if (devnode->release)
devnode->release(devnode);
@@ -281,6 +276,7 @@ void media_devnode_unregister(struct media_devnode *devnode)
/* Delete the cdev on this minor as well */
cdev_device_del(&devnode->cdev, &devnode->dev);
devnode->media_dev = NULL;
+ clear_bit(devnode->minor, media_devnode_nums);
mutex_unlock(&media_devnode_lock);
put_device(&devnode->dev);
diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c
index 045590905582..9519a537bfa2 100644
--- a/drivers/media/mc/mc-entity.c
+++ b/drivers/media/mc/mc-entity.c
@@ -682,8 +682,8 @@ done:
return 0;
dev_dbg(walk->mdev->dev,
- "media pipeline: adding unconnected pads of '%s'\n",
- local->entity->name);
+ "media pipeline: adding unconnected pads of '%s' reachable from pad %u\n",
+ origin->entity->name, origin->index);
media_entity_for_each_pad(origin->entity, local) {
/*
@@ -691,7 +691,7 @@ done:
* (already discovered through iterating over links) and pads
* not internally connected.
*/
- if (origin == local || !local->num_links ||
+ if (origin == local || local->num_links ||
!media_entity_has_pad_interdep(origin->entity, origin->index,
local->index))
continue;
diff --git a/drivers/media/mc/mc-request.c b/drivers/media/mc/mc-request.c
index 5edfc2791ce7..f66f728b1b43 100644
--- a/drivers/media/mc/mc-request.c
+++ b/drivers/media/mc/mc-request.c
@@ -6,7 +6,7 @@
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018 Google, Inc.
*
- * Author: Hans Verkuil <hansverk@cisco.com>
+ * Author: Hans Verkuil <hverkuil@kernel.org>
* Author: Sakari Ailus <sakari.ailus@linux.intel.com>
*/
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c
index 486c8ec0fa60..ab53c5b02c48 100644
--- a/drivers/media/pci/b2c2/flexcop-pci.c
+++ b/drivers/media/pci/b2c2/flexcop-pci.c
@@ -411,7 +411,7 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
if (irq_chk_intv > 0)
- cancel_delayed_work(&fc_pci->irq_check_work);
+ cancel_delayed_work_sync(&fc_pci->irq_check_work);
flexcop_pci_dma_exit(fc_pci);
flexcop_device_exit(fc_pci->fc_dev);
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 9ce67f515843..17e4529e537a 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -1620,7 +1620,7 @@ static int bttv_g_std(struct file *file, void *priv, v4l2_std_id *id)
return 0;
}
-static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id)
+static int bttv_querystd(struct file *file, void *priv, v4l2_std_id *id)
{
struct bttv *btv = video_drvdata(file);
@@ -1750,7 +1750,7 @@ static int bttv_s_frequency(struct file *file, void *priv,
return 0;
}
-static int bttv_log_status(struct file *file, void *f)
+static int bttv_log_status(struct file *file, void *priv)
{
struct video_device *vdev = video_devdata(file);
struct bttv *btv = video_drvdata(file);
@@ -1761,7 +1761,7 @@ static int bttv_log_status(struct file *file, void *f)
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int bttv_g_register(struct file *file, void *f,
+static int bttv_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
{
struct bttv *btv = video_drvdata(file);
@@ -1774,7 +1774,7 @@ static int bttv_g_register(struct file *file, void *f,
return 0;
}
-static int bttv_s_register(struct file *file, void *f,
+static int bttv_s_register(struct file *file, void *priv,
const struct v4l2_dbg_register *reg)
{
struct bttv *btv = video_drvdata(file);
@@ -2159,7 +2159,7 @@ static int bttv_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int bttv_g_parm(struct file *file, void *f,
+static int bttv_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
struct bttv *btv = video_drvdata(file);
@@ -2208,7 +2208,7 @@ static int bttv_g_pixelaspect(struct file *file, void *priv,
return 0;
}
-static int bttv_g_selection(struct file *file, void *f, struct v4l2_selection *sel)
+static int bttv_g_selection(struct file *file, void *priv, struct v4l2_selection *sel)
{
struct bttv *btv = video_drvdata(file);
@@ -2232,7 +2232,7 @@ static int bttv_g_selection(struct file *file, void *f, struct v4l2_selection *s
return 0;
}
-static int bttv_s_selection(struct file *file, void *f, struct v4l2_selection *sel)
+static int bttv_s_selection(struct file *file, void *priv, struct v4l2_selection *sel)
{
struct bttv *btv = video_drvdata(file);
const struct v4l2_rect *b;
diff --git a/drivers/media/pci/bt8xx/bttv-vbi.c b/drivers/media/pci/bt8xx/bttv-vbi.c
index a71440611e46..0ca88a2400ee 100644
--- a/drivers/media/pci/bt8xx/bttv-vbi.c
+++ b/drivers/media/pci/bt8xx/bttv-vbi.c
@@ -241,7 +241,7 @@ static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
return 0;
}
-int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
+int bttv_try_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *frt)
{
struct bttv *btv = video_drvdata(file);
const struct bttv_tvnorm *tvnorm;
@@ -258,7 +258,7 @@ int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
}
-int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
+int bttv_s_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *frt)
{
struct bttv *btv = video_drvdata(file);
const struct bttv_tvnorm *tvnorm;
@@ -301,7 +301,7 @@ int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
}
-int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
+int bttv_g_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *frt)
{
const struct bttv_tvnorm *tvnorm;
struct bttv *btv = video_drvdata(file);
diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c
index 39e25cc53edb..b7695705fdee 100644
--- a/drivers/media/pci/cobalt/cobalt-driver.c
+++ b/drivers/media/pci/cobalt/cobalt-driver.c
@@ -44,7 +44,7 @@ module_param_named(ignore_err, cobalt_ignore_err, int, 0644);
MODULE_PARM_DESC(ignore_err,
"If set then ignore missing i2c adapters/receivers. Default: 0\n");
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com> & Morten Hestnes");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org> & Morten Hestnes");
MODULE_DESCRIPTION("cobalt driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c
index ae82427e3479..51fd9576c6c2 100644
--- a/drivers/media/pci/cobalt/cobalt-v4l2.c
+++ b/drivers/media/pci/cobalt/cobalt-v4l2.c
@@ -447,7 +447,7 @@ static int cobalt_cobaltc(struct cobalt *cobalt, unsigned int cmd, void *arg)
return 0;
}
-static int cobalt_g_register(struct file *file, void *priv_fh,
+static int cobalt_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -456,7 +456,7 @@ static int cobalt_g_register(struct file *file, void *priv_fh,
return cobalt_cobaltc(cobalt, VIDIOC_DBG_G_REGISTER, reg);
}
-static int cobalt_s_register(struct file *file, void *priv_fh,
+static int cobalt_s_register(struct file *file, void *priv,
const struct v4l2_dbg_register *reg)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -467,7 +467,7 @@ static int cobalt_s_register(struct file *file, void *priv_fh,
}
#endif
-static int cobalt_querycap(struct file *file, void *priv_fh,
+static int cobalt_querycap(struct file *file, void *priv,
struct v4l2_capability *vcap)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -562,7 +562,7 @@ static void cobalt_video_input_status_show(struct cobalt_stream *s)
cobalt_info("rx%d: Packer: %x\n", rx, ioread32(&packer->control));
}
-static int cobalt_log_status(struct file *file, void *priv_fh)
+static int cobalt_log_status(struct file *file, void *priv)
{
struct cobalt_stream *s = video_drvdata(file);
struct cobalt *cobalt = s->cobalt;
@@ -596,7 +596,7 @@ static int cobalt_log_status(struct file *file, void *priv_fh)
return 0;
}
-static int cobalt_enum_dv_timings(struct file *file, void *priv_fh,
+static int cobalt_enum_dv_timings(struct file *file, void *priv,
struct v4l2_enum_dv_timings *timings)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -613,7 +613,7 @@ static int cobalt_enum_dv_timings(struct file *file, void *priv_fh,
pad, enum_dv_timings, timings);
}
-static int cobalt_s_dv_timings(struct file *file, void *priv_fh,
+static int cobalt_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -641,7 +641,7 @@ static int cobalt_s_dv_timings(struct file *file, void *priv_fh,
return err;
}
-static int cobalt_g_dv_timings(struct file *file, void *priv_fh,
+static int cobalt_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -654,7 +654,7 @@ static int cobalt_g_dv_timings(struct file *file, void *priv_fh,
pad, g_dv_timings, 0, timings);
}
-static int cobalt_query_dv_timings(struct file *file, void *priv_fh,
+static int cobalt_query_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -667,7 +667,7 @@ static int cobalt_query_dv_timings(struct file *file, void *priv_fh,
pad, query_dv_timings, 0, timings);
}
-static int cobalt_dv_timings_cap(struct file *file, void *priv_fh,
+static int cobalt_dv_timings_cap(struct file *file, void *priv,
struct v4l2_dv_timings_cap *cap)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -677,7 +677,7 @@ static int cobalt_dv_timings_cap(struct file *file, void *priv_fh,
pad, dv_timings_cap, cap);
}
-static int cobalt_enum_fmt_vid_cap(struct file *file, void *priv_fh,
+static int cobalt_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
switch (f->index) {
@@ -697,7 +697,7 @@ static int cobalt_enum_fmt_vid_cap(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_g_fmt_vid_cap(struct file *file, void *priv_fh,
+static int cobalt_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -726,7 +726,7 @@ static int cobalt_g_fmt_vid_cap(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_try_fmt_vid_cap(struct file *file, void *priv_fh,
+static int cobalt_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -787,7 +787,7 @@ static int cobalt_try_fmt_vid_cap(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_s_fmt_vid_cap(struct file *file, void *priv_fh,
+static int cobalt_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -796,7 +796,7 @@ static int cobalt_s_fmt_vid_cap(struct file *file, void *priv_fh,
if (vb2_is_busy(&s->q))
return -EBUSY;
- if (cobalt_try_fmt_vid_cap(file, priv_fh, f))
+ if (cobalt_try_fmt_vid_cap(file, priv, f))
return -EINVAL;
s->width = pix->width;
@@ -821,7 +821,7 @@ static int cobalt_s_fmt_vid_cap(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_try_fmt_vid_out(struct file *file, void *priv_fh,
+static int cobalt_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format *pix = &f->fmt.pix;
@@ -862,7 +862,7 @@ static int cobalt_try_fmt_vid_out(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_g_fmt_vid_out(struct file *file, void *priv_fh,
+static int cobalt_g_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -882,7 +882,7 @@ static int cobalt_g_fmt_vid_out(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_enum_fmt_vid_out(struct file *file, void *priv_fh,
+static int cobalt_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
switch (f->index) {
@@ -899,7 +899,7 @@ static int cobalt_enum_fmt_vid_out(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh,
+static int cobalt_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -909,7 +909,7 @@ static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh,
};
u32 code;
- if (cobalt_try_fmt_vid_out(file, priv_fh, f))
+ if (cobalt_try_fmt_vid_out(file, priv, f))
return -EINVAL;
if (vb2_is_busy(&s->q) && (pix->pixelformat != s->pixfmt ||
@@ -942,7 +942,7 @@ static int cobalt_s_fmt_vid_out(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_enum_input(struct file *file, void *priv_fh,
+static int cobalt_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -963,7 +963,7 @@ static int cobalt_enum_input(struct file *file, void *priv_fh,
video, g_input_status, &inp->status);
}
-static int cobalt_g_input(struct file *file, void *priv_fh, unsigned int *i)
+static int cobalt_g_input(struct file *file, void *priv, unsigned int *i)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -971,7 +971,7 @@ static int cobalt_g_input(struct file *file, void *priv_fh, unsigned int *i)
return 0;
}
-static int cobalt_s_input(struct file *file, void *priv_fh, unsigned int i)
+static int cobalt_s_input(struct file *file, void *priv, unsigned int i)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -990,7 +990,7 @@ static int cobalt_s_input(struct file *file, void *priv_fh, unsigned int i)
ADV76XX_PAD_HDMI_PORT_A, 0, 0);
}
-static int cobalt_enum_output(struct file *file, void *priv_fh,
+static int cobalt_enum_output(struct file *file, void *priv,
struct v4l2_output *out)
{
if (out->index)
@@ -1001,18 +1001,18 @@ static int cobalt_enum_output(struct file *file, void *priv_fh,
return 0;
}
-static int cobalt_g_output(struct file *file, void *priv_fh, unsigned int *i)
+static int cobalt_g_output(struct file *file, void *priv, unsigned int *i)
{
*i = 0;
return 0;
}
-static int cobalt_s_output(struct file *file, void *priv_fh, unsigned int i)
+static int cobalt_s_output(struct file *file, void *priv, unsigned int i)
{
return i ? -EINVAL : 0;
}
-static int cobalt_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
+static int cobalt_g_edid(struct file *file, void *priv, struct v4l2_edid *edid)
{
struct cobalt_stream *s = video_drvdata(file);
u32 pad = edid->pad;
@@ -1026,7 +1026,7 @@ static int cobalt_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
return ret;
}
-static int cobalt_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
+static int cobalt_s_edid(struct file *file, void *priv, struct v4l2_edid *edid)
{
struct cobalt_stream *s = video_drvdata(file);
u32 pad = edid->pad;
@@ -1050,7 +1050,7 @@ static int cobalt_subscribe_event(struct v4l2_fh *fh,
return v4l2_ctrl_subscribe_event(fh, sub);
}
-static int cobalt_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+static int cobalt_g_parm(struct file *file, void *priv, struct v4l2_streamparm *a)
{
struct cobalt_stream *s = video_drvdata(file);
struct v4l2_fract fps;
@@ -1065,7 +1065,7 @@ static int cobalt_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
return 0;
}
-static int cobalt_g_pixelaspect(struct file *file, void *fh,
+static int cobalt_g_pixelaspect(struct file *file, void *priv,
int type, struct v4l2_fract *f)
{
struct cobalt_stream *s = video_drvdata(file);
@@ -1084,7 +1084,7 @@ static int cobalt_g_pixelaspect(struct file *file, void *fh,
return err;
}
-static int cobalt_g_selection(struct file *file, void *fh,
+static int cobalt_g_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
struct cobalt_stream *s = video_drvdata(file);
diff --git a/drivers/media/pci/cx18/cx18-audio.c b/drivers/media/pci/cx18/cx18-audio.c
index 8602d088601b..1464795619f9 100644
--- a/drivers/media/pci/cx18/cx18-audio.c
+++ b/drivers/media/pci/cx18/cx18-audio.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-audio.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
#include "cx18-driver.h"
diff --git a/drivers/media/pci/cx18/cx18-audio.h b/drivers/media/pci/cx18/cx18-audio.h
index 36ce333ab07a..29cf89d38d60 100644
--- a/drivers/media/pci/cx18/cx18-audio.h
+++ b/drivers/media/pci/cx18/cx18-audio.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-audio.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
int cx18_audio_set_io(struct cx18 *cx);
diff --git a/drivers/media/pci/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c
index 78e05df9a7ba..644d8ca4519b 100644
--- a/drivers/media/pci/cx18/cx18-av-audio.c
+++ b/drivers/media/pci/cx18/cx18-av-audio.c
@@ -4,7 +4,7 @@
*
* Derived from cx25840-audio.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
index ee6e71157786..4fb19d26ee29 100644
--- a/drivers/media/pci/cx18/cx18-av-core.c
+++ b/drivers/media/pci/cx18/cx18-av-core.c
@@ -4,7 +4,7 @@
*
* Derived from cx25840-core.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
index 55aceb064b33..71ac9d7af28f 100644
--- a/drivers/media/pci/cx18/cx18-av-core.h
+++ b/drivers/media/pci/cx18/cx18-av-core.h
@@ -4,7 +4,7 @@
*
* Derived from cx25840-core.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-av-firmware.c b/drivers/media/pci/cx18/cx18-av-firmware.c
index 61aeb8c9af7f..02dde685a6ad 100644
--- a/drivers/media/pci/cx18/cx18-av-firmware.c
+++ b/drivers/media/pci/cx18/cx18-av-firmware.c
@@ -2,7 +2,7 @@
/*
* cx18 ADEC firmware functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-av-vbi.c b/drivers/media/pci/cx18/cx18-av-vbi.c
index 1a113aad9cd4..f9beeaeaa1cb 100644
--- a/drivers/media/pci/cx18/cx18-av-vbi.c
+++ b/drivers/media/pci/cx18/cx18-av-vbi.c
@@ -4,7 +4,7 @@
*
* Derived from cx25840-vbi.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/cx18/cx18-cards.c b/drivers/media/pci/cx18/cx18-cards.c
index f5a30959a367..bddb9e0fffe0 100644
--- a/drivers/media/pci/cx18/cx18-cards.c
+++ b/drivers/media/pci/cx18/cx18-cards.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-cards.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-cards.h b/drivers/media/pci/cx18/cx18-cards.h
index ae9cf5bfdd59..511123b741d5 100644
--- a/drivers/media/pci/cx18/cx18-cards.h
+++ b/drivers/media/pci/cx18/cx18-cards.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-cards.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-controls.c b/drivers/media/pci/cx18/cx18-controls.c
index bb5fc120473c..78eadad8b6e8 100644
--- a/drivers/media/pci/cx18/cx18-controls.c
+++ b/drivers/media/pci/cx18/cx18-controls.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-controls.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/kernel.h>
#include <linux/slab.h>
diff --git a/drivers/media/pci/cx18/cx18-controls.h b/drivers/media/pci/cx18/cx18-controls.h
index 458a3595a2ae..99de78878a76 100644
--- a/drivers/media/pci/cx18/cx18-controls.h
+++ b/drivers/media/pci/cx18/cx18-controls.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-controls.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
index 743fcc961374..b62fd12c93c1 100644
--- a/drivers/media/pci/cx18/cx18-driver.c
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-driver.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h
index 485ca9747c4c..ef38903709d0 100644
--- a/drivers/media/pci/cx18/cx18-driver.h
+++ b/drivers/media/pci/cx18/cx18-driver.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-driver.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
@@ -414,7 +414,7 @@ static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
static inline struct cx18_open_id *file2id(struct file *file)
{
- return fh2id(file->private_data);
+ return fh2id(file_to_v4l2_fh(file));
}
/* forward declaration of struct defined in cx18-cards.h */
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c
index cefa91b37f89..4944033dbb20 100644
--- a/drivers/media/pci/cx18/cx18-fileops.c
+++ b/drivers/media/pci/cx18/cx18-fileops.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-fileops.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
@@ -678,7 +678,7 @@ void cx18_stop_capture(struct cx18_stream *s, int gop_end)
int cx18_v4l2_close(struct file *filp)
{
- struct v4l2_fh *fh = filp->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(filp);
struct cx18_open_id *id = fh2id(fh);
struct cx18 *cx = id->cx;
struct cx18_stream *s = &cx->streams[id->type];
@@ -709,11 +709,11 @@ int cx18_v4l2_close(struct file *filp)
}
if (id->type == CX18_ENC_STREAM_TYPE_YUV &&
- filp->private_data == vdev->queue->owner) {
+ file_to_v4l2_fh(filp) == vdev->queue->owner) {
vb2_queue_release(vdev->queue);
vdev->queue->owner = NULL;
}
- v4l2_fh_del(fh);
+ v4l2_fh_del(fh, filp);
v4l2_fh_exit(fh);
/* 'Unclaim' this stream */
@@ -743,8 +743,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
item->type = s->type;
item->open_id = cx->open_id++;
- filp->private_data = &item->fh;
- v4l2_fh_add(&item->fh);
+ v4l2_fh_add(&item->fh, filp);
if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
v4l2_fh_is_singular_file(filp)) {
@@ -752,7 +751,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
if (atomic_read(&cx->ana_capturing) > 0) {
/* switching to radio while capture is
in progress is not polite */
- v4l2_fh_del(&item->fh);
+ v4l2_fh_del(&item->fh, filp);
v4l2_fh_exit(&item->fh);
kfree(item);
return -EBUSY;
diff --git a/drivers/media/pci/cx18/cx18-fileops.h b/drivers/media/pci/cx18/cx18-fileops.h
index 943057b83d94..bc999ea85dc2 100644
--- a/drivers/media/pci/cx18/cx18-fileops.h
+++ b/drivers/media/pci/cx18/cx18-fileops.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-fileops.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
/* Testing/Debugging */
diff --git a/drivers/media/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
index 1b038b2802bf..94e17948fb30 100644
--- a/drivers/media/pci/cx18/cx18-firmware.c
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -2,7 +2,7 @@
/*
* cx18 firmware functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-firmware.h b/drivers/media/pci/cx18/cx18-firmware.h
index 1357f76d613e..8e63677284bd 100644
--- a/drivers/media/pci/cx18/cx18-firmware.h
+++ b/drivers/media/pci/cx18/cx18-firmware.h
@@ -2,7 +2,7 @@
/*
* cx18 firmware functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
int cx18_firmware_init(struct cx18 *cx);
diff --git a/drivers/media/pci/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c
index 485a6cbeb15a..4aea92639599 100644
--- a/drivers/media/pci/cx18/cx18-gpio.c
+++ b/drivers/media/pci/cx18/cx18-gpio.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-gpio.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-gpio.h b/drivers/media/pci/cx18/cx18-gpio.h
index 8d5797dea7f5..3eefc4644101 100644
--- a/drivers/media/pci/cx18/cx18-gpio.h
+++ b/drivers/media/pci/cx18/cx18-gpio.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-gpio.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c
index a83435245251..a1abb0631cae 100644
--- a/drivers/media/pci/cx18/cx18-i2c.c
+++ b/drivers/media/pci/cx18/cx18-i2c.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-i2c.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-i2c.h b/drivers/media/pci/cx18/cx18-i2c.h
index 4526cb324fec..8ae3125c78c0 100644
--- a/drivers/media/pci/cx18/cx18-i2c.h
+++ b/drivers/media/pci/cx18/cx18-i2c.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-i2c.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
int cx18_i2c_register(struct cx18 *cx, unsigned idx);
diff --git a/drivers/media/pci/cx18/cx18-io.c b/drivers/media/pci/cx18/cx18-io.c
index 50e4e8a598d4..1d3d006e6329 100644
--- a/drivers/media/pci/cx18/cx18-io.c
+++ b/drivers/media/pci/cx18/cx18-io.c
@@ -2,7 +2,7 @@
/*
* cx18 driver PCI memory mapped IO access routines
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-io.h b/drivers/media/pci/cx18/cx18-io.h
index 190b142d047e..1f0bfad7d0f0 100644
--- a/drivers/media/pci/cx18/cx18-io.h
+++ b/drivers/media/pci/cx18/cx18-io.h
@@ -2,7 +2,7 @@
/*
* cx18 driver PCI memory mapped IO access routines
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index 9a1512b1ccaa..0f3019739d03 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-ioctl.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
@@ -52,7 +52,7 @@ static const struct v4l2_fmtdesc cx18_formats_mpeg[] = {
static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
struct cx18_stream *s = &cx->streams[id->type];
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
@@ -76,7 +76,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
int w = pixfmt->width;
@@ -121,7 +121,7 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
@@ -261,7 +261,7 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
vbifmt->sampling_rate = 27000000;
@@ -280,7 +280,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
/* sane, V4L2 spec compliant, defaults */
@@ -311,7 +311,7 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
@@ -330,7 +330,7 @@ static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
int ret;
@@ -360,7 +360,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
int ret;
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
@@ -392,7 +392,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
static int cx18_g_register(struct file *file, void *fh,
struct v4l2_dbg_register *reg)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (reg->reg & 0x3)
return -EINVAL;
@@ -406,7 +406,7 @@ static int cx18_g_register(struct file *file, void *fh,
static int cx18_s_register(struct file *file, void *fh,
const struct v4l2_dbg_register *reg)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (reg->reg & 0x3)
return -EINVAL;
@@ -420,7 +420,7 @@ static int cx18_s_register(struct file *file, void *fh,
static int cx18_querycap(struct file *file, void *fh,
struct v4l2_capability *vcap)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
strscpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
@@ -431,14 +431,14 @@ static int cx18_querycap(struct file *file, void *fh,
static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
return cx18_get_audio_input(cx, vin->index, vin);
}
static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
vin->index = cx->audio_input;
return cx18_get_audio_input(cx, vin->index, vin);
@@ -446,7 +446,7 @@ static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
static int cx18_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (vout->index >= cx->nof_audio_inputs)
return -EINVAL;
@@ -457,7 +457,7 @@ static int cx18_s_audio(struct file *file, void *fh, const struct v4l2_audio *vo
static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
/* set it to defaults from our table */
return cx18_get_input(cx, vin->index, vin);
@@ -466,7 +466,7 @@ static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
static int cx18_g_pixelaspect(struct file *file, void *fh,
int type, struct v4l2_fract *f)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -479,7 +479,7 @@ static int cx18_g_pixelaspect(struct file *file, void *fh,
static int cx18_g_selection(struct file *file, void *fh,
struct v4l2_selection *sel)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -499,7 +499,7 @@ static int cx18_g_selection(struct file *file, void *fh,
static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_fmtdesc *fmt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
if (fmt->index >= ARRAY_SIZE(cx18_formats_yuv))
@@ -515,7 +515,7 @@ static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
*i = cx->active_input;
return 0;
@@ -523,7 +523,7 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
int cx18_s_input(struct file *file, void *fh, unsigned int inp)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
v4l2_std_id std = V4L2_STD_ALL;
const struct cx18_card_video_input *card_input =
@@ -561,7 +561,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
static int cx18_g_frequency(struct file *file, void *fh,
struct v4l2_frequency *vf)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (vf->tuner != 0)
return -EINVAL;
@@ -572,7 +572,7 @@ static int cx18_g_frequency(struct file *file, void *fh,
int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
if (vf->tuner != 0)
@@ -587,7 +587,7 @@ int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
*std = cx->std;
return 0;
@@ -595,7 +595,7 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
if ((std & V4L2_STD_ALL) == 0)
@@ -644,7 +644,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
if (vt->index != 0)
@@ -656,7 +656,7 @@ static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt
static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
if (vt->index != 0)
return -EINVAL;
@@ -673,7 +673,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_sliced_vbi_cap *cap)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
int f, l;
@@ -794,7 +794,7 @@ static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
static int cx18_g_enc_index(struct file *file, void *fh,
struct v4l2_enc_idx *idx)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
s32 tmp;
struct cx18_mdl *mdl;
@@ -841,7 +841,7 @@ static int cx18_g_enc_index(struct file *file, void *fh,
static int cx18_encoder_cmd(struct file *file, void *fh,
struct v4l2_encoder_cmd *enc)
{
- struct cx18_open_id *id = fh2id(fh);
+ struct cx18_open_id *id = file2id(file);
struct cx18 *cx = id->cx;
u32 h;
@@ -900,7 +900,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
static int cx18_try_encoder_cmd(struct file *file, void *fh,
struct v4l2_encoder_cmd *enc)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
switch (enc->cmd) {
case V4L2_ENC_CMD_START:
@@ -932,7 +932,7 @@ static int cx18_try_encoder_cmd(struct file *file, void *fh,
static int cx18_log_status(struct file *file, void *fh)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
struct v4l2_input vidin;
struct v4l2_audio audin;
int i;
@@ -976,7 +976,7 @@ static int cx18_log_status(struct file *file, void *fh)
static long cx18_default(struct file *file, void *fh, bool valid_prio,
unsigned int cmd, void *arg)
{
- struct cx18 *cx = fh2id(fh)->cx;
+ struct cx18 *cx = file2id(file)->cx;
switch (cmd) {
case VIDIOC_INT_RESET: {
diff --git a/drivers/media/pci/cx18/cx18-ioctl.h b/drivers/media/pci/cx18/cx18-ioctl.h
index 221e2400fb3e..97cd9f99e22d 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.h
+++ b/drivers/media/pci/cx18/cx18-ioctl.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-ioctl.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-irq.c b/drivers/media/pci/cx18/cx18-irq.c
index db63077821b1..0ef01e98255d 100644
--- a/drivers/media/pci/cx18/cx18-irq.c
+++ b/drivers/media/pci/cx18/cx18-irq.c
@@ -2,7 +2,7 @@
/*
* cx18 interrupt handling
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-irq.h b/drivers/media/pci/cx18/cx18-irq.h
index fdb585a72827..c1456d69dffa 100644
--- a/drivers/media/pci/cx18/cx18-irq.h
+++ b/drivers/media/pci/cx18/cx18-irq.h
@@ -2,7 +2,7 @@
/*
* cx18 interrupt handling
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
index a6457c23d18c..8c70b638a40c 100644
--- a/drivers/media/pci/cx18/cx18-mailbox.c
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
@@ -2,7 +2,7 @@
/*
* cx18 mailbox functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-mailbox.h b/drivers/media/pci/cx18/cx18-mailbox.h
index 971382ac0eca..1752b8e1ca13 100644
--- a/drivers/media/pci/cx18/cx18-mailbox.h
+++ b/drivers/media/pci/cx18/cx18-mailbox.h
@@ -2,7 +2,7 @@
/*
* cx18 mailbox functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c
index 013694bfcb1c..eeb5513b1d52 100644
--- a/drivers/media/pci/cx18/cx18-queue.c
+++ b/drivers/media/pci/cx18/cx18-queue.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-queue.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
@@ -379,15 +379,22 @@ int cx18_stream_alloc(struct cx18_stream *s)
break;
}
+ buf->dma_handle = dma_map_single(&s->cx->pci_dev->dev,
+ buf->buf, s->buf_size,
+ s->dma);
+ if (dma_mapping_error(&s->cx->pci_dev->dev, buf->dma_handle)) {
+ kfree(buf->buf);
+ kfree(mdl);
+ kfree(buf);
+ break;
+ }
+
INIT_LIST_HEAD(&mdl->list);
INIT_LIST_HEAD(&mdl->buf_list);
mdl->id = s->mdl_base_idx; /* a somewhat safe value */
cx18_enqueue(s, mdl, &s->q_idle);
INIT_LIST_HEAD(&buf->list);
- buf->dma_handle = dma_map_single(&s->cx->pci_dev->dev,
- buf->buf, s->buf_size,
- s->dma);
cx18_buf_sync_for_cpu(s, buf);
list_add_tail(&buf->list, &s->buf_pool);
}
diff --git a/drivers/media/pci/cx18/cx18-queue.h b/drivers/media/pci/cx18/cx18-queue.h
index 26f2097c0496..972f234ffead 100644
--- a/drivers/media/pci/cx18/cx18-queue.h
+++ b/drivers/media/pci/cx18/cx18-queue.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-queue.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-scb.c b/drivers/media/pci/cx18/cx18-scb.c
index 4a0edc1e42e7..670dd9b0a332 100644
--- a/drivers/media/pci/cx18/cx18-scb.c
+++ b/drivers/media/pci/cx18/cx18-scb.c
@@ -2,7 +2,7 @@
/*
* cx18 System Control Block initialization
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-scb.h b/drivers/media/pci/cx18/cx18-scb.h
index 841edc0712ab..900f7291979f 100644
--- a/drivers/media/pci/cx18/cx18-scb.h
+++ b/drivers/media/pci/cx18/cx18-scb.h
@@ -2,7 +2,7 @@
/*
* cx18 System Control Block initialization
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index 42d6f7b90ede..48203ba16387 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-streams.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-streams.h b/drivers/media/pci/cx18/cx18-streams.h
index bba4349c5c2e..e01bed6b4827 100644
--- a/drivers/media/pci/cx18/cx18-streams.h
+++ b/drivers/media/pci/cx18/cx18-streams.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-streams.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*/
diff --git a/drivers/media/pci/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c
index c7cce38dd754..8dc4ce325935 100644
--- a/drivers/media/pci/cx18/cx18-vbi.c
+++ b/drivers/media/pci/cx18/cx18-vbi.c
@@ -4,7 +4,7 @@
*
* Derived from ivtv-vbi.c
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
#include "cx18-driver.h"
diff --git a/drivers/media/pci/cx18/cx18-vbi.h b/drivers/media/pci/cx18/cx18-vbi.h
index a5f81c6159f0..41f5026696c4 100644
--- a/drivers/media/pci/cx18/cx18-vbi.h
+++ b/drivers/media/pci/cx18/cx18-vbi.h
@@ -4,7 +4,7 @@
*
* Derived from ivtv-vbi.h
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_mdl *mdl,
diff --git a/drivers/media/pci/cx18/cx18-version.h b/drivers/media/pci/cx18/cx18-version.h
index e7396182fc5a..e8636ac5d5a5 100644
--- a/drivers/media/pci/cx18/cx18-version.h
+++ b/drivers/media/pci/cx18/cx18-version.h
@@ -2,7 +2,7 @@
/*
* cx18 driver version information
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
#ifndef CX18_VERSION_H
diff --git a/drivers/media/pci/cx18/cx18-video.c b/drivers/media/pci/cx18/cx18-video.c
index 2fde8c2d3fdc..86cd44053d34 100644
--- a/drivers/media/pci/cx18/cx18-video.c
+++ b/drivers/media/pci/cx18/cx18-video.c
@@ -2,7 +2,7 @@
/*
* cx18 video interface functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
#include "cx18-driver.h"
diff --git a/drivers/media/pci/cx18/cx18-video.h b/drivers/media/pci/cx18/cx18-video.h
index f613975ca5f0..ef212f1c5b17 100644
--- a/drivers/media/pci/cx18/cx18-video.h
+++ b/drivers/media/pci/cx18/cx18-video.h
@@ -2,7 +2,7 @@
/*
* cx18 video interface functions
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
void cx18_video_set_io(struct cx18 *cx);
diff --git a/drivers/media/pci/cx18/cx23418.h b/drivers/media/pci/cx18/cx23418.h
index 8859c0e8557f..22486f39bcda 100644
--- a/drivers/media/pci/cx18/cx23418.h
+++ b/drivers/media/pci/cx18/cx23418.h
@@ -2,7 +2,7 @@
/*
* cx18 header containing common defines.
*
- * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org>
*/
#ifndef CX23418_H
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
index 6030bd23b4b9..d1fece6210ab 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
@@ -109,7 +109,7 @@ static int csi2_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
case V4L2_EVENT_FRAME_SYNC:
return v4l2_event_subscribe(fh, sub, 10, NULL);
case V4L2_EVENT_CTRL:
- return v4l2_ctrl_subscribe_event(fh, sub);
+ return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
default:
return -EINVAL;
}
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c
index 0a06de5c739c..463a0adf9e13 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c
@@ -81,6 +81,12 @@ unsigned int ipu6_isys_mbus_code_to_mipi(u32 code)
case MEDIA_BUS_FMT_SGRBG8_1X8:
case MEDIA_BUS_FMT_SRGGB8_1X8:
return MIPI_CSI2_DT_RAW8;
+ case MEDIA_BUS_FMT_META_8:
+ case MEDIA_BUS_FMT_META_10:
+ case MEDIA_BUS_FMT_META_12:
+ case MEDIA_BUS_FMT_META_16:
+ case MEDIA_BUS_FMT_META_24:
+ return MIPI_CSI2_DT_EMBEDDED_8B;
default:
/* return unavailable MIPI data type - 0x3f */
WARN_ON(1);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
index 24a2ef93474c..f3f3bc0615e5 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -1306,7 +1306,6 @@ int ipu6_isys_video_init(struct ipu6_isys_video *av)
__ipu6_isys_vidioc_try_fmt_meta_cap(av, &format_meta);
av->meta_fmt = format_meta.fmt.meta;
- set_bit(V4L2_FL_USES_V4L2_FH, &av->vdev.flags);
video_set_drvdata(&av->vdev, av);
ret = video_register_device(&av->vdev, VFL_TYPE_VIDEO, -1);
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
index 8f346d7da9c8..269a799ec046 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
@@ -148,14 +148,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
- v4l2_fh_init(&item.fh, &s->vdev);
item.itv = itv;
item.type = s->type;
/* See if the stream is available */
if (ivtv_claim_stream(&item, item.type)) {
/* No, it's already in use */
- v4l2_fh_exit(&item.fh);
snd_ivtv_unlock(itvsc);
return -EBUSY;
}
diff --git a/drivers/media/pci/ivtv/ivtv-cards.c b/drivers/media/pci/ivtv/ivtv-cards.c
index c8f4ed7ff2c6..f2ccf8e98664 100644
--- a/drivers/media/pci/ivtv/ivtv-cards.c
+++ b/drivers/media/pci/ivtv/ivtv-cards.c
@@ -2,7 +2,7 @@
/*
Functions to query card hardware
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-cards.h b/drivers/media/pci/ivtv/ivtv-cards.h
index c252733df340..af64e55d3b80 100644
--- a/drivers/media/pci/ivtv/ivtv-cards.h
+++ b/drivers/media/pci/ivtv/ivtv-cards.h
@@ -2,7 +2,7 @@
/*
Functions to query card hardware
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-controls.c b/drivers/media/pci/ivtv/ivtv-controls.c
index a0b9a5a5c7f1..f087a12c4ebd 100644
--- a/drivers/media/pci/ivtv/ivtv-controls.c
+++ b/drivers/media/pci/ivtv/ivtv-controls.c
@@ -2,7 +2,7 @@
/*
ioctl control functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-controls.h b/drivers/media/pci/ivtv/ivtv-controls.h
index 444c86a47e5a..d152691ea255 100644
--- a/drivers/media/pci/ivtv/ivtv-controls.h
+++ b/drivers/media/pci/ivtv/ivtv-controls.h
@@ -2,7 +2,7 @@
/*
ioctl control functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index ecc20cd89926..72a8f76a41f4 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
ivtv driver initialization and card probing
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
/* Main Driver file for the ivtv project:
diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h
index a6ffa99e16bc..f1f18911332e 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.h
+++ b/drivers/media/pci/ivtv/ivtv-driver.h
@@ -1,22 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
ivtv driver internal defines and structures
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
#ifndef IVTV_DRIVER_H
@@ -322,6 +309,7 @@ struct ivtv_queue {
};
struct ivtv; /* forward reference */
+struct ivtv_open_id;
struct ivtv_stream {
/* These first four fields are always set, even if the stream
@@ -331,7 +319,7 @@ struct ivtv_stream {
const char *name; /* name of the stream */
int type; /* stream type */
- struct v4l2_fh *fh; /* pointer to the streaming filehandle */
+ struct ivtv_open_id *id; /* pointer to the streaming ivtv_open_id */
spinlock_t qlock; /* locks access to the queues */
unsigned long s_flags; /* status flags, see above */
int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
@@ -383,9 +371,9 @@ struct ivtv_open_id {
struct ivtv *itv;
};
-static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh)
+static inline struct ivtv_open_id *file2id(struct file *filp)
{
- return container_of(fh, struct ivtv_open_id, fh);
+ return container_of(file_to_v4l2_fh(filp), struct ivtv_open_id, fh);
}
struct yuv_frame_info
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c
index cfa28d035586..ef9ec062c03a 100644
--- a/drivers/media/pci/ivtv/ivtv-fileops.c
+++ b/drivers/media/pci/ivtv/ivtv-fileops.c
@@ -3,7 +3,7 @@
file operation functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
@@ -39,16 +39,16 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
/* someone already claimed this stream */
- if (s->fh == &id->fh) {
+ if (s->id == id) {
/* yes, this file descriptor did. So that's OK. */
return 0;
}
- if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
+ if (s->id == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
type == IVTV_ENC_STREAM_TYPE_VBI)) {
/* VBI is handled already internally, now also assign
the file descriptor to this stream for external
reading of the stream. */
- s->fh = &id->fh;
+ s->id = id;
IVTV_DEBUG_INFO("Start Read VBI\n");
return 0;
}
@@ -56,7 +56,7 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
IVTV_DEBUG_INFO("Stream %d is busy\n", type);
return -EBUSY;
}
- s->fh = &id->fh;
+ s->id = id;
if (type == IVTV_DEC_STREAM_TYPE_VBI) {
/* Enable reinsertion interrupt */
ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
@@ -94,7 +94,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
struct ivtv *itv = s->itv;
struct ivtv_stream *s_vbi;
- s->fh = NULL;
+ s->id = NULL;
if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
/* this stream is still in use internally */
@@ -126,7 +126,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
/* was already cleared */
return;
}
- if (s_vbi->fh) {
+ if (s_vbi->id) {
/* VBI stream still claimed by a file descriptor */
return;
}
@@ -359,7 +359,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
size_t tot_written = 0;
int single_frame = 0;
- if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
+ if (atomic_read(&itv->capturing) == 0 && s->id == NULL) {
/* shouldn't happen */
IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
return -EIO;
@@ -502,7 +502,7 @@ int ivtv_start_capture(struct ivtv_open_id *id)
ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
{
- struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
ssize_t rc;
@@ -564,7 +564,7 @@ static int ivtv_schedule_dma(struct ivtv_stream *s)
static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
{
- struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
struct yuv_playback_info *yi = &itv->yuv_info;
@@ -719,7 +719,7 @@ retry:
ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
{
- struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
ssize_t res;
@@ -732,7 +732,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
__poll_t ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
{
- struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
__poll_t res = 0;
@@ -767,7 +767,7 @@ __poll_t ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
__poll_t ivtv_v4l2_enc_poll(struct file *filp, poll_table *wait)
{
__poll_t req_events = poll_requested_events(wait);
- struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
@@ -831,7 +831,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
/* Also used internally, don't stop capturing */
- s->fh = NULL;
+ s->id = NULL;
}
else {
ivtv_stop_v4l2_encode_stream(s, gop_end);
@@ -877,8 +877,8 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
int ivtv_v4l2_close(struct file *filp)
{
- struct v4l2_fh *fh = filp->private_data;
- struct ivtv_open_id *id = fh2id(fh);
+ struct v4l2_fh *fh = file_to_v4l2_fh(filp);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
@@ -911,11 +911,11 @@ int ivtv_v4l2_close(struct file *filp)
ivtv_unmute(itv);
}
- v4l2_fh_del(fh);
+ v4l2_fh_del(fh, filp);
v4l2_fh_exit(fh);
/* Easy case first: this stream was never claimed by us */
- if (s->fh != &id->fh)
+ if (s->id != id)
goto close_done;
/* 'Unclaim' this stream */
@@ -998,9 +998,7 @@ static int ivtv_open(struct file *filp)
v4l2_fh_init(&item->fh, &s->vdev);
item->itv = itv;
item->type = s->type;
-
- filp->private_data = &item->fh;
- v4l2_fh_add(&item->fh);
+ v4l2_fh_add(&item->fh, filp);
if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
v4l2_fh_is_singular_file(filp)) {
@@ -1008,7 +1006,7 @@ static int ivtv_open(struct file *filp)
if (atomic_read(&itv->capturing) > 0) {
/* switching to radio while capture is
in progress is not polite */
- v4l2_fh_del(&item->fh);
+ v4l2_fh_del(&item->fh, filp);
v4l2_fh_exit(&item->fh);
kfree(item);
return -EBUSY;
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.h b/drivers/media/pci/ivtv/ivtv-fileops.h
index c2c01bba5d03..7bbe42b0030c 100644
--- a/drivers/media/pci/ivtv/ivtv-fileops.h
+++ b/drivers/media/pci/ivtv/ivtv-fileops.h
@@ -2,7 +2,7 @@
/*
file operation functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c
index 56b25255faf5..1bc873ebef73 100644
--- a/drivers/media/pci/ivtv/ivtv-firmware.c
+++ b/drivers/media/pci/ivtv/ivtv-firmware.c
@@ -3,7 +3,7 @@
ivtv firmware functions.
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-firmware.h b/drivers/media/pci/ivtv/ivtv-firmware.h
index 393e94a8d0e4..ce94b6c385de 100644
--- a/drivers/media/pci/ivtv/ivtv-firmware.h
+++ b/drivers/media/pci/ivtv/ivtv-firmware.h
@@ -3,7 +3,7 @@
ivtv firmware functions.
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-gpio.c b/drivers/media/pci/ivtv/ivtv-gpio.c
index 6434c0d03a6d..d3477e1529c9 100644
--- a/drivers/media/pci/ivtv/ivtv-gpio.c
+++ b/drivers/media/pci/ivtv/ivtv-gpio.c
@@ -3,7 +3,7 @@
gpio functions.
Merging GPIO support into driver:
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-gpio.h b/drivers/media/pci/ivtv/ivtv-gpio.h
index 4ad817173f04..686c9b5e9c19 100644
--- a/drivers/media/pci/ivtv/ivtv-gpio.h
+++ b/drivers/media/pci/ivtv/ivtv-gpio.h
@@ -2,7 +2,7 @@
/*
gpio functions.
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c
index c052c57c6dce..28cb22d6a892 100644
--- a/drivers/media/pci/ivtv/ivtv-i2c.c
+++ b/drivers/media/pci/ivtv/ivtv-i2c.c
@@ -2,7 +2,7 @@
/*
I2C functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-i2c.h b/drivers/media/pci/ivtv/ivtv-i2c.h
index 2d9cdaa682c5..504bbc1dee25 100644
--- a/drivers/media/pci/ivtv/ivtv-i2c.h
+++ b/drivers/media/pci/ivtv/ivtv-i2c.h
@@ -2,7 +2,7 @@
/*
I2C functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 7947dcd615e8..84c73bd22f2d 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -2,7 +2,7 @@
/*
ioctl system call
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
@@ -308,7 +308,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
vbifmt->reserved[0] = 0;
@@ -330,7 +330,7 @@ static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
@@ -353,7 +353,7 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
vbifmt->sampling_rate = 27000000;
@@ -372,7 +372,7 @@ static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
vbifmt->reserved[0] = 0;
@@ -394,7 +394,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
@@ -434,8 +434,8 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
struct v4l2_window *winfmt = &fmt->fmt.win;
if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
@@ -461,7 +461,7 @@ static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_
static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
@@ -490,7 +490,7 @@ static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format
static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
@@ -510,7 +510,7 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
s32 w = fmt->fmt.pix.width;
s32 h = fmt->fmt.pix.height;
int field = fmt->fmt.pix.field;
@@ -544,8 +544,8 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
u32 chromakey = fmt->fmt.win.chromakey;
u8 global_alpha = fmt->fmt.win.global_alpha;
@@ -566,7 +566,7 @@ static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
@@ -597,7 +597,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
return -EBUSY;
@@ -610,7 +610,7 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
@@ -628,7 +628,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
@@ -673,7 +673,7 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
if (ret == 0) {
@@ -710,7 +710,7 @@ static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
reg->size = 4;
return ivtv_itvc(itv, true, reg->reg, &reg->val);
@@ -718,7 +718,7 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register
static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
u64 val = reg->val;
return ivtv_itvc(itv, false, reg->reg, &val);
@@ -727,7 +727,7 @@ static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_re
static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
{
- struct ivtv_open_id *id = fh2id(file->private_data);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
strscpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
@@ -738,14 +738,14 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
return ivtv_get_audio_input(itv, vin->index, vin);
}
static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
vin->index = itv->audio_input;
return ivtv_get_audio_input(itv, vin->index, vin);
@@ -753,7 +753,7 @@ static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (vout->index >= itv->nof_audio_inputs)
return -EINVAL;
@@ -766,7 +766,7 @@ static int ivtv_s_audio(struct file *file, void *fh, const struct v4l2_audio *vo
static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
/* set it to defaults from our table */
return ivtv_get_audio_output(itv, vin->index, vin);
@@ -774,7 +774,7 @@ static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vi
static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
vin->index = 0;
return ivtv_get_audio_output(itv, vin->index, vin);
@@ -782,7 +782,7 @@ static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (itv->card->video_outputs == NULL || vout->index != 0)
return -EINVAL;
@@ -791,7 +791,7 @@ static int ivtv_s_audout(struct file *file, void *fh, const struct v4l2_audioout
static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
/* set it to defaults from our table */
return ivtv_get_input(itv, vin->index, vin);
@@ -799,7 +799,7 @@ static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
return ivtv_get_output(itv, vout->index, vout);
}
@@ -807,7 +807,7 @@ static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vou
static int ivtv_g_pixelaspect(struct file *file, void *fh,
int type, struct v4l2_fract *f)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
@@ -825,7 +825,7 @@ static int ivtv_g_pixelaspect(struct file *file, void *fh,
static int ivtv_s_selection(struct file *file, void *fh,
struct v4l2_selection *sel)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
struct v4l2_rect r = { 0, 0, 720, 0 };
@@ -868,7 +868,7 @@ static int ivtv_s_selection(struct file *file, void *fh,
static int ivtv_g_selection(struct file *file, void *fh,
struct v4l2_selection *sel)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
struct v4l2_rect r = { 0, 0, 720, 0 };
@@ -924,8 +924,8 @@ static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes
.description = "MPEG",
.pixelformat = V4L2_PIX_FMT_MPEG,
};
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
if (fmt->index)
return -EINVAL;
@@ -951,8 +951,8 @@ static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdes
.description = "MPEG",
.pixelformat = V4L2_PIX_FMT_MPEG,
};
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
if (fmt->index)
return -EINVAL;
@@ -967,7 +967,7 @@ static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdes
static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
*i = itv->active_input;
@@ -976,7 +976,7 @@ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
v4l2_std_id std;
int i;
@@ -1019,7 +1019,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL;
@@ -1031,7 +1031,7 @@ static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (outp >= itv->card->nof_outputs)
return -EINVAL;
@@ -1053,8 +1053,8 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
{
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
if (s->vdev.vfl_dir)
return -ENOTTY;
@@ -1067,8 +1067,8 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
{
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
if (s->vdev.vfl_dir)
return -ENOTTY;
@@ -1084,7 +1084,7 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
*std = itv->std;
return 0;
@@ -1157,7 +1157,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)
static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if ((std & V4L2_STD_ALL) == 0)
return -EINVAL;
@@ -1185,7 +1185,7 @@ static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id std)
static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
if (vt->index != 0)
@@ -1198,7 +1198,7 @@ static int ivtv_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt
static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (vt->index != 0)
return -EINVAL;
@@ -1214,7 +1214,7 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
int f, l;
@@ -1249,7 +1249,7 @@ static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced
static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
struct v4l2_enc_idx_entry *e = idx->entry;
int entries;
int i;
@@ -1275,7 +1275,7 @@ static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *id
static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
@@ -1327,7 +1327,7 @@ static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd
static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
switch (enc->cmd) {
case V4L2_ENC_CMD_START:
@@ -1357,8 +1357,8 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder
static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
{
- struct ivtv *itv = fh2id(fh)->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv *itv = file2id(file)->itv;
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
u32 data[CX2341X_MBOX_MAX_DATA];
struct yuv_playback_info *yi = &itv->yuv_info;
@@ -1444,9 +1444,9 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
struct yuv_playback_info *yi = &itv->yuv_info;
if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
@@ -1465,9 +1465,9 @@ static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffe
static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
{
- struct ivtv_open_id *id = fh2id(fh);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
+ struct ivtv_stream *s = &itv->streams[file2id(file)->type];
if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
return -ENOTTY;
@@ -1492,7 +1492,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subs
static int ivtv_log_status(struct file *file, void *fh)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
u32 data[CX2341X_MBOX_MAX_DATA];
int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
@@ -1584,7 +1584,7 @@ static int ivtv_log_status(struct file *file, void *fh)
static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
{
- struct ivtv_open_id *id = fh2id(file->private_data);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
@@ -1593,7 +1593,7 @@ static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd
static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
{
- struct ivtv_open_id *id = fh2id(file->private_data);
+ struct ivtv_open_id *id = file2id(file);
struct ivtv *itv = id->itv;
IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
@@ -1602,7 +1602,7 @@ static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder
static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
{
- struct ivtv_open_id *id = fh2id(filp->private_data);
+ struct ivtv_open_id *id = file2id(filp);
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
@@ -1645,7 +1645,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
static long ivtv_default(struct file *file, void *fh, bool valid_prio,
unsigned int cmd, void *arg)
{
- struct ivtv *itv = fh2id(fh)->itv;
+ struct ivtv *itv = file2id(file)->itv;
if (!valid_prio) {
switch (cmd) {
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.h b/drivers/media/pci/ivtv/ivtv-ioctl.h
index 42c2516379fc..7f8c6f43d397 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.h
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.h
@@ -2,7 +2,7 @@
/*
ioctl system call
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c
index 748c14e87963..05e0293b4d44 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -2,7 +2,7 @@
/* interrupt handling
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
@@ -305,7 +305,7 @@ static void dma_post(struct ivtv_stream *s)
ivtv_process_vbi_data(itv, buf, 0, s->type);
s->q_dma.bytesused += buf->bytesused;
}
- if (s->fh == NULL) {
+ if (s->id == NULL) {
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
return;
}
@@ -330,7 +330,7 @@ static void dma_post(struct ivtv_stream *s)
set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
}
- if (s->fh)
+ if (s->id)
wake_up(&s->waitq);
}
@@ -351,7 +351,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
/* Insert buffer block for YUV if needed */
if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) {
- if (yi->blanking_dmaptr) {
+ if (yi->blanking_ptr) {
s->sg_pending[idx].src = yi->blanking_dmaptr;
s->sg_pending[idx].dst = offset;
s->sg_pending[idx].size = 720 * 16;
diff --git a/drivers/media/pci/ivtv/ivtv-irq.h b/drivers/media/pci/ivtv/ivtv-irq.h
index b8b0703a1c82..8a780bea7de4 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.h
+++ b/drivers/media/pci/ivtv/ivtv-irq.h
@@ -3,7 +3,7 @@
interrupt handling
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-mailbox.c b/drivers/media/pci/ivtv/ivtv-mailbox.c
index d3fdaaa903f1..cd7c9f2d473f 100644
--- a/drivers/media/pci/ivtv/ivtv-mailbox.c
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.c
@@ -3,7 +3,7 @@
mailbox functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-mailbox.h b/drivers/media/pci/ivtv/ivtv-mailbox.h
index 537c90437e1d..364e7f51508e 100644
--- a/drivers/media/pci/ivtv/ivtv-mailbox.h
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.h
@@ -2,7 +2,7 @@
/*
mailbox functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-queue.c b/drivers/media/pci/ivtv/ivtv-queue.c
index f9b192ab7e7c..f7d2d159d800 100644
--- a/drivers/media/pci/ivtv/ivtv-queue.c
+++ b/drivers/media/pci/ivtv/ivtv-queue.c
@@ -3,7 +3,7 @@
buffer queues.
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-queue.h b/drivers/media/pci/ivtv/ivtv-queue.h
index 983e99642364..9619745d6de1 100644
--- a/drivers/media/pci/ivtv/ivtv-queue.h
+++ b/drivers/media/pci/ivtv/ivtv-queue.h
@@ -3,7 +3,7 @@
buffer queues.
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-routing.c b/drivers/media/pci/ivtv/ivtv-routing.c
index 57d4d5a3cb87..b1dfc2e96d91 100644
--- a/drivers/media/pci/ivtv/ivtv-routing.c
+++ b/drivers/media/pci/ivtv/ivtv-routing.c
@@ -2,7 +2,7 @@
/*
Audio/video-routing-related ivtv functions.
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-routing.h b/drivers/media/pci/ivtv/ivtv-routing.h
index e4a0ae0694d2..69ddb66ef26f 100644
--- a/drivers/media/pci/ivtv/ivtv-routing.h
+++ b/drivers/media/pci/ivtv/ivtv-routing.h
@@ -2,7 +2,7 @@
/*
Audio/video-routing-related ivtv functions.
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c
index ac085925d3cb..d98fe0c9d9f1 100644
--- a/drivers/media/pci/ivtv/ivtv-streams.c
+++ b/drivers/media/pci/ivtv/ivtv-streams.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
init/start/stop/exit stream functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
/* License: GPL
diff --git a/drivers/media/pci/ivtv/ivtv-streams.h b/drivers/media/pci/ivtv/ivtv-streams.h
index 5f35c57fcdfd..43d4ecd6dd6f 100644
--- a/drivers/media/pci/ivtv/ivtv-streams.h
+++ b/drivers/media/pci/ivtv/ivtv-streams.h
@@ -2,7 +2,7 @@
/*
init/start/stop/exit stream functions
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
index f467a00492f4..7dedf04f9f87 100644
--- a/drivers/media/pci/ivtv/ivtv-udma.c
+++ b/drivers/media/pci/ivtv/ivtv-udma.c
@@ -4,7 +4,7 @@
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-udma.h b/drivers/media/pci/ivtv/ivtv-udma.h
index 12b9426b2db2..3030fadfdbc7 100644
--- a/drivers/media/pci/ivtv/ivtv-udma.h
+++ b/drivers/media/pci/ivtv/ivtv-udma.h
@@ -2,7 +2,7 @@
/*
Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2006-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2006-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-vbi.c b/drivers/media/pci/ivtv/ivtv-vbi.c
index 80478b026d75..ae7a00f46257 100644
--- a/drivers/media/pci/ivtv/ivtv-vbi.c
+++ b/drivers/media/pci/ivtv/ivtv-vbi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
Vertical Blank Interval support functions
- Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2004-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-vbi.h b/drivers/media/pci/ivtv/ivtv-vbi.h
index 780f73d2ab6b..12fe27da544b 100644
--- a/drivers/media/pci/ivtv/ivtv-vbi.h
+++ b/drivers/media/pci/ivtv/ivtv-vbi.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
Vertical Blank Interval support functions
- Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2004-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-version.h b/drivers/media/pci/ivtv/ivtv-version.h
index 996f1871e49c..21e26d1f66b8 100644
--- a/drivers/media/pci/ivtv/ivtv-version.h
+++ b/drivers/media/pci/ivtv/ivtv-version.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
ivtv driver version information
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2005-2007 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
index 2d9274537725..71f040106647 100644
--- a/drivers/media/pci/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -125,7 +125,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
/* If we've offset the y plane, ensure top area is blanked */
- if (f->offset_y && yi->blanking_dmaptr) {
+ if (f->offset_y && yi->blanking_ptr) {
dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
@@ -929,6 +929,12 @@ static void ivtv_yuv_init(struct ivtv *itv)
yi->blanking_dmaptr = dma_map_single(&itv->pdev->dev,
yi->blanking_ptr,
720 * 16, DMA_TO_DEVICE);
+ if (dma_mapping_error(&itv->pdev->dev, yi->blanking_dmaptr)) {
+ kfree(yi->blanking_ptr);
+ yi->blanking_ptr = NULL;
+ yi->blanking_dmaptr = 0;
+ IVTV_DEBUG_WARN("Failed to dma_map yuv blanking buffer\n");
+ }
} else {
yi->blanking_dmaptr = 0;
IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
diff --git a/drivers/media/pci/mgb4/mgb4_trigger.c b/drivers/media/pci/mgb4/mgb4_trigger.c
index 923650d53d4c..d7dddc5c8728 100644
--- a/drivers/media/pci/mgb4/mgb4_trigger.c
+++ b/drivers/media/pci/mgb4/mgb4_trigger.c
@@ -91,7 +91,7 @@ static irqreturn_t trigger_handler(int irq, void *p)
struct {
u32 data;
s64 ts __aligned(8);
- } scan;
+ } scan = { };
scan.data = mgb4_read_reg(&st->mgbdev->video, 0xA0);
mgb4_write_reg(&st->mgbdev->video, 0xA0, scan.data);
diff --git a/drivers/media/pci/mgb4/mgb4_vin.c b/drivers/media/pci/mgb4/mgb4_vin.c
index 989e93f67f75..42c327bc50e1 100644
--- a/drivers/media/pci/mgb4/mgb4_vin.c
+++ b/drivers/media/pci/mgb4/mgb4_vin.c
@@ -610,8 +610,7 @@ static int vidioc_s_dv_timings(struct file *file, void *fh,
timings->bt.height < video_timings_cap.bt.min_height ||
timings->bt.height > video_timings_cap.bt.max_height)
return -EINVAL;
- if (timings->bt.width == vindev->timings.bt.width &&
- timings->bt.height == vindev->timings.bt.height)
+ if (v4l2_match_dv_timings(timings, &vindev->timings, 0, false))
return 0;
if (vb2_is_busy(&vindev->queue))
return -EBUSY;
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index c88939bce56b..4a51b873e47a 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1302,7 +1302,7 @@ static int saa7134_g_pixelaspect(struct file *file, void *priv,
return 0;
}
-static int saa7134_g_selection(struct file *file, void *f, struct v4l2_selection *sel)
+static int saa7134_g_selection(struct file *file, void *priv, struct v4l2_selection *sel)
{
struct saa7134_dev *dev = video_drvdata(file);
@@ -1325,7 +1325,7 @@ static int saa7134_g_selection(struct file *file, void *f, struct v4l2_selection
return 0;
}
-static int saa7134_s_selection(struct file *file, void *f, struct v4l2_selection *sel)
+static int saa7134_s_selection(struct file *file, void *priv, struct v4l2_selection *sel)
{
struct saa7134_dev *dev = video_drvdata(file);
struct v4l2_rect *b = &dev->crop_bounds;
diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
index bf73e9e83f52..66d650b5f69a 100644
--- a/drivers/media/pci/saa7164/saa7164-encoder.c
+++ b/drivers/media/pci/saa7164/saa7164-encoder.c
@@ -219,7 +219,7 @@ int saa7164_s_std(struct saa7164_port *port, v4l2_std_id id)
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
return saa7164_s_std(fh->port, id);
}
@@ -232,7 +232,7 @@ int saa7164_g_std(struct saa7164_port *port, v4l2_std_id *id)
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
return saa7164_g_std(fh->port, id);
}
@@ -277,7 +277,7 @@ int saa7164_g_input(struct saa7164_port *port, unsigned int *i)
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
return saa7164_g_input(fh->port, i);
}
@@ -301,14 +301,14 @@ int saa7164_s_input(struct saa7164_port *port, unsigned int i)
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
return saa7164_s_input(fh->port, i);
}
int saa7164_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
@@ -347,7 +347,7 @@ int saa7164_g_frequency(struct saa7164_port *port, struct v4l2_frequency *f)
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
return saa7164_g_frequency(fh->port, f);
}
@@ -400,7 +400,7 @@ int saa7164_s_frequency(struct saa7164_port *port,
static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
return saa7164_s_frequency(fh->port, f);
}
@@ -483,7 +483,7 @@ static int saa7164_s_ctrl(struct v4l2_ctrl *ctrl)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
@@ -510,7 +510,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
struct saa7164_port *port = fh->port;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
@@ -725,15 +725,14 @@ static int fops_open(struct file *file)
fh->port = port;
v4l2_fh_init(&fh->fh, video_devdata(file));
- v4l2_fh_add(&fh->fh);
- file->private_data = fh;
+ v4l2_fh_add(&fh->fh, file);
return 0;
}
static int fops_release(struct file *file)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
@@ -747,7 +746,7 @@ static int fops_release(struct file *file)
}
}
- v4l2_fh_del(&fh->fh);
+ v4l2_fh_del(&fh->fh, file);
v4l2_fh_exit(&fh->fh);
kfree(fh);
@@ -787,7 +786,7 @@ saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
static ssize_t fops_read(struct file *file, char __user *buffer,
size_t count, loff_t *pos)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_user_buffer *ubuf = NULL;
struct saa7164_dev *dev = port->dev;
@@ -893,8 +892,7 @@ err:
static __poll_t fops_poll(struct file *file, poll_table *wait)
{
__poll_t req_events = poll_requested_events(wait);
- struct saa7164_encoder_fh *fh =
- (struct saa7164_encoder_fh *)file->private_data;
+ struct saa7164_encoder_fh *fh = to_saa7164_encoder_fh(file);
struct saa7164_port *port = fh->port;
__poll_t mask = v4l2_ctrl_poll(file, wait);
diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c
index ac958a5fca78..57e4362c0d19 100644
--- a/drivers/media/pci/saa7164/saa7164-vbi.c
+++ b/drivers/media/pci/saa7164/saa7164-vbi.c
@@ -144,28 +144,28 @@ static int saa7164_vbi_initialize(struct saa7164_port *port)
/* -- V4L2 --------------------------------------------------------- */
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
return saa7164_s_std(fh->port->enc_port, id);
}
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
{
- struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
return saa7164_g_std(fh->port->enc_port, id);
}
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
return saa7164_g_input(fh->port->enc_port, i);
}
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
return saa7164_s_input(fh->port->enc_port, i);
}
@@ -173,7 +173,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
return saa7164_g_frequency(fh->port->enc_port, f);
}
@@ -181,7 +181,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
int ret = saa7164_s_frequency(fh->port->enc_port, f);
if (ret == 0)
@@ -192,7 +192,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
@@ -428,15 +428,14 @@ static int fops_open(struct file *file)
fh->port = port;
v4l2_fh_init(&fh->fh, video_devdata(file));
- v4l2_fh_add(&fh->fh);
- file->private_data = fh;
+ v4l2_fh_add(&fh->fh, file);
return 0;
}
static int fops_release(struct file *file)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
@@ -450,7 +449,7 @@ static int fops_release(struct file *file)
}
}
- v4l2_fh_del(&fh->fh);
+ v4l2_fh_del(&fh->fh, file);
v4l2_fh_exit(&fh->fh);
kfree(fh);
@@ -489,7 +488,7 @@ saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
static ssize_t fops_read(struct file *file, char __user *buffer,
size_t count, loff_t *pos)
{
- struct saa7164_vbi_fh *fh = file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
struct saa7164_port *port = fh->port;
struct saa7164_user_buffer *ubuf = NULL;
struct saa7164_dev *dev = port->dev;
@@ -596,7 +595,7 @@ err:
static __poll_t fops_poll(struct file *file, poll_table *wait)
{
- struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
+ struct saa7164_vbi_fh *fh = to_saa7164_vbi_fh(file);
struct saa7164_port *port = fh->port;
__poll_t mask = 0;
diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index e1bac1fe19d3..94e987e7b5e5 100644
--- a/drivers/media/pci/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -180,12 +180,22 @@ struct saa7164_encoder_fh {
atomic_t v4l_reading;
};
+static inline struct saa7164_encoder_fh *to_saa7164_encoder_fh(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct saa7164_encoder_fh, fh);
+}
+
struct saa7164_vbi_fh {
struct v4l2_fh fh;
struct saa7164_port *port;
atomic_t v4l_reading;
};
+static inline struct saa7164_vbi_fh *to_saa7164_vbi_fh(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct saa7164_vbi_fh, fh);
+}
+
struct saa7164_histogram_bucket {
u32 val;
u32 count;
diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c
index 35dd19b2427e..08b7ce1043aa 100644
--- a/drivers/media/pci/tw68/tw68-core.c
+++ b/drivers/media/pci/tw68/tw68-core.c
@@ -14,7 +14,7 @@
*
* Refactored and updated to the latest v4l core frameworks:
*
- * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2014 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/init.h>
@@ -37,7 +37,7 @@
MODULE_DESCRIPTION("v4l2 driver module for tw6800 based video capture cards");
MODULE_AUTHOR("William M. Brack");
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_LICENSE("GPL");
static unsigned int latency = UNSET;
diff --git a/drivers/media/pci/tw68/tw68-reg.h b/drivers/media/pci/tw68/tw68-reg.h
index dcd9931b25cc..8aeef452ea8a 100644
--- a/drivers/media/pci/tw68/tw68-reg.h
+++ b/drivers/media/pci/tw68/tw68-reg.h
@@ -13,7 +13,7 @@
*
* Refactored and updated to the latest v4l core frameworks:
*
- * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2014 Hans Verkuil <hverkuil@kernel.org>
*/
#ifndef _TW68_REG_H_
diff --git a/drivers/media/pci/tw68/tw68-risc.c b/drivers/media/pci/tw68/tw68-risc.c
index dacb136c4f3a..e793db6134e4 100644
--- a/drivers/media/pci/tw68/tw68-risc.c
+++ b/drivers/media/pci/tw68/tw68-risc.c
@@ -14,7 +14,7 @@
*
* Refactored and updated to the latest v4l core frameworks:
*
- * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2014 Hans Verkuil <hverkuil@kernel.org>
*/
#include "tw68.h"
diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c
index 77773dec48b8..6232bac170d0 100644
--- a/drivers/media/pci/tw68/tw68-video.c
+++ b/drivers/media/pci/tw68/tw68-video.c
@@ -13,7 +13,7 @@
*
* Refactored and updated to the latest v4l core frameworks:
*
- * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2014 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/module.h>
diff --git a/drivers/media/pci/tw68/tw68.h b/drivers/media/pci/tw68/tw68.h
index a1f422d6e600..66be6b3bb7b6 100644
--- a/drivers/media/pci/tw68/tw68.h
+++ b/drivers/media/pci/tw68/tw68.h
@@ -13,7 +13,7 @@
*
* Refactored and updated to the latest v4l core frameworks:
*
- * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2014 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/pci.h>
diff --git a/drivers/media/pci/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h
index 1cd990468d3d..d05e222b3921 100644
--- a/drivers/media/pci/zoran/zoran.h
+++ b/drivers/media/pci/zoran/zoran.h
@@ -154,12 +154,6 @@ struct zoran_jpg_settings {
struct zoran;
-/* zoran_fh contains per-open() settings */
-struct zoran_fh {
- struct v4l2_fh fh;
- struct zoran *zr;
-};
-
struct card_info {
enum card_type type;
char name[32];
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index e31f9f19a48a..d81facf735d9 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -67,10 +67,6 @@ module_param(pass_through, int, 0644);
MODULE_PARM_DESC(pass_through,
"Pass TV signal through to TV-out when idling");
-int zr36067_debug = 1;
-module_param_named(debug, zr36067_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-5)");
-
#define ZORAN_VERSION "0.10.1"
MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
diff --git a/drivers/media/pci/zoran/zoran_card.h b/drivers/media/pci/zoran/zoran_card.h
index 518cb426b446..c4f81777e6ce 100644
--- a/drivers/media/pci/zoran/zoran_card.h
+++ b/drivers/media/pci/zoran/zoran_card.h
@@ -12,8 +12,6 @@
#ifndef __ZORAN_CARD_H__
#define __ZORAN_CARD_H__
-extern int zr36067_debug;
-
/* Anybody who uses more than four? */
#define BUZ_MAX 4
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index f42f596d3e62..5b4d5dd06edb 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -245,7 +245,7 @@ static int zoran_set_input(struct zoran *zr, int input)
* ioctl routine
*/
-static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
+static int zoran_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
{
struct zoran *zr = video_drvdata(file);
@@ -278,7 +278,7 @@ static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
return -EINVAL;
}
-static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
+static int zoran_enum_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{
struct zoran *zr = video_drvdata(file);
@@ -286,7 +286,7 @@ static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
}
-static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
+static int zoran_g_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *fmt)
{
struct zoran *zr = video_drvdata(file);
@@ -308,13 +308,13 @@ static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
return 0;
}
-static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
+static int zoran_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
struct zoran *zr = video_drvdata(file);
if (zr->map_mode != ZORAN_MAP_MODE_RAW)
- return zoran_g_fmt_vid_out(file, __fh, fmt);
+ return zoran_g_fmt_vid_out(file, fh, fmt);
fmt->fmt.pix.width = zr->v4l_settings.width;
fmt->fmt.pix.height = zr->v4l_settings.height;
fmt->fmt.pix.sizeimage = zr->buffer_size;
@@ -328,7 +328,7 @@ static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
return 0;
}
-static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
+static int zoran_try_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *fmt)
{
struct zoran *zr = video_drvdata(file);
@@ -391,7 +391,7 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
return res;
}
-static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
+static int zoran_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
struct zoran *zr = video_drvdata(file);
@@ -399,7 +399,7 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
int i;
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
- return zoran_try_fmt_vid_out(file, __fh, fmt);
+ return zoran_try_fmt_vid_out(file, fh, fmt);
for (i = 0; i < NUM_FORMATS; i++)
if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
@@ -427,7 +427,7 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
return 0;
}
-static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
+static int zoran_s_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *fmt)
{
struct zoran *zr = video_drvdata(file);
@@ -507,11 +507,10 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
return res;
}
-static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
+static int zoran_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
struct zoran *zr = video_drvdata(file);
- struct zoran_fh *fh = __fh;
int i;
int res = 0;
@@ -556,7 +555,7 @@ static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
return res;
}
-static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
+static int zoran_g_std(struct file *file, void *fh, v4l2_std_id *std)
{
struct zoran *zr = video_drvdata(file);
@@ -564,7 +563,7 @@ static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
return 0;
}
-static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)
+static int zoran_s_std(struct file *file, void *fh, v4l2_std_id std)
{
struct zoran *zr = video_drvdata(file);
int res = 0;
@@ -579,7 +578,7 @@ static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std)
return res;
}
-static int zoran_enum_input(struct file *file, void *__fh,
+static int zoran_enum_input(struct file *file, void *fh,
struct v4l2_input *inp)
{
struct zoran *zr = video_drvdata(file);
@@ -596,7 +595,7 @@ static int zoran_enum_input(struct file *file, void *__fh,
return 0;
}
-static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
+static int zoran_g_input(struct file *file, void *fh, unsigned int *input)
{
struct zoran *zr = video_drvdata(file);
@@ -605,7 +604,7 @@ static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
return 0;
}
-static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
+static int zoran_s_input(struct file *file, void *fh, unsigned int input)
{
struct zoran *zr = video_drvdata(file);
int res;
@@ -618,7 +617,7 @@ static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
}
/* cropping (sub-frame capture) */
-static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
+static int zoran_g_selection(struct file *file, void *fh, struct v4l2_selection *sel)
{
struct zoran *zr = video_drvdata(file);
@@ -653,7 +652,7 @@ static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selectio
return 0;
}
-static int zoran_s_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
+static int zoran_s_selection(struct file *file, void *fh, struct v4l2_selection *sel)
{
struct zoran *zr = video_drvdata(file);
struct zoran_jpg_settings settings;
diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
index eb03df0d8652..510c3c9661d9 100644
--- a/drivers/media/platform/allegro-dvt/allegro-core.c
+++ b/drivers/media/platform/allegro-dvt/allegro-core.c
@@ -197,8 +197,6 @@ static const struct regmap_config allegro_sram_config = {
.cache_type = REGCACHE_NONE,
};
-#define fh_to_channel(__fh) container_of(__fh, struct allegro_channel, fh)
-
struct allegro_channel {
struct allegro_dev *dev;
struct v4l2_fh fh;
@@ -302,6 +300,11 @@ struct allegro_channel {
unsigned int error;
};
+static inline struct allegro_channel *file_to_channel(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct allegro_channel, fh);
+}
+
static inline int
allegro_channel_get_i_frame_qp(struct allegro_channel *channel)
{
@@ -3214,8 +3217,7 @@ static int allegro_open(struct file *file)
}
list_add(&channel->list, &dev->channels);
- file->private_data = &channel->fh;
- v4l2_fh_add(&channel->fh);
+ v4l2_fh_add(&channel->fh, file);
allegro_channel_adjust(channel);
@@ -3229,7 +3231,7 @@ error:
static int allegro_release(struct file *file)
{
- struct allegro_channel *channel = fh_to_channel(file->private_data);
+ struct allegro_channel *channel = file_to_channel(file);
v4l2_m2m_ctx_release(channel->fh.m2m_ctx);
@@ -3237,7 +3239,7 @@ static int allegro_release(struct file *file)
v4l2_ctrl_handler_free(&channel->ctrl_handler);
- v4l2_fh_del(&channel->fh);
+ v4l2_fh_del(&channel->fh, file);
v4l2_fh_exit(&channel->fh);
kfree(channel);
@@ -3280,7 +3282,7 @@ static int allegro_enum_fmt_vid(struct file *file, void *fh,
static int allegro_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
f->fmt.pix.field = V4L2_FIELD_NONE;
f->fmt.pix.width = channel->width;
@@ -3322,7 +3324,7 @@ static int allegro_try_fmt_vid_cap(struct file *file, void *fh,
static int allegro_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
struct vb2_queue *vq;
int err;
@@ -3346,7 +3348,7 @@ static int allegro_s_fmt_vid_cap(struct file *file, void *fh,
static int allegro_g_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
f->fmt.pix.field = V4L2_FIELD_NONE;
@@ -3393,7 +3395,7 @@ static int allegro_try_fmt_vid_out(struct file *file, void *fh,
static int allegro_s_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
int err;
err = allegro_try_fmt_vid_out(file, fh, f);
@@ -3434,7 +3436,7 @@ static int allegro_channel_cmd_start(struct allegro_channel *channel)
static int allegro_encoder_cmd(struct file *file, void *fh,
struct v4l2_encoder_cmd *cmd)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
int err;
err = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
@@ -3483,8 +3485,7 @@ static int allegro_enum_framesizes(struct file *file, void *fh,
static int allegro_ioctl_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct v4l2_fh *fh = file->private_data;
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
int err;
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
@@ -3493,13 +3494,13 @@ static int allegro_ioctl_streamon(struct file *file, void *priv,
return err;
}
- return v4l2_m2m_streamon(file, fh->m2m_ctx, type);
+ return v4l2_m2m_streamon(file, channel->fh.m2m_ctx, type);
}
static int allegro_g_parm(struct file *file, void *fh,
struct v4l2_streamparm *a)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
struct v4l2_fract *timeperframe;
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -3516,7 +3517,7 @@ static int allegro_g_parm(struct file *file, void *fh,
static int allegro_s_parm(struct file *file, void *fh,
struct v4l2_streamparm *a)
{
- struct allegro_channel *channel = fh_to_channel(fh);
+ struct allegro_channel *channel = file_to_channel(file);
struct v4l2_fract *timeperframe;
int div;
diff --git a/drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c b/drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c
index 1011ab3ebac7..b9e4ef3fc308 100644
--- a/drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c
+++ b/drivers/media/platform/amlogic/c3/mipi-csi2/c3-mipi-csi2.c
@@ -388,13 +388,12 @@ static void c3_mipi_csi_cfg_host(struct c3_csi_device *csi)
c3_mipi_csi_write(csi, CSI2_HOST_N_LANES, csi->bus.num_data_lanes - 1);
}
-static int c3_mipi_csi_start_stream(struct c3_csi_device *csi,
- struct v4l2_subdev *src_sd)
+static int c3_mipi_csi_start_stream(struct c3_csi_device *csi)
{
s64 link_freq;
s64 lane_rate;
- link_freq = v4l2_get_link_freq(src_sd->ctrl_handler, 0, 0);
+ link_freq = v4l2_get_link_freq(csi->src_pad, 0, 0);
if (link_freq < 0) {
dev_err(csi->dev,
"Unable to obtain link frequency: %lld\n", link_freq);
@@ -434,7 +433,7 @@ static int c3_mipi_csi_enable_streams(struct v4l2_subdev *sd,
pm_runtime_resume_and_get(csi->dev);
- c3_mipi_csi_start_stream(csi, src_sd);
+ c3_mipi_csi_start_stream(csi);
ret = v4l2_subdev_enable_streams(src_sd, csi->src_pad->index, BIT(0));
if (ret) {
diff --git a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
index 0c004bb8ba05..5744853a4003 100644
--- a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
+++ b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
@@ -82,6 +82,11 @@ struct ge2d_ctx {
u32 xy_swap;
};
+static inline struct ge2d_ctx *file_to_ge2d_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct ge2d_ctx, fh);
+}
+
struct meson_ge2d {
struct v4l2_device v4l2_dev;
struct v4l2_m2m_dev *m2m_dev;
@@ -452,7 +457,7 @@ static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f
static int vidioc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct ge2d_ctx *ctx = priv;
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
struct ge2d_frame *f;
bool use_frame = false;
@@ -502,7 +507,7 @@ static int vidioc_g_selection(struct file *file, void *priv,
static int vidioc_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct ge2d_ctx *ctx = priv;
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
struct meson_ge2d *ge2d = ctx->ge2d;
struct ge2d_frame *f;
int ret = 0;
@@ -569,8 +574,8 @@ static void vidioc_setup_cap_fmt(struct ge2d_ctx *ctx, struct v4l2_pix_format *f
static int vidioc_try_fmt_cap(struct file *file, void *priv, struct v4l2_format *f)
{
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
const struct ge2d_fmt *fmt = find_fmt(f);
- struct ge2d_ctx *ctx = priv;
struct v4l2_pix_format fmt_cap;
vidioc_setup_cap_fmt(ctx, &fmt_cap);
@@ -590,7 +595,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, struct v4l2_format
static int vidioc_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *f)
{
- struct ge2d_ctx *ctx = priv;
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
struct meson_ge2d *ge2d = ctx->ge2d;
struct vb2_queue *vq;
struct ge2d_frame *frm;
@@ -626,7 +631,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *f
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct ge2d_ctx *ctx = priv;
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
struct vb2_queue *vq;
struct ge2d_frame *frm;
@@ -665,7 +670,7 @@ static int vidioc_try_fmt_out(struct file *file, void *priv, struct v4l2_format
static int vidioc_s_fmt_out(struct file *file, void *priv, struct v4l2_format *f)
{
- struct ge2d_ctx *ctx = priv;
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
struct meson_ge2d *ge2d = ctx->ge2d;
struct vb2_queue *vq;
struct ge2d_frame *frm, *frm_cap;
@@ -855,8 +860,7 @@ static int ge2d_open(struct file *file)
return ret;
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ge2d_setup_ctrls(ctx);
@@ -871,8 +875,7 @@ static int ge2d_open(struct file *file)
static int ge2d_release(struct file *file)
{
- struct ge2d_ctx *ctx =
- container_of(file->private_data, struct ge2d_ctx, fh);
+ struct ge2d_ctx *ctx = file_to_ge2d_ctx(file);
struct meson_ge2d *ge2d = ctx->ge2d;
mutex_lock(&ge2d->mutex);
@@ -880,7 +883,7 @@ static int ge2d_release(struct file *file)
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
index cac0f1a64fea..bfd171a3ded4 100644
--- a/drivers/media/platform/amphion/vpu.h
+++ b/drivers/media/platform/amphion/vpu.h
@@ -328,7 +328,7 @@ static inline const char *vpu_core_type_desc(enum vpu_core_type type)
static inline struct vpu_inst *to_inst(struct file *filp)
{
- return container_of(filp->private_data, struct vpu_inst, fh);
+ return container_of(file_to_v4l2_fh(filp), struct vpu_inst, fh);
}
#define ctrl_to_inst(ctrl) \
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
index 74668fa362e2..fcb2eff813ac 100644
--- a/drivers/media/platform/amphion/vpu_v4l2.c
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -24,6 +24,11 @@
#include "vpu_msgs.h"
#include "vpu_helpers.h"
+static char *vpu_type_name(u32 type)
+{
+ return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
+}
+
void vpu_inst_lock(struct vpu_inst *inst)
{
mutex_lock(&inst->lock);
@@ -42,7 +47,7 @@ dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
vb->planes[plane_no].data_offset;
}
-unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
+static unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
{
if (plane_no >= vb->num_planes)
return 0;
@@ -81,7 +86,7 @@ void vpu_v4l2_set_error(struct vpu_inst *inst)
vpu_inst_unlock(inst);
}
-int vpu_notify_eos(struct vpu_inst *inst)
+static int vpu_notify_eos(struct vpu_inst *inst)
{
static const struct v4l2_event ev = {
.id = 0,
@@ -573,7 +578,8 @@ static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
call_void_vop(inst, on_queue_empty, q->type);
}
-void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state)
+static void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type,
+ enum vb2_buffer_state state)
{
struct vb2_v4l2_buffer *buf;
@@ -718,8 +724,6 @@ static int vpu_v4l2_release(struct vpu_inst *inst)
v4l2_ctrl_handler_free(&inst->ctrl_handler);
mutex_destroy(&inst->lock);
- v4l2_fh_del(&inst->fh);
- v4l2_fh_exit(&inst->fh);
call_void_vop(inst, cleanup);
@@ -756,7 +760,7 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
inst->min_buffer_cap = 2;
inst->min_buffer_out = 2;
v4l2_fh_init(&inst->fh, func->vfd);
- v4l2_fh_add(&inst->fh);
+ v4l2_fh_add(&inst->fh, file);
ret = call_vop(inst, ctrl_init);
if (ret)
@@ -770,7 +774,6 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
}
inst->fh.ctrl_handler = &inst->ctrl_handler;
- file->private_data = &inst->fh;
inst->state = VPU_CODEC_STATE_DEINIT;
inst->workqueue = alloc_ordered_workqueue("vpu_inst", WQ_MEM_RECLAIM);
if (inst->workqueue) {
@@ -788,6 +791,8 @@ int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
return 0;
error:
+ v4l2_fh_del(&inst->fh, file);
+ v4l2_fh_exit(&inst->fh);
vpu_inst_put(inst);
return ret;
}
@@ -807,6 +812,9 @@ int vpu_v4l2_close(struct file *file)
call_void_vop(inst, release);
vpu_inst_unlock(inst);
+ v4l2_fh_del(&inst->fh, file);
+ v4l2_fh_exit(&inst->fh);
+
vpu_inst_unregister(inst);
vpu_inst_put(inst);
diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h
index 56f2939fa84d..4a87b06ae520 100644
--- a/drivers/media/platform/amphion/vpu_v4l2.h
+++ b/drivers/media/platform/amphion/vpu_v4l2.h
@@ -26,15 +26,12 @@ void vpu_skip_frame(struct vpu_inst *inst, int count);
struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
void vpu_v4l2_set_error(struct vpu_inst *inst);
-int vpu_notify_eos(struct vpu_inst *inst);
int vpu_notify_source_change(struct vpu_inst *inst);
int vpu_set_last_buffer_dequeued(struct vpu_inst *inst, bool eos);
-void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state);
int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
bool vpu_is_source_empty(struct vpu_inst *inst);
dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
-unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
{
if (V4L2_TYPE_IS_OUTPUT(type))
@@ -43,11 +40,6 @@ static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
return &inst->cap_format;
}
-static inline char *vpu_type_name(u32 type)
-{
- return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
-}
-
static inline int vpu_vb_is_codecconfig(struct vb2_v4l2_buffer *vbuf)
{
#ifdef V4L2_BUF_FLAG_CODECCONFIG
diff --git a/drivers/media/platform/aspeed/aspeed-video.c b/drivers/media/platform/aspeed/aspeed-video.c
index 54cae0da9aca..b83e43245277 100644
--- a/drivers/media/platform/aspeed/aspeed-video.c
+++ b/drivers/media/platform/aspeed/aspeed-video.c
@@ -4,6 +4,7 @@
#include <linux/atomic.h>
#include <linux/bitfield.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -25,6 +26,8 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/ktime.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
@@ -203,6 +206,25 @@
#define VE_MEM_RESTRICT_START 0x310
#define VE_MEM_RESTRICT_END 0x314
+/* SCU's registers */
+#define SCU_MISC_CTRL 0xC0
+#define SCU_DPLL_SOURCE BIT(20)
+
+/* GFX's registers */
+#define GFX_CTRL 0x60
+#define GFX_CTRL_ENABLE BIT(0)
+#define GFX_CTRL_FMT GENMASK(9, 7)
+
+#define GFX_H_DISPLAY 0x70
+#define GFX_H_DISPLAY_DE GENMASK(28, 16)
+#define GFX_H_DISPLAY_TOTAL GENMASK(12, 0)
+
+#define GFX_V_DISPLAY 0x78
+#define GFX_V_DISPLAY_DE GENMASK(27, 16)
+#define GFX_V_DISPLAY_TOTAL GENMASK(11, 0)
+
+#define GFX_DISPLAY_ADDR 0x80
+
/*
* VIDEO_MODE_DETECT_DONE: a flag raised if signal lock
* VIDEO_RES_CHANGE: a flag raised if res_change work on-going
@@ -262,6 +284,7 @@ struct aspeed_video_perf {
/*
* struct aspeed_video - driver data
*
+ * version: holds the version of aspeed SoC
* res_work: holds the delayed_work for res-detection if unlock
* buffers: holds the list of buffer queued from user
* flags: holds the state of video
@@ -273,6 +296,7 @@ struct aspeed_video_perf {
* yuv420: a flag raised if JPEG subsampling is 420
* format: holds the video format
* hq_mode: a flag raised if HQ is enabled. Only for VIDEO_FMT_ASPEED
+ * input: holds the video input
* frame_rate: holds the frame_rate
* jpeg_quality: holds jpeq's quality (0~11)
* jpeg_hq_quality: holds hq's quality (1~12) only if hq_mode enabled
@@ -298,6 +322,9 @@ struct aspeed_video {
struct video_device vdev;
struct mutex video_lock; /* v4l2 and videobuf2 lock */
+ struct regmap *scu;
+ struct regmap *gfx;
+ u32 version;
u32 jpeg_mode;
u32 comp_size_read;
@@ -316,6 +343,7 @@ struct aspeed_video {
bool yuv420;
enum aspeed_video_format format;
bool hq_mode;
+ enum aspeed_video_input input;
unsigned int frame_rate;
unsigned int jpeg_quality;
unsigned int jpeg_hq_quality;
@@ -331,21 +359,25 @@ struct aspeed_video {
#define to_aspeed_video(x) container_of((x), struct aspeed_video, v4l2_dev)
struct aspeed_video_config {
+ u32 version;
u32 jpeg_mode;
u32 comp_size_read;
};
static const struct aspeed_video_config ast2400_config = {
+ .version = 4,
.jpeg_mode = AST2400_VE_SEQ_CTRL_JPEG_MODE,
.comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
};
static const struct aspeed_video_config ast2500_config = {
+ .version = 5,
.jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
.comp_size_read = AST2400_VE_COMP_SIZE_READ_BACK,
};
static const struct aspeed_video_config ast2600_config = {
+ .version = 6,
.jpeg_mode = AST2500_VE_SEQ_CTRL_JPEG_MODE,
.comp_size_read = AST2600_VE_COMP_SIZE_READ_BACK,
};
@@ -485,6 +517,7 @@ static const struct v4l2_dv_timings_cap aspeed_video_timings_cap = {
static const char * const format_str[] = {"Standard JPEG",
"Aspeed JPEG"};
+static const char * const input_str[] = {"HOST VGA", "BMC GFX"};
static unsigned int debug;
@@ -609,6 +642,14 @@ static int aspeed_video_start_frame(struct aspeed_video *video)
aspeed_video_free_buf(video, &video->bcd);
}
+ if (video->input == VIDEO_INPUT_GFX) {
+ u32 val;
+
+ // update input buffer address as gfx's
+ regmap_read(video->gfx, GFX_DISPLAY_ADDR, &val);
+ aspeed_video_write(video, VE_TGS_0, val);
+ }
+
spin_lock_irqsave(&video->lock, flags);
buf = list_first_entry_or_null(&video->buffers,
struct aspeed_video_buffer, link);
@@ -1026,9 +1067,23 @@ static void aspeed_video_get_timings(struct aspeed_video *v,
}
}
+static void aspeed_video_get_resolution_gfx(struct aspeed_video *video,
+ struct v4l2_bt_timings *det)
+{
+ u32 h_val, v_val;
+
+ regmap_read(video->gfx, GFX_H_DISPLAY, &h_val);
+ regmap_read(video->gfx, GFX_V_DISPLAY, &v_val);
+
+ det->width = FIELD_GET(GFX_H_DISPLAY_DE, h_val) + 1;
+ det->height = FIELD_GET(GFX_V_DISPLAY_DE, v_val) + 1;
+ video->v4l2_input_status = 0;
+}
+
#define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
-static void aspeed_video_get_resolution(struct aspeed_video *video)
+static void aspeed_video_get_resolution_vga(struct aspeed_video *video,
+ struct v4l2_bt_timings *det)
{
bool invalid_resolution = true;
int rc;
@@ -1036,7 +1091,6 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
u32 mds;
u32 src_lr_edge;
u32 src_tb_edge;
- struct v4l2_bt_timings *det = &video->detected_timings;
det->width = MIN_WIDTH;
det->height = MIN_HEIGHT;
@@ -1113,14 +1167,20 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
aspeed_video_get_timings(video, det);
- /*
- * Enable mode-detect watchdog, resolution-change watchdog and
- * automatic compression after frame capture.
- */
+ /* Enable mode-detect watchdog, resolution-change watchdog */
aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
VE_INTERRUPT_MODE_DETECT_WD);
- aspeed_video_update(video, VE_SEQ_CTRL, 0,
- VE_SEQ_CTRL_AUTO_COMP | VE_SEQ_CTRL_EN_WATCHDOG);
+ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_EN_WATCHDOG);
+}
+
+static void aspeed_video_get_resolution(struct aspeed_video *video)
+{
+ struct v4l2_bt_timings *det = &video->detected_timings;
+
+ if (video->input == VIDEO_INPUT_GFX)
+ aspeed_video_get_resolution_gfx(video, det);
+ else
+ aspeed_video_get_resolution_vga(video, det);
v4l2_dbg(1, debug, &video->v4l2_dev, "Got resolution: %dx%d\n",
det->width, det->height);
@@ -1156,7 +1216,7 @@ static void aspeed_video_set_resolution(struct aspeed_video *video)
aspeed_video_write(video, VE_SRC_SCANLINE_OFFSET, act->width * 4);
/* Don't use direct mode below 1024 x 768 (irqs don't fire) */
- if (size < DIRECT_FETCH_THRESHOLD) {
+ if (video->input == VIDEO_INPUT_VGA && size < DIRECT_FETCH_THRESHOLD) {
v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Sync Mode\n");
aspeed_video_write(video, VE_TGS_0,
FIELD_PREP(VE_TGS_FIRST,
@@ -1171,10 +1231,20 @@ static void aspeed_video_set_resolution(struct aspeed_video *video)
VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH,
VE_CTRL_INT_DE);
} else {
+ u32 ctrl, val, bpp;
+
v4l2_dbg(1, debug, &video->v4l2_dev, "Capture: Direct Mode\n");
+ ctrl = VE_CTRL_DIRECT_FETCH;
+ if (video->input == VIDEO_INPUT_GFX) {
+ regmap_read(video->gfx, GFX_CTRL, &val);
+ bpp = FIELD_GET(GFX_CTRL_FMT, val) ? 32 : 16;
+ if (bpp == 16)
+ ctrl |= VE_CTRL_INT_DE;
+ aspeed_video_write(video, VE_TGS_1, act->width * (bpp >> 3));
+ }
aspeed_video_update(video, VE_CTRL,
VE_CTRL_INT_DE | VE_CTRL_DIRECT_FETCH,
- VE_CTRL_DIRECT_FETCH);
+ ctrl);
}
size *= 4;
@@ -1207,6 +1277,22 @@ err_mem:
aspeed_video_free_buf(video, &video->srcs[0]);
}
+/*
+ * Update relative parameters when timing changed.
+ *
+ * @video: the struct of aspeed_video
+ * @timings: the new timings
+ */
+static void aspeed_video_update_timings(struct aspeed_video *video, struct v4l2_bt_timings *timings)
+{
+ video->active_timings = *timings;
+ aspeed_video_set_resolution(video);
+
+ video->pix_fmt.width = timings->width;
+ video->pix_fmt.height = timings->height;
+ video->pix_fmt.sizeimage = video->max_compressed_size;
+}
+
static void aspeed_video_update_regs(struct aspeed_video *video)
{
u8 jpeg_hq_quality = clamp((int)video->jpeg_hq_quality - 1, 0,
@@ -1219,6 +1305,8 @@ static void aspeed_video_update_regs(struct aspeed_video *video)
u32 ctrl = 0;
u32 seq_ctrl = 0;
+ v4l2_dbg(1, debug, &video->v4l2_dev, "input(%s)\n",
+ input_str[video->input]);
v4l2_dbg(1, debug, &video->v4l2_dev, "framerate(%d)\n",
video->frame_rate);
v4l2_dbg(1, debug, &video->v4l2_dev, "jpeg format(%s) subsample(%s)\n",
@@ -1234,6 +1322,9 @@ static void aspeed_video_update_regs(struct aspeed_video *video)
else
aspeed_video_update(video, VE_BCD_CTRL, VE_BCD_CTRL_EN_BCD, 0);
+ if (video->input == VIDEO_INPUT_VGA)
+ ctrl |= VE_CTRL_AUTO_OR_CURSOR;
+
if (video->frame_rate)
ctrl |= FIELD_PREP(VE_CTRL_FRC, video->frame_rate);
@@ -1252,7 +1343,9 @@ static void aspeed_video_update_regs(struct aspeed_video *video)
aspeed_video_update(video, VE_SEQ_CTRL,
video->jpeg_mode | VE_SEQ_CTRL_YUV420,
seq_ctrl);
- aspeed_video_update(video, VE_CTRL, VE_CTRL_FRC, ctrl);
+ aspeed_video_update(video, VE_CTRL,
+ VE_CTRL_FRC | VE_CTRL_AUTO_OR_CURSOR |
+ VE_CTRL_SOURCE, ctrl);
aspeed_video_update(video, VE_COMP_CTRL,
VE_COMP_CTRL_DCT_LUM | VE_COMP_CTRL_DCT_CHR |
VE_COMP_CTRL_EN_HQ | VE_COMP_CTRL_HQ_DCT_LUM |
@@ -1280,6 +1373,7 @@ static void aspeed_video_init_regs(struct aspeed_video *video)
aspeed_video_write(video, VE_JPEG_ADDR, video->jpeg.dma);
/* Set control registers */
+ aspeed_video_write(video, VE_SEQ_CTRL, VE_SEQ_CTRL_AUTO_COMP);
aspeed_video_write(video, VE_CTRL, ctrl);
aspeed_video_write(video, VE_COMP_CTRL, VE_COMP_CTRL_RSVD);
@@ -1311,12 +1405,7 @@ static void aspeed_video_start(struct aspeed_video *video)
aspeed_video_get_resolution(video);
/* Set timings since the device is being opened for the first time */
- video->active_timings = video->detected_timings;
- aspeed_video_set_resolution(video);
-
- video->pix_fmt.width = video->active_timings.width;
- video->pix_fmt.height = video->active_timings.height;
- video->pix_fmt.sizeimage = video->max_compressed_size;
+ aspeed_video_update_timings(video, &video->detected_timings);
}
static void aspeed_video_stop(struct aspeed_video *video)
@@ -1401,10 +1490,10 @@ static int aspeed_video_enum_input(struct file *file, void *fh,
{
struct aspeed_video *video = video_drvdata(file);
- if (inp->index)
+ if (inp->index >= VIDEO_INPUT_MAX)
return -EINVAL;
- strscpy(inp->name, "Host VGA capture", sizeof(inp->name));
+ sprintf(inp->name, "%s capture", input_str[inp->index]);
inp->type = V4L2_INPUT_TYPE_CAMERA;
inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
inp->status = video->v4l2_input_status;
@@ -1414,16 +1503,57 @@ static int aspeed_video_enum_input(struct file *file, void *fh,
static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
{
- *i = 0;
+ struct aspeed_video *video = video_drvdata(file);
+
+ *i = video->input;
return 0;
}
static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
{
- if (i)
+ struct aspeed_video *video = video_drvdata(file);
+
+ if (i >= VIDEO_INPUT_MAX)
return -EINVAL;
+ if (i == video->input)
+ return 0;
+
+ if (vb2_is_busy(&video->queue))
+ return -EBUSY;
+
+ if (IS_ERR(video->scu)) {
+ v4l2_dbg(1, debug, &video->v4l2_dev,
+ "%s: scu isn't ready for input-control\n", __func__);
+ return -EINVAL;
+ }
+
+ if (IS_ERR(video->gfx) && i == VIDEO_INPUT_GFX) {
+ v4l2_dbg(1, debug, &video->v4l2_dev,
+ "%s: gfx isn't ready for GFX input\n", __func__);
+ return -EINVAL;
+ }
+
+ video->input = i;
+
+ if (video->version == 6) {
+ /* modify dpll source per current input */
+ if (video->input == VIDEO_INPUT_VGA)
+ regmap_update_bits(video->scu, SCU_MISC_CTRL,
+ SCU_DPLL_SOURCE, 0);
+ else
+ regmap_update_bits(video->scu, SCU_MISC_CTRL,
+ SCU_DPLL_SOURCE, SCU_DPLL_SOURCE);
+ }
+
+ aspeed_video_update_regs(video);
+
+ /* update signal status */
+ aspeed_video_get_resolution(video);
+ if (!video->v4l2_input_status)
+ aspeed_video_update_timings(video, &video->detected_timings);
+
return 0;
}
@@ -1527,13 +1657,7 @@ static int aspeed_video_set_dv_timings(struct file *file, void *fh,
if (vb2_is_busy(&video->queue))
return -EBUSY;
- video->active_timings = timings->bt;
-
- aspeed_video_set_resolution(video);
-
- video->pix_fmt.width = timings->bt.width;
- video->pix_fmt.height = timings->bt.height;
- video->pix_fmt.sizeimage = video->max_compressed_size;
+ aspeed_video_update_timings(video, &timings->bt);
timings->type = V4L2_DV_BT_656_1120;
@@ -1909,6 +2033,7 @@ static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
val08 = aspeed_video_read(v, VE_CTRL);
if (FIELD_GET(VE_CTRL_DIRECT_FETCH, val08)) {
seq_printf(s, " %-20s:\tDirect fetch\n", "Mode");
+ seq_printf(s, " %-20s:\t%s\n", "Input", input_str[v->input]);
seq_printf(s, " %-20s:\t%s\n", "VGA bpp mode",
FIELD_GET(VE_CTRL_INT_DE, val08) ? "16" : "32");
} else {
@@ -2068,12 +2193,29 @@ static int aspeed_video_setup_video(struct aspeed_video *video)
return 0;
}
+/*
+ * Get regmap without checking res, such as clk/reset, that could lead to
+ * conflict.
+ */
+static struct regmap *aspeed_regmap_lookup(struct device_node *np, const char *property)
+{
+ struct device_node *syscon_np __free(device_node) = of_parse_phandle(np, property, 0);
+
+ if (!syscon_np)
+ return ERR_PTR(-ENODEV);
+
+ return device_node_to_regmap(syscon_np);
+}
+
static int aspeed_video_init(struct aspeed_video *video)
{
int irq;
int rc;
struct device *dev = video->dev;
+ video->scu = aspeed_regmap_lookup(dev->of_node, "aspeed,scu");
+ video->gfx = aspeed_regmap_lookup(dev->of_node, "aspeed,gfx");
+
irq = irq_of_parse_and_map(dev->of_node, 0);
if (!irq) {
dev_err(dev, "Unable to find IRQ\n");
@@ -2165,6 +2307,7 @@ static int aspeed_video_probe(struct platform_device *pdev)
if (!config)
return -ENODEV;
+ video->version = config->version;
video->jpeg_mode = config->jpeg_mode;
video->comp_size_read = config->comp_size_read;
diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 7f1ce95cdc3f..8c19f125da3e 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -5,8 +5,10 @@
* Copyright (C) 2017 Cadence Design Systems Inc.
*/
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/export.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
@@ -17,6 +19,7 @@
#include <linux/reset.h>
#include <linux/slab.h>
+#include <media/cadence/cdns-csi2rx.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -52,7 +55,9 @@
#define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n) BIT((n) + 16)
#define CSI2RX_STREAM_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x00c)
-#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF (1 << 8)
+#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF BIT(8)
+#define CSI2RX_STREAM_CFG_NUM_PIXELS_MASK GENMASK(5, 4)
+#define CSI2RX_STREAM_CFG_NUM_PIXELS(n) ((n) >> 1U)
#define CSI2RX_LANES_MAX 4
#define CSI2RX_STREAMS_MAX 4
@@ -87,7 +92,10 @@ enum csi2rx_pads {
struct csi2rx_fmt {
u32 code;
+ /* width of a single pixel on CSI-2 bus */
u8 bpp;
+ /* max pixels per clock supported on output bus */
+ u8 max_pixels;
};
struct csi2rx_event {
@@ -132,6 +140,7 @@ struct csi2rx_priv {
struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX];
struct phy *dphy;
+ u8 num_pixels[CSI2RX_STREAMS_MAX];
u8 lanes[CSI2RX_LANES_MAX];
u8 num_lanes;
u8 max_lanes;
@@ -149,22 +158,22 @@ struct csi2rx_priv {
};
static const struct csi2rx_fmt formats[] = {
- { .code = MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, },
- { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, },
- { .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, },
- { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, },
- { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },
+ { .code = MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, .max_pixels = 4, },
+ { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, .max_pixels = 2, },
+ { .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, .max_pixels = 1, },
+ { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, .max_pixels = 1, },
+ { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, .max_pixels = 1, },
};
static void csi2rx_configure_error_irq_mask(void __iomem *base,
@@ -370,7 +379,9 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
reset_control_deassert(csi2rx->pixel_rst[i]);
- writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
+ writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF |
+ FIELD_PREP(CSI2RX_STREAM_CFG_NUM_PIXELS_MASK,
+ csi2rx->num_pixels[i]),
csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
/*
@@ -569,6 +580,33 @@ static int csi2rx_init_state(struct v4l2_subdev *subdev,
return csi2rx_set_fmt(subdev, state, &format);
}
+int cdns_csi2rx_negotiate_ppc(struct v4l2_subdev *subdev, unsigned int pad,
+ u8 *ppc)
+{
+ struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
+ const struct csi2rx_fmt *csi_fmt;
+ struct v4l2_subdev_state *state;
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (!ppc || pad < CSI2RX_PAD_SOURCE_STREAM0 || pad >= CSI2RX_PAD_MAX)
+ return -EINVAL;
+
+ state = v4l2_subdev_lock_and_get_active_state(subdev);
+ fmt = v4l2_subdev_state_get_format(state, pad);
+ csi_fmt = csi2rx_get_fmt_by_code(fmt->code);
+
+ /* Reduce requested PPC if it is too high */
+ *ppc = min(*ppc, csi_fmt->max_pixels);
+
+ v4l2_subdev_unlock_state(state);
+
+ csi2rx->num_pixels[pad - CSI2RX_PAD_SOURCE_STREAM0] =
+ CSI2RX_STREAM_CFG_NUM_PIXELS(*ppc);
+
+ return 0;
+}
+EXPORT_SYMBOL_FOR_MODULES(cdns_csi2rx_negotiate_ppc, "j721e-csi2rx");
+
static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
.enum_mbus_code = csi2rx_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
@@ -595,6 +633,7 @@ static const struct v4l2_subdev_internal_ops csi2rx_internal_ops = {
static const struct media_entity_operations csi2rx_media_ops = {
.link_validate = v4l2_subdev_link_validate,
+ .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
};
static int csi2rx_async_bound(struct v4l2_async_notifier *notifier,
diff --git a/drivers/media/platform/chips-media/coda/coda-common.c b/drivers/media/platform/chips-media/coda/coda-common.c
index e6e3f5ec24f6..9a57b042d9fd 100644
--- a/drivers/media/platform/chips-media/coda/coda-common.c
+++ b/drivers/media/platform/chips-media/coda/coda-common.c
@@ -56,6 +56,11 @@
#define fh_to_ctx(__fh) container_of(__fh, struct coda_ctx, fh)
+static inline struct coda_ctx *file_to_ctx(struct file *filp)
+{
+ return fh_to_ctx(file_to_v4l2_fh(filp));
+}
+
int coda_debug;
module_param(coda_debug, int, 0644);
MODULE_PARM_DESC(coda_debug, "Debug level (0-2)");
@@ -422,7 +427,7 @@ out:
static int coda_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
strscpy(cap->driver, CODA_NAME, sizeof(cap->driver));
strscpy(cap->card, coda_product_name(ctx->dev->devtype->product),
@@ -442,7 +447,7 @@ static int coda_enum_fmt(struct file *file, void *priv,
{
struct video_device *vdev = video_devdata(file);
const struct coda_video_device *cvd = to_coda_video_device(vdev);
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
const u32 *formats;
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -492,7 +497,7 @@ static int coda_g_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
struct coda_q_data *q_data;
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
q_data = get_q_data(ctx, f->type);
if (!q_data)
@@ -653,7 +658,7 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec,
static int coda_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
const struct coda_q_data *q_data_src;
const struct coda_codec *codec;
struct vb2_queue *src_vq;
@@ -759,7 +764,7 @@ static void coda_set_default_colorspace(struct v4l2_pix_format *fmt)
static int coda_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_dev *dev = ctx->dev;
const struct coda_q_data *q_data_dst;
const struct coda_codec *codec;
@@ -853,7 +858,7 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
static int coda_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_q_data *q_data_src;
const struct coda_codec *codec;
struct v4l2_rect r;
@@ -905,7 +910,7 @@ static int coda_s_fmt_vid_cap(struct file *file, void *priv,
static int coda_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
const struct coda_codec *codec;
struct v4l2_format f_cap;
struct vb2_queue *dst_vq;
@@ -961,7 +966,7 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv,
static int coda_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *rb)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
int ret;
ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb);
@@ -981,7 +986,7 @@ static int coda_reqbufs(struct file *file, void *priv,
static int coda_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
if (ctx->inst_type == CODA_INST_DECODER &&
buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -992,7 +997,7 @@ static int coda_qbuf(struct file *file, void *priv,
static int coda_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = file_to_ctx(file);
int ret;
ret = v4l2_m2m_dqbuf(file, ctx->fh.m2m_ctx, buf);
@@ -1020,7 +1025,7 @@ void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
static int coda_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_q_data *q_data;
struct v4l2_rect r, *rsel;
@@ -1066,7 +1071,7 @@ static int coda_g_selection(struct file *file, void *fh,
static int coda_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_q_data *q_data;
switch (s->target) {
@@ -1121,7 +1126,7 @@ static void coda_wake_up_capture_queue(struct coda_ctx *ctx)
static int coda_encoder_cmd(struct file *file, void *fh,
struct v4l2_encoder_cmd *ec)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct vb2_v4l2_buffer *buf;
int ret;
@@ -1202,7 +1207,7 @@ static bool coda_mark_last_dst_buf(struct coda_ctx *ctx)
static int coda_decoder_cmd(struct file *file, void *fh,
struct v4l2_decoder_cmd *dc)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_dev *dev = ctx->dev;
struct vb2_v4l2_buffer *buf;
struct vb2_queue *dst_vq;
@@ -1281,7 +1286,7 @@ static int coda_decoder_cmd(struct file *file, void *fh,
static int coda_enum_framesizes(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_q_data *q_data_dst;
const struct coda_codec *codec;
@@ -1314,7 +1319,7 @@ static int coda_enum_framesizes(struct file *file, void *fh,
static int coda_enum_frameintervals(struct file *file, void *fh,
struct v4l2_frmivalenum *f)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct coda_q_data *q_data;
const struct coda_codec *codec;
@@ -1353,7 +1358,7 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
static int coda_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct v4l2_fract *tpf;
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -1436,7 +1441,7 @@ static uint32_t coda_timeperframe_to_frate(struct v4l2_fract *timeperframe)
static int coda_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
{
- struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_ctx *ctx = file_to_ctx(file);
struct v4l2_fract *tpf;
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -2637,8 +2642,7 @@ static int coda_open(struct file *file)
if (ctx->ops->seq_end_work)
INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->dev = dev;
ctx->idx = idx;
@@ -2721,7 +2725,7 @@ err_clk_ahb:
err_clk_enable:
pm_runtime_put_sync(dev->dev);
err_pm_get:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
err_coda_name_init:
ida_free(&dev->ida, ctx->idx);
@@ -2733,7 +2737,7 @@ err_coda_max:
static int coda_release(struct file *file)
{
struct coda_dev *dev = video_drvdata(file);
- struct coda_ctx *ctx = fh_to_ctx(file->private_data);
+ struct coda_ctx *ctx = file_to_ctx(file);
coda_dbg(1, ctx, "release instance (%p)\n", ctx);
@@ -2759,7 +2763,7 @@ static int coda_release(struct file *file)
clk_disable_unprepare(dev->clk_ahb);
clk_disable_unprepare(dev->clk_per);
pm_runtime_put_sync(dev->dev);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
ida_free(&dev->ida, ctx->idx);
if (ctx->ops->release)
diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.c b/drivers/media/platform/chips-media/wave5/wave5-helper.c
index 2c9d8cbca6e4..f03ad9c0de22 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-helper.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-helper.c
@@ -27,7 +27,7 @@ const char *state_to_str(enum vpu_instance_state state)
}
}
-void wave5_cleanup_instance(struct vpu_instance *inst)
+void wave5_cleanup_instance(struct vpu_instance *inst, struct file *filp)
{
int i;
@@ -46,7 +46,7 @@ void wave5_cleanup_instance(struct vpu_instance *inst)
wave5_vdi_free_dma_memory(inst->dev, &inst->bitstream_vbuf);
v4l2_ctrl_handler_free(&inst->v4l2_ctrl_hdl);
if (inst->v4l2_fh.vdev) {
- v4l2_fh_del(&inst->v4l2_fh);
+ v4l2_fh_del(&inst->v4l2_fh, filp);
v4l2_fh_exit(&inst->v4l2_fh);
}
list_del_init(&inst->list);
@@ -59,7 +59,7 @@ int wave5_vpu_release_device(struct file *filp,
int (*close_func)(struct vpu_instance *inst, u32 *fail_res),
char *name)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(filp->private_data);
+ struct vpu_instance *inst = file_to_vpu_inst(filp);
int ret = 0;
v4l2_m2m_ctx_release(inst->v4l2_fh.m2m_ctx);
@@ -78,7 +78,7 @@ int wave5_vpu_release_device(struct file *filp,
}
}
- wave5_cleanup_instance(inst);
+ wave5_cleanup_instance(inst, filp);
return ret;
}
@@ -142,7 +142,7 @@ int wave5_vpu_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscr
int wave5_vpu_g_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
int i;
f->fmt.pix_mp.width = inst->src_fmt.width;
diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.h b/drivers/media/platform/chips-media/wave5/wave5-helper.h
index 9937fce553fc..976a402e426f 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-helper.h
+++ b/drivers/media/platform/chips-media/wave5/wave5-helper.h
@@ -14,7 +14,7 @@
#define MAX_FMTS 12
const char *state_to_str(enum vpu_instance_state state);
-void wave5_cleanup_instance(struct vpu_instance *inst);
+void wave5_cleanup_instance(struct vpu_instance *inst, struct file *filp);
int wave5_vpu_release_device(struct file *filp,
int (*close_func)(struct vpu_instance *inst, u32 *fail_res),
char *name);
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index a9ce032cc5a2..e3038c18ca36 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -505,7 +505,7 @@ static int wave5_vpu_dec_enum_fmt_cap(struct file *file, void *fh, struct v4l2_f
static int wave5_vpu_dec_try_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
struct dec_info *p_dec_info = &inst->codec_info->dec_info;
const struct v4l2_frmsize_stepwise *frmsize;
const struct vpu_format *vpu_fmt;
@@ -546,7 +546,7 @@ static int wave5_vpu_dec_try_fmt_cap(struct file *file, void *fh, struct v4l2_fo
static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
int i, ret;
dev_dbg(inst->dev->dev,
@@ -605,7 +605,7 @@ static int wave5_vpu_dec_s_fmt_cap(struct file *file, void *fh, struct v4l2_form
static int wave5_vpu_dec_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
int i;
f->fmt.pix_mp.width = inst->dst_fmt.width;
@@ -629,7 +629,7 @@ static int wave5_vpu_dec_g_fmt_cap(struct file *file, void *fh, struct v4l2_form
static int wave5_vpu_dec_enum_fmt_out(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct vpu_format *vpu_fmt;
dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index);
@@ -646,7 +646,7 @@ static int wave5_vpu_dec_enum_fmt_out(struct file *file, void *fh, struct v4l2_f
static int wave5_vpu_dec_try_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct v4l2_frmsize_stepwise *frmsize;
const struct vpu_format *vpu_fmt;
int width, height;
@@ -677,7 +677,7 @@ static int wave5_vpu_dec_try_fmt_out(struct file *file, void *fh, struct v4l2_fo
static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct vpu_format *vpu_fmt;
int i, ret;
@@ -726,7 +726,7 @@ static int wave5_vpu_dec_s_fmt_out(struct file *file, void *fh, struct v4l2_form
static int wave5_vpu_dec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
dev_dbg(inst->dev->dev, "%s: type: %u | target: %u\n", __func__, s->type, s->target);
@@ -760,7 +760,7 @@ static int wave5_vpu_dec_g_selection(struct file *file, void *fh, struct v4l2_se
static int wave5_vpu_dec_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -871,7 +871,7 @@ unlock_and_return:
static int wave5_vpu_dec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dc)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
int ret;
@@ -1757,8 +1757,7 @@ static int wave5_vpu_open_dec(struct file *filp)
return -ENOMEM;
v4l2_fh_init(&inst->v4l2_fh, vdev);
- filp->private_data = &inst->v4l2_fh;
- v4l2_fh_add(&inst->v4l2_fh);
+ v4l2_fh_add(&inst->v4l2_fh, filp);
INIT_LIST_HEAD(&inst->list);
@@ -1836,7 +1835,7 @@ static int wave5_vpu_open_dec(struct file *filp)
return 0;
cleanup_inst:
- wave5_cleanup_instance(inst);
+ wave5_cleanup_instance(inst, filp);
return ret;
}
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
index 35913a7de834..9bfaa9fb3ceb 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
@@ -360,7 +360,7 @@ static int wave5_vpu_enc_enum_framesizes(struct file *f, void *fh, struct v4l2_f
static int wave5_vpu_enc_enum_fmt_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct vpu_format *vpu_fmt;
dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index);
@@ -377,7 +377,7 @@ static int wave5_vpu_enc_enum_fmt_cap(struct file *file, void *fh, struct v4l2_f
static int wave5_vpu_enc_try_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct v4l2_frmsize_stepwise *frmsize;
const struct vpu_format *vpu_fmt;
int width, height;
@@ -411,7 +411,7 @@ static int wave5_vpu_enc_try_fmt_cap(struct file *file, void *fh, struct v4l2_fo
static int wave5_vpu_enc_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
int i, ret;
dev_dbg(inst->dev->dev, "%s: fourcc: %u width: %u height: %u num_planes: %u field: %u\n",
@@ -445,7 +445,7 @@ static int wave5_vpu_enc_s_fmt_cap(struct file *file, void *fh, struct v4l2_form
static int wave5_vpu_enc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
int i;
f->fmt.pix_mp.width = inst->dst_fmt.width;
@@ -469,7 +469,7 @@ static int wave5_vpu_enc_g_fmt_cap(struct file *file, void *fh, struct v4l2_form
static int wave5_vpu_enc_enum_fmt_out(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct vpu_format *vpu_fmt;
dev_dbg(inst->dev->dev, "%s: index: %u\n", __func__, f->index);
@@ -486,7 +486,7 @@ static int wave5_vpu_enc_enum_fmt_out(struct file *file, void *fh, struct v4l2_f
static int wave5_vpu_enc_try_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct v4l2_frmsize_stepwise *frmsize;
const struct vpu_format *vpu_fmt;
int width, height;
@@ -515,7 +515,7 @@ static int wave5_vpu_enc_try_fmt_out(struct file *file, void *fh, struct v4l2_fo
static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
const struct vpu_format *vpu_fmt;
const struct v4l2_format_info *info;
int i, ret;
@@ -543,7 +543,7 @@ static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_form
if (!info)
return -EINVAL;
- inst->cbcr_interleave = (info->comp_planes == 2) ? true : false;
+ inst->cbcr_interleave = info->comp_planes == 2;
switch (inst->src_fmt.pixelformat) {
case V4L2_PIX_FMT_NV21:
@@ -576,7 +576,7 @@ static int wave5_vpu_enc_s_fmt_out(struct file *file, void *fh, struct v4l2_form
static int wave5_vpu_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
dev_dbg(inst->dev->dev, "%s: type: %u | target: %u\n", __func__, s->type, s->target);
@@ -605,7 +605,7 @@ static int wave5_vpu_enc_g_selection(struct file *file, void *fh, struct v4l2_se
static int wave5_vpu_enc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
@@ -628,7 +628,7 @@ static int wave5_vpu_enc_s_selection(struct file *file, void *fh, struct v4l2_se
static int wave5_vpu_enc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *ec)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
int ret;
@@ -661,7 +661,7 @@ static int wave5_vpu_enc_encoder_cmd(struct file *file, void *fh, struct v4l2_en
static int wave5_vpu_enc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, a->type);
@@ -681,7 +681,7 @@ static int wave5_vpu_enc_g_parm(struct file *file, void *fh, struct v4l2_streamp
static int wave5_vpu_enc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
{
- struct vpu_instance *inst = wave5_to_vpu_inst(fh);
+ struct vpu_instance *inst = file_to_vpu_inst(file);
dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, a->type);
@@ -1582,8 +1582,7 @@ static int wave5_vpu_open_enc(struct file *filp)
return -ENOMEM;
v4l2_fh_init(&inst->v4l2_fh, vdev);
- filp->private_data = &inst->v4l2_fh;
- v4l2_fh_add(&inst->v4l2_fh);
+ v4l2_fh_add(&inst->v4l2_fh, filp);
INIT_LIST_HEAD(&inst->list);
@@ -1779,7 +1778,7 @@ static int wave5_vpu_open_enc(struct file *filp)
return 0;
cleanup_inst:
- wave5_cleanup_instance(inst);
+ wave5_cleanup_instance(inst, filp);
return ret;
}
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.h b/drivers/media/platform/chips-media/wave5/wave5-vpu.h
index 3847332551fc..5943bdaa9c4c 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.h
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.h
@@ -46,6 +46,11 @@ static inline struct vpu_instance *wave5_to_vpu_inst(struct v4l2_fh *vfh)
return container_of(vfh, struct vpu_instance, v4l2_fh);
}
+static inline struct vpu_instance *file_to_vpu_inst(struct file *filp)
+{
+ return wave5_to_vpu_inst(file_to_v4l2_fh(filp));
+}
+
static inline struct vpu_instance *wave5_ctrl_to_vpu_inst(struct v4l2_ctrl *vctrl)
{
return container_of(vctrl->handler, struct vpu_instance, v4l2_ctrl_hdl);
diff --git a/drivers/media/platform/imagination/e5010-jpeg-enc.c b/drivers/media/platform/imagination/e5010-jpeg-enc.c
index ae868d9f73e1..c4e0097cb8b7 100644
--- a/drivers/media/platform/imagination/e5010-jpeg-enc.c
+++ b/drivers/media/platform/imagination/e5010-jpeg-enc.c
@@ -253,7 +253,7 @@ static int e5010_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
{
int i, index = 0;
struct e5010_fmt *fmt = NULL;
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
v4l2_err(&ctx->e5010->v4l2_dev, "ENUMFMT with Invalid type: %d\n", f->type);
@@ -279,7 +279,7 @@ static int e5010_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
static int e5010_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
struct e5010_q_data *queue;
int i;
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
@@ -380,14 +380,14 @@ static int e5010_jpeg_try_fmt(struct v4l2_format *f, struct e5010_context *ctx)
static int e5010_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
return e5010_jpeg_try_fmt(f, ctx);
}
static int e5010_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
struct vb2_queue *vq;
int ret = 0, i = 0;
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
@@ -462,7 +462,7 @@ static int e5010_enum_framesizes(struct file *file, void *priv, struct v4l2_frms
static int e5010_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
struct e5010_q_data *queue;
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -490,7 +490,7 @@ static int e5010_g_selection(struct file *file, void *fh, struct v4l2_selection
static int e5010_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
struct e5010_q_data *queue;
struct vb2_queue *vq;
struct v4l2_rect base_rect;
@@ -742,8 +742,7 @@ static int e5010_open(struct file *file)
}
v4l2_fh_init(&ctx->fh, vdev);
- file->private_data = ctx;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->e5010 = e5010;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(e5010->m2m_dev, ctx, queue_init);
@@ -770,7 +769,7 @@ static int e5010_open(struct file *file)
err_ctrls_setup:
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
exit:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mutex_unlock(&e5010->mutex);
free:
@@ -781,13 +780,13 @@ free:
static int e5010_release(struct file *file)
{
struct e5010_dev *e5010 = video_drvdata(file);
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
dprintk(e5010, 1, "Releasing instance: 0x%p, m2m_ctx: 0x%p\n", ctx, ctx->fh.m2m_ctx);
mutex_lock(&e5010->mutex);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mutex_unlock(&e5010->mutex);
@@ -1262,7 +1261,7 @@ static void e5010_buf_queue(struct vb2_buffer *vb)
static int e5010_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *cmd)
{
- struct e5010_context *ctx = file->private_data;
+ struct e5010_context *ctx = to_e5010_context(file);
int ret;
struct vb2_queue *cap_vq;
diff --git a/drivers/media/platform/imagination/e5010-jpeg-enc.h b/drivers/media/platform/imagination/e5010-jpeg-enc.h
index 71f49ead6898..da57bc1baa46 100644
--- a/drivers/media/platform/imagination/e5010-jpeg-enc.h
+++ b/drivers/media/platform/imagination/e5010-jpeg-enc.h
@@ -120,6 +120,11 @@ struct e5010_context {
u8 chroma_qp[QP_TABLE_SIZE];
};
+static inline struct e5010_context *to_e5010_context(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct e5010_context, fh);
+}
+
/*
* Buffer structure
* Contains info for all buffers
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 5188f3189096..e07e57d4206b 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -142,6 +142,11 @@ struct deinterlace_ctx {
struct dma_interleaved_template *xt;
};
+static inline struct deinterlace_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct deinterlace_ctx, fh);
+}
+
/*
* mem2mem callbacks
*/
@@ -512,13 +517,13 @@ static int vidioc_g_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f)
static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- return vidioc_g_fmt(priv, f);
+ return vidioc_g_fmt(file_to_ctx(file), f);
}
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- return vidioc_g_fmt(priv, f);
+ return vidioc_g_fmt(file_to_ctx(file), f);
}
static int vidioc_try_fmt(struct v4l2_format *f, struct deinterlace_fmt *fmt)
@@ -539,8 +544,8 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct deinterlace_fmt *fmt)
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct deinterlace_ctx *ctx = file_to_ctx(file);
struct deinterlace_fmt *fmt;
- struct deinterlace_ctx *ctx = priv;
fmt = find_format(f);
if (!fmt || !(fmt->types & MEM2MEM_CAPTURE))
@@ -633,20 +638,20 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
ret = vidioc_try_fmt_vid_cap(file, priv, f);
if (ret)
return ret;
- return vidioc_s_fmt(priv, f);
+ return vidioc_s_fmt(file_to_ctx(file), f);
}
static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct deinterlace_ctx *ctx = priv;
+ struct deinterlace_ctx *ctx = file_to_ctx(file);
int ret;
ret = vidioc_try_fmt_vid_out(file, priv, f);
if (ret)
return ret;
- ret = vidioc_s_fmt(priv, f);
+ ret = vidioc_s_fmt(ctx, f);
if (!ret)
ctx->colorspace = f->fmt.pix.colorspace;
@@ -656,8 +661,8 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
+ struct deinterlace_ctx *ctx = file_to_ctx(file);
struct deinterlace_q_data *s_q_data, *d_q_data;
- struct deinterlace_ctx *ctx = priv;
s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
d_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
@@ -842,7 +847,6 @@ static int deinterlace_open(struct file *file)
return -ENOMEM;
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = pcdev;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
@@ -861,7 +865,7 @@ static int deinterlace_open(struct file *file)
}
ctx->colorspace = V4L2_COLORSPACE_REC709;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n",
ctx, ctx->fh.m2m_ctx);
@@ -872,11 +876,11 @@ static int deinterlace_open(struct file *file)
static int deinterlace_release(struct file *file)
{
struct deinterlace_dev *pcdev = video_drvdata(file);
- struct deinterlace_ctx *ctx = file->private_data;
+ struct deinterlace_ctx *ctx = file_to_ctx(file);
dprintk(pcdev, "Releasing instance %p\n", ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
kfree(ctx->xt);
diff --git a/drivers/media/platform/marvell/cafe-driver.c b/drivers/media/platform/marvell/cafe-driver.c
index ef810249def6..f9796de92aa7 100644
--- a/drivers/media/platform/marvell/cafe-driver.c
+++ b/drivers/media/platform/marvell/cafe-driver.c
@@ -14,7 +14,7 @@
* Written by Jonathan Corbet, corbet@lwn.net.
*
* v4l2_device/v4l2_subdev conversion by:
- * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 7eb12449b63a..6268d651bdcf 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -119,9 +119,9 @@ static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl);
}
-static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh)
+static inline struct mtk_jpeg_ctx *mtk_jpeg_file_to_ctx(struct file *filp)
{
- return container_of(fh, struct mtk_jpeg_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct mtk_jpeg_ctx, fh);
}
static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
@@ -212,7 +212,7 @@ static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
struct mtk_jpeg_dev *jpeg = ctx->jpeg;
return mtk_jpeg_enum_fmt(jpeg->variant->formats,
@@ -223,7 +223,7 @@ static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
struct mtk_jpeg_dev *jpeg = ctx->jpeg;
return mtk_jpeg_enum_fmt(jpeg->variant->formats,
@@ -305,7 +305,7 @@ static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
struct vb2_queue *vq;
struct mtk_jpeg_q_data *q_data = NULL;
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
struct mtk_jpeg_dev *jpeg = ctx->jpeg;
int i;
@@ -351,7 +351,7 @@ static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
struct mtk_jpeg_dev *jpeg = ctx->jpeg;
struct mtk_jpeg_fmt *fmt;
@@ -380,7 +380,7 @@ static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
struct mtk_jpeg_dev *jpeg = ctx->jpeg;
struct mtk_jpeg_fmt *fmt;
@@ -470,7 +470,7 @@ static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
if (ret)
return ret;
- return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f,
+ return mtk_jpeg_s_fmt_mplane(mtk_jpeg_file_to_ctx(file), f,
MTK_JPEG_FMT_FLAG_OUTPUT);
}
@@ -483,7 +483,7 @@ static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
if (ret)
return ret;
- return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f,
+ return mtk_jpeg_s_fmt_mplane(mtk_jpeg_file_to_ctx(file), f,
MTK_JPEG_FMT_FLAG_CAPTURE);
}
@@ -512,7 +512,7 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
static int mtk_jpeg_enc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
@@ -537,7 +537,7 @@ static int mtk_jpeg_enc_g_selection(struct file *file, void *priv,
static int mtk_jpeg_dec_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -566,7 +566,7 @@ static int mtk_jpeg_dec_g_selection(struct file *file, void *priv,
static int mtk_jpeg_enc_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
@@ -588,8 +588,8 @@ static int mtk_jpeg_enc_s_selection(struct file *file, void *priv,
static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct v4l2_fh *fh = file->private_data;
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
struct vb2_queue *vq;
struct vb2_buffer *vb;
struct mtk_jpeg_src_buf *jpeg_src_buf;
@@ -1171,8 +1171,7 @@ static int mtk_jpeg_open(struct file *file)
INIT_LIST_HEAD(&ctx->dst_done_queue);
spin_lock_init(&ctx->done_queue_lock);
v4l2_fh_init(&ctx->fh, vfd);
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->jpeg = jpeg;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx,
@@ -1197,7 +1196,7 @@ static int mtk_jpeg_open(struct file *file)
return 0;
error:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mutex_unlock(&jpeg->lock);
free:
@@ -1208,12 +1207,12 @@ free:
static int mtk_jpeg_release(struct file *file)
{
struct mtk_jpeg_dev *jpeg = video_drvdata(file);
- struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(file->private_data);
+ struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
mutex_lock(&jpeg->lock);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mutex_unlock(&jpeg->lock);
diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c
index d0fd77dcf8e2..03c07948dfdd 100644
--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c
@@ -348,9 +348,9 @@ static int mtk_mdp_try_crop(struct mtk_mdp_ctx *ctx, u32 type,
return 0;
}
-static inline struct mtk_mdp_ctx *fh_to_ctx(struct v4l2_fh *fh)
+static inline struct mtk_mdp_ctx *file_to_ctx(struct file *filp)
{
- return container_of(fh, struct mtk_mdp_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct mtk_mdp_ctx, fh);
}
static inline struct mtk_mdp_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
@@ -589,7 +589,7 @@ static const struct vb2_ops mtk_mdp_m2m_qops = {
static int mtk_mdp_m2m_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
struct mtk_mdp_dev *mdp = ctx->mdp_dev;
strscpy(cap->driver, MTK_MDP_MODULE_NAME, sizeof(cap->driver));
@@ -627,7 +627,7 @@ static int mtk_mdp_m2m_enum_fmt_vid_out(struct file *file, void *priv,
static int mtk_mdp_m2m_g_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
struct mtk_mdp_frame *frame;
struct v4l2_pix_format_mplane *pix_mp;
int i;
@@ -666,7 +666,7 @@ static int mtk_mdp_m2m_g_fmt_mplane(struct file *file, void *fh,
static int mtk_mdp_m2m_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
if (!mtk_mdp_try_fmt_mplane(ctx, f))
return -EINVAL;
@@ -676,7 +676,7 @@ static int mtk_mdp_m2m_try_fmt_mplane(struct file *file, void *fh,
static int mtk_mdp_m2m_s_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
struct vb2_queue *vq;
struct mtk_mdp_frame *frame;
struct v4l2_pix_format_mplane *pix_mp;
@@ -722,7 +722,7 @@ static int mtk_mdp_m2m_s_fmt_mplane(struct file *file, void *fh,
static int mtk_mdp_m2m_reqbufs(struct file *file, void *fh,
struct v4l2_requestbuffers *reqbufs)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
}
@@ -730,7 +730,7 @@ static int mtk_mdp_m2m_reqbufs(struct file *file, void *fh,
static int mtk_mdp_m2m_streamon(struct file *file, void *fh,
enum v4l2_buf_type type)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
int ret;
if (!mtk_mdp_ctx_state_is_set(ctx, MTK_MDP_VPU_INIT)) {
@@ -768,8 +768,8 @@ static inline bool mtk_mdp_is_target_crop(u32 target)
static int mtk_mdp_m2m_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
struct mtk_mdp_frame *frame;
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
bool valid = false;
if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
@@ -835,8 +835,8 @@ static int mtk_mdp_check_scaler_ratio(struct mtk_mdp_variant *var, int src_w,
static int mtk_mdp_m2m_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
struct mtk_mdp_frame *frame;
- struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
struct v4l2_rect new_r;
struct mtk_mdp_variant *variant = ctx->mdp_dev->variant;
int ret;
@@ -1065,14 +1065,13 @@ static int mtk_mdp_m2m_open(struct file *file)
mutex_init(&ctx->slock);
ctx->id = mdp->id_counter++;
v4l2_fh_init(&ctx->fh, vfd);
- file->private_data = &ctx->fh;
ret = mtk_mdp_ctrls_create(ctx);
if (ret)
goto error_ctrls;
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
INIT_LIST_HEAD(&ctx->list);
ctx->mdp_dev = mdp;
@@ -1126,7 +1125,7 @@ err_load_vpu:
error_m2m_ctx:
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
error_ctrls:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mutex_unlock(&mdp->lock);
err_lock:
@@ -1137,14 +1136,14 @@ err_lock:
static int mtk_mdp_m2m_release(struct file *file)
{
- struct mtk_mdp_ctx *ctx = fh_to_ctx(file->private_data);
+ struct mtk_mdp_ctx *ctx = file_to_ctx(file);
struct mtk_mdp_dev *mdp = ctx->mdp_dev;
flush_workqueue(mdp->job_wq);
mutex_lock(&mdp->lock);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mtk_mdp_vpu_deinit(&ctx->vpu);
mdp->ctx_num--;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
index 683c066ed975..7fcb2fbdd64e 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
@@ -1530,6 +1530,9 @@ static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = {
}, {
.compatible = "mediatek,mt8195-mdp3-tcc",
.data = (void *)MDP_COMP_TYPE_TCC,
+ }, {
+ .compatible = "mediatek,mt8188-mdp3-rdma",
+ .data = (void *)MDP_COMP_TYPE_RDMA,
},
{}
};
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
index 8de2c8e4d333..6559d72d5d42 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -282,7 +282,7 @@ static int mdp_probe(struct platform_device *pdev)
}
mdp->rproc_handle = scp_get_rproc(mdp->scp);
- dev_dbg(&pdev->dev, "MDP rproc_handle: %pK", mdp->rproc_handle);
+ dev_dbg(&pdev->dev, "MDP rproc_handle: %p", mdp->rproc_handle);
mutex_init(&mdp->vpu_lock);
mutex_init(&mdp->m2m_lock);
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
index 59ce5cce0698..9ef956b565a7 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
@@ -10,9 +10,9 @@
#include <media/videobuf2-dma-contig.h>
#include "mtk-mdp3-m2m.h"
-static inline struct mdp_m2m_ctx *fh_to_ctx(struct v4l2_fh *fh)
+static inline struct mdp_m2m_ctx *file_to_ctx(struct file *filp)
{
- return container_of(fh, struct mdp_m2m_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct mdp_m2m_ctx, fh);
}
static inline struct mdp_m2m_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
@@ -285,7 +285,7 @@ static int mdp_m2m_querycap(struct file *file, void *fh,
static int mdp_m2m_enum_fmt_mplane(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
return mdp_enum_fmt_mplane(ctx->mdp_dev, f);
}
@@ -293,7 +293,7 @@ static int mdp_m2m_enum_fmt_mplane(struct file *file, void *fh,
static int mdp_m2m_g_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
struct mdp_frame *frame;
struct v4l2_pix_format_mplane *pix_mp;
@@ -311,7 +311,7 @@ static int mdp_m2m_g_fmt_mplane(struct file *file, void *fh,
static int mdp_m2m_s_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
struct mdp_frame *frame = ctx_get_frame(ctx, f->type);
struct mdp_frame *capture;
const struct mdp_format *fmt;
@@ -354,7 +354,7 @@ static int mdp_m2m_s_fmt_mplane(struct file *file, void *fh,
static int mdp_m2m_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
if (!mdp_try_fmt_mplane(ctx->mdp_dev, f, &ctx->curr_param, ctx->id))
return -EINVAL;
@@ -365,7 +365,7 @@ static int mdp_m2m_try_fmt_mplane(struct file *file, void *fh,
static int mdp_m2m_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
struct mdp_frame *frame;
bool valid = false;
@@ -417,7 +417,7 @@ static int mdp_m2m_g_selection(struct file *file, void *fh,
static int mdp_m2m_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
struct mdp_frame *frame = ctx_get_frame(ctx, s->type);
struct mdp_frame *capture;
struct v4l2_rect r;
@@ -585,14 +585,13 @@ static int mdp_m2m_open(struct file *file)
ctx->mdp_dev = mdp;
v4l2_fh_init(&ctx->fh, vdev);
- file->private_data = &ctx->fh;
ret = mdp_m2m_ctrls_create(ctx);
if (ret)
goto err_exit_fh;
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
mutex_init(&ctx->ctx_lock);
ctx->m2m_ctx = v4l2_m2m_ctx_init(mdp->m2m_dev, ctx, mdp_m2m_queue_init);
@@ -629,7 +628,7 @@ err_release_m2m_ctx:
v4l2_m2m_ctx_release(ctx->m2m_ctx);
err_release_handler:
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
err_exit_fh:
v4l2_fh_exit(&ctx->fh);
ida_free(&mdp->mdp_ida, ctx->id);
@@ -643,7 +642,7 @@ err_free_ctx:
static int mdp_m2m_release(struct file *file)
{
- struct mdp_m2m_ctx *ctx = fh_to_ctx(file->private_data);
+ struct mdp_m2m_ctx *ctx = file_to_ctx(file);
struct mdp_dev *mdp = video_drvdata(file);
struct device *dev = &mdp->pdev->dev;
@@ -653,7 +652,7 @@ static int mdp_m2m_release(struct file *file)
mdp_vpu_put_locked(mdp);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
ida_free(&mdp->mdp_ida, ctx->id);
mutex_unlock(&mdp->m2m_lock);
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
index da3a892ad867..fae3e1ad2df7 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
@@ -221,7 +221,7 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
}
dev_dbg(&mdp->pdev->dev,
- "VPU param:%pK pa:%pad sz:%zx, work:%pK pa:%pad sz:%zx, config:%pK pa:%pad sz:%zx",
+ "VPU param:%p pa:%pad sz:%zx, work:%p pa:%pad sz:%zx, config:%p pa:%pad sz:%zx",
vpu->param, &vpu->param_addr, vpu->param_size,
vpu->work, &vpu->work_addr, vpu->work_size,
vpu->config, &vpu->config_addr, vpu->config_size);
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
index 98838217b97d..d691bd533103 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
@@ -87,7 +87,7 @@ static int stateful_try_decoder_cmd(struct file *file, void *priv, struct v4l2_d
static int stateful_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
struct vb2_queue *src_vq, *dst_vq;
int ret;
@@ -132,7 +132,7 @@ static int stateless_try_decoder_cmd(struct file *file, void *priv, struct v4l2_
static int stateless_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
int ret;
ret = v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, cmd);
@@ -158,7 +158,7 @@ static int stateless_decoder_cmd(struct file *file, void *priv, struct v4l2_deco
static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
if (ctx->dev->vdec_pdata->uses_stateless_api)
return stateless_try_decoder_cmd(file, priv, cmd);
@@ -168,7 +168,7 @@ static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_dec
static int vidioc_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
if (ctx->dev->vdec_pdata->uses_stateless_api)
return stateless_decoder_cmd(file, priv, cmd);
@@ -233,7 +233,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_dec_ctx *ctx)
static int vidioc_vdec_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
if (ctx->state == MTK_STATE_ABORT) {
mtk_v4l2_vdec_err(ctx, "[%d] Call on QBUF after unrecoverable error", ctx->id);
@@ -246,7 +246,7 @@ static int vidioc_vdec_qbuf(struct file *file, void *priv,
static int vidioc_vdec_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
if (ctx->state == MTK_STATE_ABORT) {
mtk_v4l2_vdec_err(ctx, "[%d] Call on DQBUF after unrecoverable error", ctx->id);
@@ -259,7 +259,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,
static int vidioc_vdec_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
struct device *dev = &ctx->dev->plat_dev->dev;
strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
@@ -354,7 +354,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
fmt = mtk_vdec_find_format(f, dec_pdata);
@@ -372,7 +372,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
{
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
fmt = mtk_vdec_find_format(f, dec_pdata);
@@ -393,7 +393,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
static int vidioc_vdec_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
struct mtk_q_data *q_data;
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -442,7 +442,7 @@ static int vidioc_vdec_g_selection(struct file *file, void *priv,
static int vidioc_vdec_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -464,7 +464,7 @@ static int vidioc_vdec_s_selection(struct file *file, void *priv,
static int vidioc_vdec_s_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
struct v4l2_pix_format_mplane *pix_mp;
struct mtk_q_data *q_data;
int ret = 0;
@@ -594,7 +594,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
int i = 0;
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
if (fsize->index != 0)
@@ -623,10 +623,10 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
+static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
bool output_queue)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
const struct mtk_video_fmt *fmt;
int i, j = 0;
@@ -660,19 +660,19 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- return vidioc_enum_fmt(f, priv, false);
+ return vidioc_enum_fmt(file, f, false);
}
static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- return vidioc_enum_fmt(f, priv, true);
+ return vidioc_enum_fmt(file, f, true);
}
static int vidioc_vdec_g_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(priv);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
struct vb2_queue *vq;
struct mtk_q_data *q_data;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
index 9247d92d431d..46d176e6de63 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -206,8 +206,7 @@ static int fops_vcodec_open(struct file *file)
mutex_lock(&dev->dev_mutex);
ctx->id = dev->id_counter++;
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
INIT_LIST_HEAD(&ctx->list);
ctx->dev = dev;
if (ctx->dev->vdec_pdata->is_subdev_supported) {
@@ -283,7 +282,7 @@ err_load_fw:
err_m2m_ctx_init:
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
err_ctrls_setup:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mutex_unlock(&dev->dev_mutex);
@@ -294,7 +293,7 @@ err_ctrls_setup:
static int fops_vcodec_release(struct file *file)
{
struct mtk_vcodec_dec_dev *dev = video_drvdata(file);
- struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(file->private_data);
+ struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
mtk_v4l2_vdec_dbg(0, ctx, "[%d] decoder", ctx->id);
mutex_lock(&dev->dev_mutex);
@@ -308,7 +307,7 @@ static int fops_vcodec_release(struct file *file)
v4l2_m2m_ctx_release(ctx->m2m_ctx);
mtk_vcodec_dec_release(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
index aececca7ecf8..d047d7c580fb 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
@@ -314,6 +314,11 @@ static inline struct mtk_vcodec_dec_ctx *fh_to_dec_ctx(struct v4l2_fh *fh)
return container_of(fh, struct mtk_vcodec_dec_ctx, fh);
}
+static inline struct mtk_vcodec_dec_ctx *file_to_dec_ctx(struct file *filp)
+{
+ return fh_to_dec_ctx(file_to_v4l2_fh(filp));
+}
+
static inline struct mtk_vcodec_dec_ctx *ctrl_to_dec_ctx(struct v4l2_ctrl *ctrl)
{
return container_of(ctrl->handler, struct mtk_vcodec_dec_ctx, ctrl_hdl);
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
index a01dc25a7699..d815e962ab89 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
@@ -159,7 +159,7 @@ static int vidioc_enum_framesizes(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize)
{
const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(fh);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
if (fsize->index != 0)
return -EINVAL;
@@ -183,7 +183,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
const struct mtk_vcodec_enc_pdata *pdata =
- fh_to_enc_ctx(priv)->dev->venc_pdata;
+ file_to_enc_ctx(file)->dev->venc_pdata;
return vidioc_enum_fmt(f, pdata->capture_formats,
pdata->num_capture_formats);
@@ -193,15 +193,14 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
const struct mtk_vcodec_enc_pdata *pdata =
- fh_to_enc_ctx(priv)->dev->venc_pdata;
+ file_to_enc_ctx(file)->dev->venc_pdata;
return vidioc_enum_fmt(f, pdata->output_formats,
pdata->num_output_formats);
}
-static int mtk_vcodec_enc_get_chip_name(void *priv)
+static int mtk_vcodec_enc_get_chip_name(struct mtk_vcodec_enc_ctx *ctx)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
struct device *dev = &ctx->dev->plat_dev->dev;
if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-enc"))
@@ -221,9 +220,9 @@ static int mtk_vcodec_enc_get_chip_name(void *priv)
static int vidioc_venc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
struct device *dev = &ctx->dev->plat_dev->dev;
- int platform_name = mtk_vcodec_enc_get_chip_name(priv);
+ int platform_name = mtk_vcodec_enc_get_chip_name(ctx);
strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
snprintf(cap->card, sizeof(cap->card), "MT%d video encoder", platform_name);
@@ -234,7 +233,7 @@ static int vidioc_venc_querycap(struct file *file, void *priv,
static int vidioc_venc_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *a)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
struct v4l2_fract *timeperframe = &a->parm.output.timeperframe;
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
@@ -257,7 +256,7 @@ static int vidioc_venc_s_parm(struct file *file, void *priv,
static int vidioc_venc_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *a)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return -EINVAL;
@@ -414,7 +413,7 @@ static void mtk_venc_set_param(struct mtk_vcodec_enc_ctx *ctx,
static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
struct vb2_queue *vq;
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
@@ -469,7 +468,7 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
struct vb2_queue *vq;
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
@@ -524,7 +523,7 @@ static int vidioc_venc_g_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
struct vb2_queue *vq;
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
int i;
@@ -557,7 +556,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
@@ -579,7 +578,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
@@ -600,7 +599,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
static int vidioc_venc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -630,7 +629,7 @@ static int vidioc_venc_g_selection(struct file *file, void *priv,
static int vidioc_venc_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -655,7 +654,7 @@ static int vidioc_venc_s_selection(struct file *file, void *priv,
static int vidioc_venc_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
if (ctx->state == MTK_STATE_ABORT) {
mtk_v4l2_venc_err(ctx, "[%d] Call on QBUF after unrecoverable error",
@@ -669,7 +668,7 @@ static int vidioc_venc_qbuf(struct file *file, void *priv,
static int vidioc_venc_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
int ret;
if (ctx->state == MTK_STATE_ABORT) {
@@ -707,7 +706,7 @@ static int vidioc_venc_dqbuf(struct file *file, void *priv,
static int vidioc_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *cmd)
{
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(priv);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
struct vb2_queue *src_vq, *dst_vq;
int ret;
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
index a1e4483abcdb..fb1c3bdc2dae 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
@@ -129,8 +129,7 @@ static int fops_vcodec_open(struct file *file)
*/
ctx->id = dev->id_counter++;
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
INIT_LIST_HEAD(&ctx->list);
ctx->dev = dev;
init_waitqueue_head(&ctx->queue[0]);
@@ -192,7 +191,7 @@ err_load_fw:
err_m2m_ctx_init:
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
err_ctrls_setup:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mutex_unlock(&dev->dev_mutex);
@@ -203,14 +202,14 @@ err_ctrls_setup:
static int fops_vcodec_release(struct file *file)
{
struct mtk_vcodec_enc_dev *dev = video_drvdata(file);
- struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(file->private_data);
+ struct mtk_vcodec_enc_ctx *ctx = file_to_enc_ctx(file);
mtk_v4l2_venc_dbg(1, ctx, "[%d] encoder", ctx->id);
mutex_lock(&dev->dev_mutex);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
mtk_vcodec_enc_release(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
index 0bd85d0fb379..5b304a551236 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
@@ -217,9 +217,9 @@ struct mtk_vcodec_enc_dev {
struct mtk_vcodec_dbgfs dbgfs;
};
-static inline struct mtk_vcodec_enc_ctx *fh_to_enc_ctx(struct v4l2_fh *fh)
+static inline struct mtk_vcodec_enc_ctx *file_to_enc_ctx(struct file *filp)
{
- return container_of(fh, struct mtk_vcodec_enc_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct mtk_vcodec_enc_ctx, fh);
}
static inline struct mtk_vcodec_enc_ctx *ctrl_to_enc_ctx(struct v4l2_ctrl *ctrl)
diff --git a/drivers/media/platform/nvidia/tegra-vde/v4l2.c b/drivers/media/platform/nvidia/tegra-vde/v4l2.c
index e3726cab0c82..d94978ae2baf 100644
--- a/drivers/media/platform/nvidia/tegra-vde/v4l2.c
+++ b/drivers/media/platform/nvidia/tegra-vde/v4l2.c
@@ -46,9 +46,9 @@ static const struct v4l2_ctrl_config ctrl_cfgs[] = {
},
};
-static inline struct tegra_ctx *fh_to_tegra_ctx(struct v4l2_fh *fh)
+static inline struct tegra_ctx *file_to_tegra_ctx(struct file *file)
{
- return container_of(fh, struct tegra_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct tegra_ctx, fh);
}
static void tegra_set_control_data(struct tegra_ctx *ctx, void *data, u32 id)
@@ -506,7 +506,7 @@ static int tegra_querycap(struct file *file, void *priv,
static int tegra_enum_decoded_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
if (WARN_ON(!ctx->coded_fmt_desc))
return -EINVAL;
@@ -522,7 +522,7 @@ static int tegra_enum_decoded_fmt(struct file *file, void *priv,
static int tegra_g_decoded_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
*f = ctx->decoded_fmt;
return 0;
@@ -531,8 +531,8 @@ static int tegra_g_decoded_fmt(struct file *file, void *priv,
static int tegra_try_decoded_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
const struct tegra_coded_fmt_desc *coded_desc;
unsigned int i;
@@ -571,7 +571,7 @@ static int tegra_try_decoded_fmt(struct file *file, void *priv,
static int tegra_s_decoded_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
struct vb2_queue *vq;
int err;
@@ -593,7 +593,7 @@ static int tegra_s_decoded_fmt(struct file *file, void *priv,
static int tegra_enum_coded_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
const struct tegra_vde_soc *soc = ctx->vde->soc;
if (f->index >= soc->num_coded_fmts)
@@ -607,7 +607,7 @@ static int tegra_enum_coded_fmt(struct file *file, void *priv,
static int tegra_g_coded_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
*f = ctx->coded_fmt;
return 0;
@@ -631,7 +631,7 @@ static int tegra_try_coded_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
const struct tegra_vde_soc *soc = ctx->vde->soc;
int size = pix_mp->plane_fmt[0].sizeimage;
const struct tegra_coded_fmt_desc *desc;
@@ -656,7 +656,7 @@ static int tegra_try_coded_fmt(struct file *file, void *priv,
static int tegra_s_coded_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
const struct tegra_coded_fmt_desc *desc;
struct vb2_queue *peer_vq, *vq;
@@ -718,7 +718,7 @@ static int tegra_s_coded_fmt(struct file *file, void *priv,
static int tegra_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
- struct tegra_ctx *ctx = fh_to_tegra_ctx(priv);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
const struct tegra_coded_fmt_desc *fmt;
if (fsize->index)
@@ -832,14 +832,13 @@ static int tegra_open(struct file *file)
goto free_ctrls;
}
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
tegra_reset_coded_fmt(ctx);
- tegra_try_coded_fmt(file, file->private_data, &ctx->coded_fmt);
+ tegra_try_coded_fmt(file, &ctx->fh, &ctx->coded_fmt);
tegra_reset_decoded_fmt(ctx);
- tegra_try_decoded_fmt(file, file->private_data, &ctx->decoded_fmt);
+ tegra_try_decoded_fmt(file, &ctx->fh, &ctx->decoded_fmt);
return 0;
@@ -853,11 +852,11 @@ free_ctx:
static int tegra_release(struct file *file)
{
- struct v4l2_fh *fh = file->private_data;
- struct tegra_ctx *ctx = fh_to_tegra_ctx(fh);
+ struct tegra_ctx *ctx = file_to_tegra_ctx(file);
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct tegra_vde *vde = ctx->vde;
- v4l2_fh_del(fh);
+ v4l2_fh_del(fh, file);
v4l2_m2m_ctx_release(fh->m2m_ctx);
v4l2_ctrl_handler_free(&ctx->hdl);
v4l2_fh_exit(fh);
diff --git a/drivers/media/platform/nxp/dw100/dw100.c b/drivers/media/platform/nxp/dw100/dw100.c
index 3d1db1121bf9..97744c7b7c03 100644
--- a/drivers/media/platform/nxp/dw100/dw100.c
+++ b/drivers/media/platform/nxp/dw100/dw100.c
@@ -266,7 +266,7 @@ static inline int dw100_dump_regs(struct seq_file *m)
static inline struct dw100_ctx *dw100_file2ctx(struct file *file)
{
- return container_of(file->private_data, struct dw100_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct dw100_ctx, fh);
}
static struct dw100_q_data *dw100_get_q_data(struct dw100_ctx *ctx,
@@ -607,7 +607,6 @@ static int dw100_open(struct file *file)
mutex_init(&ctx->vq_mutex);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dw_dev = dw_dev;
ctx->q_data[DW100_QUEUE_SRC].fmt = &formats[0];
@@ -651,7 +650,7 @@ static int dw100_open(struct file *file)
goto err;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
return 0;
@@ -668,7 +667,7 @@ static int dw100_release(struct file *file)
{
struct dw100_ctx *ctx = dw100_file2ctx(file);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index 8681dd193033..df3ccdf767ba 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -644,9 +644,9 @@ static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf,
}
}
-static inline struct mxc_jpeg_ctx *mxc_jpeg_fh_to_ctx(struct v4l2_fh *fh)
+static inline struct mxc_jpeg_ctx *mxc_jpeg_file_to_ctx(struct file *filp)
{
- return container_of(fh, struct mxc_jpeg_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct mxc_jpeg_ctx, fh);
}
static int enum_fmt(const struct mxc_jpeg_fmt *mxc_formats, int n,
@@ -1604,8 +1604,8 @@ end:
static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *cmd)
{
- struct v4l2_fh *fh = file->private_data;
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
unsigned long flags;
int ret;
@@ -1637,8 +1637,8 @@ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *cmd)
{
- struct v4l2_fh *fh = file->private_data;
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
unsigned long flags;
int ret;
@@ -2200,8 +2200,7 @@ static int mxc_jpeg_open(struct file *file)
}
v4l2_fh_init(&ctx->fh, mxc_vfd);
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->mxc_jpeg = mxc_jpeg;
@@ -2234,7 +2233,7 @@ static int mxc_jpeg_open(struct file *file)
err_ctrls_setup:
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
error:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mutex_unlock(&mxc_jpeg->lock);
free:
@@ -2256,7 +2255,7 @@ static int mxc_jpeg_querycap(struct file *file, void *priv,
static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
@@ -2296,7 +2295,7 @@ static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC :
MXC_JPEG_FMT_TYPE_RAW;
int ret;
@@ -2437,7 +2436,7 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f,
static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
struct device *dev = jpeg->dev;
struct mxc_jpeg_q_data tmp_q;
@@ -2456,7 +2455,7 @@ static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
struct device *dev = jpeg->dev;
struct mxc_jpeg_q_data tmp_q;
@@ -2508,20 +2507,20 @@ static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
static int mxc_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- return mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
+ return mxc_jpeg_s_fmt(mxc_jpeg_file_to_ctx(file), f);
}
static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
int ret;
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct vb2_queue *dst_vq;
struct mxc_jpeg_q_data *q_data_cap;
enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
struct v4l2_format fc;
- ret = mxc_jpeg_s_fmt(mxc_jpeg_fh_to_ctx(priv), f);
+ ret = mxc_jpeg_s_fmt(ctx, f);
if (ret)
return ret;
@@ -2550,7 +2549,7 @@ static int mxc_jpeg_s_fmt_vid_out(struct file *file, void *priv,
static int mxc_jpeg_g_fmt_vid(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg;
struct device *dev = jpeg->dev;
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
@@ -2588,7 +2587,7 @@ static int mxc_jpeg_g_fmt_vid(struct file *file, void *priv,
static int mxc_jpeg_dec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_q_data *q_data_cap;
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
@@ -2617,7 +2616,7 @@ static int mxc_jpeg_dec_g_selection(struct file *file, void *fh, struct v4l2_sel
static int mxc_jpeg_enc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_q_data *q_data_out;
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
@@ -2645,7 +2644,7 @@ static int mxc_jpeg_enc_g_selection(struct file *file, void *fh, struct v4l2_sel
static int mxc_jpeg_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
return mxc_jpeg_dec_g_selection(file, fh, s);
@@ -2655,7 +2654,7 @@ static int mxc_jpeg_g_selection(struct file *file, void *fh, struct v4l2_selecti
static int mxc_jpeg_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
{
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct mxc_jpeg_q_data *q_data_out;
if (ctx->mxc_jpeg->mode != MXC_JPEG_ENCODE)
@@ -2735,7 +2734,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
static int mxc_jpeg_release(struct file *file)
{
struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file);
- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(file->private_data);
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_file_to_ctx(file);
struct device *dev = mxc_jpeg->dev;
mutex_lock(&mxc_jpeg->lock);
@@ -2747,7 +2746,7 @@ static int mxc_jpeg_release(struct file *file)
ctx->slot);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mutex_unlock(&mxc_jpeg->lock);
diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c
index 2beb5f43c2c0..d5de7854f579 100644
--- a/drivers/media/platform/nxp/imx-mipi-csis.c
+++ b/drivers/media/platform/nxp/imx-mipi-csis.c
@@ -54,23 +54,19 @@
/* CSIS common control */
#define MIPI_CSIS_CMN_CTRL 0x04
-#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW BIT(16)
-#define MIPI_CSIS_CMN_CTRL_INTER_MODE BIT(10)
+#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW(n) BIT((n) + 16)
+#define MIPI_CSIS_CMN_CTRL_INTERLEAVE_MODE_DT BIT(10)
+#define MIPI_CSIS_CMN_CTRL_LANE_NUMBER(n) ((n) << 8)
+#define MIPI_CSIS_CMN_CTRL_LANE_NUMBER_MASK GENMASK(9, 8)
#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL BIT(2)
-#define MIPI_CSIS_CMN_CTRL_RESET BIT(1)
-#define MIPI_CSIS_CMN_CTRL_ENABLE BIT(0)
-
-#define MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET 8
-#define MIPI_CSIS_CMN_CTRL_LANE_NR_MASK (3 << 8)
+#define MIPI_CSIS_CMN_CTRL_SW_RESET BIT(1)
+#define MIPI_CSIS_CMN_CTRL_CSI_EN BIT(0)
/* CSIS clock control */
#define MIPI_CSIS_CLK_CTRL 0x08
-#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH3(x) ((x) << 28)
-#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH2(x) ((x) << 24)
-#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH1(x) ((x) << 20)
-#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(x) ((x) << 16)
-#define MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK (0xf << 4)
-#define MIPI_CSIS_CLK_CTRL_WCLK_SRC BIT(0)
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL(n, x) ((x) << ((n) * 4 + 16))
+#define MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MASK GENMASK(7, 4)
+#define MIPI_CSIS_CLK_CTRL_WCLK_SRC(n) BIT(n)
/* CSIS Interrupt mask */
#define MIPI_CSIS_INT_MSK 0x10
@@ -87,7 +83,7 @@
#define MIPI_CSIS_INT_MSK_ERR_WRONG_CFG BIT(3)
#define MIPI_CSIS_INT_MSK_ERR_ECC BIT(2)
#define MIPI_CSIS_INT_MSK_ERR_CRC BIT(1)
-#define MIPI_CSIS_INT_MSK_ERR_UNKNOWN BIT(0)
+#define MIPI_CSIS_INT_MSK_ERR_ID BIT(0)
/* CSIS Interrupt source */
#define MIPI_CSIS_INT_SRC 0x14
@@ -98,16 +94,16 @@
#define MIPI_CSIS_INT_SRC_ODD_AFTER BIT(28)
#define MIPI_CSIS_INT_SRC_ODD (0x3 << 28)
#define MIPI_CSIS_INT_SRC_NON_IMAGE_DATA (0xf << 28)
-#define MIPI_CSIS_INT_SRC_FRAME_START BIT(24)
-#define MIPI_CSIS_INT_SRC_FRAME_END BIT(20)
-#define MIPI_CSIS_INT_SRC_ERR_SOT_HS BIT(16)
-#define MIPI_CSIS_INT_SRC_ERR_LOST_FS BIT(12)
-#define MIPI_CSIS_INT_SRC_ERR_LOST_FE BIT(8)
-#define MIPI_CSIS_INT_SRC_ERR_OVER BIT(4)
+#define MIPI_CSIS_INT_SRC_FRAME_START(n) BIT((n) + 24)
+#define MIPI_CSIS_INT_SRC_FRAME_END(n) BIT((n) + 20)
+#define MIPI_CSIS_INT_SRC_ERR_SOT_HS(n) BIT((n) + 16)
+#define MIPI_CSIS_INT_SRC_ERR_LOST_FS(n) BIT((n) + 12)
+#define MIPI_CSIS_INT_SRC_ERR_LOST_FE(n) BIT((n) + 8)
+#define MIPI_CSIS_INT_SRC_ERR_OVER(n) BIT((n) + 4)
#define MIPI_CSIS_INT_SRC_ERR_WRONG_CFG BIT(3)
#define MIPI_CSIS_INT_SRC_ERR_ECC BIT(2)
#define MIPI_CSIS_INT_SRC_ERR_CRC BIT(1)
-#define MIPI_CSIS_INT_SRC_ERR_UNKNOWN BIT(0)
+#define MIPI_CSIS_INT_SRC_ERR_ID BIT(0)
#define MIPI_CSIS_INT_SRC_ERRORS 0xfffff
/* D-PHY status control */
@@ -123,8 +119,8 @@
#define MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE_MASK GENMASK(31, 24)
#define MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(n) ((n) << 22)
#define MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE_MASK GENMASK(23, 22)
-#define MIPI_CSIS_DPHY_CMN_CTRL_DPDN_SWAP_CLK BIT(6)
-#define MIPI_CSIS_DPHY_CMN_CTRL_DPDN_SWAP_DAT BIT(5)
+#define MIPI_CSIS_DPHY_CMN_CTRL_S_DPDN_SWAP_CLK BIT(6)
+#define MIPI_CSIS_DPHY_CMN_CTRL_S_DPDN_SWAP_DAT BIT(5)
#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE_DAT BIT(1)
#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE_CLK BIT(0)
#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE (0x1f << 0)
@@ -174,26 +170,28 @@
/* ISP Configuration register */
#define MIPI_CSIS_ISP_CONFIG_CH(n) (0x40 + (n) * 0x10)
-#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK (0xff << 24)
+#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MASK GENMASK(31, 24)
#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x) ((x) << 24)
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_SINGLE (0 << 12)
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL (1 << 12)
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_QUAD (2 << 12) /* i.MX8M[MNP] only */
-#define MIPI_CSIS_ISPCFG_PIXEL_MASK (3 << 12)
-#define MIPI_CSIS_ISPCFG_ALIGN_32BIT BIT(11)
-#define MIPI_CSIS_ISPCFG_FMT(fmt) ((fmt) << 2)
-#define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2)
+#define MIPI_CSIS_ISPCFG_PIXEL_MODE_MASK GENMASK(13, 12)
+#define MIPI_CSIS_ISPCFG_PARALLEL BIT(11)
+#define MIPI_CSIS_ISPCFG_DATAFORMAT(fmt) ((fmt) << 2)
+#define MIPI_CSIS_ISPCFG_DATAFORMAT_MASK GENMASK(7, 2)
/* ISP Image Resolution register */
#define MIPI_CSIS_ISP_RESOL_CH(n) (0x44 + (n) * 0x10)
+#define MIPI_CSIS_ISP_RESOL_VRESOL(n) ((n) << 16)
+#define MIPI_CSIS_ISP_RESOL_HRESOL(n) ((n) << 0)
#define CSIS_MAX_PIX_WIDTH 0xffff
#define CSIS_MAX_PIX_HEIGHT 0xffff
/* ISP SYNC register */
#define MIPI_CSIS_ISP_SYNC_CH(n) (0x48 + (n) * 0x10)
-#define MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET 18
-#define MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET 12
-#define MIPI_CSIS_ISP_SYNC_VSYNC_EINTV_OFFSET 0
+#define MIPI_CSIS_ISP_SYNC_HSYNC_LINTV(n) ((n) << 18)
+#define MIPI_CSIS_ISP_SYNC_VSYNC_SINTV(n) ((n) << 12)
+#define MIPI_CSIS_ISP_SYNC_VSYNC_EINTV(n) ((n) << 0)
/* ISP shadow registers */
#define MIPI_CSIS_SDW_CONFIG_CH(n) (0x80 + (n) * 0x10)
@@ -203,23 +201,23 @@
/* Debug control register */
#define MIPI_CSIS_DBG_CTRL 0xc0
#define MIPI_CSIS_DBG_INTR_MSK 0xc4
-#define MIPI_CSIS_DBG_INTR_MSK_DT_NOT_SUPPORT BIT(25)
-#define MIPI_CSIS_DBG_INTR_MSK_DT_IGNORE BIT(24)
-#define MIPI_CSIS_DBG_INTR_MSK_ERR_FRAME_SIZE BIT(20)
-#define MIPI_CSIS_DBG_INTR_MSK_TRUNCATED_FRAME BIT(16)
-#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FE BIT(12)
-#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FS BIT(8)
-#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_FALL BIT(4)
-#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_RISE BIT(0)
+#define MIPI_CSIS_DBG_INTR_MSK_DT_NOT_SUPPORT BIT(25)
+#define MIPI_CSIS_DBG_INTR_MSK_DT_IGNORE BIT(24)
+#define MIPI_CSIS_DBG_INTR_MSK_ERR_FRAME_SIZE(n) BIT((n) + 20)
+#define MIPI_CSIS_DBG_INTR_MSK_TRUNCATED_FRAME(n) BIT((n) + 16)
+#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FE(n) BIT((n) + 12)
+#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FS(n) BIT((n) + 8)
+#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_FALL(n) BIT((n) + 4)
+#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_RISE(n) BIT((n) + 0)
#define MIPI_CSIS_DBG_INTR_SRC 0xc8
-#define MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT BIT(25)
-#define MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE BIT(24)
-#define MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE BIT(20)
-#define MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME BIT(16)
-#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FE BIT(12)
-#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FS BIT(8)
-#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL BIT(4)
-#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE BIT(0)
+#define MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT BIT(25)
+#define MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE BIT(24)
+#define MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE(n) BIT((n) + 20)
+#define MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME(n) BIT((n) + 16)
+#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FE(n) BIT((n) + 12)
+#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FS(n) BIT((n) + 8)
+#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL(n) BIT((n) + 4)
+#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE(n) BIT((n) + 0)
#define MIPI_CSIS_FRAME_COUNTER_CH(n) (0x0100 + (n) * 4)
@@ -228,10 +226,11 @@
#define MIPI_CSIS_PKTDATA_EVEN 0x3000
#define MIPI_CSIS_PKTDATA_SIZE SZ_4K
-#define DEFAULT_SCLK_CSIS_FREQ 166000000UL
+#define MIPI_CSIS_MAX_CHANNELS 4
struct mipi_csis_event {
bool debug;
+ unsigned int channel;
u32 mask;
const char * const name;
unsigned int counter;
@@ -239,33 +238,70 @@ struct mipi_csis_event {
static const struct mipi_csis_event mipi_csis_events[] = {
/* Errors */
- { false, MIPI_CSIS_INT_SRC_ERR_SOT_HS, "SOT Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_LOST_FS, "Lost Frame Start Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_LOST_FE, "Lost Frame End Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_OVER, "FIFO Overflow Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_WRONG_CFG, "Wrong Configuration Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_ECC, "ECC Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_CRC, "CRC Error" },
- { false, MIPI_CSIS_INT_SRC_ERR_UNKNOWN, "Unknown Error" },
- { true, MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT, "Data Type Not Supported" },
- { true, MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE, "Data Type Ignored" },
- { true, MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE, "Frame Size Error" },
- { true, MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME, "Truncated Frame" },
- { true, MIPI_CSIS_DBG_INTR_SRC_EARLY_FE, "Early Frame End" },
- { true, MIPI_CSIS_DBG_INTR_SRC_EARLY_FS, "Early Frame Start" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_SOT_HS(0), "SOT 0 Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_SOT_HS(1), "SOT 1 Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_SOT_HS(2), "SOT 2 Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_SOT_HS(3), "SOT 3 Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_LOST_FS(0), "Lost Frame Start Error 0" },
+ { false, 1, MIPI_CSIS_INT_SRC_ERR_LOST_FS(1), "Lost Frame Start Error 1" },
+ { false, 2, MIPI_CSIS_INT_SRC_ERR_LOST_FS(2), "Lost Frame Start Error 2" },
+ { false, 3, MIPI_CSIS_INT_SRC_ERR_LOST_FS(3), "Lost Frame Start Error 3" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_LOST_FE(0), "Lost Frame End Error 0" },
+ { false, 1, MIPI_CSIS_INT_SRC_ERR_LOST_FE(1), "Lost Frame End Error 1" },
+ { false, 2, MIPI_CSIS_INT_SRC_ERR_LOST_FE(2), "Lost Frame End Error 2" },
+ { false, 3, MIPI_CSIS_INT_SRC_ERR_LOST_FE(3), "Lost Frame End Error 3" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_OVER(0), "FIFO Overflow Error 0" },
+ { false, 1, MIPI_CSIS_INT_SRC_ERR_OVER(1), "FIFO Overflow Error 1" },
+ { false, 2, MIPI_CSIS_INT_SRC_ERR_OVER(2), "FIFO Overflow Error 2" },
+ { false, 3, MIPI_CSIS_INT_SRC_ERR_OVER(3), "FIFO Overflow Error 3" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_WRONG_CFG, "Wrong Configuration Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_ECC, "ECC Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_CRC, "CRC Error" },
+ { false, 0, MIPI_CSIS_INT_SRC_ERR_ID, "Unknown ID Error" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT, "Data Type Not Supported" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE, "Data Type Ignored" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE(0), "Frame Size Error 0" },
+ { true, 1, MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE(1), "Frame Size Error 1" },
+ { true, 2, MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE(2), "Frame Size Error 2" },
+ { true, 3, MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE(3), "Frame Size Error 3" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME(0), "Truncated Frame 0" },
+ { true, 1, MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME(1), "Truncated Frame 1" },
+ { true, 2, MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME(2), "Truncated Frame 2" },
+ { true, 3, MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME(3), "Truncated Frame 3" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_EARLY_FE(0), "Early Frame End 0" },
+ { true, 1, MIPI_CSIS_DBG_INTR_SRC_EARLY_FE(1), "Early Frame End 1" },
+ { true, 2, MIPI_CSIS_DBG_INTR_SRC_EARLY_FE(2), "Early Frame End 2" },
+ { true, 3, MIPI_CSIS_DBG_INTR_SRC_EARLY_FE(3), "Early Frame End 3" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_EARLY_FS(0), "Early Frame Start 0" },
+ { true, 1, MIPI_CSIS_DBG_INTR_SRC_EARLY_FS(1), "Early Frame Start 1" },
+ { true, 2, MIPI_CSIS_DBG_INTR_SRC_EARLY_FS(2), "Early Frame Start 2" },
+ { true, 3, MIPI_CSIS_DBG_INTR_SRC_EARLY_FS(3), "Early Frame Start 3" },
/* Non-image data receive events */
- { false, MIPI_CSIS_INT_SRC_EVEN_BEFORE, "Non-image data before even frame" },
- { false, MIPI_CSIS_INT_SRC_EVEN_AFTER, "Non-image data after even frame" },
- { false, MIPI_CSIS_INT_SRC_ODD_BEFORE, "Non-image data before odd frame" },
- { false, MIPI_CSIS_INT_SRC_ODD_AFTER, "Non-image data after odd frame" },
+ { false, 0, MIPI_CSIS_INT_SRC_EVEN_BEFORE, "Non-image data before even frame" },
+ { false, 0, MIPI_CSIS_INT_SRC_EVEN_AFTER, "Non-image data after even frame" },
+ { false, 0, MIPI_CSIS_INT_SRC_ODD_BEFORE, "Non-image data before odd frame" },
+ { false, 0, MIPI_CSIS_INT_SRC_ODD_AFTER, "Non-image data after odd frame" },
/* Frame start/end */
- { false, MIPI_CSIS_INT_SRC_FRAME_START, "Frame Start" },
- { false, MIPI_CSIS_INT_SRC_FRAME_END, "Frame End" },
- { true, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL, "VSYNC Falling Edge" },
- { true, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE, "VSYNC Rising Edge" },
+ { false, 0, MIPI_CSIS_INT_SRC_FRAME_START(0), "Frame Start 0" },
+ { false, 1, MIPI_CSIS_INT_SRC_FRAME_START(1), "Frame Start 1" },
+ { false, 2, MIPI_CSIS_INT_SRC_FRAME_START(2), "Frame Start 2" },
+ { false, 3, MIPI_CSIS_INT_SRC_FRAME_START(3), "Frame Start 3" },
+ { false, 0, MIPI_CSIS_INT_SRC_FRAME_END(0), "Frame End 0" },
+ { false, 1, MIPI_CSIS_INT_SRC_FRAME_END(1), "Frame End 1" },
+ { false, 2, MIPI_CSIS_INT_SRC_FRAME_END(2), "Frame End 2" },
+ { false, 3, MIPI_CSIS_INT_SRC_FRAME_END(3), "Frame End 3" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL(0), "VSYNC Falling Edge 0" },
+ { true, 1, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL(1), "VSYNC Falling Edge 1" },
+ { true, 2, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL(2), "VSYNC Falling Edge 2" },
+ { true, 3, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL(3), "VSYNC Falling Edge 3" },
+ { true, 0, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE(0), "VSYNC Rising Edge 0" },
+ { true, 1, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE(1), "VSYNC Rising Edge 1" },
+ { true, 2, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE(2), "VSYNC Rising Edge 2" },
+ { true, 3, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE(3), "VSYNC Rising Edge 3" },
};
-#define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events)
+#define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events)
+#define MIPI_CSIS_NUM_ERROR_EVENTS 38
enum mipi_csis_clk {
MIPI_CSIS_CLK_PCLK,
@@ -297,7 +333,9 @@ struct mipi_csis_device {
struct clk_bulk_data *clks;
struct reset_control *mrst;
struct regulator *mipi_phy_regulator;
+
const struct mipi_csis_info *info;
+ unsigned int num_channels;
struct v4l2_subdev sd;
struct media_pad pads[CSIS_PADS_NUM];
@@ -517,7 +555,7 @@ static void mipi_csis_sw_reset(struct mipi_csis_device *csis)
u32 val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL);
mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL,
- val | MIPI_CSIS_CMN_CTRL_RESET);
+ val | MIPI_CSIS_CMN_CTRL_SW_RESET);
usleep_range(10, 20);
}
@@ -527,9 +565,9 @@ static void mipi_csis_system_enable(struct mipi_csis_device *csis, int on)
val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL);
if (on)
- val |= MIPI_CSIS_CMN_CTRL_ENABLE;
+ val |= MIPI_CSIS_CMN_CTRL_CSI_EN;
else
- val &= ~MIPI_CSIS_CMN_CTRL_ENABLE;
+ val &= ~MIPI_CSIS_CMN_CTRL_CSI_EN;
mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL, val);
val = mipi_csis_read(csis, MIPI_CSIS_DPHY_CMN_CTRL);
@@ -549,8 +587,8 @@ static void __mipi_csis_set_format(struct mipi_csis_device *csis,
/* Color format */
val = mipi_csis_read(csis, MIPI_CSIS_ISP_CONFIG_CH(0));
- val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK
- | MIPI_CSIS_ISPCFG_PIXEL_MASK);
+ val &= ~(MIPI_CSIS_ISPCFG_PARALLEL | MIPI_CSIS_ISPCFG_PIXEL_MODE_MASK |
+ MIPI_CSIS_ISPCFG_DATAFORMAT_MASK);
/*
* YUV 4:2:2 can be transferred with 8 or 16 bits per clock sample
@@ -568,24 +606,23 @@ static void __mipi_csis_set_format(struct mipi_csis_device *csis,
if (csis_fmt->data_type == MIPI_CSI2_DT_YUV422_8B)
val |= MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL;
- val |= MIPI_CSIS_ISPCFG_FMT(csis_fmt->data_type);
+ val |= MIPI_CSIS_ISPCFG_DATAFORMAT(csis_fmt->data_type);
mipi_csis_write(csis, MIPI_CSIS_ISP_CONFIG_CH(0), val);
/* Pixel resolution */
- val = format->width | (format->height << 16);
- mipi_csis_write(csis, MIPI_CSIS_ISP_RESOL_CH(0), val);
+ mipi_csis_write(csis, MIPI_CSIS_ISP_RESOL_CH(0),
+ MIPI_CSIS_ISP_RESOL_VRESOL(format->height) |
+ MIPI_CSIS_ISP_RESOL_HRESOL(format->width));
}
static int mipi_csis_calculate_params(struct mipi_csis_device *csis,
const struct csis_pix_format *csis_fmt)
{
- struct media_pad *src_pad =
- &csis->source.sd->entity.pads[csis->source.pad->index];
s64 link_freq;
u32 lane_rate;
/* Calculate the line rate from the pixel rate. */
- link_freq = v4l2_get_link_freq(src_pad, csis_fmt->width,
+ link_freq = v4l2_get_link_freq(csis->source.pad, csis_fmt->width,
csis->bus.num_data_lanes * 2);
if (link_freq < 0) {
dev_err(csis->dev, "Unable to obtain link frequency: %d\n",
@@ -635,10 +672,10 @@ static void mipi_csis_set_params(struct mipi_csis_device *csis,
u32 val;
val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL);
- val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK;
- val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET;
+ val &= ~MIPI_CSIS_CMN_CTRL_LANE_NUMBER_MASK;
+ val |= MIPI_CSIS_CMN_CTRL_LANE_NUMBER(lanes - 1);
if (csis->info->version == MIPI_CSIS_V3_3)
- val |= MIPI_CSIS_CMN_CTRL_INTER_MODE;
+ val |= MIPI_CSIS_CMN_CTRL_INTERLEAVE_MODE_DT;
mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL, val);
__mipi_csis_set_format(csis, format, csis_fmt);
@@ -647,15 +684,15 @@ static void mipi_csis_set_params(struct mipi_csis_device *csis,
MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(csis->hs_settle) |
MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(csis->clk_settle));
- val = (0 << MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET)
- | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET)
- | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_EINTV_OFFSET);
- mipi_csis_write(csis, MIPI_CSIS_ISP_SYNC_CH(0), val);
+ mipi_csis_write(csis, MIPI_CSIS_ISP_SYNC_CH(0),
+ MIPI_CSIS_ISP_SYNC_HSYNC_LINTV(0) |
+ MIPI_CSIS_ISP_SYNC_VSYNC_SINTV(0) |
+ MIPI_CSIS_ISP_SYNC_VSYNC_EINTV(0));
val = mipi_csis_read(csis, MIPI_CSIS_CLK_CTRL);
- val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC;
- val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(15);
- val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK;
+ val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC(0);
+ val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL(0, 15);
+ val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MASK;
mipi_csis_write(csis, MIPI_CSIS_CLK_CTRL, val);
mipi_csis_write(csis, MIPI_CSIS_DPHY_BCTRL_L,
@@ -671,7 +708,7 @@ static void mipi_csis_set_params(struct mipi_csis_device *csis,
/* Update the shadow register. */
val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL);
mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL,
- val | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW |
+ val | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW(0) |
MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL);
}
@@ -704,12 +741,17 @@ static int mipi_csis_clk_get(struct mipi_csis_device *csis)
if (ret < 0)
return ret;
- /* Set clock rate */
- ret = clk_set_rate(csis->clks[MIPI_CSIS_CLK_WRAP].clk,
- csis->clk_frequency);
- if (ret < 0)
- dev_err(csis->dev, "set rate=%d failed: %d\n",
- csis->clk_frequency, ret);
+ if (csis->clk_frequency) {
+ /*
+ * Set the clock rate. This is deprecated, for backward
+ * compatibility with old device trees.
+ */
+ ret = clk_set_rate(csis->clks[MIPI_CSIS_CLK_WRAP].clk,
+ csis->clk_frequency);
+ if (ret < 0)
+ dev_err(csis->dev, "set rate=%d failed: %d\n",
+ csis->clk_frequency, ret);
+ }
return ret;
}
@@ -757,16 +799,19 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id)
/* Update the event/error counters */
if ((status & MIPI_CSIS_INT_SRC_ERRORS) || csis->debug.enable) {
- for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) {
+ for (i = 0; i < ARRAY_SIZE(csis->events); i++) {
struct mipi_csis_event *event = &csis->events[i];
+ if (event->channel >= csis->num_channels)
+ continue;
+
if ((!event->debug && (status & event->mask)) ||
(event->debug && (dbg_status & event->mask)))
event->counter++;
}
}
- if (status & MIPI_CSIS_INT_SRC_FRAME_START)
+ if (status & MIPI_CSIS_INT_SRC_FRAME_START(0))
mipi_csis_queue_event_sof(csis);
spin_unlock_irqrestore(&csis->slock, flags);
@@ -843,7 +888,7 @@ static void mipi_csis_clear_counters(struct mipi_csis_device *csis)
static void mipi_csis_log_counters(struct mipi_csis_device *csis, bool non_errors)
{
unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS
- : MIPI_CSIS_NUM_EVENTS - 8;
+ : MIPI_CSIS_NUM_ERROR_EVENTS;
unsigned int counters[MIPI_CSIS_NUM_EVENTS];
unsigned long flags;
unsigned int i;
@@ -854,45 +899,67 @@ static void mipi_csis_log_counters(struct mipi_csis_device *csis, bool non_error
spin_unlock_irqrestore(&csis->slock, flags);
for (i = 0; i < num_events; ++i) {
+ const struct mipi_csis_event *event = &csis->events[i];
+
+ if (event->channel >= csis->num_channels)
+ continue;
+
if (counters[i] > 0 || csis->debug.enable)
dev_info(csis->dev, "%s events: %d\n",
- csis->events[i].name,
- counters[i]);
+ event->name, counters[i]);
}
}
+struct mipi_csis_reg_info {
+ u32 addr;
+ unsigned int offset;
+ const char * const name;
+};
+
+static void mipi_csis_dump_channel_reg(struct mipi_csis_device *csis,
+ const struct mipi_csis_reg_info *reg,
+ unsigned int channel)
+{
+ dev_info(csis->dev, "%16s%u: 0x%08x\n", reg->name, channel,
+ mipi_csis_read(csis, reg->addr + channel * reg->offset));
+}
+
static int mipi_csis_dump_regs(struct mipi_csis_device *csis)
{
- static const struct {
- u32 offset;
- const char * const name;
- } registers[] = {
- { MIPI_CSIS_CMN_CTRL, "CMN_CTRL" },
- { MIPI_CSIS_CLK_CTRL, "CLK_CTRL" },
- { MIPI_CSIS_INT_MSK, "INT_MSK" },
- { MIPI_CSIS_DPHY_STATUS, "DPHY_STATUS" },
- { MIPI_CSIS_DPHY_CMN_CTRL, "DPHY_CMN_CTRL" },
- { MIPI_CSIS_DPHY_SCTRL_L, "DPHY_SCTRL_L" },
- { MIPI_CSIS_DPHY_SCTRL_H, "DPHY_SCTRL_H" },
- { MIPI_CSIS_ISP_CONFIG_CH(0), "ISP_CONFIG_CH0" },
- { MIPI_CSIS_ISP_RESOL_CH(0), "ISP_RESOL_CH0" },
- { MIPI_CSIS_SDW_CONFIG_CH(0), "SDW_CONFIG_CH0" },
- { MIPI_CSIS_SDW_RESOL_CH(0), "SDW_RESOL_CH0" },
- { MIPI_CSIS_DBG_CTRL, "DBG_CTRL" },
- { MIPI_CSIS_FRAME_COUNTER_CH(0), "FRAME_COUNTER_CH0" },
+ static const struct mipi_csis_reg_info common_registers[] = {
+ { MIPI_CSIS_CMN_CTRL, 0, "CMN_CTRL" },
+ { MIPI_CSIS_CLK_CTRL, 0, "CLK_CTRL" },
+ { MIPI_CSIS_INT_MSK, 0, "INT_MSK" },
+ { MIPI_CSIS_DPHY_STATUS, 0, "DPHY_STATUS" },
+ { MIPI_CSIS_DPHY_CMN_CTRL, 0, "DPHY_CMN_CTRL" },
+ { MIPI_CSIS_DPHY_SCTRL_L, 0, "DPHY_SCTRL_L" },
+ { MIPI_CSIS_DPHY_SCTRL_H, 0, "DPHY_SCTRL_H" },
+ { MIPI_CSIS_DBG_CTRL, 0, "DBG_CTRL" },
+ };
+ static const struct mipi_csis_reg_info channel_registers[] = {
+ { MIPI_CSIS_ISP_CONFIG_CH(0), 0x10, "ISP_CONFIG_CH" },
+ { MIPI_CSIS_ISP_RESOL_CH(0), 0x10, "ISP_RESOL_CH" },
+ { MIPI_CSIS_SDW_CONFIG_CH(0), 0x10, "SDW_CONFIG_CH" },
+ { MIPI_CSIS_SDW_RESOL_CH(0), 0x10, "SDW_RESOL_CH" },
+ { MIPI_CSIS_FRAME_COUNTER_CH(0), 4, "FRAME_COUNTER_CH" },
};
-
- unsigned int i;
- u32 cfg;
if (!pm_runtime_get_if_in_use(csis->dev))
return 0;
dev_info(csis->dev, "--- REGISTERS ---\n");
- for (i = 0; i < ARRAY_SIZE(registers); i++) {
- cfg = mipi_csis_read(csis, registers[i].offset);
- dev_info(csis->dev, "%14s: 0x%08x\n", registers[i].name, cfg);
+ for (unsigned int i = 0; i < ARRAY_SIZE(common_registers); i++) {
+ const struct mipi_csis_reg_info *reg = &common_registers[i];
+
+ dev_info(csis->dev, "%17s: 0x%08x\n", reg->name,
+ mipi_csis_read(csis, reg->addr));
+ }
+
+ for (unsigned int chan = 0; chan < csis->num_channels; chan++) {
+ for (unsigned int i = 0; i < ARRAY_SIZE(channel_registers); ++i)
+ mipi_csis_dump_channel_reg(csis, &channel_registers[i],
+ chan);
}
pm_runtime_put(csis->dev);
@@ -998,7 +1065,7 @@ err_unlock:
}
static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum *code)
{
/*
@@ -1011,7 +1078,7 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index > 0)
return -EINVAL;
- fmt = v4l2_subdev_state_get_format(sd_state, code->pad);
+ fmt = v4l2_subdev_state_get_format(state, code->pad);
code->code = fmt->code;
return 0;
}
@@ -1028,10 +1095,10 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd,
}
static int mipi_csis_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *sdformat)
{
- struct csis_pix_format const *csis_fmt;
+ const struct csis_pix_format *csis_fmt;
struct v4l2_mbus_framefmt *fmt;
unsigned int align;
@@ -1040,7 +1107,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd,
* modified.
*/
if (sdformat->pad == CSIS_PAD_SOURCE)
- return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
+ return v4l2_subdev_get_fmt(sd, state, sdformat);
if (sdformat->pad != CSIS_PAD_SINK)
return -EINVAL;
@@ -1078,7 +1145,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd,
&sdformat->format.height, 1,
CSIS_MAX_PIX_HEIGHT, 0, 0);
- fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
+ fmt = v4l2_subdev_state_get_format(state, sdformat->pad);
fmt->code = csis_fmt->code;
fmt->width = sdformat->format.width;
@@ -1092,7 +1159,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd,
sdformat->format = *fmt;
/* Propagate the format from sink to source. */
- fmt = v4l2_subdev_state_get_format(sd_state, CSIS_PAD_SOURCE);
+ fmt = v4l2_subdev_state_get_format(state, CSIS_PAD_SOURCE);
*fmt = sdformat->format;
/* The format on the source pad might change due to unpacking. */
@@ -1132,7 +1199,7 @@ static int mipi_csis_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
}
static int mipi_csis_init_state(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state)
+ struct v4l2_subdev_state *state)
{
struct v4l2_subdev_format fmt = {
.pad = CSIS_PAD_SINK,
@@ -1149,7 +1216,7 @@ static int mipi_csis_init_state(struct v4l2_subdev *sd,
V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt.format.colorspace,
fmt.format.ycbcr_enc);
- return mipi_csis_set_fmt(sd, sd_state, &fmt);
+ return mipi_csis_set_fmt(sd, state, &fmt);
}
static int mipi_csis_log_status(struct v4l2_subdev *sd)
@@ -1413,9 +1480,13 @@ static int mipi_csis_parse_dt(struct mipi_csis_device *csis)
{
struct device_node *node = csis->dev->of_node;
- if (of_property_read_u32(node, "clock-frequency",
- &csis->clk_frequency))
- csis->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
+ of_property_read_u32(node, "clock-frequency", &csis->clk_frequency);
+
+ csis->num_channels = 1;
+ of_property_read_u32(node, "fsl,num-channels", &csis->num_channels);
+ if (csis->num_channels < 1 || csis->num_channels > MIPI_CSIS_MAX_CHANNELS)
+ return dev_err_probe(csis->dev, -EINVAL,
+ "Invalid fsl,num-channels value\n");
return 0;
}
@@ -1440,10 +1511,8 @@ static int mipi_csis_probe(struct platform_device *pdev)
/* Parse DT properties. */
ret = mipi_csis_parse_dt(csis);
- if (ret < 0) {
- dev_err(dev, "Failed to parse device tree: %d\n", ret);
+ if (ret < 0)
return ret;
- }
/* Acquire resources. */
csis->regs = devm_platform_ioremap_resource(pdev, 0);
diff --git a/drivers/media/platform/nxp/imx-pxp.c b/drivers/media/platform/nxp/imx-pxp.c
index 7f8ffbac582f..6cc9b07ea53a 100644
--- a/drivers/media/platform/nxp/imx-pxp.c
+++ b/drivers/media/platform/nxp/imx-pxp.c
@@ -248,7 +248,7 @@ struct pxp_ctx {
static inline struct pxp_ctx *file2ctx(struct file *file)
{
- return container_of(file->private_data, struct pxp_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct pxp_ctx, fh);
}
static struct pxp_q_data *get_q_data(struct pxp_ctx *ctx,
@@ -1660,7 +1660,6 @@ static int pxp_open(struct file *file)
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = dev;
hdl = &ctx->hdl;
v4l2_ctrl_handler_init(hdl, 4);
@@ -1699,7 +1698,7 @@ static int pxp_open(struct file *file)
goto open_unlock;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
atomic_inc(&dev->num_inst);
dprintk(dev, "Created instance: %p, m2m_ctx: %p\n",
@@ -1717,7 +1716,7 @@ static int pxp_release(struct file *file)
dprintk(dev, "Releasing instance %p\n", ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
mutex_lock(&dev->dev_mutex);
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
index 981648a03113..adc8d9960bf0 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
@@ -374,6 +374,8 @@ static int mxc_isi_pm_suspend(struct device *dev)
mxc_isi_video_suspend(pipe);
}
+ mxc_isi_m2m_suspend(&isi->m2m);
+
return pm_runtime_force_suspend(dev);
}
@@ -403,6 +405,12 @@ static int mxc_isi_pm_resume(struct device *dev)
}
}
+ ret = mxc_isi_m2m_resume(&isi->m2m);
+ if (ret) {
+ dev_err(dev, "Failed to resume ISI (%d) for m2m\n", ret);
+ err = ret;
+ }
+
return err;
}
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
index 206995bedca4..e84af5127e4e 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
@@ -202,9 +202,8 @@ struct mxc_isi_video {
struct video_device vdev;
struct media_pad pad;
- /* Protects is_streaming, and the vdev and vb2_q operations */
+ /* Protects the vdev and vb2_q operations */
struct mutex lock;
- bool is_streaming;
struct v4l2_pix_format_mplane pix;
const struct mxc_isi_format_info *fmtinfo;
@@ -343,6 +342,8 @@ int mxc_isi_video_buffer_prepare(struct mxc_isi_dev *isi, struct vb2_buffer *vb2
#ifdef CONFIG_VIDEO_IMX8_ISI_M2M
int mxc_isi_m2m_register(struct mxc_isi_dev *isi, struct v4l2_device *v4l2_dev);
int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi);
+void mxc_isi_m2m_suspend(struct mxc_isi_m2m *m2m);
+int mxc_isi_m2m_resume(struct mxc_isi_m2m *m2m);
#else
static inline int mxc_isi_m2m_register(struct mxc_isi_dev *isi,
struct v4l2_device *v4l2_dev)
@@ -353,6 +354,13 @@ static inline int mxc_isi_m2m_unregister(struct mxc_isi_dev *isi)
{
return 0;
}
+static inline void mxc_isi_m2m_suspend(struct mxc_isi_m2m *m2m)
+{
+}
+static inline int mxc_isi_m2m_resume(struct mxc_isi_m2m *m2m)
+{
+ return 0;
+}
#endif
int mxc_isi_channel_acquire(struct mxc_isi_pipe *pipe,
@@ -362,7 +370,7 @@ void mxc_isi_channel_get(struct mxc_isi_pipe *pipe);
void mxc_isi_channel_put(struct mxc_isi_pipe *pipe);
void mxc_isi_channel_enable(struct mxc_isi_pipe *pipe);
void mxc_isi_channel_disable(struct mxc_isi_pipe *pipe);
-int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe, bool bypass);
+int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe);
void mxc_isi_channel_unchain(struct mxc_isi_pipe *pipe);
void mxc_isi_channel_config(struct mxc_isi_pipe *pipe,
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
index 5623914f95e6..9225a7ac1c3e 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
@@ -587,7 +587,7 @@ void mxc_isi_channel_release(struct mxc_isi_pipe *pipe)
*
* TODO: Support secondary line buffer for downscaling YUV420 images.
*/
-int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe, bool bypass)
+int mxc_isi_channel_chain(struct mxc_isi_pipe *pipe)
{
/* Channel chaining requires both line and output buffer. */
const u8 resources = MXC_ISI_CHANNEL_RES_OUTPUT_BUF
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
index 22e49d3a1287..00afcbfbdde4 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c
@@ -43,7 +43,6 @@ struct mxc_isi_m2m_ctx_queue_data {
struct v4l2_pix_format_mplane format;
const struct mxc_isi_format_info *info;
u32 sequence;
- bool streaming;
};
struct mxc_isi_m2m_ctx {
@@ -74,9 +73,9 @@ to_isi_m2m_buffer(struct vb2_v4l2_buffer *buf)
return container_of(buf, struct mxc_isi_m2m_buffer, buf.vb);
}
-static inline struct mxc_isi_m2m_ctx *to_isi_m2m_ctx(struct v4l2_fh *fh)
+static inline struct mxc_isi_m2m_ctx *file_to_isi_m2m_ctx(struct file *filp)
{
- return container_of(fh, struct mxc_isi_m2m_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct mxc_isi_m2m_ctx, fh);
}
static inline struct mxc_isi_m2m_ctx_queue_data *
@@ -236,6 +235,70 @@ static void mxc_isi_m2m_vb2_buffer_queue(struct vb2_buffer *vb2)
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
}
+static int mxc_isi_m2m_vb2_prepare_streaming(struct vb2_queue *q)
+{
+ struct mxc_isi_m2m_ctx *ctx = vb2_get_drv_priv(q);
+ const struct v4l2_pix_format_mplane *out_pix = &ctx->queues.out.format;
+ const struct v4l2_pix_format_mplane *cap_pix = &ctx->queues.cap.format;
+ const struct mxc_isi_format_info *cap_info = ctx->queues.cap.info;
+ const struct mxc_isi_format_info *out_info = ctx->queues.out.info;
+ struct mxc_isi_m2m *m2m = ctx->m2m;
+ int ret;
+
+ guard(mutex)(&m2m->lock);
+
+ if (m2m->usage_count == INT_MAX)
+ return -EOVERFLOW;
+
+ ret = pm_runtime_resume_and_get(m2m->isi->dev);
+ if (ret)
+ return ret;
+
+ /*
+ * Acquire the pipe and initialize the channel with the first user of
+ * the M2M device.
+ */
+ if (m2m->usage_count == 0) {
+ bool bypass = cap_pix->width == out_pix->width &&
+ cap_pix->height == out_pix->height &&
+ cap_info->encoding == out_info->encoding;
+
+ ret = mxc_isi_channel_acquire(m2m->pipe,
+ &mxc_isi_m2m_frame_write_done,
+ bypass);
+ if (ret)
+ goto err_pm;
+
+ mxc_isi_channel_get(m2m->pipe);
+ }
+
+ m2m->usage_count++;
+
+ /*
+ * Allocate resources for the channel, counting how many users require
+ * buffer chaining.
+ */
+ if (!ctx->chained && out_pix->width > MXC_ISI_MAX_WIDTH_UNCHAINED) {
+ ret = mxc_isi_channel_chain(m2m->pipe);
+ if (ret)
+ goto err_deinit;
+
+ m2m->chained_count++;
+ ctx->chained = true;
+ }
+
+ return 0;
+
+err_deinit:
+ if (--m2m->usage_count == 0) {
+ mxc_isi_channel_put(m2m->pipe);
+ mxc_isi_channel_release(m2m->pipe);
+ }
+err_pm:
+ pm_runtime_put(m2m->isi->dev);
+ return ret;
+}
+
static int mxc_isi_m2m_vb2_start_streaming(struct vb2_queue *q,
unsigned int count)
{
@@ -265,13 +328,46 @@ static void mxc_isi_m2m_vb2_stop_streaming(struct vb2_queue *q)
}
}
+static void mxc_isi_m2m_vb2_unprepare_streaming(struct vb2_queue *q)
+{
+ struct mxc_isi_m2m_ctx *ctx = vb2_get_drv_priv(q);
+ struct mxc_isi_m2m *m2m = ctx->m2m;
+
+ guard(mutex)(&m2m->lock);
+
+ /*
+ * If the last context is this one, reset it to make sure the device
+ * will be reconfigured when streaming is restarted.
+ */
+ if (m2m->last_ctx == ctx)
+ m2m->last_ctx = NULL;
+
+ /* Free the channel resources if this is the last chained context. */
+ if (ctx->chained && --m2m->chained_count == 0)
+ mxc_isi_channel_unchain(m2m->pipe);
+ ctx->chained = false;
+
+ /* Turn off the light with the last user. */
+ if (--m2m->usage_count == 0) {
+ mxc_isi_channel_disable(m2m->pipe);
+ mxc_isi_channel_put(m2m->pipe);
+ mxc_isi_channel_release(m2m->pipe);
+ }
+
+ WARN_ON(m2m->usage_count < 0);
+
+ pm_runtime_put(m2m->isi->dev);
+}
+
static const struct vb2_ops mxc_isi_m2m_vb2_qops = {
.queue_setup = mxc_isi_m2m_vb2_queue_setup,
.buf_init = mxc_isi_m2m_vb2_buffer_init,
.buf_prepare = mxc_isi_m2m_vb2_buffer_prepare,
.buf_queue = mxc_isi_m2m_vb2_buffer_queue,
+ .prepare_streaming = mxc_isi_m2m_vb2_prepare_streaming,
.start_streaming = mxc_isi_m2m_vb2_start_streaming,
.stop_streaming = mxc_isi_m2m_vb2_stop_streaming,
+ .unprepare_streaming = mxc_isi_m2m_vb2_unprepare_streaming,
};
static int mxc_isi_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
@@ -427,7 +523,7 @@ static int mxc_isi_m2m_try_fmt_vid(struct file *file, void *fh,
const enum mxc_isi_video_type type =
f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
MXC_ISI_VIDEO_M2M_OUT : MXC_ISI_VIDEO_M2M_CAP;
- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
+ struct mxc_isi_m2m_ctx *ctx = file_to_isi_m2m_ctx(file);
__mxc_isi_m2m_try_fmt_vid(ctx, &f->fmt.pix_mp, type);
@@ -437,7 +533,7 @@ static int mxc_isi_m2m_try_fmt_vid(struct file *file, void *fh,
static int mxc_isi_m2m_g_fmt_vid(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
+ struct mxc_isi_m2m_ctx *ctx = file_to_isi_m2m_ctx(file);
const struct mxc_isi_m2m_ctx_queue_data *qdata =
mxc_isi_m2m_ctx_qdata(ctx, f->type);
@@ -452,7 +548,7 @@ static int mxc_isi_m2m_s_fmt_vid(struct file *file, void *fh,
const enum mxc_isi_video_type type =
f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
MXC_ISI_VIDEO_M2M_OUT : MXC_ISI_VIDEO_M2M_CAP;
- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
+ struct mxc_isi_m2m_ctx *ctx = file_to_isi_m2m_ctx(file);
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
const struct mxc_isi_format_info *info;
struct vb2_queue *vq;
@@ -481,136 +577,6 @@ static int mxc_isi_m2m_s_fmt_vid(struct file *file, void *fh,
return 0;
}
-static int mxc_isi_m2m_streamon(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
- struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type);
- const struct v4l2_pix_format_mplane *out_pix = &ctx->queues.out.format;
- const struct v4l2_pix_format_mplane *cap_pix = &ctx->queues.cap.format;
- const struct mxc_isi_format_info *cap_info = ctx->queues.cap.info;
- const struct mxc_isi_format_info *out_info = ctx->queues.out.info;
- struct mxc_isi_m2m *m2m = ctx->m2m;
- bool bypass;
- int ret;
-
- if (q->streaming)
- return 0;
-
- mutex_lock(&m2m->lock);
-
- if (m2m->usage_count == INT_MAX) {
- ret = -EOVERFLOW;
- goto unlock;
- }
-
- bypass = cap_pix->width == out_pix->width &&
- cap_pix->height == out_pix->height &&
- cap_info->encoding == out_info->encoding;
-
- /*
- * Acquire the pipe and initialize the channel with the first user of
- * the M2M device.
- */
- if (m2m->usage_count == 0) {
- ret = mxc_isi_channel_acquire(m2m->pipe,
- &mxc_isi_m2m_frame_write_done,
- bypass);
- if (ret)
- goto unlock;
-
- mxc_isi_channel_get(m2m->pipe);
- }
-
- m2m->usage_count++;
-
- /*
- * Allocate resources for the channel, counting how many users require
- * buffer chaining.
- */
- if (!ctx->chained && out_pix->width > MXC_ISI_MAX_WIDTH_UNCHAINED) {
- ret = mxc_isi_channel_chain(m2m->pipe, bypass);
- if (ret)
- goto deinit;
-
- m2m->chained_count++;
- ctx->chained = true;
- }
-
- /*
- * Drop the lock to start the stream, as the .device_run() operation
- * needs to acquire it.
- */
- mutex_unlock(&m2m->lock);
- ret = v4l2_m2m_ioctl_streamon(file, fh, type);
- if (ret) {
- /* Reacquire the lock for the cleanup path. */
- mutex_lock(&m2m->lock);
- goto unchain;
- }
-
- q->streaming = true;
-
- return 0;
-
-unchain:
- if (ctx->chained && --m2m->chained_count == 0)
- mxc_isi_channel_unchain(m2m->pipe);
- ctx->chained = false;
-
-deinit:
- if (--m2m->usage_count == 0) {
- mxc_isi_channel_put(m2m->pipe);
- mxc_isi_channel_release(m2m->pipe);
- }
-
-unlock:
- mutex_unlock(&m2m->lock);
- return ret;
-}
-
-static int mxc_isi_m2m_streamoff(struct file *file, void *fh,
- enum v4l2_buf_type type)
-{
- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh);
- struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type);
- struct mxc_isi_m2m *m2m = ctx->m2m;
-
- v4l2_m2m_ioctl_streamoff(file, fh, type);
-
- if (!q->streaming)
- return 0;
-
- mutex_lock(&m2m->lock);
-
- /*
- * If the last context is this one, reset it to make sure the device
- * will be reconfigured when streaming is restarted.
- */
- if (m2m->last_ctx == ctx)
- m2m->last_ctx = NULL;
-
- /* Free the channel resources if this is the last chained context. */
- if (ctx->chained && --m2m->chained_count == 0)
- mxc_isi_channel_unchain(m2m->pipe);
- ctx->chained = false;
-
- /* Turn off the light with the last user. */
- if (--m2m->usage_count == 0) {
- mxc_isi_channel_disable(m2m->pipe);
- mxc_isi_channel_put(m2m->pipe);
- mxc_isi_channel_release(m2m->pipe);
- }
-
- WARN_ON(m2m->usage_count < 0);
-
- mutex_unlock(&m2m->lock);
-
- q->streaming = false;
-
- return 0;
-}
-
static const struct v4l2_ioctl_ops mxc_isi_m2m_ioctl_ops = {
.vidioc_querycap = mxc_isi_m2m_querycap,
@@ -631,8 +597,8 @@ static const struct v4l2_ioctl_ops mxc_isi_m2m_ioctl_ops = {
.vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
.vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
- .vidioc_streamon = mxc_isi_m2m_streamon,
- .vidioc_streamoff = mxc_isi_m2m_streamoff,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -668,7 +634,6 @@ static int mxc_isi_m2m_open(struct file *file)
mutex_init(&ctx->vb2_lock);
v4l2_fh_init(&ctx->fh, vdev);
- file->private_data = &ctx->fh;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(m2m->m2m_dev, ctx,
&mxc_isi_m2m_queue_init);
@@ -685,16 +650,10 @@ static int mxc_isi_m2m_open(struct file *file)
if (ret)
goto err_ctx;
- ret = pm_runtime_resume_and_get(m2m->isi->dev);
- if (ret)
- goto err_ctrls;
-
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
return 0;
-err_ctrls:
- mxc_isi_m2m_ctx_ctrls_delete(ctx);
err_ctx:
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
err_fh:
@@ -706,20 +665,17 @@ err_fh:
static int mxc_isi_m2m_release(struct file *file)
{
- struct mxc_isi_m2m *m2m = video_drvdata(file);
- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(file->private_data);
+ struct mxc_isi_m2m_ctx *ctx = file_to_isi_m2m_ctx(file);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
mxc_isi_m2m_ctx_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mutex_destroy(&ctx->vb2_lock);
kfree(ctx);
- pm_runtime_put(m2m->isi->dev);
-
return 0;
}
@@ -733,6 +689,40 @@ static const struct v4l2_file_operations mxc_isi_m2m_fops = {
};
/* -----------------------------------------------------------------------------
+ * Suspend & resume
+ */
+
+void mxc_isi_m2m_suspend(struct mxc_isi_m2m *m2m)
+{
+ if (m2m->usage_count == 0)
+ return;
+
+ v4l2_m2m_suspend(m2m->m2m_dev);
+
+ if (m2m->chained_count > 0)
+ mxc_isi_channel_unchain(m2m->pipe);
+
+ mxc_isi_channel_disable(m2m->pipe);
+ mxc_isi_channel_put(m2m->pipe);
+}
+
+int mxc_isi_m2m_resume(struct mxc_isi_m2m *m2m)
+{
+ if (m2m->usage_count == 0)
+ return 0;
+
+ mxc_isi_channel_get(m2m->pipe);
+
+ if (m2m->chained_count > 0)
+ mxc_isi_channel_chain(m2m->pipe);
+
+ m2m->last_ctx = NULL;
+ v4l2_m2m_resume(m2m->m2m_dev);
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
* Registration
*/
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c
index d76eb58deb09..a41c51dd9ce0 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-pipe.c
@@ -855,7 +855,7 @@ int mxc_isi_pipe_acquire(struct mxc_isi_pipe *pipe,
/* Chain the channel if needed for wide resolutions. */
if (sink_fmt->width > MXC_ISI_MAX_WIDTH_UNCHAINED) {
- ret = mxc_isi_channel_chain(pipe, bypass);
+ ret = mxc_isi_channel_chain(pipe);
if (ret)
mxc_isi_channel_release(pipe);
}
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
index 8654150728a8..13682bf6e9f8 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
@@ -937,6 +937,47 @@ static void mxc_isi_video_init_channel(struct mxc_isi_video *video)
mxc_isi_channel_set_output_format(pipe, video->fmtinfo, &video->pix);
}
+static int mxc_isi_vb2_prepare_streaming(struct vb2_queue *q)
+{
+ struct mxc_isi_video *video = vb2_get_drv_priv(q);
+ struct media_device *mdev = &video->pipe->isi->media_dev;
+ struct media_pipeline *pipe;
+ int ret;
+
+ /* Get a pipeline for the video node and start it. */
+ scoped_guard(mutex, &mdev->graph_mutex) {
+ ret = mxc_isi_pipe_acquire(video->pipe,
+ &mxc_isi_video_frame_write_done);
+ if (ret)
+ return ret;
+
+ pipe = media_entity_pipeline(&video->vdev.entity)
+ ? : &video->pipe->pipe;
+
+ ret = __video_device_pipeline_start(&video->vdev, pipe);
+ if (ret)
+ goto err_release;
+ }
+
+ /* Verify that the video format matches the output of the subdev. */
+ ret = mxc_isi_video_validate_format(video);
+ if (ret)
+ goto err_stop;
+
+ /* Allocate buffers for discard operation. */
+ ret = mxc_isi_video_alloc_discard_buffers(video);
+ if (ret)
+ goto err_stop;
+
+ return 0;
+
+err_stop:
+ video_device_pipeline_stop(&video->vdev);
+err_release:
+ mxc_isi_pipe_release(video->pipe);
+ return ret;
+}
+
static int mxc_isi_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct mxc_isi_video *video = vb2_get_drv_priv(q);
@@ -985,13 +1026,24 @@ static void mxc_isi_vb2_stop_streaming(struct vb2_queue *q)
mxc_isi_video_return_buffers(video, VB2_BUF_STATE_ERROR);
}
+static void mxc_isi_vb2_unprepare_streaming(struct vb2_queue *q)
+{
+ struct mxc_isi_video *video = vb2_get_drv_priv(q);
+
+ mxc_isi_video_free_discard_buffers(video);
+ video_device_pipeline_stop(&video->vdev);
+ mxc_isi_pipe_release(video->pipe);
+}
+
static const struct vb2_ops mxc_isi_vb2_qops = {
.queue_setup = mxc_isi_vb2_queue_setup,
.buf_init = mxc_isi_vb2_buffer_init,
.buf_prepare = mxc_isi_vb2_buffer_prepare,
.buf_queue = mxc_isi_vb2_buffer_queue,
+ .prepare_streaming = mxc_isi_vb2_prepare_streaming,
.start_streaming = mxc_isi_vb2_start_streaming,
.stop_streaming = mxc_isi_vb2_stop_streaming,
+ .unprepare_streaming = mxc_isi_vb2_unprepare_streaming,
};
/* -----------------------------------------------------------------------------
@@ -1145,97 +1197,6 @@ static int mxc_isi_video_s_fmt(struct file *file, void *priv,
return 0;
}
-static int mxc_isi_video_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct mxc_isi_video *video = video_drvdata(file);
- struct media_device *mdev = &video->pipe->isi->media_dev;
- struct media_pipeline *pipe;
- int ret;
-
- if (vb2_queue_is_busy(&video->vb2_q, file))
- return -EBUSY;
-
- /*
- * Get a pipeline for the video node and start it. This must be done
- * here and not in the queue .start_streaming() handler, so that
- * pipeline start errors can be reported from VIDIOC_STREAMON and not
- * delayed until subsequent VIDIOC_QBUF calls.
- */
- mutex_lock(&mdev->graph_mutex);
-
- ret = mxc_isi_pipe_acquire(video->pipe, &mxc_isi_video_frame_write_done);
- if (ret) {
- mutex_unlock(&mdev->graph_mutex);
- return ret;
- }
-
- pipe = media_entity_pipeline(&video->vdev.entity) ? : &video->pipe->pipe;
-
- ret = __video_device_pipeline_start(&video->vdev, pipe);
- if (ret) {
- mutex_unlock(&mdev->graph_mutex);
- goto err_release;
- }
-
- mutex_unlock(&mdev->graph_mutex);
-
- /* Verify that the video format matches the output of the subdev. */
- ret = mxc_isi_video_validate_format(video);
- if (ret)
- goto err_stop;
-
- /* Allocate buffers for discard operation. */
- ret = mxc_isi_video_alloc_discard_buffers(video);
- if (ret)
- goto err_stop;
-
- ret = vb2_streamon(&video->vb2_q, type);
- if (ret)
- goto err_free;
-
- video->is_streaming = true;
-
- return 0;
-
-err_free:
- mxc_isi_video_free_discard_buffers(video);
-err_stop:
- video_device_pipeline_stop(&video->vdev);
-err_release:
- mxc_isi_pipe_release(video->pipe);
- return ret;
-}
-
-static void mxc_isi_video_cleanup_streaming(struct mxc_isi_video *video)
-{
- lockdep_assert_held(&video->lock);
-
- if (!video->is_streaming)
- return;
-
- mxc_isi_video_free_discard_buffers(video);
- video_device_pipeline_stop(&video->vdev);
- mxc_isi_pipe_release(video->pipe);
-
- video->is_streaming = false;
-}
-
-static int mxc_isi_video_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct mxc_isi_video *video = video_drvdata(file);
- int ret;
-
- ret = vb2_ioctl_streamoff(file, priv, type);
- if (ret)
- return ret;
-
- mxc_isi_video_cleanup_streaming(video);
-
- return 0;
-}
-
static int mxc_isi_video_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
@@ -1291,9 +1252,8 @@ static const struct v4l2_ioctl_ops mxc_isi_video_ioctl_ops = {
.vidioc_expbuf = vb2_ioctl_expbuf,
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
-
- .vidioc_streamon = mxc_isi_video_streamon,
- .vidioc_streamoff = mxc_isi_video_streamoff,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
.vidioc_enum_framesizes = mxc_isi_video_enum_framesizes,
@@ -1332,10 +1292,6 @@ static int mxc_isi_video_release(struct file *file)
if (ret)
dev_err(video->pipe->isi->dev, "%s fail\n", __func__);
- mutex_lock(&video->lock);
- mxc_isi_video_cleanup_streaming(video);
- mutex_unlock(&video->lock);
-
pm_runtime_put(video->pipe->isi->dev);
return ret;
}
@@ -1357,7 +1313,7 @@ void mxc_isi_video_suspend(struct mxc_isi_pipe *pipe)
{
struct mxc_isi_video *video = &pipe->video;
- if (!video->is_streaming)
+ if (!vb2_is_streaming(&video->vb2_q))
return;
mxc_isi_pipe_disable(pipe);
@@ -1388,7 +1344,7 @@ int mxc_isi_video_resume(struct mxc_isi_pipe *pipe)
{
struct mxc_isi_video *video = &pipe->video;
- if (!video->is_streaming)
+ if (!vb2_is_streaming(&video->vb2_q))
return 0;
mxc_isi_video_init_channel(video);
diff --git a/drivers/media/platform/nxp/mx2_emmaprp.c b/drivers/media/platform/nxp/mx2_emmaprp.c
index 0c6cc120fd2a..3aae8c0b690c 100644
--- a/drivers/media/platform/nxp/mx2_emmaprp.c
+++ b/drivers/media/platform/nxp/mx2_emmaprp.c
@@ -214,6 +214,11 @@ struct emmaprp_ctx {
struct emmaprp_q_data q_data[2];
};
+static inline struct emmaprp_ctx *file_to_emmaprp_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct emmaprp_ctx, fh);
+}
+
static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx,
enum v4l2_buf_type type)
{
@@ -451,13 +456,13 @@ static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- return vidioc_g_fmt(priv, f);
+ return vidioc_g_fmt(file_to_emmaprp_ctx(file), f);
}
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- return vidioc_g_fmt(priv, f);
+ return vidioc_g_fmt(file_to_emmaprp_ctx(file), f);
}
static int vidioc_try_fmt(struct v4l2_format *f)
@@ -497,8 +502,8 @@ static int vidioc_try_fmt(struct v4l2_format *f)
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct emmaprp_ctx *ctx = file_to_emmaprp_ctx(file);
struct emmaprp_fmt *fmt;
- struct emmaprp_ctx *ctx = priv;
fmt = find_format(f);
if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
@@ -514,8 +519,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct emmaprp_ctx *ctx = file_to_emmaprp_ctx(file);
struct emmaprp_fmt *fmt;
- struct emmaprp_ctx *ctx = priv;
fmt = find_format(f);
if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
@@ -575,7 +580,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
if (ret)
return ret;
- return vidioc_s_fmt(priv, f);
+ return vidioc_s_fmt(file_to_emmaprp_ctx(file), f);
}
static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
@@ -587,7 +592,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
if (ret)
return ret;
- return vidioc_s_fmt(priv, f);
+ return vidioc_s_fmt(file_to_emmaprp_ctx(file), f);
}
static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = {
@@ -725,7 +730,6 @@ static int emmaprp_open(struct file *file)
return -ENOMEM;
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = pcdev;
if (mutex_lock_interruptible(&pcdev->dev_mutex)) {
@@ -747,7 +751,7 @@ static int emmaprp_open(struct file *file)
clk_prepare_enable(pcdev->clk_emma_ahb);
ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1];
ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
mutex_unlock(&pcdev->dev_mutex);
dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx);
@@ -758,14 +762,14 @@ static int emmaprp_open(struct file *file)
static int emmaprp_release(struct file *file)
{
struct emmaprp_dev *pcdev = video_drvdata(file);
- struct emmaprp_ctx *ctx = file->private_data;
+ struct emmaprp_ctx *ctx = file_to_emmaprp_ctx(file);
dprintk(pcdev, "Releasing instance %p\n", ctx);
mutex_lock(&pcdev->dev_mutex);
clk_disable_unprepare(pcdev->clk_emma_ahb);
clk_disable_unprepare(pcdev->clk_emma_ipg);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
mutex_unlock(&pcdev->dev_mutex);
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index d26a9c24a430..23960d02877d 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -6,9 +6,10 @@ qcom-camss-objs += \
camss-csid.o \
camss-csid-4-1.o \
camss-csid-4-7.o \
+ camss-csid-340.o \
camss-csid-680.o \
camss-csid-gen2.o \
- camss-csid-780.o \
+ camss-csid-gen3.o \
camss-csiphy-2ph-1-0.o \
camss-csiphy-3ph-1-0.o \
camss-csiphy.o \
@@ -17,9 +18,10 @@ qcom-camss-objs += \
camss-vfe-4-7.o \
camss-vfe-4-8.o \
camss-vfe-17x.o \
+ camss-vfe-340.o \
camss-vfe-480.o \
camss-vfe-680.o \
- camss-vfe-780.o \
+ camss-vfe-gen3.o \
camss-vfe-gen1.o \
camss-vfe.o \
camss-video.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csid-340.c b/drivers/media/platform/qcom/camss/camss-csid-340.c
new file mode 100644
index 000000000000..22a30510fb79
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-340.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module 340
+ *
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/completion.h>
+#include <linux/bitfield.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include "camss.h"
+#include "camss-csid.h"
+#include "camss-csid-gen2.h"
+
+#define CSID_RST_STROBES (0x010)
+#define CSID_RST_SW_REGS BIT(0)
+#define CSID_RST_IRQ BIT(1)
+#define CSID_RST_IFE_CLK BIT(2)
+#define CSID_RST_PHY_CLK BIT(3)
+#define CSID_RST_CSID_CLK BIT(4)
+
+#define CSID_IRQ_STATUS (0x070)
+#define CSID_IRQ_MASK (0x074)
+#define CSID_IRQ_MASK_RST_DONE BIT(0)
+#define CSID_IRQ_CLEAR (0x078)
+#define CSID_IRQ_CMD (0x080)
+#define CSID_IRQ_CMD_CLEAR BIT(0)
+
+#define CSID_CSI2_RX_CFG0 (0x100)
+#define CSI2_RX_CFG0_NUM_ACTIVE_LANES_MASK GENMASK(1, 0)
+#define CSI2_RX_CFG0_DLX_INPUT_SEL_MASK GENMASK(17, 4)
+#define CSI2_RX_CFG0_PHY_NUM_SEL_MASK GENMASK(21, 20)
+#define CSI2_RX_CFG0_PHY_NUM_SEL_BASE_IDX 1
+#define CSI2_RX_CFG0_PHY_TYPE_SEL BIT(24)
+
+#define CSID_CSI2_RX_CFG1 (0x104)
+#define CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN BIT(0)
+#define CSI2_RX_CFG1_MISR_EN BIT(6)
+#define CSI2_RX_CFG1_CGC_MODE BIT(7)
+
+#define CSID_RDI_CFG0(rdi) (0x300 + 0x100 * (rdi))
+#define CSID_RDI_CFG0_BYTE_CNTR_EN BIT(0)
+#define CSID_RDI_CFG0_TIMESTAMP_EN BIT(1)
+#define CSID_RDI_CFG0_DECODE_FORMAT_MASK GENMASK(15, 12)
+#define CSID_RDI_CFG0_DECODE_FORMAT_NOP CSID_RDI_CFG0_DECODE_FORMAT_MASK
+#define CSID_RDI_CFG0_DT_MASK GENMASK(21, 16)
+#define CSID_RDI_CFG0_VC_MASK GENMASK(23, 22)
+#define CSID_RDI_CFG0_DTID_MASK GENMASK(28, 27)
+#define CSID_RDI_CFG0_ENABLE BIT(31)
+
+#define CSID_RDI_CTRL(rdi) (0x308 + 0x100 * (rdi))
+#define CSID_RDI_CTRL_HALT_AT_FRAME_BOUNDARY 0
+#define CSID_RDI_CTRL_RESUME_AT_FRAME_BOUNDARY 1
+
+static void __csid_configure_rx(struct csid_device *csid,
+ struct csid_phy_config *phy, int vc)
+{
+ u32 val;
+
+ val = FIELD_PREP(CSI2_RX_CFG0_NUM_ACTIVE_LANES_MASK, phy->lane_cnt - 1);
+ val |= FIELD_PREP(CSI2_RX_CFG0_DLX_INPUT_SEL_MASK, phy->lane_assign);
+ val |= FIELD_PREP(CSI2_RX_CFG0_PHY_NUM_SEL_MASK,
+ phy->csiphy_id + CSI2_RX_CFG0_PHY_NUM_SEL_BASE_IDX);
+ writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
+
+ val = CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
+ writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
+}
+
+static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
+{
+ writel_relaxed(!!enable, csid->base + CSID_RDI_CTRL(rdi));
+}
+
+static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc)
+{
+ struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
+ const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
+ csid->res->formats->nformats,
+ input_format->code);
+ u8 lane_cnt = csid->phy.lane_cnt;
+ u8 dt_id;
+ u32 val;
+
+ if (!lane_cnt)
+ lane_cnt = 4;
+
+ /*
+ * DT_ID is a two bit bitfield that is concatenated with
+ * the four least significant bits of the five bit VC
+ * bitfield to generate an internal CID value.
+ *
+ * CSID_RDI_CFG0(vc)
+ * DT_ID : 28:27
+ * VC : 26:22
+ * DT : 21:16
+ *
+ * CID : VC 3:0 << 2 | DT_ID 1:0
+ */
+ dt_id = vc & 0x03;
+
+ val = CSID_RDI_CFG0_DECODE_FORMAT_NOP; /* only for RDI path */
+ val |= FIELD_PREP(CSID_RDI_CFG0_DT_MASK, format->data_type);
+ val |= FIELD_PREP(CSID_RDI_CFG0_VC_MASK, vc);
+ val |= FIELD_PREP(CSID_RDI_CFG0_DTID_MASK, dt_id);
+
+ if (enable)
+ val |= CSID_RDI_CFG0_ENABLE;
+
+ dev_dbg(csid->camss->dev, "CSID%u: Stream %s (dt:0x%x vc=%u)\n",
+ csid->id, enable ? "enable" : "disable", format->data_type, vc);
+
+ writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
+}
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ int i;
+
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ __csid_configure_rdi_stream(csid, enable, i);
+ __csid_configure_rx(csid, &csid->phy, i);
+ __csid_ctrl_rdi(csid, enable, i);
+ }
+ }
+}
+
+static int csid_reset(struct csid_device *csid)
+{
+ unsigned long time;
+
+ writel_relaxed(CSID_IRQ_MASK_RST_DONE, csid->base + CSID_IRQ_MASK);
+ writel_relaxed(CSID_IRQ_MASK_RST_DONE, csid->base + CSID_IRQ_CLEAR);
+ writel_relaxed(CSID_IRQ_CMD_CLEAR, csid->base + CSID_IRQ_CMD);
+
+ reinit_completion(&csid->reset_complete);
+
+ /* Reset with registers preserved */
+ writel(CSID_RST_IRQ | CSID_RST_IFE_CLK | CSID_RST_PHY_CLK | CSID_RST_CSID_CLK,
+ csid->base + CSID_RST_STROBES);
+
+ time = wait_for_completion_timeout(&csid->reset_complete,
+ msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+ if (!time) {
+ dev_err(csid->camss->dev, "CSID%u: reset timeout\n", csid->id);
+ return -EIO;
+ }
+
+ dev_dbg(csid->camss->dev, "CSID%u: reset done\n", csid->id);
+
+ return 0;
+}
+
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+ struct csid_device *csid = dev;
+ u32 val;
+
+ val = readl_relaxed(csid->base + CSID_IRQ_STATUS);
+ writel_relaxed(val, csid->base + CSID_IRQ_CLEAR);
+ writel_relaxed(CSID_IRQ_CMD_CLEAR, csid->base + CSID_IRQ_CMD);
+
+ if (val & CSID_IRQ_MASK_RST_DONE)
+ complete(&csid->reset_complete);
+ else
+ dev_warn_ratelimited(csid->camss->dev, "Spurious CSID interrupt\n");
+
+ return IRQ_HANDLED;
+}
+
+static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
+{
+ return -EOPNOTSUPP; /* Not part of CSID */
+}
+
+static void csid_subdev_init(struct csid_device *csid) {}
+
+const struct csid_hw_ops csid_ops_340 = {
+ .configure_testgen_pattern = csid_configure_testgen_pattern,
+ .configure_stream = csid_configure_stream,
+ .hw_version = csid_hw_version,
+ .isr = csid_isr,
+ .reset = csid_reset,
+ .src_pad_code = csid_src_pad_code,
+ .subdev_init = csid_subdev_init,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csid-780.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
index 4c720d177731..664245cf6eb0 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-780.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c
@@ -13,7 +13,7 @@
#include "camss.h"
#include "camss-csid.h"
-#include "camss-csid-780.h"
+#include "camss-csid-gen3.h"
#define CSID_IO_PATH_CFG0(csid) (0x4 * (csid))
#define OUTPUT_IFE_EN 0x100
@@ -45,8 +45,12 @@
#define CSID_CSI2_RX_IRQ_CLEAR 0xA4
#define CSID_CSI2_RX_IRQ_SET 0xA8
+#define IS_CSID_690(csid) ((csid->camss->res->version == CAMSS_8775P) \
+ || (csid->camss->res->version == CAMSS_8300))
#define CSID_BUF_DONE_IRQ_STATUS 0x8C
-#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ? 1 : 14)
+#define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ?\
+ 1 : (IS_CSID_690(csid) ?\
+ 13 : 14))
#define CSID_BUF_DONE_IRQ_MASK 0x90
#define CSID_BUF_DONE_IRQ_CLEAR 0x94
#define CSID_BUF_DONE_IRQ_SET 0x98
@@ -59,6 +63,7 @@
#define CSID_CSI2_RX_CFG0 0x200
#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
+#define CSI2_RX_CFG0_VC_MODE 3
#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
#define CSI2_RX_CFG0_PHY_NUM_SEL 20
@@ -66,7 +71,9 @@
#define CSI2_RX_CFG1_ECC_CORRECTION_EN BIT(0)
#define CSI2_RX_CFG1_VC_MODE BIT(2)
-#define CSID_RDI_CFG0(rdi) (0x500 + 0x100 * (rdi))
+#define CSID_RDI_CFG0(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\
+ (0x300 + 0x100 * (rdi)) :\
+ (0x500 + 0x100 * (rdi)))
#define RDI_CFG0_TIMESTAMP_EN BIT(6)
#define RDI_CFG0_TIMESTAMP_STB_SEL BIT(8)
#define RDI_CFG0_DECODE_FORMAT 12
@@ -75,10 +82,14 @@
#define RDI_CFG0_DT_ID 27
#define RDI_CFG0_EN BIT(31)
-#define CSID_RDI_CTRL(rdi) (0x504 + 0x100 * (rdi))
+#define CSID_RDI_CTRL(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\
+ (0x304 + 0x100 * (rdi)) :\
+ (0x504 + 0x100 * (rdi)))
#define RDI_CTRL_START_CMD BIT(0)
-#define CSID_RDI_CFG1(rdi) (0x510 + 0x100 * (rdi))
+#define CSID_RDI_CFG1(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\
+ (0x310 + 0x100 * (rdi)) :\
+ (0x510 + 0x100 * (rdi)))
#define RDI_CFG1_DROP_H_EN BIT(5)
#define RDI_CFG1_DROP_V_EN BIT(6)
#define RDI_CFG1_CROP_H_EN BIT(7)
@@ -86,9 +97,12 @@
#define RDI_CFG1_PIX_STORE BIT(10)
#define RDI_CFG1_PACKING_FORMAT_MIPI BIT(15)
-#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) (0x548 + 0x100 * (rdi))
-#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) (0x54C + 0x100 * (rdi))
-
+#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\
+ (0x348 + 0x100 * (rdi)) :\
+ (0x548 + 0x100 * (rdi)))
+#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\
+ (0x34C + 0x100 * (rdi)) :\
+ (0x54C + 0x100 * (rdi)))
#define CSI2_RX_CFG0_PHY_SEL_BASE_IDX 1
static void __csid_configure_rx(struct csid_device *csid,
@@ -259,7 +273,7 @@ static irqreturn_t csid_isr(int irq, void *dev)
if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i)) {
/*
- * For Titan 780, bus done and RUP IRQ have been moved to
+ * For Titan Gen3, bus done and RUP IRQ have been moved to
* CSID from VFE. Once CSID received bus done, need notify
* VFE of this event. Trigger VFE to handle bus done process.
*/
@@ -325,7 +339,7 @@ static void csid_subdev_init(struct csid_device *csid)
csid->testgen.nmodes = CSID_PAYLOAD_MODE_DISABLED;
}
-const struct csid_hw_ops csid_ops_780 = {
+const struct csid_hw_ops csid_ops_gen3 = {
.configure_stream = csid_configure_stream,
.configure_testgen_pattern = csid_configure_testgen_pattern,
.hw_version = csid_hw_version,
diff --git a/drivers/media/platform/qcom/camss/camss-csid-780.h b/drivers/media/platform/qcom/camss/camss-csid-gen3.h
index a990c66a60ff..6ee62da770c1 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-780.h
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.h
@@ -1,13 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * camss-csid-780.h
+ * camss-csid-gen3.h
*
* Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module Generation 3
*
* Copyright (c) 2024 Qualcomm Technologies, Inc.
*/
-#ifndef __QC_MSM_CAMSS_CSID_780_H__
-#define __QC_MSM_CAMSS_CSID_780_H__
+#ifndef __QC_MSM_CAMSS_CSID_GEN3_H__
+#define __QC_MSM_CAMSS_CSID_GEN3_H__
#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
@@ -22,4 +22,4 @@
#define PLAIN_FORMAT_PLAIN16 0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */
#define PLAIN_FORMAT_PLAIN32 0x2 /* supports UNCOMPRESSED_20_BIT */
-#endif /* __QC_MSM_CAMSS_CSID_780_H__ */
+#endif /* __QC_MSM_CAMSS_CSID_GEN3_H__ */
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 9dc826d8c8f6..aedc96ed84b2 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -213,9 +213,10 @@ extern const struct csid_formats csid_formats_gen2;
extern const struct csid_hw_ops csid_ops_4_1;
extern const struct csid_hw_ops csid_ops_4_7;
+extern const struct csid_hw_ops csid_ops_340;
extern const struct csid_hw_ops csid_ops_680;
extern const struct csid_hw_ops csid_ops_gen2;
-extern const struct csid_hw_ops csid_ops_780;
+extern const struct csid_hw_ops csid_ops_gen3;
/*
* csid_is_lite - Check if CSID is CSID lite.
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index 88c0ba495c32..a229ba04b158 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -64,6 +64,85 @@ struct csiphy_lane_regs {
u32 csiphy_param_type;
};
+/* 5nm 2PH v 1.3.0 2p5Gbps 4 lane DPHY mode */
+static const struct
+csiphy_lane_regs lane_regs_sa8775p[] = {
+ {0x0724, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x070C, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0708, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0024, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0000, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0224, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0200, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0208, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0424, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0400, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0408, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0624, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0600, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0608, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x005C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0060, 0xFD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x025C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0260, 0xFD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x045C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0460, 0xFD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x065C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0660, 0xFD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+};
+
/* GEN2 1.0 2PH */
static const struct
csiphy_lane_regs lane_regs_sdm845[] = {
@@ -319,6 +398,90 @@ csiphy_lane_regs lane_regs_sm8250[] = {
{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
};
+/* 14nm 2PH v 2.0.1 2p5Gbps 4 lane DPHY mode */
+static const struct
+csiphy_lane_regs lane_regs_qcm2290[] = {
+ {0x0030, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x002c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0034, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0028, 0x04, 0x00, CSIPHY_DNP_PARAMS},
+ {0x003c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x001c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0000, 0xd7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0004, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x000c, 0xff, 0x00, CSIPHY_DNP_PARAMS},
+ {0x0010, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0038, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0064, 0x3f, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0730, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x072c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0734, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x073c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x071c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0700, 0xc0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0704, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0720, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0708, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x070c, 0xff, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0710, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0738, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0764, 0x3f, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0230, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x022c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0234, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0228, 0x04, 0x00, CSIPHY_DNP_PARAMS},
+ {0x023c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x021c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0200, 0xd7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0204, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0220, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0208, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x020c, 0xff, 0x00, CSIPHY_DNP_PARAMS},
+ {0x0210, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0238, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0264, 0x3f, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0430, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x042c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0434, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0428, 0x04, 0x00, CSIPHY_DNP_PARAMS},
+ {0x043c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x041c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0400, 0xd7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0404, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0408, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x040C, 0xff, 0x00, CSIPHY_DNP_PARAMS},
+ {0x0410, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0438, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0464, 0x3f, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0630, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x062c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0634, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0628, 0x04, 0x00, CSIPHY_DNP_PARAMS},
+ {0x063c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x061c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0600, 0xd7, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0604, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0620, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0608, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x060C, 0xff, 0x00, CSIPHY_DNP_PARAMS},
+ {0x0610, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0638, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0664, 0x3f, 0x00, CSIPHY_DEFAULT_PARAMS},
+};
+
/* GEN2 2.1.2 2PH DPHY mode */
static const struct
csiphy_lane_regs lane_regs_sm8550[] = {
@@ -744,11 +907,14 @@ static bool csiphy_is_gen2(u32 version)
bool ret = false;
switch (version) {
+ case CAMSS_2290:
case CAMSS_7280:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8300:
case CAMSS_845:
case CAMSS_8550:
+ case CAMSS_8775P:
case CAMSS_X1E80100:
ret = true;
break;
@@ -829,6 +995,10 @@ static int csiphy_init(struct csiphy_device *csiphy)
regs->lane_regs = &lane_regs_sdm845[0];
regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845);
break;
+ case CAMSS_2290:
+ regs->lane_regs = &lane_regs_qcm2290[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_qcm2290);
+ break;
case CAMSS_7280:
case CAMSS_8250:
regs->lane_regs = &lane_regs_sm8250[0];
@@ -848,6 +1018,11 @@ static int csiphy_init(struct csiphy_device *csiphy)
regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550);
regs->offset = 0x1000;
break;
+ case CAMSS_8300:
+ case CAMSS_8775P:
+ regs->lane_regs = &lane_regs_sa8775p[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p);
+ break;
default:
break;
}
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-340.c b/drivers/media/platform/qcom/camss/camss-vfe-340.c
new file mode 100644
index 000000000000..30d7630b3e8b
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-340.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module 340 (TFE)
+ *
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/bitfield.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+#define TFE_GLOBAL_RESET_CMD (0x014)
+#define TFE_GLOBAL_RESET_CMD_CORE BIT(0)
+
+#define TFE_REG_UPDATE_CMD (0x02c)
+
+#define TFE_IRQ_CMD (0x030)
+#define TFE_IRQ_CMD_CLEAR BIT(0)
+#define TFE_IRQ_MASK_0 (0x034)
+#define TFE_IRQ_MASK_0_RST_DONE BIT(0)
+#define TFE_IRQ_MASK_0_BUS_WR BIT(1)
+#define TFE_IRQ_MASK_1 (0x038)
+#define TFE_IRQ_MASK_2 (0x03c)
+#define TFE_IRQ_CLEAR_0 (0x040)
+
+#define TFE_IRQ_STATUS_0 (0x04c)
+
+#define BUS_REG(a) (0xa00 + (a))
+
+#define TFE_BUS_IRQ_MASK_0 BUS_REG(0x18)
+#define TFE_BUS_IRQ_MASK_RUP_DONE_MASK GENMASK(3, 0)
+#define TFE_BUS_IRQ_MASK_RUP_DONE(sc) FIELD_PREP(TFE_BUS_IRQ_MASK_RUP_DONE_MASK, BIT(sc))
+#define TFE_BUS_IRQ_MASK_BUF_DONE_MASK GENMASK(15, 8)
+#define TFE_BUS_IRQ_MASK_BUF_DONE(sg) FIELD_PREP(TFE_BUS_IRQ_MASK_BUF_DONE_MASK, BIT(sg))
+#define TFE_BUS_IRQ_MASK_0_CONS_VIOL BIT(28)
+#define TFE_BUS_IRQ_MASK_0_VIOL BIT(30)
+#define TFE_BUS_IRQ_MASK_0_IMG_VIOL BIT(31)
+
+#define TFE_BUS_IRQ_MASK_1 BUS_REG(0x1c)
+#define TFE_BUS_IRQ_CLEAR_0 BUS_REG(0x20)
+#define TFE_BUS_IRQ_STATUS_0 BUS_REG(0x28)
+#define TFE_BUS_IRQ_CMD BUS_REG(0x30)
+#define TFE_BUS_IRQ_CMD_CLEAR BIT(0)
+
+#define TFE_BUS_STATUS_CLEAR BUS_REG(0x60)
+#define TFE_BUS_VIOLATION_STATUS BUS_REG(0x64)
+#define TFE_BUS_OVERFLOW_STATUS BUS_REG(0x68)
+#define TFE_BUS_IMAGE_SZ_VIOLATION_STATUS BUS_REG(0x70)
+
+#define TFE_BUS_CLIENT_CFG(c) BUS_REG(0x200 + (c) * 0x100)
+#define TFE_BUS_CLIENT_CFG_EN BIT(0)
+#define TFE_BUS_CLIENT_CFG_MODE_FRAME BIT(16)
+#define TFE_BUS_IMAGE_ADDR(c) BUS_REG(0x204 + (c) * 0x100)
+#define TFE_BUS_FRAME_INCR(c) BUS_REG(0x208 + (c) * 0x100)
+#define TFE_BUS_IMAGE_CFG_0(c) BUS_REG(0x20c + (c) * 0x100)
+#define TFE_BUS_IMAGE_CFG_0_DEFAULT 0xffff
+#define TFE_BUS_IMAGE_CFG_1(c) BUS_REG(0x210 + (c) * 0x100)
+#define TFE_BUS_IMAGE_CFG_2(c) BUS_REG(0x214 + (c) * 0x100)
+#define TFE_BUS_IMAGE_CFG_2_DEFAULT 0xffff
+#define TFE_BUS_PACKER_CFG(c) BUS_REG(0x218 + (c) * 0x100)
+#define TFE_BUS_PACKER_CFG_FMT_PLAIN64 0xa
+#define TFE_BUS_IRQ_SUBSAMPLE_CFG_0(c) BUS_REG(0x230 + (c) * 0x100)
+#define TFE_BUS_IRQ_SUBSAMPLE_CFG_1(c) BUS_REG(0x234 + (c) * 0x100)
+#define TFE_BUS_FRAMEDROP_CFG_0(c) BUS_REG(0x238 + (c) * 0x100)
+#define TFE_BUS_FRAMEDROP_CFG_1(c) BUS_REG(0x23c + (c) * 0x100)
+
+/*
+ * TODO: differentiate the port id based on requested type of RDI, BHIST etc
+ *
+ * TFE write master IDs (clients)
+ *
+ * BAYER 0
+ * IDEAL_RAW 1
+ * STATS_TINTLESS_BG 2
+ * STATS_BHIST 3
+ * STATS_AWB_BG 4
+ * STATS_AEC_BG 5
+ * STATS_BAF 6
+ * RDI0 7
+ * RDI1 8
+ * RDI2 9
+ */
+#define RDI_WM(n) (7 + (n))
+#define TFE_WM_NUM 10
+
+enum tfe_iface {
+ TFE_IFACE_PIX,
+ TFE_IFACE_RDI0,
+ TFE_IFACE_RDI1,
+ TFE_IFACE_RDI2,
+ TFE_IFACE_NUM
+};
+
+enum tfe_subgroups {
+ TFE_SUBGROUP_BAYER,
+ TFE_SUBGROUP_IDEAL_RAW,
+ TFE_SUBGROUP_HDR,
+ TFE_SUBGROUP_BG,
+ TFE_SUBGROUP_BAF,
+ TFE_SUBGROUP_RDI0,
+ TFE_SUBGROUP_RDI1,
+ TFE_SUBGROUP_RDI2,
+ TFE_SUBGROUP_NUM
+};
+
+static enum tfe_iface tfe_line_iface_map[VFE_LINE_NUM_MAX] = {
+ [VFE_LINE_RDI0] = TFE_IFACE_RDI0,
+ [VFE_LINE_RDI1] = TFE_IFACE_RDI1,
+ [VFE_LINE_RDI2] = TFE_IFACE_RDI2,
+ [VFE_LINE_PIX] = TFE_IFACE_PIX,
+};
+
+static enum vfe_line_id tfe_subgroup_line_map[TFE_SUBGROUP_NUM] = {
+ [TFE_SUBGROUP_BAYER] = VFE_LINE_PIX,
+ [TFE_SUBGROUP_IDEAL_RAW] = VFE_LINE_PIX,
+ [TFE_SUBGROUP_HDR] = VFE_LINE_PIX,
+ [TFE_SUBGROUP_BG] = VFE_LINE_PIX,
+ [TFE_SUBGROUP_BAF] = VFE_LINE_PIX,
+ [TFE_SUBGROUP_RDI0] = VFE_LINE_RDI0,
+ [TFE_SUBGROUP_RDI1] = VFE_LINE_RDI1,
+ [TFE_SUBGROUP_RDI2] = VFE_LINE_RDI2,
+};
+
+static inline enum tfe_iface __line_to_iface(enum vfe_line_id line_id)
+{
+ if (line_id <= VFE_LINE_NONE || line_id >= VFE_LINE_NUM_MAX) {
+ pr_warn("VFE: Invalid line %d\n", line_id);
+ return TFE_IFACE_RDI0;
+ }
+
+ return tfe_line_iface_map[line_id];
+}
+
+static inline enum vfe_line_id __iface_to_line(unsigned int iface)
+{
+ int i;
+
+ for (i = 0; i < VFE_LINE_NUM_MAX; i++) {
+ if (tfe_line_iface_map[i] == iface)
+ return i;
+ }
+
+ return VFE_LINE_NONE;
+}
+
+static inline enum vfe_line_id __subgroup_to_line(enum tfe_subgroups sg)
+{
+ if (sg >= TFE_SUBGROUP_NUM)
+ return VFE_LINE_NONE;
+
+ return tfe_subgroup_line_map[sg];
+}
+
+static void vfe_global_reset(struct vfe_device *vfe)
+{
+ writel(TFE_IRQ_MASK_0_RST_DONE, vfe->base + TFE_IRQ_MASK_0);
+ writel(TFE_GLOBAL_RESET_CMD_CORE, vfe->base + TFE_GLOBAL_RESET_CMD);
+}
+
+static irqreturn_t vfe_isr(int irq, void *dev)
+{
+ struct vfe_device *vfe = dev;
+ u32 status;
+ int i;
+
+ status = readl_relaxed(vfe->base + TFE_IRQ_STATUS_0);
+ writel_relaxed(status, vfe->base + TFE_IRQ_CLEAR_0);
+ writel_relaxed(TFE_IRQ_CMD_CLEAR, vfe->base + TFE_IRQ_CMD);
+
+ if (status & TFE_IRQ_MASK_0_RST_DONE) {
+ dev_dbg(vfe->camss->dev, "VFE%u: Reset done!", vfe->id);
+ vfe_isr_reset_ack(vfe);
+ }
+
+ if (status & TFE_IRQ_MASK_0_BUS_WR) {
+ u32 bus_status = readl_relaxed(vfe->base + TFE_BUS_IRQ_STATUS_0);
+
+ writel_relaxed(bus_status, vfe->base + TFE_BUS_IRQ_CLEAR_0);
+ writel_relaxed(TFE_BUS_IRQ_CMD_CLEAR, vfe->base + TFE_BUS_IRQ_CMD);
+
+ for (i = 0; i < TFE_IFACE_NUM; i++) {
+ if (bus_status & TFE_BUS_IRQ_MASK_RUP_DONE(i))
+ vfe->res->hw_ops->reg_update_clear(vfe, __iface_to_line(i));
+ }
+
+ for (i = 0; i < TFE_SUBGROUP_NUM; i++) {
+ if (bus_status & TFE_BUS_IRQ_MASK_BUF_DONE(i))
+ vfe_buf_done(vfe, __subgroup_to_line(i));
+ }
+
+ if (bus_status & TFE_BUS_IRQ_MASK_0_CONS_VIOL)
+ dev_err_ratelimited(vfe->camss->dev, "VFE%u: Bad config violation",
+ vfe->id);
+
+ if (bus_status & TFE_BUS_IRQ_MASK_0_VIOL)
+ dev_err_ratelimited(vfe->camss->dev, "VFE%u: Input data violation",
+ vfe->id);
+
+ if (bus_status & TFE_BUS_IRQ_MASK_0_IMG_VIOL)
+ dev_err_ratelimited(vfe->camss->dev, "VFE%u: Image size violation",
+ vfe->id);
+ }
+
+ status = readl_relaxed(vfe->base + TFE_BUS_OVERFLOW_STATUS);
+ if (status) {
+ writel_relaxed(status, vfe->base + TFE_BUS_STATUS_CLEAR);
+ for (i = 0; i < TFE_WM_NUM; i++) {
+ if (status & BIT(i))
+ dev_err_ratelimited(vfe->camss->dev,
+ "VFE%u: bus overflow for wm %u\n",
+ vfe->id, i);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int vfe_halt(struct vfe_device *vfe)
+{
+ /* rely on vfe_disable_output() to stop the VFE */
+ return 0;
+}
+
+static void vfe_enable_irq(struct vfe_device *vfe)
+{
+ writel(TFE_IRQ_MASK_0_RST_DONE | TFE_IRQ_MASK_0_BUS_WR,
+ vfe->base + TFE_IRQ_MASK_0);
+ writel(TFE_BUS_IRQ_MASK_RUP_DONE_MASK | TFE_BUS_IRQ_MASK_BUF_DONE_MASK |
+ TFE_BUS_IRQ_MASK_0_CONS_VIOL | TFE_BUS_IRQ_MASK_0_VIOL |
+ TFE_BUS_IRQ_MASK_0_IMG_VIOL, vfe->base + TFE_BUS_IRQ_MASK_0);
+}
+
+static void vfe_wm_update(struct vfe_device *vfe, u8 rdi, u32 addr,
+ struct vfe_line *line)
+{
+ u8 wm = RDI_WM(rdi);
+
+ writel_relaxed(addr, vfe->base + TFE_BUS_IMAGE_ADDR(wm));
+}
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 rdi, struct vfe_line *line)
+{
+ struct v4l2_pix_format_mplane *pix = &line->video_out.active_fmt.fmt.pix_mp;
+ u32 stride = pix->plane_fmt[0].bytesperline;
+ u8 wm = RDI_WM(rdi);
+
+ /* Configuration for plain RDI frames */
+ writel_relaxed(TFE_BUS_IMAGE_CFG_0_DEFAULT, vfe->base + TFE_BUS_IMAGE_CFG_0(wm));
+ writel_relaxed(0u, vfe->base + TFE_BUS_IMAGE_CFG_1(wm));
+ writel_relaxed(TFE_BUS_IMAGE_CFG_2_DEFAULT, vfe->base + TFE_BUS_IMAGE_CFG_2(wm));
+ writel_relaxed(stride * pix->height, vfe->base + TFE_BUS_FRAME_INCR(wm));
+ writel_relaxed(TFE_BUS_PACKER_CFG_FMT_PLAIN64, vfe->base + TFE_BUS_PACKER_CFG(wm));
+
+ /* No dropped frames, one irq per frame */
+ writel_relaxed(0, vfe->base + TFE_BUS_FRAMEDROP_CFG_0(wm));
+ writel_relaxed(1, vfe->base + TFE_BUS_FRAMEDROP_CFG_1(wm));
+ writel_relaxed(0, vfe->base + TFE_BUS_IRQ_SUBSAMPLE_CFG_0(wm));
+ writel_relaxed(1, vfe->base + TFE_BUS_IRQ_SUBSAMPLE_CFG_1(wm));
+
+ vfe_enable_irq(vfe);
+
+ writel(TFE_BUS_CLIENT_CFG_EN | TFE_BUS_CLIENT_CFG_MODE_FRAME,
+ vfe->base + TFE_BUS_CLIENT_CFG(wm));
+
+ dev_dbg(vfe->camss->dev, "VFE%u: Started RDI%u width %u height %u stride %u\n",
+ vfe->id, rdi, pix->width, pix->height, stride);
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 rdi)
+{
+ u8 wm = RDI_WM(rdi);
+
+ writel(0, vfe->base + TFE_BUS_CLIENT_CFG(wm));
+
+ dev_dbg(vfe->camss->dev, "VFE%u: Stopped RDI%u\n", vfe->id, rdi);
+}
+
+static const struct camss_video_ops vfe_video_ops_520 = {
+ .queue_buffer = vfe_queue_buffer_v2,
+ .flush_buffers = vfe_flush_buffers,
+};
+
+static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
+{
+ vfe->video_ops = vfe_video_ops_520;
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ vfe->reg_update |= BIT(__line_to_iface(line_id));
+ writel_relaxed(vfe->reg_update, vfe->base + TFE_REG_UPDATE_CMD);
+}
+
+static void vfe_reg_update_clear(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ vfe->reg_update &= ~BIT(__line_to_iface(line_id));
+}
+
+const struct vfe_hw_ops vfe_ops_340 = {
+ .global_reset = vfe_global_reset,
+ .hw_version = vfe_hw_version,
+ .isr = vfe_isr,
+ .pm_domain_off = vfe_pm_domain_off,
+ .pm_domain_on = vfe_pm_domain_on,
+ .subdev_init = vfe_subdev_init,
+ .vfe_disable = vfe_disable,
+ .vfe_enable = vfe_enable_v2,
+ .vfe_halt = vfe_halt,
+ .vfe_wm_start = vfe_wm_start,
+ .vfe_wm_stop = vfe_wm_stop,
+ .vfe_buf_done = vfe_buf_done,
+ .vfe_wm_update = vfe_wm_update,
+ .reg_update = vfe_reg_update,
+ .reg_update_clear = vfe_reg_update_clear,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-780.c b/drivers/media/platform/qcom/camss/camss-vfe-gen3.c
index b9812d70f91b..22579617def7 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-780.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-gen3.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v780 (SM8550)
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module gen3
*
* Copyright (c) 2024 Qualcomm Technologies, Inc.
*/
@@ -12,13 +12,44 @@
#include "camss.h"
#include "camss-vfe.h"
-#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x200 : 0xC00)
+#define IS_VFE_690(vfe) \
+ ((vfe->camss->res->version == CAMSS_8775P) \
+ || (vfe->camss->res->version == CAMSS_8300))
+
+#define BUS_REG_BASE_690 \
+ (vfe_is_lite(vfe) ? 0x480 : 0x400)
+#define BUS_REG_BASE_780 \
+ (vfe_is_lite(vfe) ? 0x200 : 0xC00)
+#define BUS_REG_BASE \
+ (IS_VFE_690(vfe) ? BUS_REG_BASE_690 : BUS_REG_BASE_780)
+
+#define VFE_TOP_CORE_CFG (0x24)
+#define VFE_DISABLE_DSCALING_DS4 BIT(21)
+#define VFE_DISABLE_DSCALING_DS16 BIT(22)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL_690 (BUS_REG_BASE + 0xFC)
+#define VFE_BUS_WM_TEST_BUS_CTRL_780 (BUS_REG_BASE + 0xDC)
+#define VFE_BUS_WM_TEST_BUS_CTRL \
+ (IS_VFE_690(vfe) ? VFE_BUS_WM_TEST_BUS_CTRL_690 \
+ : VFE_BUS_WM_TEST_BUS_CTRL_780)
+/*
+ * Bus client mapping:
+ *
+ * Full VFE:
+ * VFE_690: 16 = RDI0, 17 = RDI1, 18 = RDI2
+ * VFE_780: 23 = RDI0, 24 = RDI1, 25 = RDI2
+ *
+ * VFE LITE:
+ * VFE_690 : 0 = RDI0, 1 = RDI1, 2 = RDI2, 3 = RDI3, 4 = RDI4, 5 = RDI5
+ * VFE_780 : 0 = RDI0, 1 = RDI1, 2 = RDI2, 3 = RDI3, 4 = RDI4
+ */
+#define RDI_WM_690(n) ((vfe_is_lite(vfe) ? 0x0 : 0x10) + (n))
+#define RDI_WM_780(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n))
+#define RDI_WM(n) (IS_VFE_690(vfe) ? RDI_WM_690(n) : RDI_WM_780(n))
#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
-#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0xDC)
-
#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x200 + (n) * 0x100)
#define WM_CFG_EN BIT(0)
#define WM_VIR_FRM_EN BIT(1)
@@ -39,17 +70,6 @@
#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x260 + (n) * 0x100)
#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x264 + (n) * 0x100)
-/*
- * Bus client mapping:
- *
- * Full VFE:
- * 23 = RDI0, 24 = RDI1, 25 = RDI2
- *
- * VFE LITE:
- * 0 = RDI0, 1 = RDI1, 2 = RDI3, 4 = RDI4
- */
-#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n))
-
static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
{
struct v4l2_pix_format_mplane *pix =
@@ -62,14 +82,24 @@ static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
- writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
- vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+ if (IS_VFE_690(vfe))
+ writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height,
+ vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+ else
+ writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
+ vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+
writel((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
writel(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
+ /* TOP CORE CFG */
+ if (IS_VFE_690(vfe))
+ writel(VFE_DISABLE_DSCALING_DS4 | VFE_DISABLE_DSCALING_DS16,
+ vfe->base + VFE_TOP_CORE_CFG);
+
/* no dropped frames, one irq per frame */
writel(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
writel(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
@@ -92,7 +122,11 @@ static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
struct vfe_line *line)
{
wm = RDI_WM(wm);
- writel((addr >> 8) & 0xFFFFFFFF, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+
+ if (IS_VFE_690(vfe))
+ writel(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+ else
+ writel((addr >> 8), vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%x\n",
wm, addr);
@@ -113,14 +147,14 @@ static inline void vfe_reg_update_clear(struct vfe_device *vfe,
camss_reg_update(vfe->camss, vfe->id, port_id, true);
}
-static const struct camss_video_ops vfe_video_ops_780 = {
+static const struct camss_video_ops vfe_video_ops_gen3 = {
.queue_buffer = vfe_queue_buffer_v2,
.flush_buffers = vfe_flush_buffers,
};
static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
{
- vfe->video_ops = vfe_video_ops_780;
+ vfe->video_ops = vfe_video_ops_gen3;
}
static void vfe_global_reset(struct vfe_device *vfe)
@@ -140,7 +174,7 @@ static int vfe_halt(struct vfe_device *vfe)
return 0;
}
-const struct vfe_hw_ops vfe_ops_780 = {
+const struct vfe_hw_ops vfe_ops_gen3 = {
.global_reset = vfe_global_reset,
.hw_version = vfe_hw_version,
.isr = vfe_isr,
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 4bca6c3abaff..dff8d0a1e8c2 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -340,12 +340,15 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
}
break;
case CAMSS_660:
+ case CAMSS_2290:
case CAMSS_7280:
case CAMSS_8x96:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8300:
case CAMSS_845:
case CAMSS_8550:
+ case CAMSS_8775P:
case CAMSS_X1E80100:
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
@@ -910,7 +913,24 @@ static int vfe_match_clock_names(struct vfe_device *vfe,
return (!strcmp(clock->name, vfe_name) ||
!strcmp(clock->name, vfe_lite_name) ||
- !strcmp(clock->name, "vfe_lite"));
+ !strcmp(clock->name, "vfe_lite") ||
+ !strcmp(clock->name, "camnoc_axi"));
+}
+
+/*
+ * vfe_check_clock_levels - Calculate and set clock rates on VFE module
+ * @clock: clocks data
+ *
+ * Return false if there is no non-zero clock level and true otherwise.
+ */
+static bool vfe_check_clock_levels(struct camss_clock *clock)
+{
+ int i;
+
+ for (i = 0; i < clock->nfreqs; i++)
+ if (clock->freq[i])
+ return true;
+ return false;
}
/*
@@ -936,7 +956,7 @@ static int vfe_set_clock_rates(struct vfe_device *vfe)
for (i = 0; i < vfe->nclocks; i++) {
struct camss_clock *clock = &vfe->clock[i];
- if (vfe_match_clock_names(vfe, clock)) {
+ if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) {
u64 min_rate = 0;
long rate;
@@ -1017,7 +1037,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe)
for (i = 0; i < vfe->nclocks; i++) {
struct camss_clock *clock = &vfe->clock[i];
- if (vfe_match_clock_names(vfe, clock)) {
+ if (vfe_match_clock_names(vfe, clock) && vfe_check_clock_levels(clock)) {
u64 min_rate = 0;
unsigned long rate;
@@ -1972,8 +1992,10 @@ static int vfe_bpl_align(struct vfe_device *vfe)
case CAMSS_7280:
case CAMSS_8250:
case CAMSS_8280XP:
+ case CAMSS_8300:
case CAMSS_845:
case CAMSS_8550:
+ case CAMSS_8775P:
case CAMSS_X1E80100:
ret = 16;
break;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index a23f666be753..0300efdb1c46 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -242,9 +242,10 @@ extern const struct vfe_hw_ops vfe_ops_4_1;
extern const struct vfe_hw_ops vfe_ops_4_7;
extern const struct vfe_hw_ops vfe_ops_4_8;
extern const struct vfe_hw_ops vfe_ops_170;
+extern const struct vfe_hw_ops vfe_ops_340;
extern const struct vfe_hw_ops vfe_ops_480;
extern const struct vfe_hw_ops vfe_ops_680;
-extern const struct vfe_hw_ops vfe_ops_780;
+extern const struct vfe_hw_ops vfe_ops_gen3;
int vfe_get(struct vfe_device *vfe);
void vfe_put(struct vfe_device *vfe);
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 8d05802d1735..831486e14754 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -604,50 +604,11 @@ static const struct v4l2_ioctl_ops msm_vid_ioctl_ops = {
* V4L2 file operations
*/
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct camss_video *video = video_drvdata(file);
- struct v4l2_fh *vfh;
- int ret;
-
- mutex_lock(&video->lock);
-
- vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
- if (vfh == NULL) {
- ret = -ENOMEM;
- goto error_alloc;
- }
-
- v4l2_fh_init(vfh, vdev);
- v4l2_fh_add(vfh);
-
- file->private_data = vfh;
-
- mutex_unlock(&video->lock);
-
- return 0;
-
-error_alloc:
- mutex_unlock(&video->lock);
-
- return ret;
-}
-
-static int video_release(struct file *file)
-{
- vb2_fop_release(file);
-
- file->private_data = NULL;
-
- return 0;
-}
-
static const struct v4l2_file_operations msm_vid_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = video_ioctl2,
- .open = video_open,
- .release = video_release,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
.poll = vb2_fop_poll,
.mmap = vb2_fop_mmap,
.read = vb2_fop_read,
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index e08e70b93824..2fbcd0e343aa 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -515,6 +515,140 @@ static const struct camss_subdev_resources vfe_res_8x96[] = {
}
};
+static const struct camss_subdev_resources csiphy_res_2290[] = {
+ /* CSIPHY0 */
+ {
+ .regulators = { "vdd-csiphy-1p2", "vdd-csiphy-1p8" },
+ .clock = { "top_ahb", "ahb", "csiphy0", "csiphy0_timer" },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 240000000, 341330000, 384000000 },
+ { 100000000, 200000000, 268800000 } },
+ .reg = { "csiphy0" },
+ .interrupt = { "csiphy0" },
+ .csiphy = {
+ .id = 0,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845
+ }
+ },
+
+ /* CSIPHY1 */
+ {
+ .regulators = { "vdd-csiphy-1p2", "vdd-csiphy-1p8" },
+ .clock = { "top_ahb", "ahb", "csiphy1", "csiphy1_timer" },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 240000000, 341330000, 384000000 },
+ { 100000000, 200000000, 268800000 } },
+ .reg = { "csiphy1" },
+ .interrupt = { "csiphy1" },
+ .csiphy = {
+ .id = 1,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845
+ }
+ }
+};
+
+static const struct camss_subdev_resources csid_res_2290[] = {
+ /* CSID0 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ahb", "csi0", "vfe0_cphy_rx", "vfe0" },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 192000000, 240000000, 384000000, 426400000 },
+ { 0 },
+ { 0 } },
+ .reg = { "csid0" },
+ .interrupt = { "csid0" },
+ .csid = {
+ .hw_ops = &csid_ops_340,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+
+ /* CSID1 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ahb", "csi1", "vfe1_cphy_rx", "vfe1" },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 192000000, 240000000, 384000000, 426400000 },
+ { 0 },
+ { 0 } },
+ .reg = { "csid1" },
+ .interrupt = { "csid1" },
+ .csid = {
+ .hw_ops = &csid_ops_340,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ }
+};
+
+static const struct camss_subdev_resources vfe_res_2290[] = {
+ /* VFE0 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ahb", "axi", "vfe0", "camnoc_rt_axi", "camnoc_nrt_axi" },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 0 },
+ { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 },
+ { 0 },
+ { 0 }, },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .vfe = {
+ .line_num = 4,
+ .hw_ops = &vfe_ops_340,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+
+ /* VFE1 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ahb", "axi", "vfe1", "camnoc_rt_axi", "camnoc_nrt_axi" },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 0 },
+ { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 },
+ { 0 },
+ { 0 }, },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" },
+ .vfe = {
+ .line_num = 4,
+ .hw_ops = &vfe_ops_340,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+};
+
+static const struct resources_icc icc_res_2290[] = {
+ {
+ .name = "ahb",
+ .icc_bw_tbl.avg = 150000,
+ .icc_bw_tbl.peak = 300000,
+ },
+ {
+ .name = "hf_mnoc",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 3000000,
+ },
+ {
+ .name = "sf_mnoc",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 3000000,
+ },
+};
+
static const struct camss_subdev_resources csiphy_res_660[] = {
/* CSIPHY0 */
{
@@ -2285,7 +2419,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.csid = {
.is_lite = false,
.parent_dev_ops = &vfe_parent_dev_ops,
- .hw_ops = &csid_ops_780,
+ .hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2
}
},
@@ -2300,7 +2434,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.csid = {
.is_lite = false,
.parent_dev_ops = &vfe_parent_dev_ops,
- .hw_ops = &csid_ops_780,
+ .hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2
}
},
@@ -2315,7 +2449,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.csid = {
.is_lite = false,
.parent_dev_ops = &vfe_parent_dev_ops,
- .hw_ops = &csid_ops_780,
+ .hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2
}
},
@@ -2330,7 +2464,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.csid = {
.is_lite = true,
.parent_dev_ops = &vfe_parent_dev_ops,
- .hw_ops = &csid_ops_780,
+ .hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2
}
},
@@ -2345,7 +2479,7 @@ static const struct camss_subdev_resources csid_res_8550[] = {
.csid = {
.is_lite = true,
.parent_dev_ops = &vfe_parent_dev_ops,
- .hw_ops = &csid_ops_780,
+ .hw_ops = &csid_ops_gen3,
.formats = &csid_formats_gen2
}
}
@@ -2371,7 +2505,7 @@ static const struct camss_subdev_resources vfe_res_8550[] = {
.is_lite = false,
.has_pd = true,
.pd_name = "ife0",
- .hw_ops = &vfe_ops_780,
+ .hw_ops = &vfe_ops_gen3,
.formats_rdi = &vfe_formats_rdi_845,
.formats_pix = &vfe_formats_pix_845
}
@@ -2395,7 +2529,7 @@ static const struct camss_subdev_resources vfe_res_8550[] = {
.is_lite = false,
.has_pd = true,
.pd_name = "ife1",
- .hw_ops = &vfe_ops_780,
+ .hw_ops = &vfe_ops_gen3,
.formats_rdi = &vfe_formats_rdi_845,
.formats_pix = &vfe_formats_pix_845
}
@@ -2419,7 +2553,7 @@ static const struct camss_subdev_resources vfe_res_8550[] = {
.is_lite = false,
.has_pd = true,
.pd_name = "ife2",
- .hw_ops = &vfe_ops_780,
+ .hw_ops = &vfe_ops_gen3,
.formats_rdi = &vfe_formats_rdi_845,
.formats_pix = &vfe_formats_pix_845
}
@@ -2441,7 +2575,7 @@ static const struct camss_subdev_resources vfe_res_8550[] = {
.vfe = {
.line_num = 4,
.is_lite = true,
- .hw_ops = &vfe_ops_780,
+ .hw_ops = &vfe_ops_gen3,
.formats_rdi = &vfe_formats_rdi_845,
.formats_pix = &vfe_formats_pix_845
}
@@ -2463,7 +2597,7 @@ static const struct camss_subdev_resources vfe_res_8550[] = {
.vfe = {
.line_num = 4,
.is_lite = true,
- .hw_ops = &vfe_ops_780,
+ .hw_ops = &vfe_ops_gen3,
.formats_rdi = &vfe_formats_rdi_845,
.formats_pix = &vfe_formats_pix_845
}
@@ -2483,6 +2617,467 @@ static const struct resources_icc icc_res_sm8550[] = {
},
};
+static const struct camss_subdev_resources csiphy_res_8300[] = {
+ /* CSIPHY0 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+
+ .clock = { "csiphy_rx", "csiphy0", "csiphy0_timer" },
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy0" },
+ .interrupt = { "csiphy0" },
+ .csiphy = {
+ .id = 0,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ }
+ },
+ /* CSIPHY1 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+
+ .clock = { "csiphy_rx", "csiphy1", "csiphy1_timer" },
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy1" },
+ .interrupt = { "csiphy1" },
+ .csiphy = {
+ .id = 1,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ }
+ },
+ /* CSIPHY2 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+
+ .clock = { "csiphy_rx", "csiphy2", "csiphy2_timer" },
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy2" },
+ .interrupt = { "csiphy2" },
+ .csiphy = {
+ .id = 2,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ }
+ },
+};
+
+static const struct camss_subdev_resources csiphy_res_8775p[] = {
+ /* CSIPHY0 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "csiphy_rx", "csiphy0", "csiphy0_timer"},
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy0" },
+ .interrupt = { "csiphy0" },
+ .csiphy = {
+ .id = 0,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845
+ }
+ },
+ /* CSIPHY1 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "csiphy_rx", "csiphy1", "csiphy1_timer"},
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy1" },
+ .interrupt = { "csiphy1" },
+ .csiphy = {
+ .id = 1,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845
+ }
+ },
+ /* CSIPHY2 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "csiphy_rx", "csiphy2", "csiphy2_timer"},
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy2" },
+ .interrupt = { "csiphy2" },
+ .csiphy = {
+ .id = 2,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845
+ }
+ },
+ /* CSIPHY3 */
+ {
+ .regulators = { "vdda-phy", "vdda-pll" },
+ .clock = { "csiphy_rx", "csiphy3", "csiphy3_timer"},
+ .clock_rate = {
+ { 400000000 },
+ { 0 },
+ { 400000000 },
+ },
+ .reg = { "csiphy3" },
+ .interrupt = { "csiphy3" },
+ .csiphy = {
+ .id = 3,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845
+ }
+ },
+};
+
+static const struct camss_subdev_resources csid_res_8775p[] = {
+ /* CSID0 */
+ {
+ .regulators = {},
+ .clock = { "csid", "csiphy_rx"},
+ .clock_rate = {
+ { 400000000, 400000000},
+ { 400000000, 400000000}
+ },
+ .reg = { "csid0" },
+ .interrupt = { "csid0" },
+ .csid = {
+ .is_lite = false,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID1 */
+ {
+ .regulators = {},
+ .clock = { "csid", "csiphy_rx"},
+ .clock_rate = {
+ { 400000000, 400000000},
+ { 400000000, 400000000}
+ },
+ .reg = { "csid1" },
+ .interrupt = { "csid1" },
+ .csid = {
+ .is_lite = false,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+
+ /* CSID2 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 400000000, 400000000, 0},
+ { 0, 0, 400000000, 480000000, 0}
+ },
+ .reg = { "csid_lite0" },
+ .interrupt = { "csid_lite0" },
+ .csid = {
+ .is_lite = true,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID3 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 400000000, 400000000, 0},
+ { 0, 0, 400000000, 480000000, 0}
+ },
+ .reg = { "csid_lite1" },
+ .interrupt = { "csid_lite1" },
+ .csid = {
+ .is_lite = true,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID4 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 400000000, 400000000, 0},
+ { 0, 0, 400000000, 480000000, 0}
+ },
+ .reg = { "csid_lite2" },
+ .interrupt = { "csid_lite2" },
+ .csid = {
+ .is_lite = true,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID5 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 400000000, 400000000, 0},
+ { 0, 0, 400000000, 480000000, 0}
+ },
+ .reg = { "csid_lite3" },
+ .interrupt = { "csid_lite3" },
+ .csid = {
+ .is_lite = true,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID6 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 400000000, 400000000, 0},
+ { 0, 0, 400000000, 480000000, 0}
+ },
+ .reg = { "csid_lite4" },
+ .interrupt = { "csid_lite4" },
+ .csid = {
+ .is_lite = true,
+ .hw_ops = &csid_ops_gen3,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_gen2
+ }
+ },
+};
+
+static const struct camss_subdev_resources vfe_res_8775p[] = {
+ /* VFE0 */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe0", "vfe0", "vfe0_fast_ahb",
+ "cpas_ahb", "gcc_axi_hf",
+ "cpas_fast_ahb_clk",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0 },
+ { 480000000 },
+ { 300000000, 400000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 300000000, 400000000 },
+ { 400000000 },
+ },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = false,
+ .pd_name = NULL,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE1 */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe1", "vfe1", "vfe1_fast_ahb",
+ "cpas_ahb", "gcc_axi_hf",
+ "cpas_fast_ahb_clk",
+ "camnoc_axi"},
+ .clock_rate = {
+ { 0 },
+ { 480000000 },
+ { 300000000, 400000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 300000000, 400000000 },
+ { 400000000 },
+ },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = false,
+ .pd_name = NULL,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE2 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 0, 0 },
+ { 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 480000000, 600000000, 600000000, 600000000 },
+ },
+ .reg = { "vfe_lite0" },
+ .interrupt = { "vfe_lite0" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE3 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 0, 0 },
+ { 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 480000000, 600000000, 600000000, 600000000 },
+ },
+ .reg = { "vfe_lite1" },
+ .interrupt = { "vfe_lite1" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE4 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 0, 0 },
+ { 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 480000000, 600000000, 600000000, 600000000 },
+ },
+ .reg = { "vfe_lite2" },
+ .interrupt = { "vfe_lite2" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE5 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 0, 0 },
+ { 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 480000000, 600000000, 600000000, 600000000 },
+ },
+ .reg = { "vfe_lite3" },
+ .interrupt = { "vfe_lite3" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE6 (lite) */
+ {
+ .regulators = {},
+ .clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+ "vfe_lite_csid", "vfe_lite_cphy_rx",
+ "vfe_lite"},
+ .clock_rate = {
+ { 0, 0, 0, 0 },
+ { 300000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 400000000, 400000000, 400000000, 400000000 },
+ { 480000000, 600000000, 600000000, 600000000 },
+ },
+ .reg = { "vfe_lite4" },
+ .interrupt = { "vfe_lite4" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+};
+
+static const struct resources_icc icc_res_qcs8300[] = {
+ {
+ .name = "ahb",
+ .icc_bw_tbl.avg = 38400,
+ .icc_bw_tbl.peak = 76800,
+ },
+ {
+ .name = "hf_0",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+};
+
+static const struct resources_icc icc_res_sa8775p[] = {
+ {
+ .name = "ahb",
+ .icc_bw_tbl.avg = 38400,
+ .icc_bw_tbl.peak = 76800,
+ },
+ {
+ .name = "hf_0",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+};
+
static const struct camss_subdev_resources csiphy_res_x1e80100[] = {
/* CSIPHY0 */
{
@@ -3041,9 +3636,6 @@ static int camss_of_parse_ports(struct camss *camss)
for_each_endpoint_of_node(dev->of_node, node) {
struct camss_async_subdev *csd;
- if (!of_device_is_available(node))
- continue;
-
remote = of_graph_get_remote_port_parent(node);
if (!remote) {
dev_err(dev, "Cannot get remote parent\n");
@@ -3143,7 +3735,6 @@ static int camss_init_subdevices(struct camss *camss)
}
/*
- * camss_link_entities - Register subdev nodes and create links
* camss_link_err - print error in case link creation fails
* @src_name: name for source of the link
* @sink_name: name for sink of the link
@@ -3557,7 +4148,6 @@ static int camss_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct camss *camss;
- int num_subdevs;
int ret;
camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
@@ -3628,17 +4218,15 @@ static int camss_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
- num_subdevs = camss_of_parse_ports(camss);
- if (num_subdevs < 0) {
- ret = num_subdevs;
+ ret = camss_of_parse_ports(camss);
+ if (ret < 0)
goto err_v4l2_device_unregister;
- }
ret = camss_register_entities(camss);
if (ret < 0)
goto err_v4l2_device_unregister;
- ret = camss->res->link_entities(camss);
+ ret = camss_link_entities(camss);
if (ret < 0)
goto err_register_subdevs;
@@ -3648,23 +4236,12 @@ static int camss_probe(struct platform_device *pdev)
goto err_register_subdevs;
}
- if (num_subdevs) {
- camss->notifier.ops = &camss_subdev_notifier_ops;
-
- ret = v4l2_async_nf_register(&camss->notifier);
- if (ret) {
- dev_err(dev,
- "Failed to register async subdev nodes: %d\n",
- ret);
- goto err_media_device_unregister;
- }
- } else {
- ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
- if (ret < 0) {
- dev_err(dev, "Failed to register subdev nodes: %d\n",
- ret);
- goto err_media_device_unregister;
- }
+ camss->notifier.ops = &camss_subdev_notifier_ops;
+ ret = v4l2_async_nf_register(&camss->notifier);
+ if (ret) {
+ dev_err(dev,
+ "Failed to register async subdev nodes: %d\n", ret);
+ goto err_media_device_unregister;
}
return 0;
@@ -3723,7 +4300,6 @@ static const struct camss_resources msm8916_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
.csid_num = ARRAY_SIZE(csid_res_8x16),
.vfe_num = ARRAY_SIZE(vfe_res_8x16),
- .link_entities = camss_link_entities
};
static const struct camss_resources msm8953_resources = {
@@ -3737,7 +4313,6 @@ static const struct camss_resources msm8953_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
.csid_num = ARRAY_SIZE(csid_res_8x53),
.vfe_num = ARRAY_SIZE(vfe_res_8x53),
- .link_entities = camss_link_entities
};
static const struct camss_resources msm8996_resources = {
@@ -3749,7 +4324,46 @@ static const struct camss_resources msm8996_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
.csid_num = ARRAY_SIZE(csid_res_8x96),
.vfe_num = ARRAY_SIZE(vfe_res_8x96),
- .link_entities = camss_link_entities
+};
+
+static const struct camss_resources qcm2290_resources = {
+ .version = CAMSS_2290,
+ .csiphy_res = csiphy_res_2290,
+ .csid_res = csid_res_2290,
+ .vfe_res = vfe_res_2290,
+ .icc_res = icc_res_2290,
+ .icc_path_num = ARRAY_SIZE(icc_res_2290),
+ .csiphy_num = ARRAY_SIZE(csiphy_res_2290),
+ .csid_num = ARRAY_SIZE(csid_res_2290),
+ .vfe_num = ARRAY_SIZE(vfe_res_2290),
+};
+
+static const struct camss_resources qcs8300_resources = {
+ .version = CAMSS_8300,
+ .pd_name = "top",
+ .csiphy_res = csiphy_res_8300,
+ .csid_res = csid_res_8775p,
+ .csid_wrapper_res = &csid_wrapper_res_sm8550,
+ .vfe_res = vfe_res_8775p,
+ .icc_res = icc_res_qcs8300,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8300),
+ .csid_num = ARRAY_SIZE(csid_res_8775p),
+ .vfe_num = ARRAY_SIZE(vfe_res_8775p),
+ .icc_path_num = ARRAY_SIZE(icc_res_qcs8300),
+};
+
+static const struct camss_resources sa8775p_resources = {
+ .version = CAMSS_8775P,
+ .pd_name = "top",
+ .csiphy_res = csiphy_res_8775p,
+ .csid_res = csid_res_8775p,
+ .csid_wrapper_res = &csid_wrapper_res_sm8550,
+ .vfe_res = vfe_res_8775p,
+ .icc_res = icc_res_sa8775p,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8775p),
+ .csid_num = ARRAY_SIZE(csid_res_8775p),
+ .vfe_num = ARRAY_SIZE(vfe_res_8775p),
+ .icc_path_num = ARRAY_SIZE(icc_res_sa8775p),
};
static const struct camss_resources sdm660_resources = {
@@ -3761,7 +4375,6 @@ static const struct camss_resources sdm660_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_660),
.csid_num = ARRAY_SIZE(csid_res_660),
.vfe_num = ARRAY_SIZE(vfe_res_660),
- .link_entities = camss_link_entities
};
static const struct camss_resources sdm670_resources = {
@@ -3772,7 +4385,6 @@ static const struct camss_resources sdm670_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_670),
.csid_num = ARRAY_SIZE(csid_res_670),
.vfe_num = ARRAY_SIZE(vfe_res_670),
- .link_entities = camss_link_entities
};
static const struct camss_resources sdm845_resources = {
@@ -3784,7 +4396,6 @@ static const struct camss_resources sdm845_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_845),
.csid_num = ARRAY_SIZE(csid_res_845),
.vfe_num = ARRAY_SIZE(vfe_res_845),
- .link_entities = camss_link_entities
};
static const struct camss_resources sm8250_resources = {
@@ -3798,7 +4409,6 @@ static const struct camss_resources sm8250_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_8250),
.csid_num = ARRAY_SIZE(csid_res_8250),
.vfe_num = ARRAY_SIZE(vfe_res_8250),
- .link_entities = camss_link_entities
};
static const struct camss_resources sc8280xp_resources = {
@@ -3813,7 +4423,6 @@ static const struct camss_resources sc8280xp_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp),
.csid_num = ARRAY_SIZE(csid_res_sc8280xp),
.vfe_num = ARRAY_SIZE(vfe_res_sc8280xp),
- .link_entities = camss_link_entities
};
static const struct camss_resources sc7280_resources = {
@@ -3827,7 +4436,6 @@ static const struct camss_resources sc7280_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_7280),
.csid_num = ARRAY_SIZE(csid_res_7280),
.vfe_num = ARRAY_SIZE(vfe_res_7280),
- .link_entities = camss_link_entities
};
static const struct camss_resources sm8550_resources = {
@@ -3842,7 +4450,6 @@ static const struct camss_resources sm8550_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_8550),
.csid_num = ARRAY_SIZE(csid_res_8550),
.vfe_num = ARRAY_SIZE(vfe_res_8550),
- .link_entities = camss_link_entities
};
static const struct camss_resources x1e80100_resources = {
@@ -3857,13 +4464,15 @@ static const struct camss_resources x1e80100_resources = {
.csiphy_num = ARRAY_SIZE(csiphy_res_x1e80100),
.csid_num = ARRAY_SIZE(csid_res_x1e80100),
.vfe_num = ARRAY_SIZE(vfe_res_x1e80100),
- .link_entities = camss_link_entities
};
static const struct of_device_id camss_dt_match[] = {
{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
+ { .compatible = "qcom,qcm2290-camss", .data = &qcm2290_resources },
+ { .compatible = "qcom,qcs8300-camss", .data = &qcs8300_resources },
+ { .compatible = "qcom,sa8775p-camss", .data = &sa8775p_resources },
{ .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 63c0afee154a..a70fbc78ccc3 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -78,14 +78,17 @@ enum pm_domain {
enum camss_version {
CAMSS_660,
+ CAMSS_2290,
CAMSS_7280,
CAMSS_8x16,
CAMSS_8x53,
CAMSS_8x96,
CAMSS_8250,
CAMSS_8280XP,
+ CAMSS_8300,
CAMSS_845,
CAMSS_8550,
+ CAMSS_8775P,
CAMSS_X1E80100,
};
@@ -107,7 +110,6 @@ struct camss_resources {
const unsigned int csiphy_num;
const unsigned int csid_num;
const unsigned int vfe_num;
- int (*link_entities)(struct camss *camss);
};
struct camss {
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
index e86d00ee6f15..13270cd6d899 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -1,5 +1,5 @@
-qcom-iris-objs += \
- iris_buffer.o \
+qcom-iris-objs += iris_buffer.o \
+ iris_common.o \
iris_core.o \
iris_ctrls.o \
iris_firmware.o \
@@ -19,6 +19,7 @@ qcom-iris-objs += \
iris_vidc.o \
iris_vb2.o \
iris_vdec.o \
+ iris_venc.o \
iris_vpu2.o \
iris_vpu3x.o \
iris_vpu_buffer.o \
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index 6425e4919e3b..c0900038e7de 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -63,7 +63,12 @@
static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst)
{
u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines;
- struct v4l2_format *f = inst->fmt_dst;
+ struct v4l2_format *f;
+
+ if (inst->domain == DECODER)
+ f = inst->fmt_dst;
+ else
+ f = inst->fmt_src;
y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN);
uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN);
@@ -194,7 +199,7 @@ static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst)
return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K);
}
-static u32 iris_bitstream_buffer_size(struct iris_inst *inst)
+static u32 iris_dec_bitstream_buffer_size(struct iris_inst *inst)
{
struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
u32 base_res_mbs = NUM_MBS_4K;
@@ -219,18 +224,58 @@ static u32 iris_bitstream_buffer_size(struct iris_inst *inst)
return ALIGN(frame_size, PIXELS_4K);
}
+static u32 iris_enc_bitstream_buffer_size(struct iris_inst *inst)
+{
+ u32 aligned_width, aligned_height, bitstream_size, yuv_size;
+ int bitrate_mode, frame_rc;
+ struct v4l2_format *f;
+
+ f = inst->fmt_dst;
+
+ bitrate_mode = inst->fw_caps[BITRATE_MODE].value;
+ frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value;
+
+ aligned_width = ALIGN(f->fmt.pix_mp.width, 32);
+ aligned_height = ALIGN(f->fmt.pix_mp.height, 32);
+ bitstream_size = aligned_width * aligned_height * 3;
+ yuv_size = (aligned_width * aligned_height * 3) >> 1;
+ if (aligned_width * aligned_height > (4096 * 2176))
+ /* bitstream_size = 0.25 * yuv_size; */
+ bitstream_size = (bitstream_size >> 3);
+ else if (aligned_width * aligned_height > (1280 * 720))
+ /* bitstream_size = 0.5 * yuv_size; */
+ bitstream_size = (bitstream_size >> 2);
+
+ if ((!frame_rc || bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) &&
+ bitstream_size < yuv_size)
+ bitstream_size = (bitstream_size << 1);
+
+ return ALIGN(bitstream_size, 4096);
+}
+
int iris_get_buffer_size(struct iris_inst *inst,
enum iris_buffer_type buffer_type)
{
- switch (buffer_type) {
- case BUF_INPUT:
- return iris_bitstream_buffer_size(inst);
- case BUF_OUTPUT:
- return iris_yuv_buffer_size_nv12(inst);
- case BUF_DPB:
- return iris_yuv_buffer_size_qc08c(inst);
- default:
- return 0;
+ if (inst->domain == DECODER) {
+ switch (buffer_type) {
+ case BUF_INPUT:
+ return iris_dec_bitstream_buffer_size(inst);
+ case BUF_OUTPUT:
+ return iris_yuv_buffer_size_nv12(inst);
+ case BUF_DPB:
+ return iris_yuv_buffer_size_qc08c(inst);
+ default:
+ return 0;
+ }
+ } else {
+ switch (buffer_type) {
+ case BUF_INPUT:
+ return iris_yuv_buffer_size_nv12(inst);
+ case BUF_OUTPUT:
+ return iris_enc_bitstream_buffer_size(inst);
+ default:
+ return 0;
+ }
}
}
@@ -239,7 +284,7 @@ static void iris_fill_internal_buf_info(struct iris_inst *inst,
{
struct iris_buffers *buffers = &inst->buffers[buffer_type];
- buffers->size = iris_vpu_buf_size(inst, buffer_type);
+ buffers->size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, buffer_type);
buffers->min_count = iris_vpu_buf_count(inst, buffer_type);
}
@@ -249,16 +294,30 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane)
const u32 *internal_buf_type;
u32 internal_buffer_count, i;
- if (V4L2_TYPE_IS_OUTPUT(plane)) {
- internal_buf_type = platform_data->dec_ip_int_buf_tbl;
- internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
- for (i = 0; i < internal_buffer_count; i++)
- iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+ if (inst->domain == DECODER) {
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ for (i = 0; i < internal_buffer_count; i++)
+ iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+ } else {
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
+ for (i = 0; i < internal_buffer_count; i++)
+ iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+ }
} else {
- internal_buf_type = platform_data->dec_op_int_buf_tbl;
- internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
- for (i = 0; i < internal_buffer_count; i++)
- iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->enc_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size;
+ for (i = 0; i < internal_buffer_count; i++)
+ iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+ } else {
+ internal_buf_type = platform_data->enc_op_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_op_int_buf_tbl_size;
+ for (i = 0; i < internal_buffer_count; i++)
+ iris_fill_internal_buf_info(inst, internal_buf_type[i]);
+ }
}
}
@@ -299,12 +358,22 @@ int iris_create_internal_buffers(struct iris_inst *inst, u32 plane)
const u32 *internal_buf_type;
int ret;
- if (V4L2_TYPE_IS_OUTPUT(plane)) {
- internal_buf_type = platform_data->dec_ip_int_buf_tbl;
- internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ if (inst->domain == DECODER) {
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
+ }
} else {
- internal_buf_type = platform_data->dec_op_int_buf_tbl;
- internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->enc_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->enc_op_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_op_int_buf_tbl_size;
+ }
}
for (i = 0; i < internal_buffer_count; i++) {
@@ -334,6 +403,29 @@ int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
return 0;
}
+int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type)
+{
+ struct iris_buffer *buffer, *next;
+ struct iris_buffers *buffers;
+ int ret = 0;
+
+ buffers = &inst->buffers[buffer_type];
+ list_for_each_entry_safe(buffer, next, &buffers->list, list) {
+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+ continue;
+ if (buffer->attr & BUF_ATTR_QUEUED)
+ continue;
+
+ if (buffer->attr & BUF_ATTR_DEFERRED) {
+ ret = iris_queue_buffer(inst, buffer);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
{
const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
@@ -343,12 +435,22 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
u32 internal_buffer_count, i;
int ret;
- if (V4L2_TYPE_IS_OUTPUT(plane)) {
- internal_buf_type = platform_data->dec_ip_int_buf_tbl;
- internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ if (inst->domain == DECODER) {
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
+ }
} else {
- internal_buf_type = platform_data->dec_op_int_buf_tbl;
- internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->enc_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->enc_op_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_op_int_buf_tbl_size;
+ }
}
for (i = 0; i < internal_buffer_count; i++) {
@@ -358,6 +460,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane)
continue;
if (buffer->attr & BUF_ATTR_QUEUED)
continue;
+ if (buffer->type == BUF_DPB && inst->state != IRIS_INST_STREAMING) {
+ buffer->attr |= BUF_ATTR_DEFERRED;
+ continue;
+ }
ret = iris_queue_buffer(inst, buffer);
if (ret)
return ret;
@@ -388,12 +494,22 @@ static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool
u32 i, len;
int ret;
- if (V4L2_TYPE_IS_OUTPUT(plane)) {
- internal_buf_type = platform_data->dec_ip_int_buf_tbl;
- len = platform_data->dec_ip_int_buf_tbl_size;
+ if (inst->domain == DECODER) {
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
+ len = platform_data->dec_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
+ len = platform_data->dec_op_int_buf_tbl_size;
+ }
} else {
- internal_buf_type = platform_data->dec_op_int_buf_tbl;
- len = platform_data->dec_op_int_buf_tbl_size;
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ internal_buf_type = platform_data->enc_ip_int_buf_tbl;
+ len = platform_data->enc_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->enc_op_int_buf_tbl;
+ len = platform_data->enc_op_int_buf_tbl_size;
+ }
}
for (i = 0; i < len; i++) {
@@ -413,6 +529,19 @@ static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool
}
}
+ if (force) {
+ if (inst->domain == DECODER)
+ buffers = &inst->buffers[BUF_PERSIST];
+ else
+ buffers = &inst->buffers[BUF_ARP];
+
+ list_for_each_entry_safe(buf, next, &buffers->list, list) {
+ ret = iris_destroy_internal_buffer(inst, buf);
+ if (ret)
+ return ret;
+ }
+ }
+
return 0;
}
@@ -455,8 +584,13 @@ static int iris_release_input_internal_buffers(struct iris_inst *inst)
u32 internal_buffer_count, i;
int ret;
- internal_buf_type = platform_data->dec_ip_int_buf_tbl;
- internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ if (inst->domain == DECODER) {
+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
+ } else {
+ internal_buf_type = platform_data->enc_ip_int_buf_tbl;
+ internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size;
+ }
for (i = 0; i < internal_buffer_count; i++) {
ret = iris_release_internal_buffers(inst, internal_buf_type[i]);
@@ -467,9 +601,9 @@ static int iris_release_input_internal_buffers(struct iris_inst *inst)
return 0;
}
-int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst, enum iris_buffer_type buffer_type)
{
- struct iris_buffers *buffers = &inst->buffers[BUF_PERSIST];
+ struct iris_buffers *buffers = &inst->buffers[buffer_type];
struct iris_buffer *buffer, *next;
int ret;
u32 i;
@@ -477,10 +611,10 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst)
if (!list_empty(&buffers->list))
return 0;
- iris_fill_internal_buf_info(inst, BUF_PERSIST);
+ iris_fill_internal_buf_info(inst, buffer_type);
for (i = 0; i < buffers->min_count; i++) {
- ret = iris_create_internal_buffer(inst, BUF_PERSIST, i);
+ ret = iris_create_internal_buffer(inst, buffer_type, i);
if (ret)
return ret;
}
@@ -614,6 +748,8 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf)
vb2 = &vbuf->vb2_buf;
+ vbuf->flags |= buf->flags;
+
if (buf->flags & V4L2_BUF_FLAG_ERROR) {
state = VB2_BUF_STATE_ERROR;
vb2_set_plane_payload(vb2, 0, 0);
@@ -622,8 +758,6 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf)
return 0;
}
- vbuf->flags |= buf->flags;
-
if (V4L2_TYPE_IS_CAPTURE(type)) {
vb2_set_plane_payload(vb2, 0, buf->data_size);
vbuf->sequence = inst->sequence_cap++;
diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h
index 00825ad2dc3a..325d30fce5c9 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -25,6 +25,8 @@ struct iris_inst;
* @BUF_DPB: buffer to store display picture buffers for reference
* @BUF_PERSIST: buffer to store session context data
* @BUF_SCRATCH_1: buffer to store decoding/encoding context data for HW
+ * @BUF_SCRATCH_2: buffer to store encoding context data for HW
+ * @BUF_VPSS: buffer to store VPSS context data for HW
* @BUF_TYPE_MAX: max buffer types
*/
enum iris_buffer_type {
@@ -38,6 +40,8 @@ enum iris_buffer_type {
BUF_DPB,
BUF_PERSIST,
BUF_SCRATCH_1,
+ BUF_SCRATCH_2,
+ BUF_VPSS,
BUF_TYPE_MAX,
};
@@ -105,10 +109,11 @@ int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_ty
void iris_get_internal_buffers(struct iris_inst *inst, u32 plane);
int iris_create_internal_buffers(struct iris_inst *inst, u32 plane);
int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);
+int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type);
int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer);
int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane);
int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane);
-int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst, enum iris_buffer_type buf_type);
int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);
int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type);
diff --git a/drivers/media/platform/qcom/iris/iris_common.c b/drivers/media/platform/qcom/iris/iris_common.c
new file mode 100644
index 000000000000..9fc663bdaf3f
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_common.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <media/v4l2-mem2mem.h>
+
+#include "iris_common.h"
+#include "iris_ctrls.h"
+#include "iris_instance.h"
+#include "iris_power.h"
+
+int iris_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
+
+ buf->type = iris_v4l2_type_to_driver(vb2->type);
+ buf->index = vb2->index;
+ buf->fd = vb2->planes[0].m.fd;
+ buf->buffer_size = vb2->planes[0].length;
+ buf->data_offset = vb2->planes[0].data_offset;
+ buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset;
+ buf->flags = vbuf->flags;
+ buf->timestamp = vb2->timestamp;
+ buf->attr = 0;
+
+ return 0;
+}
+
+void iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+ u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ struct vb2_buffer *vb = &vbuf->vb2_buf;
+ u64 ts_us = vb->timestamp;
+
+ if (inst->metadata_idx >= ARRAY_SIZE(inst->tss))
+ inst->metadata_idx = 0;
+
+ do_div(ts_us, NSEC_PER_USEC);
+
+ inst->tss[inst->metadata_idx].flags = vbuf->flags & mask;
+ inst->tss[inst->metadata_idx].tc = vbuf->timecode;
+ inst->tss[inst->metadata_idx].ts_us = ts_us;
+ inst->tss[inst->metadata_idx].ts_ns = vb->timestamp;
+
+ inst->metadata_idx++;
+}
+
+int iris_process_streamon_input(struct iris_inst *inst)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ enum iris_inst_sub_state set_sub_state = 0;
+ int ret;
+
+ iris_scale_power(inst);
+
+ ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+ ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
+ if (ret)
+ return ret;
+ }
+
+ if (inst->domain == DECODER &&
+ (inst->sub_state & IRIS_INST_SUB_DRC ||
+ inst->sub_state & IRIS_INST_SUB_DRAIN ||
+ inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) {
+ if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
+ if (hfi_ops->session_pause) {
+ ret = hfi_ops->session_pause(inst,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+ }
+ set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
+ }
+ }
+
+ ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ inst->last_buffer_dequeued = false;
+
+ return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+int iris_process_streamon_output(struct iris_inst *inst)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ bool drain_active = false, drc_active = false;
+ enum iris_inst_sub_state clear_sub_state = 0;
+ int ret = 0;
+
+ iris_scale_power(inst);
+
+ drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN &&
+ inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
+
+ drc_active = inst->sub_state & IRIS_INST_SUB_DRC &&
+ inst->sub_state & IRIS_INST_SUB_DRC_LAST;
+
+ if (drc_active)
+ clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
+ else if (drain_active)
+ clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
+
+ if (inst->domain == DECODER && inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+ ret = iris_alloc_and_queue_input_int_bufs(inst);
+ if (ret)
+ return ret;
+ ret = iris_set_stage(inst, STAGE);
+ if (ret)
+ return ret;
+ ret = iris_set_pipe(inst, PIPE);
+ if (ret)
+ return ret;
+ }
+
+ if (inst->state == IRIS_INST_INPUT_STREAMING &&
+ inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+ if (!drain_active)
+ ret = hfi_ops->session_resume_drc(inst,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ else if (hfi_ops->session_resume_drain)
+ ret = hfi_ops->session_resume_drain(inst,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+ clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
+ }
+
+ if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
+ clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC;
+
+ ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ return ret;
+
+ if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
+ clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
+
+ ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ return ret;
+
+ inst->last_buffer_dequeued = false;
+
+ return iris_inst_change_sub_state(inst, clear_sub_state, 0);
+}
+
+static void iris_flush_deferred_buffers(struct iris_inst *inst,
+ enum iris_buffer_type type)
+{
+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
+ struct v4l2_m2m_buffer *buffer, *n;
+ struct iris_buffer *buf;
+
+ if (type == BUF_INPUT) {
+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
+ buf = to_iris_buffer(&buffer->vb);
+ if (buf->attr & BUF_ATTR_DEFERRED) {
+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+ buf->attr |= BUF_ATTR_BUFFER_DONE;
+ buf->data_size = 0;
+ iris_vb2_buffer_done(inst, buf);
+ }
+ }
+ }
+ } else {
+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
+ buf = to_iris_buffer(&buffer->vb);
+ if (buf->attr & BUF_ATTR_DEFERRED) {
+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+ buf->attr |= BUF_ATTR_BUFFER_DONE;
+ buf->data_size = 0;
+ iris_vb2_buffer_done(inst, buf);
+ }
+ }
+ }
+ }
+}
+
+static void iris_kill_session(struct iris_inst *inst)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+
+ if (!inst->session_id)
+ return;
+
+ hfi_ops->session_close(inst);
+ iris_inst_change_state(inst, IRIS_INST_ERROR);
+}
+
+int iris_session_streamoff(struct iris_inst *inst, u32 plane)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ enum iris_buffer_type buffer_type;
+ int ret;
+
+ switch (plane) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ buffer_type = BUF_INPUT;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ buffer_type = BUF_OUTPUT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = hfi_ops->session_stop(inst, plane);
+ if (ret)
+ goto error;
+
+ ret = iris_inst_state_change_streamoff(inst, plane);
+ if (ret)
+ goto error;
+
+ iris_flush_deferred_buffers(inst, buffer_type);
+
+ return 0;
+
+error:
+ iris_kill_session(inst);
+ iris_flush_deferred_buffers(inst, buffer_type);
+
+ return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_common.h b/drivers/media/platform/qcom/iris/iris_common.h
new file mode 100644
index 000000000000..b2a27b781c9a
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_common.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __IRIS_COMMON_H__
+#define __IRIS_COMMON_H__
+
+struct iris_inst;
+struct iris_buffer;
+
+int iris_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf);
+void iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
+int iris_process_streamon_input(struct iris_inst *inst);
+int iris_process_streamon_output(struct iris_inst *inst);
+int iris_session_streamoff(struct iris_inst *inst, u32 plane);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c
index 0fa0a3b549a2..8406c48d635b 100644
--- a/drivers/media/platform/qcom/iris/iris_core.c
+++ b/drivers/media/platform/qcom/iris/iris_core.c
@@ -15,10 +15,12 @@ void iris_core_deinit(struct iris_core *core)
pm_runtime_resume_and_get(core->dev);
mutex_lock(&core->lock);
- iris_fw_unload(core);
- iris_vpu_power_off(core);
- iris_hfi_queues_deinit(core);
- core->state = IRIS_CORE_DEINIT;
+ if (core->state != IRIS_CORE_DEINIT) {
+ iris_fw_unload(core);
+ iris_vpu_power_off(core);
+ iris_hfi_queues_deinit(core);
+ core->state = IRIS_CORE_DEINIT;
+ }
mutex_unlock(&core->lock);
pm_runtime_put_sync(core->dev);
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
index aeeac32a1f6d..fb194c967ad4 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -25,6 +25,11 @@ struct icc_info {
#define IRIS_FW_VERSION_LENGTH 128
#define IFACEQ_CORE_PKT_SIZE (1024 * 4)
+enum domain_type {
+ ENCODER = BIT(0),
+ DECODER = BIT(1),
+};
+
/**
* struct iris_core - holds core parameters valid for all instances
*
@@ -33,8 +38,10 @@ struct icc_info {
* @irq: iris irq
* @v4l2_dev: a holder for v4l2 device structure
* @vdev_dec: iris video device structure for decoder
+ * @vdev_enc: iris video device structure for encoder
* @iris_v4l2_file_ops: iris v4l2 file ops
- * @iris_v4l2_ioctl_ops: iris v4l2 ioctl ops
+ * @iris_v4l2_ioctl_ops_dec: iris v4l2 ioctl ops for decoder
+ * @iris_v4l2_ioctl_ops_enc: iris v4l2 ioctl ops for encoder
* @iris_vb2_ops: iris vb2 ops
* @icc_tbl: table of iris interconnects
* @icc_count: count of iris interconnects
@@ -64,7 +71,8 @@ struct icc_info {
* @intr_status: interrupt status
* @sys_error_handler: a delayed work for handling system fatal error
* @instances: a list_head of all instances
- * @inst_fw_caps: an array of supported instance capabilities
+ * @inst_fw_caps_dec: an array of supported instance capabilities by decoder
+ * @inst_fw_caps_enc: an array of supported instance capabilities by encoder
*/
struct iris_core {
@@ -73,8 +81,10 @@ struct iris_core {
int irq;
struct v4l2_device v4l2_dev;
struct video_device *vdev_dec;
+ struct video_device *vdev_enc;
const struct v4l2_file_operations *iris_v4l2_file_ops;
- const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops;
+ const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops_dec;
+ const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops_enc;
const struct vb2_ops *iris_vb2_ops;
struct icc_bulk_data *icc_tbl;
u32 icc_count;
@@ -104,7 +114,9 @@ struct iris_core {
u32 intr_status;
struct delayed_work sys_error_handler;
struct list_head instances;
- struct platform_inst_fw_cap inst_fw_caps[INST_FW_CAP_MAX];
+ /* encoder and decoder have overlapping caps, so two different arrays are required */
+ struct platform_inst_fw_cap inst_fw_caps_dec[INST_FW_CAP_MAX];
+ struct platform_inst_fw_cap inst_fw_caps_enc[INST_FW_CAP_MAX];
};
int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c
index 9136b723c0f2..754a5ad718bc 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -7,8 +7,13 @@
#include <media/v4l2-mem2mem.h>
#include "iris_ctrls.h"
+#include "iris_hfi_gen1_defines.h"
+#include "iris_hfi_gen2_defines.h"
#include "iris_instance.h"
+#define CABAC_MAX_BITRATE 160000000
+#define CAVLC_MAX_BITRATE 220000000
+
static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id)
{
return cap_id >= 1 && cap_id < INST_FW_CAP_MAX;
@@ -31,6 +36,68 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
return LEVEL_VP9;
case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
return TIER;
+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+ return HEADER_MODE;
+ case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR:
+ return PREPEND_SPSPPS_TO_IDR;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return BITRATE;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ return BITRATE_PEAK;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ return BITRATE_MODE;
+ case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE:
+ return FRAME_SKIP_MODE;
+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+ return FRAME_RC_ENABLE;
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ return GOP_SIZE;
+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
+ return ENTROPY_MODE;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+ return MIN_FRAME_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:
+ return MIN_FRAME_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+ return MAX_FRAME_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:
+ return MAX_FRAME_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP:
+ return I_FRAME_MIN_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP:
+ return I_FRAME_MIN_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP:
+ return P_FRAME_MIN_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP:
+ return P_FRAME_MIN_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP:
+ return B_FRAME_MIN_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP:
+ return B_FRAME_MIN_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP:
+ return I_FRAME_MAX_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP:
+ return I_FRAME_MAX_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP:
+ return P_FRAME_MAX_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP:
+ return P_FRAME_MAX_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP:
+ return B_FRAME_MAX_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP:
+ return B_FRAME_MAX_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+ return I_FRAME_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
+ return I_FRAME_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+ return P_FRAME_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:
+ return P_FRAME_QP_HEVC;
+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+ return B_FRAME_QP_H264;
+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:
+ return B_FRAME_QP_HEVC;
default:
return INST_FW_CAP_MAX;
}
@@ -56,12 +123,74 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id)
return V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
case TIER:
return V4L2_CID_MPEG_VIDEO_HEVC_TIER;
+ case HEADER_MODE:
+ return V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+ case PREPEND_SPSPPS_TO_IDR:
+ return V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR;
+ case BITRATE:
+ return V4L2_CID_MPEG_VIDEO_BITRATE;
+ case BITRATE_PEAK:
+ return V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
+ case BITRATE_MODE:
+ return V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
+ case FRAME_SKIP_MODE:
+ return V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE;
+ case FRAME_RC_ENABLE:
+ return V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
+ case GOP_SIZE:
+ return V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+ case ENTROPY_MODE:
+ return V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
+ case MIN_FRAME_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
+ case MIN_FRAME_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP;
+ case MAX_FRAME_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
+ case MAX_FRAME_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP;
+ case I_FRAME_MIN_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP;
+ case I_FRAME_MIN_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP;
+ case P_FRAME_MIN_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP;
+ case P_FRAME_MIN_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP;
+ case B_FRAME_MIN_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP;
+ case B_FRAME_MIN_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP;
+ case I_FRAME_MAX_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP;
+ case I_FRAME_MAX_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP;
+ case P_FRAME_MAX_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP;
+ case P_FRAME_MAX_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP;
+ case B_FRAME_MAX_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP;
+ case B_FRAME_MAX_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP;
+ case I_FRAME_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
+ case I_FRAME_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP;
+ case P_FRAME_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
+ case P_FRAME_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP;
+ case B_FRAME_QP_H264:
+ return V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
+ case B_FRAME_QP_HEVC:
+ return V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP;
default:
return 0;
}
}
-static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
+static int iris_op_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
enum platform_inst_fw_cap_type cap_id;
@@ -82,11 +211,16 @@ static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
inst->fw_caps[cap_id].value = ctrl->val;
+ if (vb2_is_streaming(q)) {
+ if (cap[cap_id].set)
+ cap[cap_id].set(inst, cap_id);
+ }
+
return 0;
}
static const struct v4l2_ctrl_ops iris_ctrl_ops = {
- .s_ctrl = iris_vdec_op_s_ctrl,
+ .s_ctrl = iris_op_s_ctrl,
};
int iris_ctrls_init(struct iris_inst *inst)
@@ -101,7 +235,10 @@ int iris_ctrls_init(struct iris_inst *inst)
num_ctrls++;
}
- /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
+ /* Adding 1 to num_ctrls to include
+ * V4L2_CID_MIN_BUFFERS_FOR_CAPTURE for decoder and
+ * V4L2_CID_MIN_BUFFERS_FOR_OUTPUT for encoder
+ */
ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1);
if (ret)
@@ -143,8 +280,13 @@ int iris_ctrls_init(struct iris_inst *inst)
ctrl_idx++;
}
- v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
- V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
+ if (inst->domain == DECODER) {
+ v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
+ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4);
+ } else {
+ v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
+ V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 4);
+ }
ret = inst->ctrl_handler.error;
if (ret)
@@ -162,32 +304,57 @@ void iris_session_init_caps(struct iris_core *core)
struct platform_inst_fw_cap *caps;
u32 i, num_cap, cap_id;
- caps = core->iris_platform_data->inst_fw_caps;
- num_cap = core->iris_platform_data->inst_fw_caps_size;
+ caps = core->iris_platform_data->inst_fw_caps_dec;
+ num_cap = core->iris_platform_data->inst_fw_caps_dec_size;
+
+ for (i = 0; i < num_cap; i++) {
+ cap_id = caps[i].cap_id;
+ if (!iris_valid_cap_id(cap_id))
+ continue;
+
+ core->inst_fw_caps_dec[cap_id].cap_id = caps[i].cap_id;
+ core->inst_fw_caps_dec[cap_id].min = caps[i].min;
+ core->inst_fw_caps_dec[cap_id].max = caps[i].max;
+ core->inst_fw_caps_dec[cap_id].step_or_mask = caps[i].step_or_mask;
+ core->inst_fw_caps_dec[cap_id].value = caps[i].value;
+ core->inst_fw_caps_dec[cap_id].flags = caps[i].flags;
+ core->inst_fw_caps_dec[cap_id].hfi_id = caps[i].hfi_id;
+ core->inst_fw_caps_dec[cap_id].set = caps[i].set;
+ }
+
+ caps = core->iris_platform_data->inst_fw_caps_enc;
+ num_cap = core->iris_platform_data->inst_fw_caps_enc_size;
for (i = 0; i < num_cap; i++) {
cap_id = caps[i].cap_id;
if (!iris_valid_cap_id(cap_id))
continue;
- core->inst_fw_caps[cap_id].cap_id = caps[i].cap_id;
- core->inst_fw_caps[cap_id].min = caps[i].min;
- core->inst_fw_caps[cap_id].max = caps[i].max;
- core->inst_fw_caps[cap_id].step_or_mask = caps[i].step_or_mask;
- core->inst_fw_caps[cap_id].value = caps[i].value;
- core->inst_fw_caps[cap_id].flags = caps[i].flags;
- core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id;
- core->inst_fw_caps[cap_id].set = caps[i].set;
+ core->inst_fw_caps_enc[cap_id].cap_id = caps[i].cap_id;
+ core->inst_fw_caps_enc[cap_id].min = caps[i].min;
+ core->inst_fw_caps_enc[cap_id].max = caps[i].max;
+ core->inst_fw_caps_enc[cap_id].step_or_mask = caps[i].step_or_mask;
+ core->inst_fw_caps_enc[cap_id].value = caps[i].value;
+ core->inst_fw_caps_enc[cap_id].flags = caps[i].flags;
+ core->inst_fw_caps_enc[cap_id].hfi_id = caps[i].hfi_id;
+ core->inst_fw_caps_enc[cap_id].set = caps[i].set;
}
}
static u32 iris_get_port_info(struct iris_inst *inst,
enum platform_inst_fw_cap_type cap_id)
{
- if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
- return HFI_PORT_BITSTREAM;
- else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
- return HFI_PORT_RAW;
+ if (inst->domain == DECODER) {
+ if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
+ return HFI_PORT_BITSTREAM;
+ else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
+ return HFI_PORT_RAW;
+ } else {
+ if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT)
+ return HFI_PORT_RAW;
+ else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
+ return HFI_PORT_BITSTREAM;
+ }
return HFI_PORT_NONE;
}
@@ -227,8 +394,10 @@ int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id
u32 width = inp_f->fmt.pix_mp.width;
u32 work_mode = STAGE_2;
- if (iris_res_is_less_than(width, height, 1280, 720))
- work_mode = STAGE_1;
+ if (inst->domain == DECODER) {
+ if (iris_res_is_less_than(width, height, 1280, 720))
+ work_mode = STAGE_1;
+ }
return hfi_ops->session_set_property(inst, hfi_id,
HFI_HOST_FLAGS_NONE,
@@ -250,6 +419,470 @@ int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
&work_route, sizeof(u32));
}
+int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 hfi_id, hfi_value;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ hfi_id = inst->fw_caps[PROFILE_H264].hfi_id;
+ hfi_value = inst->fw_caps[PROFILE_H264].value;
+ } else {
+ hfi_id = inst->fw_caps[PROFILE_HEVC].hfi_id;
+ hfi_value = inst->fw_caps[PROFILE_HEVC].value;
+ }
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &hfi_value, sizeof(u32));
+}
+
+int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 hfi_id, hfi_value;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ hfi_id = inst->fw_caps[LEVEL_H264].hfi_id;
+ hfi_value = inst->fw_caps[LEVEL_H264].value;
+ } else {
+ hfi_id = inst->fw_caps[LEVEL_HEVC].hfi_id;
+ hfi_value = inst->fw_caps[LEVEL_HEVC].value;
+ }
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &hfi_value, sizeof(u32));
+}
+
+int iris_set_profile_level_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct hfi_profile_level pl;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ pl.profile = inst->fw_caps[PROFILE_H264].value;
+ pl.level = inst->fw_caps[LEVEL_H264].value;
+ } else {
+ pl.profile = inst->fw_caps[PROFILE_HEVC].value;
+ pl.level = inst->fw_caps[LEVEL_HEVC].value;
+ }
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &pl, sizeof(u32));
+}
+
+int iris_set_header_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 header_mode = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 hfi_val;
+
+ if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)
+ hfi_val = 0;
+ else
+ hfi_val = 1;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &hfi_val, sizeof(u32));
+}
+
+int iris_set_header_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 prepend_sps_pps = inst->fw_caps[PREPEND_SPSPPS_TO_IDR].value;
+ u32 header_mode = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 hfi_val;
+
+ if (prepend_sps_pps)
+ hfi_val = HFI_SEQ_HEADER_PREFIX_WITH_SYNC_FRAME;
+ else if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)
+ hfi_val = HFI_SEQ_HEADER_JOINED_WITH_1ST_FRAME;
+ else
+ hfi_val = HFI_SEQ_HEADER_SEPERATE_FRAME;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &hfi_val, sizeof(u32));
+}
+
+int iris_set_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 entropy_mode = inst->fw_caps[ENTROPY_MODE].value;
+ u32 bitrate = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 max_bitrate;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC)
+ max_bitrate = CABAC_MAX_BITRATE;
+
+ if (entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
+ max_bitrate = CABAC_MAX_BITRATE;
+ else
+ max_bitrate = CAVLC_MAX_BITRATE;
+
+ bitrate = min(bitrate, max_bitrate);
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &bitrate, sizeof(u32));
+}
+
+int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 rc_mode = inst->fw_caps[BITRATE_MODE].value;
+ u32 peak_bitrate = inst->fw_caps[cap_id].value;
+ u32 bitrate = inst->fw_caps[BITRATE].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+
+ if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ return 0;
+
+ if (inst->fw_caps[cap_id].flags & CAP_FLAG_CLIENT_SET) {
+ if (peak_bitrate < bitrate)
+ peak_bitrate = bitrate;
+ } else {
+ peak_bitrate = bitrate;
+ }
+
+ inst->fw_caps[cap_id].value = peak_bitrate;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &peak_bitrate, sizeof(u32));
+}
+
+int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 bitrate_mode = inst->fw_caps[BITRATE_MODE].value;
+ u32 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value;
+ u32 frame_skip = inst->fw_caps[FRAME_SKIP_MODE].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 rc_mode = 0;
+
+ if (!frame_rc)
+ rc_mode = HFI_RATE_CONTROL_OFF;
+ else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+ rc_mode = frame_skip ? HFI_RATE_CONTROL_VBR_VFR : HFI_RATE_CONTROL_VBR_CFR;
+ else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ rc_mode = frame_skip ? HFI_RATE_CONTROL_CBR_VFR : HFI_RATE_CONTROL_CBR_CFR;
+ else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
+ rc_mode = HFI_RATE_CONTROL_CQ;
+
+ inst->hfi_rc_type = rc_mode;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &rc_mode, sizeof(u32));
+}
+
+int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 bitrate_mode = inst->fw_caps[BITRATE_MODE].value;
+ u32 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value;
+ u32 frame_skip = inst->fw_caps[FRAME_SKIP_MODE].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 rc_mode = 0;
+
+ if (!frame_rc)
+ rc_mode = HFI_RC_OFF;
+ else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+ rc_mode = HFI_RC_VBR_CFR;
+ else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ rc_mode = frame_skip ? HFI_RC_CBR_VFR : HFI_RC_CBR_CFR;
+ else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
+ rc_mode = HFI_RC_CQ;
+
+ inst->hfi_rc_type = rc_mode;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32_ENUM,
+ &rc_mode, sizeof(u32));
+}
+
+int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 entropy_mode = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 hfi_val;
+
+ if (inst->codec != V4L2_PIX_FMT_H264)
+ return 0;
+
+ hfi_val = (entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) ?
+ HFI_H264_ENTROPY_CAVLC : HFI_H264_ENTROPY_CABAC;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &hfi_val, sizeof(u32));
+}
+
+int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 entropy_mode = inst->fw_caps[cap_id].value;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 profile;
+
+ if (inst->codec != V4L2_PIX_FMT_H264)
+ return 0;
+
+ profile = inst->fw_caps[PROFILE_H264].value;
+
+ if (profile == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE ||
+ profile == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)
+ entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
+
+ inst->fw_caps[cap_id].value = entropy_mode;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_U32,
+ &entropy_mode, sizeof(u32));
+}
+
+int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+ u32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0;
+ u32 min_qp_enable = 0, client_qp_enable = 0;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 hfi_val;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ if (inst->fw_caps[MIN_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
+ min_qp_enable = 1;
+ if (min_qp_enable ||
+ (inst->fw_caps[I_FRAME_MIN_QP_H264].flags & CAP_FLAG_CLIENT_SET))
+ i_qp_enable = 1;
+ if (min_qp_enable ||
+ (inst->fw_caps[P_FRAME_MIN_QP_H264].flags & CAP_FLAG_CLIENT_SET))
+ p_qp_enable = 1;
+ if (min_qp_enable ||
+ (inst->fw_caps[B_FRAME_MIN_QP_H264].flags & CAP_FLAG_CLIENT_SET))
+ b_qp_enable = 1;
+ } else {
+ if (inst->fw_caps[MIN_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
+ min_qp_enable = 1;
+ if (min_qp_enable ||
+ (inst->fw_caps[I_FRAME_MIN_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
+ i_qp_enable = 1;
+ if (min_qp_enable ||
+ (inst->fw_caps[P_FRAME_MIN_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
+ p_qp_enable = 1;
+ if (min_qp_enable ||
+ (inst->fw_caps[B_FRAME_MIN_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
+ b_qp_enable = 1;
+ }
+
+ client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+ if (!client_qp_enable)
+ return 0;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ i_frame_qp = max(inst->fw_caps[I_FRAME_MIN_QP_H264].value,
+ inst->fw_caps[MIN_FRAME_QP_H264].value);
+ p_frame_qp = max(inst->fw_caps[P_FRAME_MIN_QP_H264].value,
+ inst->fw_caps[MIN_FRAME_QP_H264].value);
+ b_frame_qp = max(inst->fw_caps[B_FRAME_MIN_QP_H264].value,
+ inst->fw_caps[MIN_FRAME_QP_H264].value);
+ } else {
+ i_frame_qp = max(inst->fw_caps[I_FRAME_MIN_QP_HEVC].value,
+ inst->fw_caps[MIN_FRAME_QP_HEVC].value);
+ p_frame_qp = max(inst->fw_caps[P_FRAME_MIN_QP_HEVC].value,
+ inst->fw_caps[MIN_FRAME_QP_HEVC].value);
+ b_frame_qp = max(inst->fw_caps[B_FRAME_MIN_QP_HEVC].value,
+ inst->fw_caps[MIN_FRAME_QP_HEVC].value);
+ }
+
+ hfi_val = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 | client_qp_enable << 24;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_32_PACKED,
+ &hfi_val, sizeof(u32));
+}
+
+int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+ u32 max_qp_enable = 0, client_qp_enable;
+ u32 i_frame_qp, p_frame_qp, b_frame_qp;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ u32 hfi_val;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ if (inst->fw_caps[MAX_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
+ max_qp_enable = 1;
+ if (max_qp_enable ||
+ (inst->fw_caps[I_FRAME_MAX_QP_H264].flags & CAP_FLAG_CLIENT_SET))
+ i_qp_enable = 1;
+ if (max_qp_enable ||
+ (inst->fw_caps[P_FRAME_MAX_QP_H264].flags & CAP_FLAG_CLIENT_SET))
+ p_qp_enable = 1;
+ if (max_qp_enable ||
+ (inst->fw_caps[B_FRAME_MAX_QP_H264].flags & CAP_FLAG_CLIENT_SET))
+ b_qp_enable = 1;
+ } else {
+ if (inst->fw_caps[MAX_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
+ max_qp_enable = 1;
+ if (max_qp_enable ||
+ (inst->fw_caps[I_FRAME_MAX_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
+ i_qp_enable = 1;
+ if (max_qp_enable ||
+ (inst->fw_caps[P_FRAME_MAX_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
+ p_qp_enable = 1;
+ if (max_qp_enable ||
+ (inst->fw_caps[B_FRAME_MAX_QP_HEVC].flags & CAP_FLAG_CLIENT_SET))
+ b_qp_enable = 1;
+ }
+
+ client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+ if (!client_qp_enable)
+ return 0;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ i_frame_qp = min(inst->fw_caps[I_FRAME_MAX_QP_H264].value,
+ inst->fw_caps[MAX_FRAME_QP_H264].value);
+ p_frame_qp = min(inst->fw_caps[P_FRAME_MAX_QP_H264].value,
+ inst->fw_caps[MAX_FRAME_QP_H264].value);
+ b_frame_qp = min(inst->fw_caps[B_FRAME_MAX_QP_H264].value,
+ inst->fw_caps[MAX_FRAME_QP_H264].value);
+ } else {
+ i_frame_qp = min(inst->fw_caps[I_FRAME_MAX_QP_HEVC].value,
+ inst->fw_caps[MAX_FRAME_QP_HEVC].value);
+ p_frame_qp = min(inst->fw_caps[P_FRAME_MAX_QP_HEVC].value,
+ inst->fw_caps[MAX_FRAME_QP_HEVC].value);
+ b_frame_qp = min(inst->fw_caps[B_FRAME_MAX_QP_HEVC].value,
+ inst->fw_caps[MAX_FRAME_QP_HEVC].value);
+ }
+
+ hfi_val = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+ client_qp_enable << 24;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_32_PACKED,
+ &hfi_val, sizeof(u32));
+}
+
+int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0, client_qp_enable;
+ u32 i_frame_qp, p_frame_qp, b_frame_qp;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+ struct vb2_queue *q;
+ u32 hfi_val;
+
+ q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+ if (vb2_is_streaming(q)) {
+ if (inst->hfi_rc_type != HFI_RC_OFF)
+ return 0;
+ }
+
+ if (inst->hfi_rc_type == HFI_RC_OFF) {
+ i_qp_enable = 1;
+ p_qp_enable = 1;
+ b_qp_enable = 1;
+ } else {
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ if (inst->fw_caps[I_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
+ i_qp_enable = 1;
+ if (inst->fw_caps[P_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
+ p_qp_enable = 1;
+ if (inst->fw_caps[B_FRAME_QP_H264].flags & CAP_FLAG_CLIENT_SET)
+ b_qp_enable = 1;
+ } else {
+ if (inst->fw_caps[I_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
+ i_qp_enable = 1;
+ if (inst->fw_caps[P_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
+ p_qp_enable = 1;
+ if (inst->fw_caps[B_FRAME_QP_HEVC].flags & CAP_FLAG_CLIENT_SET)
+ b_qp_enable = 1;
+ }
+ }
+
+ client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+ if (!client_qp_enable)
+ return 0;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ i_frame_qp = inst->fw_caps[I_FRAME_QP_H264].value;
+ p_frame_qp = inst->fw_caps[P_FRAME_QP_H264].value;
+ b_frame_qp = inst->fw_caps[B_FRAME_QP_H264].value;
+ } else {
+ i_frame_qp = inst->fw_caps[I_FRAME_QP_HEVC].value;
+ p_frame_qp = inst->fw_caps[P_FRAME_QP_HEVC].value;
+ b_frame_qp = inst->fw_caps[B_FRAME_QP_HEVC].value;
+ }
+
+ hfi_val = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+ client_qp_enable << 24;
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_32_PACKED,
+ &hfi_val, sizeof(u32));
+}
+
+int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ struct hfi_quantization_range_v2 range;
+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ range.min_qp.qp_packed = inst->fw_caps[MIN_FRAME_QP_HEVC].value;
+ range.max_qp.qp_packed = inst->fw_caps[MAX_FRAME_QP_HEVC].value;
+ } else {
+ range.min_qp.qp_packed = inst->fw_caps[MIN_FRAME_QP_H264].value;
+ range.max_qp.qp_packed = inst->fw_caps[MAX_FRAME_QP_H264].value;
+ }
+
+ return hfi_ops->session_set_property(inst, hfi_id,
+ HFI_HOST_FLAGS_NONE,
+ iris_get_port_info(inst, cap_id),
+ HFI_PAYLOAD_32_PACKED,
+ &range, sizeof(range));
+}
+
int iris_set_properties(struct iris_inst *inst, u32 plane)
{
const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h
index 9b5741868933..30af333cc494 100644
--- a/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -17,6 +17,21 @@ int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap
int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_profile_level_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_header_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_header_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
+int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id);
int iris_set_properties(struct iris_inst *inst, u32 plane);
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
index f1b5cd56db32..9ab499fad946 100644
--- a/drivers/media/platform/qcom/iris/iris_firmware.c
+++ b/drivers/media/platform/qcom/iris/iris_firmware.c
@@ -60,16 +60,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
ret = qcom_mdt_load(dev, firmware, fw_name,
pas_id, mem_virt, mem_phys, res_size, NULL);
- if (ret)
- goto err_mem_unmap;
-
- ret = qcom_scm_pas_auth_and_reset(pas_id);
- if (ret)
- goto err_mem_unmap;
-
- return ret;
-err_mem_unmap:
memunmap(mem_virt);
err_release_fw:
release_firmware(firmware);
@@ -94,6 +85,12 @@ int iris_fw_load(struct iris_core *core)
return -ENOMEM;
}
+ ret = qcom_scm_pas_auth_and_reset(core->iris_platform_data->pas_id);
+ if (ret) {
+ dev_err(core->dev, "auth and reset failed: %d\n", ret);
+ return ret;
+ }
+
ret = qcom_scm_mem_protect_video_var(cp_config->cp_start,
cp_config->cp_size,
cp_config->cp_nonpixel_start,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h
index 9e6aadb83783..b51471fb32c7 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_common.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h
@@ -102,7 +102,7 @@ enum hfi_matrix_coefficients {
struct iris_hfi_prop_type_handle {
u32 type;
- int (*handle)(struct iris_inst *inst);
+ int (*handle)(struct iris_inst *inst, u32 plane);
};
struct iris_hfi_command_ops {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index 5fc30d54af4d..e1788c266bb1 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -21,6 +21,10 @@ static u32 iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer_type)
return HFI_BUFFER_INTERNAL_SCRATCH;
case BUF_SCRATCH_1:
return HFI_BUFFER_INTERNAL_SCRATCH_1;
+ case BUF_SCRATCH_2:
+ return HFI_BUFFER_INTERNAL_SCRATCH_2;
+ case BUF_ARP:
+ return HFI_BUFFER_INTERNAL_PERSIST;
default:
return -EINVAL;
}
@@ -109,7 +113,12 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst)
packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;
packet.shdr.session_id = inst->session_id;
- packet.session_domain = HFI_SESSION_TYPE_DEC;
+
+ if (inst->domain == DECODER)
+ packet.session_domain = HFI_SESSION_TYPE_DEC;
+ else
+ packet.session_domain = HFI_SESSION_TYPE_ENC;
+
packet.session_codec = codec;
reinit_completion(&inst->completion);
@@ -184,47 +193,70 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
u32 flush_type = 0;
int ret = 0;
- if ((V4L2_TYPE_IS_OUTPUT(plane) &&
- inst->state == IRIS_INST_INPUT_STREAMING) ||
- (V4L2_TYPE_IS_CAPTURE(plane) &&
- inst->state == IRIS_INST_OUTPUT_STREAMING) ||
- inst->state == IRIS_INST_ERROR) {
- reinit_completion(&inst->completion);
- iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
- ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
- if (!ret)
- ret = iris_wait_for_session_response(inst, false);
-
- reinit_completion(&inst->completion);
- iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RESOURCES);
- ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
- if (!ret)
- ret = iris_wait_for_session_response(inst, false);
-
- iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
+ if (inst->domain == DECODER) {
+ if (inst->state == IRIS_INST_STREAMING) {
+ if (V4L2_TYPE_IS_OUTPUT(plane))
+ flush_type = HFI_FLUSH_ALL;
+ else if (V4L2_TYPE_IS_CAPTURE(plane))
+ flush_type = HFI_FLUSH_OUTPUT;
+
+ reinit_completion(&inst->flush_completion);
+
+ flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
+ flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
+ flush_pkt.shdr.session_id = inst->session_id;
+ flush_pkt.flush_type = flush_type;
+
+ ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
+ if (!ret) {
+ inst->flush_responses_pending++;
+ ret = iris_wait_for_session_response(inst, true);
+ }
+ } else if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) {
+ reinit_completion(&inst->completion);
+ iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
+ ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
+ if (!ret)
+ ret = iris_wait_for_session_response(inst, false);
+
+ reinit_completion(&inst->completion);
+ iris_hfi_gen1_packet_session_cmd(inst, &pkt,
+ HFI_CMD_SESSION_RELEASE_RESOURCES);
+ ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
+ if (!ret)
+ ret = iris_wait_for_session_response(inst, false);
+
+ iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
+
+ iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ VB2_BUF_STATE_ERROR);
+ iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ VB2_BUF_STATE_ERROR);
+ }
+ } else {
+ if (inst->state == IRIS_INST_STREAMING ||
+ inst->state == IRIS_INST_INPUT_STREAMING ||
+ inst->state == IRIS_INST_ERROR) {
+ reinit_completion(&inst->completion);
+ iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
+ ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
+ if (!ret)
+ ret = iris_wait_for_session_response(inst, false);
+
+ reinit_completion(&inst->completion);
+ iris_hfi_gen1_packet_session_cmd(inst, &pkt,
+ HFI_CMD_SESSION_RELEASE_RESOURCES);
+ ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
+ if (!ret)
+ ret = iris_wait_for_session_response(inst, false);
+
+ iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
+ }
iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
VB2_BUF_STATE_ERROR);
iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
VB2_BUF_STATE_ERROR);
- } else if (inst->state == IRIS_INST_STREAMING) {
- if (V4L2_TYPE_IS_OUTPUT(plane))
- flush_type = HFI_FLUSH_ALL;
- else if (V4L2_TYPE_IS_CAPTURE(plane))
- flush_type = HFI_FLUSH_OUTPUT;
-
- reinit_completion(&inst->flush_completion);
-
- flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
- flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
- flush_pkt.shdr.session_id = inst->session_id;
- flush_pkt.flush_type = flush_type;
-
- ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
- if (!ret) {
- inst->flush_responses_pending++;
- ret = iris_wait_for_session_response(inst, true);
- }
}
return ret;
@@ -241,23 +273,44 @@ static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane)
static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf)
{
- struct hfi_session_empty_buffer_compressed_pkt ip_pkt;
-
- ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
- ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
- ip_pkt.shdr.session_id = inst->session_id;
- ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
- ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
- ip_pkt.flags = buf->flags;
- ip_pkt.mark_target = 0;
- ip_pkt.mark_data = 0;
- ip_pkt.offset = buf->data_offset;
- ip_pkt.alloc_len = buf->buffer_size;
- ip_pkt.filled_len = buf->data_size;
- ip_pkt.input_tag = buf->index;
- ip_pkt.packet_buffer = buf->device_addr;
-
- return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
+ struct hfi_session_empty_buffer_compressed_pkt com_ip_pkt;
+ struct hfi_session_empty_buffer_uncompressed_pkt uncom_ip_pkt;
+
+ if (inst->domain == DECODER) {
+ com_ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
+ com_ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
+ com_ip_pkt.shdr.session_id = inst->session_id;
+ com_ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
+ com_ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
+ com_ip_pkt.flags = buf->flags;
+ com_ip_pkt.mark_target = 0;
+ com_ip_pkt.mark_data = 0;
+ com_ip_pkt.offset = buf->data_offset;
+ com_ip_pkt.alloc_len = buf->buffer_size;
+ com_ip_pkt.filled_len = buf->data_size;
+ com_ip_pkt.input_tag = buf->index;
+ com_ip_pkt.packet_buffer = buf->device_addr;
+ return iris_hfi_queue_cmd_write(inst->core, &com_ip_pkt,
+ com_ip_pkt.shdr.hdr.size);
+ } else {
+ uncom_ip_pkt.shdr.hdr.size =
+ sizeof(struct hfi_session_empty_buffer_uncompressed_pkt);
+ uncom_ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
+ uncom_ip_pkt.shdr.session_id = inst->session_id;
+ uncom_ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
+ uncom_ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
+ uncom_ip_pkt.view_id = 0;
+ uncom_ip_pkt.flags = buf->flags;
+ uncom_ip_pkt.mark_target = 0;
+ uncom_ip_pkt.mark_data = 0;
+ uncom_ip_pkt.offset = buf->data_offset;
+ uncom_ip_pkt.alloc_len = buf->buffer_size;
+ uncom_ip_pkt.filled_len = buf->data_size;
+ uncom_ip_pkt.input_tag = buf->index;
+ uncom_ip_pkt.packet_buffer = buf->device_addr;
+ return iris_hfi_queue_cmd_write(inst->core, &uncom_ip_pkt,
+ uncom_ip_pkt.shdr.hdr.size);
+ }
}
static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struct iris_buffer *buf)
@@ -330,6 +383,8 @@ static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iri
case BUF_PERSIST:
case BUF_BIN:
case BUF_SCRATCH_1:
+ case BUF_SCRATCH_2:
+ case BUF_ARP:
return iris_hfi_gen1_queue_internal_buffer(inst, buf);
default:
return -EINVAL;
@@ -395,16 +450,31 @@ exit:
static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane)
{
- struct hfi_session_empty_buffer_compressed_pkt ip_pkt = {0};
+ if (inst->domain == DECODER) {
+ struct hfi_session_empty_buffer_compressed_pkt ip_pkt = {0};
+
+ ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
+ ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
+ ip_pkt.shdr.session_id = inst->session_id;
+ ip_pkt.flags = HFI_BUFFERFLAG_EOS;
+ ip_pkt.packet_buffer = 0xdeadb000;
+
+ return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
+ }
+
+ if (inst->domain == ENCODER) {
+ struct hfi_session_empty_buffer_uncompressed_pkt ip_pkt = {0};
- ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
- ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
- ip_pkt.shdr.session_id = inst->session_id;
- ip_pkt.flags = HFI_BUFFERFLAG_EOS;
- if (inst->codec == V4L2_PIX_FMT_VP9)
+ ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_uncompressed_pkt);
+ ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
+ ip_pkt.shdr.session_id = inst->session_id;
+ ip_pkt.flags = HFI_BUFFERFLAG_EOS;
ip_pkt.packet_buffer = 0xdeadb000;
- return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
+ return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
+ }
+
+ return -EINVAL;
}
static int
@@ -507,6 +577,114 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p
packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
break;
}
+ case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: {
+ struct hfi_profile_level *in = pdata, *pl = prop_data;
+
+ pl->level = in->level;
+ pl->profile = in->profile;
+ if (pl->profile <= 0)
+ /* Profile not supported, falling back to high */
+ pl->profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
+
+ if (!pl->level)
+ /* Level not supported, falling back to 1 */
+ pl->level = 1;
+
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*pl);
+ break;
+ }
+ case HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER: {
+ struct hfi_enable *en = prop_data;
+ u32 *in = pdata;
+
+ en->enable = *in;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*en);
+ break;
+ }
+ case HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE: {
+ struct hfi_bitrate *brate = prop_data;
+ u32 *in = pdata;
+
+ brate->bitrate = *in;
+ brate->layer_id = 0;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*brate);
+ break;
+ }
+ case HFI_PROPERTY_PARAM_VENC_RATE_CONTROL: {
+ u32 *in = pdata;
+
+ switch (*in) {
+ case HFI_RATE_CONTROL_OFF:
+ case HFI_RATE_CONTROL_CBR_CFR:
+ case HFI_RATE_CONTROL_CBR_VFR:
+ case HFI_RATE_CONTROL_VBR_CFR:
+ case HFI_RATE_CONTROL_VBR_VFR:
+ case HFI_RATE_CONTROL_CQ:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ packet->data[1] = *in;
+ packet->shdr.hdr.size += sizeof(u32) * 2;
+ break;
+ }
+ case HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL: {
+ struct hfi_h264_entropy_control *entropy = prop_data;
+ u32 *in = pdata;
+
+ entropy->entropy_mode = *in;
+ if (entropy->entropy_mode == HFI_H264_ENTROPY_CABAC)
+ entropy->cabac_model = HFI_H264_CABAC_MODEL_0;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*entropy);
+ break;
+ }
+ case HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2: {
+ struct hfi_quantization_range_v2 *range = prop_data;
+ struct hfi_quantization_range_v2 *in = pdata;
+ u32 min_qp, max_qp;
+
+ min_qp = in->min_qp.qp_packed;
+ max_qp = in->max_qp.qp_packed;
+
+ /* We'll be packing in the qp, so make sure we
+ * won't be losing data when masking
+ */
+ if (min_qp > 0xff || max_qp > 0xff)
+ return -ERANGE;
+
+ range->min_qp.layer_id = 0xFF;
+ range->max_qp.layer_id = 0xFF;
+ range->min_qp.qp_packed = (min_qp & 0xFF) | ((min_qp & 0xFF) << 8) |
+ ((min_qp & 0xFF) << 16);
+ range->max_qp.qp_packed = (max_qp & 0xFF) | ((max_qp & 0xFF) << 8) |
+ ((max_qp & 0xFF) << 16);
+ range->min_qp.enable = 7;
+ range->max_qp.enable = 7;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*range);
+ break;
+ }
+ case HFI_PROPERTY_CONFIG_FRAME_RATE: {
+ struct hfi_framerate *frate = prop_data;
+ struct hfi_framerate *in = pdata;
+
+ frate->buffer_type = in->buffer_type;
+ frate->framerate = in->framerate;
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*frate);
+ break;
+ }
+ case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO: {
+ struct hfi_uncompressed_plane_actual_info *plane_actual_info = prop_data;
+ struct hfi_uncompressed_plane_actual_info *in = pdata;
+
+ plane_actual_info->buffer_type = in->buffer_type;
+ plane_actual_info->num_planes = in->num_planes;
+ plane_actual_info->plane_format[0] = in->plane_format[0];
+ if (in->num_planes > 1)
+ plane_actual_info->plane_format[1] = in->plane_format[1];
+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*plane_actual_info);
+ break;
+ }
default:
return -EINVAL;
}
@@ -549,7 +727,7 @@ static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet
return hfi_gen1_set_property(inst, packet_type, payload, payload_size);
}
-static int iris_hfi_gen1_set_resolution(struct iris_inst *inst)
+static int iris_hfi_gen1_set_resolution(struct iris_inst *inst, u32 plane)
{
u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
struct hfi_framesize fs;
@@ -564,14 +742,18 @@ static int iris_hfi_gen1_set_resolution(struct iris_inst *inst)
if (ret)
return ret;
}
- fs.buffer_type = HFI_BUFFER_OUTPUT2;
+ if (inst->domain == DECODER)
+ fs.buffer_type = HFI_BUFFER_OUTPUT2;
+ else
+ fs.buffer_type = HFI_BUFFER_OUTPUT;
+
fs.width = inst->fmt_dst->fmt.pix_mp.width;
fs.height = inst->fmt_dst->fmt.pix_mp.height;
return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
}
-static int iris_hfi_gen1_decide_core(struct iris_inst *inst)
+static int iris_hfi_gen1_decide_core(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
struct hfi_videocores_usage_type cu;
@@ -581,36 +763,45 @@ static int iris_hfi_gen1_decide_core(struct iris_inst *inst)
return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu));
}
-static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst)
+static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
- u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
struct hfi_uncompressed_format_select fmt;
+ u32 pixelformat;
int ret;
- if (iris_split_mode_enabled(inst)) {
- fmt.buffer_type = HFI_BUFFER_OUTPUT;
- fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0;
+ if (inst->domain == DECODER) {
+ pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
+ if (iris_split_mode_enabled(inst)) {
+ fmt.buffer_type = HFI_BUFFER_OUTPUT;
+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ?
+ HFI_COLOR_FORMAT_NV12_UBWC : 0;
- ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
- if (ret)
- return ret;
+ ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+ if (ret)
+ return ret;
- fmt.buffer_type = HFI_BUFFER_OUTPUT2;
- fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
+ fmt.buffer_type = HFI_BUFFER_OUTPUT2;
+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
- ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+ ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+ } else {
+ fmt.buffer_type = HFI_BUFFER_OUTPUT;
+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
+
+ ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
+ }
} else {
- fmt.buffer_type = HFI_BUFFER_OUTPUT;
+ pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
+ fmt.buffer_type = HFI_BUFFER_INPUT;
fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
-
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
}
return ret;
}
-static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst)
+static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO;
struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
@@ -630,7 +821,7 @@ static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst)
return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint));
}
-static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
+static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst, u32 plane)
{
u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
struct hfi_buffer_count_actual buf_count;
@@ -644,20 +835,28 @@ static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
if (ret)
return ret;
- if (iris_split_mode_enabled(inst)) {
- buf_count.type = HFI_BUFFER_OUTPUT;
- buf_count.count_actual = VIDEO_MAX_FRAME;
- buf_count.count_min_host = VIDEO_MAX_FRAME;
+ if (inst->domain == DECODER) {
+ if (iris_split_mode_enabled(inst)) {
+ buf_count.type = HFI_BUFFER_OUTPUT;
+ buf_count.count_actual = VIDEO_MAX_FRAME;
+ buf_count.count_min_host = VIDEO_MAX_FRAME;
- ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
- if (ret)
- return ret;
+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
+ if (ret)
+ return ret;
- buf_count.type = HFI_BUFFER_OUTPUT2;
- buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB);
- buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB);
+ buf_count.type = HFI_BUFFER_OUTPUT2;
+ buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB);
+ buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB);
- ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
+ } else {
+ buf_count.type = HFI_BUFFER_OUTPUT;
+ buf_count.count_actual = VIDEO_MAX_FRAME;
+ buf_count.count_min_host = VIDEO_MAX_FRAME;
+
+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
+ }
} else {
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = VIDEO_MAX_FRAME;
@@ -669,7 +868,7 @@ static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
return ret;
}
-static int iris_hfi_gen1_set_multistream(struct iris_inst *inst)
+static int iris_hfi_gen1_set_multistream(struct iris_inst *inst, u32 plane)
{
u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
struct hfi_multi_stream multi = {0};
@@ -704,7 +903,7 @@ static int iris_hfi_gen1_set_multistream(struct iris_inst *inst)
return ret;
}
-static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
+static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst, u32 plane)
{
const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
struct hfi_buffer_size_actual bufsz;
@@ -712,7 +911,7 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
if (iris_split_mode_enabled(inst)) {
bufsz.type = HFI_BUFFER_OUTPUT;
- bufsz.size = iris_vpu_buf_size(inst, BUF_DPB);
+ bufsz.size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, BUF_DPB);
ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
if (ret)
@@ -739,14 +938,49 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
return ret;
}
+static int iris_hfi_gen1_set_frame_rate(struct iris_inst *inst, u32 plane)
+{
+ const u32 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE;
+ struct hfi_framerate frate;
+
+ if (V4L2_TYPE_IS_OUTPUT(plane))
+ return 0;
+
+ frate.buffer_type = HFI_BUFFER_OUTPUT;
+ frate.framerate = inst->frame_rate << 16;
+
+ return hfi_gen1_set_property(inst, ptype, &frate, sizeof(frate));
+}
+
+static int iris_hfi_gen1_set_stride(struct iris_inst *inst, u32 plane)
+{
+ const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO;
+ struct hfi_uncompressed_plane_actual_info plane_actual_info;
+
+ plane_actual_info.buffer_type = HFI_BUFFER_INPUT;
+ plane_actual_info.num_planes = 2;
+ plane_actual_info.plane_format[0].actual_stride =
+ ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
+ plane_actual_info.plane_format[0].actual_plane_buffer_height =
+ ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
+ plane_actual_info.plane_format[1].actual_stride =
+ ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
+ plane_actual_info.plane_format[1].actual_plane_buffer_height =
+ (ALIGN(inst->fmt_src->fmt.pix_mp.height, 32)) / 2;
+
+ return hfi_gen1_set_property(inst, ptype, &plane_actual_info, sizeof(plane_actual_info));
+}
+
static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane)
{
+ struct iris_hfi_prop_type_handle const *handler = NULL;
+ u32 handler_size = 0;
struct iris_core *core = inst->core;
u32 config_params_size, i, j;
const u32 *config_params;
int ret;
- static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = {
+ static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_inp_arr[] = {
{HFI_PROPERTY_PARAM_FRAME_SIZE,
iris_hfi_gen1_set_resolution},
{HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE,
@@ -763,7 +997,7 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p
iris_hfi_gen1_set_bufsize},
};
- static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = {
+ static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_out_arr[] = {
{HFI_PROPERTY_PARAM_FRAME_SIZE,
iris_hfi_gen1_set_resolution},
{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
@@ -778,29 +1012,43 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p
iris_hfi_gen1_set_bufsize},
};
- config_params = core->iris_platform_data->input_config_params_default;
- config_params_size = core->iris_platform_data->input_config_params_default_size;
-
- if (V4L2_TYPE_IS_OUTPUT(plane)) {
- for (i = 0; i < config_params_size; i++) {
- for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) {
- if (prop_type_handle_inp_arr[j].type == config_params[i]) {
- ret = prop_type_handle_inp_arr[j].handle(inst);
- if (ret)
- return ret;
- break;
- }
- }
+ static const struct iris_hfi_prop_type_handle venc_prop_type_handle_inp_arr[] = {
+ {HFI_PROPERTY_CONFIG_FRAME_RATE,
+ iris_hfi_gen1_set_frame_rate},
+ {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO,
+ iris_hfi_gen1_set_stride},
+ {HFI_PROPERTY_PARAM_FRAME_SIZE,
+ iris_hfi_gen1_set_resolution},
+ {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
+ iris_hfi_gen1_set_raw_format},
+ {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
+ iris_hfi_gen1_set_num_bufs},
+ };
+
+ if (inst->domain == DECODER) {
+ config_params = core->iris_platform_data->dec_input_config_params_default;
+ config_params_size = core->iris_platform_data->dec_input_config_params_default_size;
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ handler = vdec_prop_type_handle_inp_arr;
+ handler_size = ARRAY_SIZE(vdec_prop_type_handle_inp_arr);
+ } else if (V4L2_TYPE_IS_CAPTURE(plane)) {
+ handler = vdec_prop_type_handle_out_arr;
+ handler_size = ARRAY_SIZE(vdec_prop_type_handle_out_arr);
}
- } else if (V4L2_TYPE_IS_CAPTURE(plane)) {
- for (i = 0; i < config_params_size; i++) {
- for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) {
- if (prop_type_handle_out_arr[j].type == config_params[i]) {
- ret = prop_type_handle_out_arr[j].handle(inst);
- if (ret)
- return ret;
- break;
- }
+ } else {
+ config_params = core->iris_platform_data->enc_input_config_params;
+ config_params_size = core->iris_platform_data->enc_input_config_params_size;
+ handler = venc_prop_type_handle_inp_arr;
+ handler_size = ARRAY_SIZE(venc_prop_type_handle_inp_arr);
+ }
+
+ for (i = 0; i < config_params_size; i++) {
+ for (j = 0; j < handler_size; j++) {
+ if (handler[j].type == config_params[i]) {
+ ret = handler[j].handle(inst, plane);
+ if (ret)
+ return ret;
+ break;
}
}
}
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
index d4d119ca98b0..42226ccee3d9 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h
@@ -10,6 +10,7 @@
#define HFI_VIDEO_ARCH_OX 0x1
+#define HFI_SESSION_TYPE_ENC 1
#define HFI_SESSION_TYPE_DEC 2
#define HFI_VIDEO_CODEC_H264 0x00000002
@@ -73,18 +74,22 @@
#define HFI_BUFFER_INPUT 0x1
#define HFI_BUFFER_OUTPUT 0x2
#define HFI_BUFFER_OUTPUT2 0x3
+#define HFI_BUFFER_INTERNAL_PERSIST 0x4
#define HFI_BUFFER_INTERNAL_PERSIST_1 0x5
#define HFI_BUFFER_INTERNAL_SCRATCH 0x6
#define HFI_BUFFER_INTERNAL_SCRATCH_1 0x7
+#define HFI_BUFFER_INTERNAL_SCRATCH_2 0x8
#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5
#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6
#define HFI_PROPERTY_PARAM_FRAME_SIZE 0x1001
+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO 0x1002
#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT 0x1003
#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT 0x1005
#define HFI_PROPERTY_PARAM_WORK_MODE 0x1015
#define HFI_PROPERTY_PARAM_WORK_ROUTE 0x1017
+#define HFI_PROPERTY_CONFIG_FRAME_RATE 0x2001
#define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE 0x2002
#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM 0x1003001
@@ -111,15 +116,32 @@
#define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a
#define HFI_MSG_SESSION_RELEASE_BUFFERS 0x22100c
-#define HFI_PICTURE_I 0x00000001
-#define HFI_PICTURE_P 0x00000002
-#define HFI_PICTURE_B 0x00000004
-#define HFI_PICTURE_IDR 0x00000008
+#define HFI_GEN1_PICTURE_I 0x00000001
+#define HFI_GEN1_PICTURE_P 0x00000002
+#define HFI_GEN1_PICTURE_B 0x00000004
+#define HFI_GEN1_PICTURE_IDR 0x00000008
#define HFI_FRAME_NOTCODED 0x7f002000
#define HFI_FRAME_YUV 0x7f004000
#define HFI_UNUSED_PICT 0x10000000
-#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008
-#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000
+#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008
+#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000
+#define HFI_RATE_CONTROL_OFF 0x1000001
+#define HFI_RATE_CONTROL_VBR_VFR 0x1000002
+#define HFI_RATE_CONTROL_VBR_CFR 0x1000003
+#define HFI_RATE_CONTROL_CBR_VFR 0x1000004
+#define HFI_RATE_CONTROL_CBR_CFR 0x1000005
+#define HFI_RATE_CONTROL_CQ 0x1000008
+
+#define HFI_H264_ENTROPY_CAVLC 0x1
+#define HFI_H264_ENTROPY_CABAC 0x2
+
+#define HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL 0x2005002
+#define HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL 0x2005003
+#define HFI_PROPERTY_PARAM_VENC_RATE_CONTROL 0x2005004
+#define HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2 0x2005009
+#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
+#define HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE 0x2006001
+#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER 0x2006008
struct hfi_pkt_hdr {
u32 size;
@@ -194,6 +216,23 @@ struct hfi_session_empty_buffer_compressed_pkt {
u32 data;
};
+struct hfi_session_empty_buffer_uncompressed_pkt {
+ struct hfi_session_hdr_pkt shdr;
+ u32 view_id;
+ u32 time_stamp_hi;
+ u32 time_stamp_lo;
+ u32 flags;
+ u32 mark_target;
+ u32 mark_data;
+ u32 alloc_len;
+ u32 filled_len;
+ u32 offset;
+ u32 input_tag;
+ u32 packet_buffer;
+ u32 extradata_buffer;
+ u32 data;
+};
+
struct hfi_session_fill_buffer_pkt {
struct hfi_session_hdr_pkt shdr;
u32 stream_id;
@@ -340,6 +379,17 @@ struct hfi_uncompressed_plane_actual_constraints_info {
struct hfi_uncompressed_plane_constraints plane_format[2];
};
+struct hfi_uncompressed_plane_actual {
+ int actual_stride;
+ u32 actual_plane_buffer_height;
+};
+
+struct hfi_uncompressed_plane_actual_info {
+ u32 buffer_type;
+ u32 num_planes;
+ struct hfi_uncompressed_plane_actual plane_format[2];
+};
+
struct hfi_buffer_count_actual {
u32 type;
u32 count_actual;
@@ -367,6 +417,36 @@ struct hfi_buffer_requirements {
u32 alignment;
};
+struct hfi_bitrate {
+ u32 bitrate;
+ u32 layer_id;
+};
+
+#define HFI_H264_CABAC_MODEL_0 0x1
+
+struct hfi_h264_entropy_control {
+ u32 entropy_mode;
+ u32 cabac_model;
+};
+
+struct hfi_quantization_v2 {
+ u32 qp_packed;
+ u32 layer_id;
+ u32 enable;
+ u32 reserved[3];
+};
+
+struct hfi_quantization_range_v2 {
+ struct hfi_quantization_v2 min_qp;
+ struct hfi_quantization_v2 max_qp;
+ u32 reserved[4];
+};
+
+struct hfi_framerate {
+ u32 buffer_type;
+ u32 framerate;
+};
+
struct hfi_event_data {
u32 error;
u32 height;
@@ -398,6 +478,26 @@ struct hfi_msg_session_empty_buffer_done_pkt {
u32 data[];
};
+struct hfi_msg_session_fbd_compressed_pkt {
+ struct hfi_session_hdr_pkt shdr;
+ u32 time_stamp_hi;
+ u32 time_stamp_lo;
+ u32 error_type;
+ u32 flags;
+ u32 mark_target;
+ u32 mark_data;
+ u32 stats;
+ u32 offset;
+ u32 alloc_len;
+ u32 filled_len;
+ u32 input_tag;
+ u32 output_tag;
+ u32 picture_type;
+ u32 packet_buffer;
+ u32 extradata_buffer;
+ u32 data[];
+};
+
struct hfi_msg_session_fbd_uncompressed_plane0_pkt {
struct hfi_session_hdr_pkt shdr;
u32 stream_id;
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 8d1ce8a19a45..8e864c239e29 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -387,24 +387,43 @@ error:
static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
{
- struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt = packet;
+ struct hfi_msg_session_fbd_uncompressed_plane0_pkt *uncom_pkt = packet;
+ struct hfi_msg_session_fbd_compressed_pkt *com_pkt = packet;
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
struct v4l2_m2m_buffer *m2m_buffer, *n;
struct hfi_session_flush_pkt flush_pkt;
- u32 timestamp_hi = pkt->time_stamp_hi;
- u32 timestamp_lo = pkt->time_stamp_lo;
+ u32 timestamp_hi;
+ u32 timestamp_lo;
struct iris_core *core = inst->core;
- u32 filled_len = pkt->filled_len;
- u32 pic_type = pkt->picture_type;
- u32 output_tag = pkt->output_tag;
+ u32 filled_len;
+ u32 pic_type;
+ u32 output_tag;
struct iris_buffer *buf, *iter;
struct iris_buffers *buffers;
- u32 hfi_flags = pkt->flags;
- u32 offset = pkt->offset;
+ u32 hfi_flags;
+ u32 offset;
u64 timestamp_us = 0;
bool found = false;
u32 flags = 0;
+ if (inst->domain == DECODER) {
+ timestamp_hi = uncom_pkt->time_stamp_hi;
+ timestamp_lo = uncom_pkt->time_stamp_lo;
+ filled_len = uncom_pkt->filled_len;
+ pic_type = uncom_pkt->picture_type;
+ output_tag = uncom_pkt->output_tag;
+ hfi_flags = uncom_pkt->flags;
+ offset = uncom_pkt->offset;
+ } else {
+ timestamp_hi = com_pkt->time_stamp_hi;
+ timestamp_lo = com_pkt->time_stamp_lo;
+ filled_len = com_pkt->filled_len;
+ pic_type = com_pkt->picture_type;
+ output_tag = com_pkt->output_tag;
+ hfi_flags = com_pkt->flags;
+ offset = com_pkt->offset;
+ }
+
if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) {
reinit_completion(&inst->flush_completion);
@@ -416,11 +435,10 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
inst->flush_responses_pending++;
iris_inst_sub_state_change_drain_last(inst);
-
- return;
}
- if (iris_split_mode_enabled(inst) && pkt->stream_id == 0) {
+ if (iris_split_mode_enabled(inst) && inst->domain == DECODER &&
+ uncom_pkt->stream_id == 0) {
buffers = &inst->buffers[BUF_DPB];
if (!buffers)
goto error;
@@ -461,8 +479,14 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
timestamp_us = timestamp_hi;
timestamp_us = (timestamp_us << 32) | timestamp_lo;
} else {
- if (pkt->stream_id == 1 && !inst->last_buffer_dequeued) {
- if (iris_drc_pending(inst)) {
+ if (inst->domain == DECODER && uncom_pkt->stream_id == 1 &&
+ !inst->last_buffer_dequeued) {
+ if (iris_drc_pending(inst) || iris_drain_pending(inst)) {
+ flags |= V4L2_BUF_FLAG_LAST;
+ inst->last_buffer_dequeued = true;
+ }
+ } else if (inst->domain == ENCODER) {
+ if (!inst->last_buffer_dequeued && iris_drain_pending(inst)) {
flags |= V4L2_BUF_FLAG_LAST;
inst->last_buffer_dequeued = true;
}
@@ -471,14 +495,14 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet)
buf->timestamp = timestamp_us;
switch (pic_type) {
- case HFI_PICTURE_IDR:
- case HFI_PICTURE_I:
+ case HFI_GEN1_PICTURE_IDR:
+ case HFI_GEN1_PICTURE_I:
flags |= V4L2_BUF_FLAG_KEYFRAME;
break;
- case HFI_PICTURE_P:
+ case HFI_GEN1_PICTURE_P:
flags |= V4L2_BUF_FLAG_PFRAME;
break;
- case HFI_PICTURE_B:
+ case HFI_GEN1_PICTURE_B:
flags |= V4L2_BUF_FLAG_BFRAME;
break;
case HFI_FRAME_NOTCODED:
@@ -553,7 +577,7 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
},
{
.pkt = HFI_MSG_SESSION_FILL_BUFFER,
- .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
+ .pkt_sz = sizeof(struct hfi_msg_session_fbd_compressed_pkt),
},
{
.pkt = HFI_MSG_SESSION_FLUSH,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 7ca5ae13d62b..4ce71a142508 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -88,33 +88,63 @@ static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core)
return ret;
}
-static u32 iris_hfi_gen2_get_port(u32 plane)
+static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane)
{
- switch (plane) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- return HFI_PORT_BITSTREAM;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- return HFI_PORT_RAW;
- default:
- return HFI_PORT_NONE;
+ if (inst->domain == DECODER) {
+ switch (plane) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ return HFI_PORT_BITSTREAM;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ return HFI_PORT_RAW;
+ default:
+ return HFI_PORT_NONE;
+ }
+ } else {
+ switch (plane) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ return HFI_PORT_RAW;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ return HFI_PORT_BITSTREAM;
+ default:
+ return HFI_PORT_NONE;
+ }
}
}
-static u32 iris_hfi_gen2_get_port_from_buf_type(enum iris_buffer_type buffer_type)
+static u32 iris_hfi_gen2_get_port_from_buf_type(struct iris_inst *inst,
+ enum iris_buffer_type buffer_type)
{
- switch (buffer_type) {
- case BUF_INPUT:
- case BUF_BIN:
- case BUF_COMV:
- case BUF_NON_COMV:
- case BUF_LINE:
- return HFI_PORT_BITSTREAM;
- case BUF_OUTPUT:
- case BUF_DPB:
- return HFI_PORT_RAW;
- case BUF_PERSIST:
- default:
- return HFI_PORT_NONE;
+ if (inst->domain == DECODER) {
+ switch (buffer_type) {
+ case BUF_INPUT:
+ case BUF_BIN:
+ case BUF_COMV:
+ case BUF_NON_COMV:
+ case BUF_LINE:
+ return HFI_PORT_BITSTREAM;
+ case BUF_OUTPUT:
+ case BUF_DPB:
+ return HFI_PORT_RAW;
+ case BUF_PERSIST:
+ default:
+ return HFI_PORT_NONE;
+ }
+ } else {
+ switch (buffer_type) {
+ case BUF_INPUT:
+ case BUF_VPSS:
+ return HFI_PORT_RAW;
+ case BUF_OUTPUT:
+ case BUF_BIN:
+ case BUF_COMV:
+ case BUF_NON_COMV:
+ case BUF_LINE:
+ case BUF_SCRATCH_2:
+ return HFI_PORT_BITSTREAM;
+ case BUF_ARP:
+ default:
+ return HFI_PORT_NONE;
+ }
}
}
@@ -136,34 +166,77 @@ static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet
inst_hfi_gen2->packet->size);
}
-static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst)
+static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
{
- struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
inst->fmt_src->fmt.pix_mp.height;
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
- inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
+ return iris_hfi_gen2_session_set_property(inst,
+ HFI_PROP_RAW_RESOLUTION,
+ HFI_HOST_FLAGS_NONE,
+ port,
+ HFI_PAYLOAD_32_PACKED,
+ &resolution,
+ sizeof(u32));
+}
+
+static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
+{
+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
+ enum hfi_packet_payload_info payload_type;
+ u32 resolution, codec_align;
+
+ if (inst->domain == DECODER) {
+ resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
+ inst->fmt_src->fmt.pix_mp.height;
+ inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
+ payload_type = HFI_PAYLOAD_U32;
+ } else {
+ codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
+ resolution = ALIGN(inst->fmt_dst->fmt.pix_mp.width, codec_align) << 16 |
+ ALIGN(inst->fmt_dst->fmt.pix_mp.height, codec_align);
+ inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
+ payload_type = HFI_PAYLOAD_32_PACKED;
+ }
return iris_hfi_gen2_session_set_property(inst,
HFI_PROP_BITSTREAM_RESOLUTION,
HFI_HOST_FLAGS_NONE,
port,
- HFI_PAYLOAD_U32,
+ payload_type,
&resolution,
sizeof(u32));
}
-static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst)
+static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
{
- u32 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
- u32 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- u32 left_offset = inst->crop.left;
- u32 top_offset = inst->crop.top;
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
+ u32 bottom_offset, right_offset;
+ u32 left_offset, top_offset;
u32 payload[2];
+ if (inst->domain == DECODER) {
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
+ right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
+ left_offset = inst->crop.left;
+ top_offset = inst->crop.top;
+ } else {
+ bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height);
+ right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width);
+ left_offset = inst->compose.left;
+ top_offset = inst->compose.top;
+ }
+ } else {
+ bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
+ right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
+ left_offset = inst->crop.left;
+ top_offset = inst->crop.top;
+ }
+
payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
@@ -178,10 +251,10 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst)
sizeof(u64));
}
-static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
+static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 bitdepth = BIT_DEPTH_8;
inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
@@ -195,10 +268,10 @@ static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst)
+static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 coded_frames = 0;
if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
@@ -214,11 +287,11 @@ static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst)
+static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
@@ -231,10 +304,10 @@ static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst)
+static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 poc = 0;
inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
@@ -248,16 +321,16 @@ static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst)
+static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
u32 video_signal_type_present_flag = 0, color_info;
u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
u32 video_format = UNSPECIFIED_COLOR_FORMAT;
u32 full_range = V4L2_QUANTIZATION_DEFAULT;
u32 transfer_char = HFI_TRANSFER_RESERVED;
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 colour_description_present_flag = 0;
u32 primaries = HFI_PRIMARIES_RESERVED;
@@ -291,10 +364,10 @@ static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_profile(struct iris_inst *inst)
+static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 profile = 0;
switch (inst->codec) {
@@ -320,10 +393,10 @@ static int iris_hfi_gen2_set_profile(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_level(struct iris_inst *inst)
+static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 level = 0;
switch (inst->codec) {
@@ -349,33 +422,47 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst)
sizeof(u32));
}
-static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst)
+static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
{
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 hfi_colorformat, pixelformat;
- pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
- hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
+ if (inst->domain == DECODER) {
+ pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
+ hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
+ } else {
+ pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
+ hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
+ }
return iris_hfi_gen2_session_set_property(inst,
HFI_PROP_COLOR_FORMAT,
HFI_HOST_FLAGS_NONE,
port,
- HFI_PAYLOAD_U32,
+ HFI_PAYLOAD_U32_ENUM,
&hfi_colorformat,
sizeof(u32));
}
-static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
+static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane)
{
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
- u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
- u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height;
- u32 stride_y = inst->fmt_dst->fmt.pix_mp.width;
- u32 scanline_uv = scanline_y / 2;
- u32 stride_uv = stride_y;
+ u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv;
+ u32 port = iris_hfi_gen2_get_port(inst, plane);
u32 payload[2];
+ if (inst->domain == DECODER) {
+ pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
+ stride_y = inst->fmt_dst->fmt.pix_mp.width;
+ scanline_y = inst->fmt_dst->fmt.pix_mp.height;
+ } else {
+ pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
+ stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
+ scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
+ }
+
+ stride_uv = stride_y;
+ scanline_uv = scanline_y / 2;
+
if (pixelformat != V4L2_PIX_FMT_NV12)
return 0;
@@ -386,15 +473,15 @@ static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
HFI_PROP_LINEAR_STRIDE_SCANLINE,
HFI_HOST_FLAGS_NONE,
port,
- HFI_PAYLOAD_U64,
+ HFI_PAYLOAD_64_PACKED,
&payload,
sizeof(u64));
}
-static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
+static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane)
{
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
- u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
u32 tier = inst->fw_caps[TIER].value;
inst_hfi_gen2->src_subcr_params.tier = tier;
@@ -408,14 +495,29 @@ static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
sizeof(u32));
}
+static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane)
+{
+ u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ u32 frame_rate = inst->frame_rate << 16;
+
+ return iris_hfi_gen2_session_set_property(inst,
+ HFI_PROP_FRAME_RATE,
+ HFI_HOST_FLAGS_NONE,
+ port,
+ HFI_PAYLOAD_Q16,
+ &frame_rate,
+ sizeof(u32));
+}
+
static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
{
- struct iris_core *core = inst->core;
+ const struct iris_platform_data *pdata = inst->core->iris_platform_data;
u32 config_params_size = 0, i, j;
const u32 *config_params = NULL;
int ret;
static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
+ {HFI_PROP_RAW_RESOLUTION, iris_hfi_gen2_set_raw_resolution },
{HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },
{HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },
{HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames },
@@ -428,29 +530,35 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
{HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },
{HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },
{HFI_PROP_TIER, iris_hfi_gen2_set_tier },
+ {HFI_PROP_FRAME_RATE, iris_hfi_gen2_set_frame_rate },
};
- if (V4L2_TYPE_IS_OUTPUT(plane)) {
- switch (inst->codec) {
- case V4L2_PIX_FMT_H264:
- config_params = core->iris_platform_data->input_config_params_default;
- config_params_size =
- core->iris_platform_data->input_config_params_default_size;
- break;
- case V4L2_PIX_FMT_HEVC:
- config_params = core->iris_platform_data->input_config_params_hevc;
- config_params_size =
- core->iris_platform_data->input_config_params_hevc_size;
- break;
- case V4L2_PIX_FMT_VP9:
- config_params = core->iris_platform_data->input_config_params_vp9;
- config_params_size =
- core->iris_platform_data->input_config_params_vp9_size;
- break;
+ if (inst->domain == DECODER) {
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ config_params = pdata->dec_input_config_params_default;
+ config_params_size = pdata->dec_input_config_params_default_size;
+ } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ config_params = pdata->dec_input_config_params_hevc;
+ config_params_size = pdata->dec_input_config_params_hevc_size;
+ } else if (inst->codec == V4L2_PIX_FMT_VP9) {
+ config_params = pdata->dec_input_config_params_vp9;
+ config_params_size = pdata->dec_input_config_params_vp9_size;
+ } else {
+ return -EINVAL;
+ }
+ } else {
+ config_params = pdata->dec_output_config_params;
+ config_params_size = pdata->dec_output_config_params_size;
}
} else {
- config_params = core->iris_platform_data->output_config_params;
- config_params_size = core->iris_platform_data->output_config_params_size;
+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
+ config_params = pdata->enc_input_config_params;
+ config_params_size = pdata->enc_input_config_params_size;
+ } else {
+ config_params = pdata->enc_output_config_params;
+ config_params_size = pdata->enc_output_config_params_size;
+ }
}
if (!config_params || !config_params_size)
@@ -459,7 +567,7 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
for (i = 0; i < config_params_size; i++) {
for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
if (prop_type_handle_arr[j].type == config_params[i]) {
- ret = prop_type_handle_arr[j].handle(inst);
+ ret = prop_type_handle_arr[j].handle(inst, plane);
if (ret)
return ret;
break;
@@ -477,14 +585,19 @@ static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
switch (inst->codec) {
case V4L2_PIX_FMT_H264:
- codec = HFI_CODEC_DECODE_AVC;
+ if (inst->domain == ENCODER)
+ codec = HFI_CODEC_ENCODE_AVC;
+ else
+ codec = HFI_CODEC_DECODE_AVC;
break;
case V4L2_PIX_FMT_HEVC:
- codec = HFI_CODEC_DECODE_HEVC;
+ if (inst->domain == ENCODER)
+ codec = HFI_CODEC_ENCODE_HEVC;
+ else
+ codec = HFI_CODEC_DECODE_HEVC;
break;
case V4L2_PIX_FMT_VP9:
codec = HFI_CODEC_DECODE_VP9;
- break;
}
iris_hfi_gen2_packet_session_property(inst,
@@ -550,9 +663,11 @@ static int iris_hfi_gen2_session_open(struct iris_inst *inst)
if (ret)
goto fail_free_packet;
- ret = iris_hfi_gen2_session_set_default_header(inst);
- if (ret)
- goto fail_free_packet;
+ if (inst->domain == DECODER) {
+ ret = iris_hfi_gen2_session_set_default_header(inst);
+ if (ret)
+ goto fail_free_packet;
+ }
return 0;
@@ -601,7 +716,7 @@ static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
cmd,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
payload_type,
payload,
@@ -623,6 +738,9 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
u32 hfi_port = 0, i;
int ret;
+ if (inst->domain == ENCODER)
+ return 0;
+
if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
(V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
dev_err(core->dev, "invalid plane\n");
@@ -631,19 +749,19 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
switch (inst->codec) {
case V4L2_PIX_FMT_H264:
- change_param = core->iris_platform_data->input_config_params_default;
+ change_param = core->iris_platform_data->dec_input_config_params_default;
change_param_size =
- core->iris_platform_data->input_config_params_default_size;
+ core->iris_platform_data->dec_input_config_params_default_size;
break;
case V4L2_PIX_FMT_HEVC:
- change_param = core->iris_platform_data->input_config_params_hevc;
+ change_param = core->iris_platform_data->dec_input_config_params_hevc;
change_param_size =
- core->iris_platform_data->input_config_params_hevc_size;
+ core->iris_platform_data->dec_input_config_params_hevc_size;
break;
case V4L2_PIX_FMT_VP9:
- change_param = core->iris_platform_data->input_config_params_vp9;
+ change_param = core->iris_platform_data->dec_input_config_params_vp9;
change_param_size =
- core->iris_platform_data->input_config_params_vp9_size;
+ core->iris_platform_data->dec_input_config_params_vp9_size;
break;
}
@@ -664,7 +782,7 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan
if (V4L2_TYPE_IS_OUTPUT(plane)) {
inst_hfi_gen2->ipsc_properties_set = true;
} else {
- hfi_port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
memcpy(&inst_hfi_gen2->dst_subcr_params,
&inst_hfi_gen2->src_subcr_params,
sizeof(inst_hfi_gen2->src_subcr_params));
@@ -759,6 +877,9 @@ static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
payload[0] = HFI_MODE_PROPERTY;
+ if (inst->domain == ENCODER)
+ return 0;
+
if (V4L2_TYPE_IS_OUTPUT(plane)) {
subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
subcribe_prop = core->iris_platform_data->dec_input_prop;
@@ -810,7 +931,7 @@ static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
HFI_CMD_START,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -832,7 +953,7 @@ static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -854,7 +975,7 @@ static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
HFI_CMD_PAUSE,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -873,7 +994,7 @@ static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
HFI_CMD_RESUME,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_U32,
&payload,
@@ -892,7 +1013,7 @@ static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
HFI_CMD_RESUME,
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_U32,
&payload,
@@ -914,7 +1035,7 @@ static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
HFI_HOST_FLAGS_INTR_REQUIRED |
HFI_HOST_FLAGS_NON_DISCARDABLE),
- iris_hfi_gen2_get_port(plane),
+ iris_hfi_gen2_get_port(inst, plane),
inst->session_id,
HFI_PAYLOAD_NONE,
NULL,
@@ -924,13 +1045,19 @@ static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
inst_hfi_gen2->packet->size);
}
-static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)
+static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type)
{
switch (buffer_type) {
case BUF_INPUT:
- return HFI_BUFFER_BITSTREAM;
+ if (domain == DECODER)
+ return HFI_BUFFER_BITSTREAM;
+ else
+ return HFI_BUFFER_RAW;
case BUF_OUTPUT:
- return HFI_BUFFER_RAW;
+ if (domain == DECODER)
+ return HFI_BUFFER_RAW;
+ else
+ return HFI_BUFFER_BITSTREAM;
case BUF_BIN:
return HFI_BUFFER_BIN;
case BUF_COMV:
@@ -940,9 +1067,14 @@ static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)
case BUF_LINE:
return HFI_BUFFER_LINE;
case BUF_DPB:
+ case BUF_SCRATCH_2:
return HFI_BUFFER_DPB;
case BUF_PERSIST:
return HFI_BUFFER_PERSIST;
+ case BUF_ARP:
+ return HFI_BUFFER_ARP;
+ case BUF_VPSS:
+ return HFI_BUFFER_VPSS;
default:
return 0;
}
@@ -965,16 +1097,17 @@ static int iris_set_num_comv(struct iris_inst *inst)
&num_comv, sizeof(u32));
}
-static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct iris_hfi_buffer *buf)
+static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer,
+ struct iris_hfi_buffer *buf)
{
memset(buf, 0, sizeof(*buf));
- buf->type = iris_hfi_gen2_buf_type_from_driver(buffer->type);
+ buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type);
buf->index = buffer->index;
buf->base_address = buffer->device_addr;
buf->addr_offset = 0;
buf->buffer_size = buffer->buffer_size;
- if (buffer->type == BUF_INPUT)
+ if (domain == DECODER && buffer->type == BUF_INPUT)
buf->buffer_size = ALIGN(buffer->buffer_size, 256);
buf->data_offset = buffer->data_offset;
buf->data_size = buffer->data_size;
@@ -991,14 +1124,14 @@ static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iri
u32 port;
int ret;
- iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
+ iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
if (buffer->type == BUF_COMV) {
ret = iris_set_num_comv(inst);
if (ret)
return ret;
}
- port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
+ port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
iris_hfi_gen2_packet_session_command(inst,
HFI_CMD_BUFFER,
HFI_HOST_FLAGS_INTR_REQUIRED,
@@ -1018,9 +1151,9 @@ static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct i
struct iris_hfi_buffer hfi_buffer;
u32 port;
- iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
+ iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
- port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
+ port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
iris_hfi_gen2_packet_session_command(inst,
HFI_CMD_BUFFER,
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
index 5f13dc11bea5..aa1f795f5626 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h
@@ -49,18 +49,48 @@
#define HFI_PROP_TIER 0x03000109
#define HFI_PROP_STAGE 0x0300010a
#define HFI_PROP_PIPE 0x0300010b
+#define HFI_PROP_FRAME_RATE 0x0300010c
#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f
#define HFI_PROP_CODED_FRAMES 0x03000120
#define HFI_PROP_CABAC_SESSION 0x03000121
#define HFI_PROP_BUFFER_HOST_MAX_COUNT 0x03000123
#define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT 0x03000124
#define HFI_PROP_PIC_ORDER_CNT_TYPE 0x03000128
+
+enum hfi_rate_control {
+ HFI_RC_VBR_CFR = 0x00000000,
+ HFI_RC_CBR_CFR = 0x00000001,
+ HFI_RC_CQ = 0x00000002,
+ HFI_RC_OFF = 0x00000003,
+ HFI_RC_CBR_VFR = 0x00000004,
+ HFI_RC_LOSSLESS = 0x00000005,
+};
+
+#define HFI_PROP_RATE_CONTROL 0x0300012a
+#define HFI_PROP_QP_PACKED 0x0300012e
+#define HFI_PROP_MIN_QP_PACKED 0x0300012f
+#define HFI_PROP_MAX_QP_PACKED 0x03000130
+#define HFI_PROP_TOTAL_BITRATE 0x0300013b
+#define HFI_PROP_MAX_GOP_FRAMES 0x03000146
+#define HFI_PROP_MAX_B_FRAMES 0x03000147
#define HFI_PROP_QUALITY_MODE 0x03000148
+
+enum hfi_seq_header_mode {
+ HFI_SEQ_HEADER_SEPERATE_FRAME = 0x00000001,
+ HFI_SEQ_HEADER_JOINED_WITH_1ST_FRAME = 0x00000002,
+ HFI_SEQ_HEADER_PREFIX_WITH_SYNC_FRAME = 0x00000004,
+ HFI_SEQ_HEADER_METADATA = 0x00000008,
+};
+
+#define HFI_PROP_SEQ_HEADER_MODE 0x03000149
#define HFI_PROP_SIGNAL_COLOR_INFO 0x03000155
#define HFI_PROP_PICTURE_TYPE 0x03000162
#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168
#define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169
#define HFI_PROP_NO_OUTPUT 0x0300016a
+#define HFI_PROP_BUFFER_MARK 0x0300016c
+#define HFI_PROP_RAW_RESOLUTION 0x03000178
+#define HFI_PROP_TOTAL_PEAK_BITRATE 0x0300017C
#define HFI_PROP_COMV_BUFFER_COUNT 0x03000193
#define HFI_PROP_END 0x03FFFFFF
@@ -111,13 +141,13 @@ enum hfi_codec_type {
};
enum hfi_picture_type {
- HFI_PICTURE_IDR = 0x00000001,
- HFI_PICTURE_P = 0x00000002,
- HFI_PICTURE_B = 0x00000004,
- HFI_PICTURE_I = 0x00000008,
- HFI_PICTURE_CRA = 0x00000010,
- HFI_PICTURE_BLA = 0x00000020,
- HFI_PICTURE_NOSHOW = 0x00000040,
+ HFI_GEN2_PICTURE_IDR = 0x00000001,
+ HFI_GEN2_PICTURE_P = 0x00000002,
+ HFI_GEN2_PICTURE_B = 0x00000004,
+ HFI_GEN2_PICTURE_I = 0x00000008,
+ HFI_GEN2_PICTURE_CRA = 0x00000010,
+ HFI_GEN2_PICTURE_BLA = 0x00000020,
+ HFI_GEN2_PICTURE_NOSHOW = 0x00000040,
};
enum hfi_buffer_type {
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
index a8c30fc5c0d0..2f1f118eae4f 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
@@ -29,7 +29,8 @@ struct iris_hfi_gen2_packet_handle {
int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt);
};
-static u32 iris_hfi_gen2_buf_type_to_driver(enum hfi_buffer_type buf_type)
+static u32 iris_hfi_gen2_buf_type_to_driver(struct iris_inst *inst,
+ enum hfi_buffer_type buf_type)
{
switch (buf_type) {
case HFI_BUFFER_BITSTREAM:
@@ -47,7 +48,10 @@ static u32 iris_hfi_gen2_buf_type_to_driver(enum hfi_buffer_type buf_type)
case HFI_BUFFER_LINE:
return BUF_LINE;
case HFI_BUFFER_DPB:
- return BUF_DPB;
+ if (inst->domain == DECODER)
+ return BUF_DPB;
+ else
+ return BUF_SCRATCH_2;
case HFI_BUFFER_PERSIST:
return BUF_PERSIST;
default:
@@ -87,17 +91,18 @@ static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u32 buffer_type)
static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u32 hfi_flags)
{
- u32 keyframe = HFI_PICTURE_IDR | HFI_PICTURE_I | HFI_PICTURE_CRA | HFI_PICTURE_BLA;
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
+ u32 keyframe = HFI_GEN2_PICTURE_IDR | HFI_GEN2_PICTURE_I |
+ HFI_GEN2_PICTURE_CRA | HFI_GEN2_PICTURE_BLA;
u32 driver_flags = 0;
- if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_NOSHOW)
+ if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_NOSHOW)
driver_flags |= V4L2_BUF_FLAG_ERROR;
else if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe)
driver_flags |= V4L2_BUF_FLAG_KEYFRAME;
- else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P)
+ else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_P)
driver_flags |= V4L2_BUF_FLAG_PFRAME;
- else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_B)
+ else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_B)
driver_flags |= V4L2_BUF_FLAG_BFRAME;
if (inst_hfi_gen2->hfi_frame_info.data_corrupt || inst_hfi_gen2->hfi_frame_info.overflow)
@@ -420,11 +425,10 @@ static void iris_hfi_gen2_handle_dequeue_buffers(struct iris_inst *inst)
static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst,
struct iris_hfi_buffer *buffer)
{
- u32 buf_type = iris_hfi_gen2_buf_type_to_driver(buffer->type);
+ u32 buf_type = iris_hfi_gen2_buf_type_to_driver(inst, buffer->type);
struct iris_buffers *buffers = &inst->buffers[buf_type];
struct iris_buffer *buf, *iter;
bool found = false;
- int ret = 0;
list_for_each_entry(iter, &buffers->list, list) {
if (iter->device_addr == buffer->base_address) {
@@ -437,10 +441,8 @@ static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst,
return -EINVAL;
buf->attr &= ~BUF_ATTR_QUEUED;
- if (buf->attr & BUF_ATTR_PENDING_RELEASE)
- ret = iris_destroy_internal_buffer(inst, buf);
- return ret;
+ return iris_destroy_internal_buffer(inst, buf);
}
static int iris_hfi_gen2_handle_session_stop(struct iris_inst *inst,
@@ -478,12 +480,22 @@ static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst,
if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type))
return 0;
- if (buffer->type == HFI_BUFFER_BITSTREAM)
- return iris_hfi_gen2_handle_input_buffer(inst, buffer);
- else if (buffer->type == HFI_BUFFER_RAW)
- return iris_hfi_gen2_handle_output_buffer(inst, buffer);
- else
- return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
+ if (inst->domain == DECODER) {
+ if (buffer->type == HFI_BUFFER_BITSTREAM)
+ return iris_hfi_gen2_handle_input_buffer(inst, buffer);
+ else if (buffer->type == HFI_BUFFER_RAW)
+ return iris_hfi_gen2_handle_output_buffer(inst, buffer);
+ else
+ return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
+ } else {
+ if (buffer->type == HFI_BUFFER_RAW)
+ return iris_hfi_gen2_handle_input_buffer(inst, buffer);
+ else if (buffer->type == HFI_BUFFER_BITSTREAM)
+ return iris_hfi_gen2_handle_output_buffer(inst, buffer);
+ else
+ return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer);
+ }
+ return 0;
}
static int iris_hfi_gen2_handle_session_drain(struct iris_inst *inst,
diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h
index 0e1f5799b72d..5982d7adefea 100644
--- a/drivers/media/platform/qcom/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/iris/iris_instance.h
@@ -12,6 +12,20 @@
#include "iris_core.h"
#include "iris_utils.h"
+#define DEFAULT_WIDTH 320
+#define DEFAULT_HEIGHT 240
+
+enum iris_fmt_type {
+ IRIS_FMT_H264,
+ IRIS_FMT_HEVC,
+ IRIS_FMT_VP9,
+};
+
+struct iris_fmt {
+ u32 pixfmt;
+ u32 type;
+};
+
/**
* struct iris_inst - holds per video instance parameters
*
@@ -24,7 +38,9 @@
* @fmt_src: structure of v4l2_format for source
* @fmt_dst: structure of v4l2_format for destination
* @ctrl_handler: reference of v4l2 ctrl handler
+ * @domain: domain type: encoder or decoder
* @crop: structure of crop info
+ * @compose: structure of compose info
* @completion: structure of signal completions
* @flush_completion: structure of signal completions for flush cmd
* @flush_responses_pending: counter to track number of pending flush responses
@@ -45,6 +61,9 @@
* @metadata_idx: index for metadata buffer
* @codec: codec type
* @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver
+ * @frame_rate: frame rate of current instance
+ * @operating_rate: operating rate of current instance
+ * @hfi_rc_type: rate control type
*/
struct iris_inst {
@@ -57,7 +76,9 @@ struct iris_inst {
struct v4l2_format *fmt_src;
struct v4l2_format *fmt_dst;
struct v4l2_ctrl_handler ctrl_handler;
+ enum domain_type domain;
struct iris_hfi_rect_desc crop;
+ struct iris_hfi_rect_desc compose;
struct completion completion;
struct completion flush_completion;
u32 flush_responses_pending;
@@ -78,6 +99,9 @@ struct iris_inst {
u32 metadata_idx;
u32 codec;
bool last_buffer_dequeued;
+ u32 frame_rate;
+ u32 operating_rate;
+ u32 hfi_rc_type;
};
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index adafdce8a856..58d05e0a112e 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -7,6 +7,7 @@
#define __IRIS_PLATFORM_COMMON_H__
#include <linux/bits.h>
+#include "iris_buffer.h"
struct iris_core;
struct iris_inst;
@@ -21,7 +22,13 @@ struct iris_inst;
#define DEFAULT_MAX_HOST_BUF_COUNT 64
#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256
#define DEFAULT_FPS 30
-#define NUM_MBS_8K ((8192 * 4352) / 256)
+#define MAXIMUM_FPS 480
+#define NUM_MBS_8K ((8192 * 4352) / 256)
+#define MIN_QP_8BIT 1
+#define MAX_QP 51
+#define MAX_QP_HEVC 63
+#define DEFAULT_QP 20
+#define BITRATE_DEFAULT 20000000
enum stage_type {
STAGE_1 = 1,
@@ -38,11 +45,15 @@ extern struct iris_platform_data qcs8300_data;
extern struct iris_platform_data sm8250_data;
extern struct iris_platform_data sm8550_data;
extern struct iris_platform_data sm8650_data;
+extern struct iris_platform_data sm8750_data;
enum platform_clk_type {
- IRIS_AXI_CLK,
+ IRIS_AXI_CLK, /* AXI0 in case of platforms with multiple AXI clocks */
IRIS_CTRL_CLK,
IRIS_HW_CLK,
+ IRIS_AXI1_CLK,
+ IRIS_CTRL_FREERUN_CLK,
+ IRIS_HW_FREERUN_CLK,
};
struct platform_clk_data {
@@ -78,6 +89,8 @@ struct platform_inst_caps {
u32 mb_cycles_fw;
u32 mb_cycles_fw_vpp;
u32 num_comv;
+ u32 max_frame_rate;
+ u32 max_operating_rate;
};
enum platform_inst_fw_cap_type {
@@ -88,6 +101,7 @@ enum platform_inst_fw_cap_type {
LEVEL_HEVC,
LEVEL_VP9,
INPUT_BUF_HOST_MAX_COUNT,
+ OUTPUT_BUF_HOST_MAX_COUNT,
STAGE,
PIPE,
POC,
@@ -95,6 +109,37 @@ enum platform_inst_fw_cap_type {
BIT_DEPTH,
RAP_FRAME,
TIER,
+ HEADER_MODE,
+ PREPEND_SPSPPS_TO_IDR,
+ BITRATE,
+ BITRATE_PEAK,
+ BITRATE_MODE,
+ FRAME_SKIP_MODE,
+ FRAME_RC_ENABLE,
+ GOP_SIZE,
+ ENTROPY_MODE,
+ MIN_FRAME_QP_H264,
+ MIN_FRAME_QP_HEVC,
+ MAX_FRAME_QP_H264,
+ MAX_FRAME_QP_HEVC,
+ I_FRAME_MIN_QP_H264,
+ I_FRAME_MIN_QP_HEVC,
+ P_FRAME_MIN_QP_H264,
+ P_FRAME_MIN_QP_HEVC,
+ B_FRAME_MIN_QP_H264,
+ B_FRAME_MIN_QP_HEVC,
+ I_FRAME_MAX_QP_H264,
+ I_FRAME_MAX_QP_HEVC,
+ P_FRAME_MAX_QP_H264,
+ P_FRAME_MAX_QP_HEVC,
+ B_FRAME_MAX_QP_H264,
+ B_FRAME_MAX_QP_HEVC,
+ I_FRAME_QP_H264,
+ I_FRAME_QP_HEVC,
+ P_FRAME_QP_H264,
+ P_FRAME_QP_HEVC,
+ B_FRAME_QP_H264,
+ B_FRAME_QP_HEVC,
INST_FW_CAP_MAX,
};
@@ -149,6 +194,7 @@ struct iris_platform_data {
void (*init_hfi_command_ops)(struct iris_core *core);
void (*init_hfi_response_ops)(struct iris_core *core);
struct iris_inst *(*get_instance)(void);
+ u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type);
const struct vpu_ops *vpu_ops;
void (*set_preset_registers)(struct iris_core *core);
const struct icc_info *icc_tbl;
@@ -169,8 +215,10 @@ struct iris_platform_data {
const char *fwname;
u32 pas_id;
struct platform_inst_caps *inst_caps;
- struct platform_inst_fw_cap *inst_fw_caps;
- u32 inst_fw_caps_size;
+ struct platform_inst_fw_cap *inst_fw_caps_dec;
+ u32 inst_fw_caps_dec_size;
+ struct platform_inst_fw_cap *inst_fw_caps_enc;
+ u32 inst_fw_caps_enc_size;
struct tz_cp_config *tz_cp_config_data;
u32 core_arch;
u32 hw_response_timeout;
@@ -179,14 +227,20 @@ struct iris_platform_data {
u32 max_session_count;
/* max number of macroblocks per frame supported */
u32 max_core_mbpf;
- const u32 *input_config_params_default;
- unsigned int input_config_params_default_size;
- const u32 *input_config_params_hevc;
- unsigned int input_config_params_hevc_size;
- const u32 *input_config_params_vp9;
- unsigned int input_config_params_vp9_size;
- const u32 *output_config_params;
- unsigned int output_config_params_size;
+ /* max number of macroblocks per second supported */
+ u32 max_core_mbps;
+ const u32 *dec_input_config_params_default;
+ unsigned int dec_input_config_params_default_size;
+ const u32 *dec_input_config_params_hevc;
+ unsigned int dec_input_config_params_hevc_size;
+ const u32 *dec_input_config_params_vp9;
+ unsigned int dec_input_config_params_vp9_size;
+ const u32 *dec_output_config_params;
+ unsigned int dec_output_config_params_size;
+ const u32 *enc_input_config_params;
+ unsigned int enc_input_config_params_size;
+ const u32 *enc_output_config_params;
+ unsigned int enc_output_config_params_size;
const u32 *dec_input_prop;
unsigned int dec_input_prop_size;
const u32 *dec_output_prop_avc;
@@ -199,6 +253,10 @@ struct iris_platform_data {
unsigned int dec_ip_int_buf_tbl_size;
const u32 *dec_op_int_buf_tbl;
unsigned int dec_op_int_buf_tbl_size;
+ const u32 *enc_ip_int_buf_tbl;
+ unsigned int enc_ip_int_buf_tbl_size;
+ const u32 *enc_op_int_buf_tbl;
+ unsigned int enc_op_int_buf_tbl_size;
};
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
index d3026b2bcb70..36d69cc73986 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2025 Linaro Ltd
*/
#include "iris_core.h"
@@ -8,14 +9,17 @@
#include "iris_hfi_gen2.h"
#include "iris_hfi_gen2_defines.h"
#include "iris_platform_common.h"
+#include "iris_vpu_buffer.h"
#include "iris_vpu_common.h"
#include "iris_platform_qcs8300.h"
#include "iris_platform_sm8650.h"
+#include "iris_platform_sm8750.h"
#define VIDEO_ARCH_LX 1
+#define BITRATE_MAX 245000000
-static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = {
+static struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = {
{
.cap_id = PROFILE_H264,
.min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
@@ -199,6 +203,393 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = {
},
};
+static struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = {
+ {
+ .cap_id = PROFILE_H264,
+ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
+ .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_profile,
+ },
+ {
+ .cap_id = PROFILE_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
+ .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_profile,
+ },
+ {
+ .cap_id = LEVEL_H264,
+ .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_0,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0),
+ .value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_level,
+ },
+ {
+ .cap_id = LEVEL_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
+ .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_5,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_level,
+ },
+ {
+ .cap_id = STAGE,
+ .min = STAGE_1,
+ .max = STAGE_2,
+ .step_or_mask = 1,
+ .value = STAGE_2,
+ .hfi_id = HFI_PROP_STAGE,
+ .set = iris_set_stage,
+ },
+ {
+ .cap_id = HEADER_MODE,
+ .min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .max = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+ BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+ .value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .hfi_id = HFI_PROP_SEQ_HEADER_MODE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_header_mode_gen2,
+ },
+ {
+ .cap_id = PREPEND_SPSPPS_TO_IDR,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 0,
+ },
+ {
+ .cap_id = BITRATE,
+ .min = 1,
+ .max = BITRATE_MAX,
+ .step_or_mask = 1,
+ .value = BITRATE_DEFAULT,
+ .hfi_id = HFI_PROP_TOTAL_BITRATE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_bitrate,
+ },
+ {
+ .cap_id = BITRATE_PEAK,
+ .min = 1,
+ .max = BITRATE_MAX,
+ .step_or_mask = 1,
+ .value = BITRATE_DEFAULT,
+ .hfi_id = HFI_PROP_TOTAL_PEAK_BITRATE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_peak_bitrate,
+ },
+ {
+ .cap_id = BITRATE_MODE,
+ .min = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+ BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
+ .value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .hfi_id = HFI_PROP_RATE_CONTROL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_bitrate_mode_gen2,
+ },
+ {
+ .cap_id = FRAME_SKIP_MODE,
+ .min = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .max = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) |
+ BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT) |
+ BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT),
+ .value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = FRAME_RC_ENABLE,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 1,
+ },
+ {
+ .cap_id = GOP_SIZE,
+ .min = 0,
+ .max = INT_MAX,
+ .step_or_mask = 1,
+ .value = 2 * DEFAULT_FPS - 1,
+ .hfi_id = HFI_PROP_MAX_GOP_FRAMES,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_u32,
+ },
+ {
+ .cap_id = ENTROPY_MODE,
+ .min = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .max = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+ BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
+ .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .hfi_id = HFI_PROP_CABAC_SESSION,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_entropy_mode_gen2,
+ },
+ {
+ .cap_id = MIN_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ .hfi_id = HFI_PROP_MIN_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_min_qp,
+ },
+ {
+ .cap_id = MIN_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ .hfi_id = HFI_PROP_MIN_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_min_qp,
+ },
+ {
+ .cap_id = MAX_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ .hfi_id = HFI_PROP_MAX_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_max_qp,
+ },
+ {
+ .cap_id = MAX_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ .hfi_id = HFI_PROP_MAX_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_max_qp,
+ },
+ {
+ .cap_id = I_FRAME_MIN_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = I_FRAME_MIN_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = P_FRAME_MIN_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = P_FRAME_MIN_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = B_FRAME_MIN_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = B_FRAME_MIN_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = I_FRAME_MAX_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = I_FRAME_MAX_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = P_FRAME_MAX_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = P_FRAME_MAX_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = B_FRAME_MAX_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = B_FRAME_MAX_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = I_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_frame_qp,
+ },
+ {
+ .cap_id = I_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_frame_qp,
+ },
+ {
+ .cap_id = P_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_frame_qp,
+ },
+ {
+ .cap_id = P_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_frame_qp,
+ },
+ {
+ .cap_id = B_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_frame_qp,
+ },
+ {
+ .cap_id = B_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_frame_qp,
+ },
+ {
+ .cap_id = INPUT_BUF_HOST_MAX_COUNT,
+ .min = DEFAULT_MAX_HOST_BUF_COUNT,
+ .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+ .step_or_mask = 1,
+ .value = DEFAULT_MAX_HOST_BUF_COUNT,
+ .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
+ .flags = CAP_FLAG_INPUT_PORT,
+ .set = iris_set_u32,
+ },
+ {
+ .cap_id = OUTPUT_BUF_HOST_MAX_COUNT,
+ .min = DEFAULT_MAX_HOST_BUF_COUNT,
+ .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+ .step_or_mask = 1,
+ .value = DEFAULT_MAX_HOST_BUF_COUNT,
+ .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_u32,
+ },
+};
+
static struct platform_inst_caps platform_inst_cap_sm8550 = {
.min_frame_width = 96,
.max_frame_width = 8192,
@@ -209,6 +600,8 @@ static struct platform_inst_caps platform_inst_cap_sm8550 = {
.mb_cycles_fw = 489583,
.mb_cycles_fw_vpp = 66234,
.num_comv = 0,
+ .max_frame_rate = MAXIMUM_FPS,
+ .max_operating_rate = MAXIMUM_FPS,
};
static void iris_set_sm8550_preset_registers(struct iris_core *core)
@@ -289,11 +682,25 @@ static const u32 sm8550_vdec_input_config_param_vp9[] = {
HFI_PROP_LEVEL,
};
+static const u32 sm8550_venc_input_config_params[] = {
+ HFI_PROP_COLOR_FORMAT,
+ HFI_PROP_RAW_RESOLUTION,
+ HFI_PROP_CROP_OFFSETS,
+ HFI_PROP_LINEAR_STRIDE_SCANLINE,
+ HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
static const u32 sm8550_vdec_output_config_params[] = {
HFI_PROP_COLOR_FORMAT,
HFI_PROP_LINEAR_STRIDE_SCANLINE,
};
+static const u32 sm8550_venc_output_config_params[] = {
+ HFI_PROP_BITSTREAM_RESOLUTION,
+ HFI_PROP_CROP_OFFSETS,
+ HFI_PROP_FRAME_RATE,
+};
+
static const u32 sm8550_vdec_subscribe_input_properties[] = {
HFI_PROP_NO_OUTPUT,
};
@@ -322,10 +729,19 @@ static const u32 sm8550_dec_op_int_buf_tbl[] = {
BUF_DPB,
};
+static const u32 sm8550_enc_op_int_buf_tbl[] = {
+ BUF_BIN,
+ BUF_COMV,
+ BUF_NON_COMV,
+ BUF_LINE,
+ BUF_SCRATCH_2,
+};
+
struct iris_platform_data sm8550_data = {
.get_instance = iris_hfi_gen2_get_instance,
.init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
.init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+ .get_vpu_buffer_size = iris_vpu_buf_size,
.vpu_ops = &iris_vpu3_ops,
.set_preset_registers = iris_set_sm8550_preset_registers,
.icc_tbl = sm8550_icc_table,
@@ -345,8 +761,10 @@ struct iris_platform_data sm8550_data = {
.fwname = "qcom/vpu/vpu30_p4.mbn",
.pas_id = IRIS_PAS_ID,
.inst_caps = &platform_inst_cap_sm8550,
- .inst_fw_caps = inst_fw_cap_sm8550,
- .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8550),
+ .inst_fw_caps_dec = inst_fw_cap_sm8550_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec),
+ .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
.tz_cp_config_data = &tz_cp_config_sm8550,
.core_arch = VIDEO_ARCH_LX,
.hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
@@ -354,22 +772,33 @@ struct iris_platform_data sm8550_data = {
.num_vpp_pipe = 4,
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K * 2,
- .input_config_params_default =
+ .max_core_mbps = ((7680 * 4320) / 256) * 60,
+ .dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
- .input_config_params_default_size =
+ .dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
- .input_config_params_hevc =
+ .dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
- .input_config_params_hevc_size =
+ .dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
- .input_config_params_vp9 =
+ .dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
- .input_config_params_vp9_size =
+ .dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
- .output_config_params =
+ .dec_output_config_params =
sm8550_vdec_output_config_params,
- .output_config_params_size =
+ .dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
+
+ .enc_input_config_params =
+ sm8550_venc_input_config_params,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8550_venc_input_config_params),
+ .enc_output_config_params =
+ sm8550_venc_output_config_params,
+ .enc_output_config_params_size =
+ ARRAY_SIZE(sm8550_venc_output_config_params),
+
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
@@ -386,6 +815,9 @@ struct iris_platform_data sm8550_data = {
.dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
.dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
.dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
+
+ .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
+ .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
};
/*
@@ -399,6 +831,7 @@ struct iris_platform_data sm8650_data = {
.get_instance = iris_hfi_gen2_get_instance,
.init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
.init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+ .get_vpu_buffer_size = iris_vpu33_buf_size,
.vpu_ops = &iris_vpu33_ops,
.set_preset_registers = iris_set_sm8550_preset_registers,
.icc_tbl = sm8550_icc_table,
@@ -420,8 +853,10 @@ struct iris_platform_data sm8650_data = {
.fwname = "qcom/vpu/vpu33_p4.mbn",
.pas_id = IRIS_PAS_ID,
.inst_caps = &platform_inst_cap_sm8550,
- .inst_fw_caps = inst_fw_cap_sm8550,
- .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8550),
+ .inst_fw_caps_dec = inst_fw_cap_sm8550_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec),
+ .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
.tz_cp_config_data = &tz_cp_config_sm8550,
.core_arch = VIDEO_ARCH_LX,
.hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
@@ -429,22 +864,33 @@ struct iris_platform_data sm8650_data = {
.num_vpp_pipe = 4,
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K * 2,
- .input_config_params_default =
+ .max_core_mbps = ((7680 * 4320) / 256) * 60,
+ .dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
- .input_config_params_default_size =
+ .dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
- .input_config_params_hevc =
+ .dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
- .input_config_params_hevc_size =
+ .dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
- .input_config_params_vp9 =
+ .dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
- .input_config_params_vp9_size =
+ .dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
- .output_config_params =
+ .dec_output_config_params =
sm8550_vdec_output_config_params,
- .output_config_params_size =
+ .dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
+
+ .enc_input_config_params =
+ sm8550_venc_input_config_params,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8550_venc_input_config_params),
+ .enc_output_config_params =
+ sm8550_venc_output_config_params,
+ .enc_output_config_params_size =
+ ARRAY_SIZE(sm8550_venc_output_config_params),
+
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
@@ -461,6 +907,90 @@ struct iris_platform_data sm8650_data = {
.dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
.dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
.dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
+
+ .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
+ .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
+};
+
+struct iris_platform_data sm8750_data = {
+ .get_instance = iris_hfi_gen2_get_instance,
+ .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
+ .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+ .vpu_ops = &iris_vpu35_ops,
+ .set_preset_registers = iris_set_sm8550_preset_registers,
+ .icc_tbl = sm8550_icc_table,
+ .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table),
+ .clk_rst_tbl = sm8750_clk_reset_table,
+ .clk_rst_tbl_size = ARRAY_SIZE(sm8750_clk_reset_table),
+ .bw_tbl_dec = sm8550_bw_table_dec,
+ .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec),
+ .pmdomain_tbl = sm8550_pmdomain_table,
+ .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table),
+ .opp_pd_tbl = sm8550_opp_pd_table,
+ .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table),
+ .clk_tbl = sm8750_clk_table,
+ .clk_tbl_size = ARRAY_SIZE(sm8750_clk_table),
+ /* Upper bound of DMA address range */
+ .dma_mask = 0xe0000000 - 1,
+ .fwname = "qcom/vpu/vpu35_p4.mbn",
+ .pas_id = IRIS_PAS_ID,
+ .inst_caps = &platform_inst_cap_sm8550,
+ .inst_fw_caps_dec = inst_fw_cap_sm8550_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec),
+ .inst_fw_caps_enc = inst_fw_cap_sm8550_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc),
+ .tz_cp_config_data = &tz_cp_config_sm8550,
+ .core_arch = VIDEO_ARCH_LX,
+ .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
+ .ubwc_config = &ubwc_config_sm8550,
+ .num_vpp_pipe = 4,
+ .max_session_count = 16,
+ .max_core_mbpf = NUM_MBS_8K * 2,
+ .dec_input_config_params_default =
+ sm8550_vdec_input_config_params_default,
+ .dec_input_config_params_default_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_params_default),
+ .dec_input_config_params_hevc =
+ sm8550_vdec_input_config_param_hevc,
+ .dec_input_config_params_hevc_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
+ .dec_input_config_params_vp9 =
+ sm8550_vdec_input_config_param_vp9,
+ .dec_input_config_params_vp9_size =
+ ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
+ .dec_output_config_params =
+ sm8550_vdec_output_config_params,
+ .dec_output_config_params_size =
+ ARRAY_SIZE(sm8550_vdec_output_config_params),
+
+ .enc_input_config_params =
+ sm8550_venc_input_config_params,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8550_venc_input_config_params),
+ .enc_output_config_params =
+ sm8550_venc_output_config_params,
+ .enc_output_config_params_size =
+ ARRAY_SIZE(sm8550_venc_output_config_params),
+
+ .dec_input_prop = sm8550_vdec_subscribe_input_properties,
+ .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
+ .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
+ .dec_output_prop_avc_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
+ .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
+ .dec_output_prop_hevc_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
+ .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
+ .dec_output_prop_vp9_size =
+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
+
+ .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
+ .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
+
+ .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
+ .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
};
/*
@@ -472,6 +1002,7 @@ struct iris_platform_data qcs8300_data = {
.get_instance = iris_hfi_gen2_get_instance,
.init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
.init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+ .get_vpu_buffer_size = iris_vpu_buf_size,
.vpu_ops = &iris_vpu3_ops,
.set_preset_registers = iris_set_sm8550_preset_registers,
.icc_tbl = sm8550_icc_table,
@@ -491,8 +1022,10 @@ struct iris_platform_data qcs8300_data = {
.fwname = "qcom/vpu/vpu30_p4_s6.mbn",
.pas_id = IRIS_PAS_ID,
.inst_caps = &platform_inst_cap_qcs8300,
- .inst_fw_caps = inst_fw_cap_qcs8300,
- .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_qcs8300),
+ .inst_fw_caps_dec = inst_fw_cap_qcs8300_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_qcs8300_dec),
+ .inst_fw_caps_enc = inst_fw_cap_qcs8300_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_qcs8300_enc),
.tz_cp_config_data = &tz_cp_config_sm8550,
.core_arch = VIDEO_ARCH_LX,
.hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
@@ -500,22 +1033,33 @@ struct iris_platform_data qcs8300_data = {
.num_vpp_pipe = 2,
.max_session_count = 16,
.max_core_mbpf = ((4096 * 2176) / 256) * 4,
- .input_config_params_default =
+ .max_core_mbps = (((3840 * 2176) / 256) * 120),
+ .dec_input_config_params_default =
sm8550_vdec_input_config_params_default,
- .input_config_params_default_size =
+ .dec_input_config_params_default_size =
ARRAY_SIZE(sm8550_vdec_input_config_params_default),
- .input_config_params_hevc =
+ .dec_input_config_params_hevc =
sm8550_vdec_input_config_param_hevc,
- .input_config_params_hevc_size =
+ .dec_input_config_params_hevc_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
- .input_config_params_vp9 =
+ .dec_input_config_params_vp9 =
sm8550_vdec_input_config_param_vp9,
- .input_config_params_vp9_size =
+ .dec_input_config_params_vp9_size =
ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
- .output_config_params =
+ .dec_output_config_params =
sm8550_vdec_output_config_params,
- .output_config_params_size =
+ .dec_output_config_params_size =
ARRAY_SIZE(sm8550_vdec_output_config_params),
+
+ .enc_input_config_params =
+ sm8550_venc_input_config_params,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8550_venc_input_config_params),
+ .enc_output_config_params =
+ sm8550_venc_output_config_params,
+ .enc_output_config_params_size =
+ ARRAY_SIZE(sm8550_venc_output_config_params),
+
.dec_input_prop = sm8550_vdec_subscribe_input_properties,
.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
.dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
@@ -532,4 +1076,7 @@ struct iris_platform_data qcs8300_data = {
.dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
.dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl,
.dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl),
+
+ .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl,
+ .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl),
};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h b/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h
index a8d66ed388a3..35ea0efade73 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h
@@ -3,7 +3,9 @@
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
-static struct platform_inst_fw_cap inst_fw_cap_qcs8300[] = {
+#define BITRATE_MAX 245000000
+
+static struct platform_inst_fw_cap inst_fw_cap_qcs8300_dec[] = {
{
.cap_id = PROFILE_H264,
.min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
@@ -187,6 +189,352 @@ static struct platform_inst_fw_cap inst_fw_cap_qcs8300[] = {
},
};
+static struct platform_inst_fw_cap inst_fw_cap_qcs8300_enc[] = {
+ {
+ .cap_id = PROFILE_H264,
+ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
+ .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = PROFILE_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
+ .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = LEVEL_H264,
+ .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_0,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0),
+ .value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = LEVEL_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
+ .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_5,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = STAGE,
+ .min = STAGE_1,
+ .max = STAGE_2,
+ .step_or_mask = 1,
+ .value = STAGE_2,
+ .hfi_id = HFI_PROP_STAGE,
+ },
+ {
+ .cap_id = HEADER_MODE,
+ .min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .max = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+ BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+ .value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .hfi_id = HFI_PROP_SEQ_HEADER_MODE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = PREPEND_SPSPPS_TO_IDR,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 0,
+ },
+ {
+ .cap_id = BITRATE,
+ .min = 1,
+ .max = BITRATE_MAX,
+ .step_or_mask = 1,
+ .value = BITRATE_DEFAULT,
+ .hfi_id = HFI_PROP_TOTAL_BITRATE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = BITRATE_PEAK,
+ .min = 1,
+ .max = BITRATE_MAX,
+ .step_or_mask = 1,
+ .value = BITRATE_DEFAULT,
+ .hfi_id = HFI_PROP_TOTAL_PEAK_BITRATE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = BITRATE_MODE,
+ .min = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+ BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
+ .value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .hfi_id = HFI_PROP_RATE_CONTROL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = FRAME_SKIP_MODE,
+ .min = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .max = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) |
+ BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT) |
+ BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT),
+ .value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = FRAME_RC_ENABLE,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 1,
+ },
+ {
+ .cap_id = GOP_SIZE,
+ .min = 0,
+ .max = INT_MAX,
+ .step_or_mask = 1,
+ .value = 2 * DEFAULT_FPS - 1,
+ .hfi_id = HFI_PROP_MAX_GOP_FRAMES,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = ENTROPY_MODE,
+ .min = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .max = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+ BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
+ .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .hfi_id = HFI_PROP_CABAC_SESSION,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = MIN_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ .hfi_id = HFI_PROP_MIN_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = MIN_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ .hfi_id = HFI_PROP_MIN_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = MAX_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ .hfi_id = HFI_PROP_MAX_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = MAX_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ .hfi_id = HFI_PROP_MAX_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ },
+ {
+ .cap_id = I_FRAME_MIN_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = I_FRAME_MIN_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = P_FRAME_MIN_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = P_FRAME_MIN_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = B_FRAME_MIN_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = B_FRAME_MIN_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ },
+ {
+ .cap_id = I_FRAME_MAX_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = I_FRAME_MAX_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = P_FRAME_MAX_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = P_FRAME_MAX_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = B_FRAME_MAX_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = B_FRAME_MAX_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ },
+ {
+ .cap_id = I_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = I_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = P_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = P_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = B_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+ {
+ .cap_id = B_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = DEFAULT_QP,
+ .hfi_id = HFI_PROP_QP_PACKED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ },
+};
+
static struct platform_inst_caps platform_inst_cap_qcs8300 = {
.min_frame_width = 96,
.max_frame_width = 4096,
@@ -197,4 +545,6 @@ static struct platform_inst_caps platform_inst_cap_qcs8300 = {
.mb_cycles_fw = 326389,
.mb_cycles_fw_vpp = 44156,
.num_comv = 0,
+ .max_frame_rate = MAXIMUM_FPS,
+ .max_operating_rate = MAXIMUM_FPS,
};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
index 8d0816a67ae0..16486284f8ac 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c
@@ -9,9 +9,15 @@
#include "iris_resources.h"
#include "iris_hfi_gen1.h"
#include "iris_hfi_gen1_defines.h"
+#include "iris_vpu_buffer.h"
#include "iris_vpu_common.h"
-static struct platform_inst_fw_cap inst_fw_cap_sm8250[] = {
+#define BITRATE_MIN 32000
+#define BITRATE_MAX 160000000
+#define BITRATE_PEAK_DEFAULT (BITRATE_DEFAULT * 2)
+#define BITRATE_STEP 100
+
+static struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = {
{
.cap_id = PIPE,
.min = PIPE_1,
@@ -32,6 +38,200 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8250[] = {
},
};
+static struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = {
+ {
+ .cap_id = STAGE,
+ .min = STAGE_1,
+ .max = STAGE_2,
+ .step_or_mask = 1,
+ .value = STAGE_2,
+ .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
+ .set = iris_set_stage,
+ },
+ {
+ .cap_id = PROFILE_H264,
+ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .max = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH),
+ .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+ .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_profile_level_gen1,
+ },
+ {
+ .cap_id = PROFILE_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
+ .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+ .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_profile_level_gen1,
+ },
+ {
+ .cap_id = LEVEL_H264,
+ .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .max = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1),
+ .value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_profile_level_gen1,
+ },
+ {
+ .cap_id = LEVEL_HEVC,
+ .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
+ .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+ .hfi_id = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_profile_level_gen1,
+ },
+ {
+ .cap_id = HEADER_MODE,
+ .min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+ .max = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+ BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+ .value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+ .hfi_id = HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_header_mode_gen1,
+ },
+ {
+ .cap_id = BITRATE,
+ .min = BITRATE_MIN,
+ .max = BITRATE_MAX,
+ .step_or_mask = BITRATE_STEP,
+ .value = BITRATE_DEFAULT,
+ .hfi_id = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+ CAP_FLAG_DYNAMIC_ALLOWED,
+ .set = iris_set_bitrate,
+ },
+ {
+ .cap_id = BITRATE_MODE,
+ .min = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+ BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
+ .value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_bitrate_mode_gen1,
+ },
+ {
+ .cap_id = FRAME_SKIP_MODE,
+ .min = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .max = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) |
+ BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT),
+ .value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ },
+ {
+ .cap_id = FRAME_RC_ENABLE,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 1,
+ },
+ {
+ .cap_id = GOP_SIZE,
+ .min = 0,
+ .max = (1 << 16) - 1,
+ .step_or_mask = 1,
+ .value = 30,
+ .set = iris_set_u32
+ },
+ {
+ .cap_id = ENTROPY_MODE,
+ .min = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .max = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+ BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
+ .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_entropy_mode_gen1,
+ },
+ {
+ .cap_id = MIN_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_qp_range,
+ },
+ {
+ .cap_id = MIN_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP_HEVC,
+ .step_or_mask = 1,
+ .value = MIN_QP_8BIT,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_qp_range,
+ },
+ {
+ .cap_id = MAX_FRAME_QP_H264,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP,
+ .step_or_mask = 1,
+ .value = MAX_QP,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_qp_range,
+ },
+ {
+ .cap_id = MAX_FRAME_QP_HEVC,
+ .min = MIN_QP_8BIT,
+ .max = MAX_QP_HEVC,
+ .step_or_mask = 1,
+ .value = MAX_QP_HEVC,
+ .hfi_id = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2,
+ .flags = CAP_FLAG_OUTPUT_PORT,
+ .set = iris_set_qp_range,
+ },
+};
+
static struct platform_inst_caps platform_inst_cap_sm8250 = {
.min_frame_width = 128,
.max_frame_width = 8192,
@@ -40,6 +240,8 @@ static struct platform_inst_caps platform_inst_cap_sm8250 = {
.max_mbpf = 138240,
.mb_cycles_vsp = 25,
.mb_cycles_vpp = 200,
+ .max_frame_rate = MAXIMUM_FPS,
+ .max_operating_rate = MAXIMUM_FPS,
};
static void iris_set_sm8250_preset_registers(struct iris_core *core)
@@ -89,6 +291,14 @@ static const u32 sm8250_vdec_input_config_param_default[] = {
HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE,
};
+static const u32 sm8250_venc_input_config_param[] = {
+ HFI_PROPERTY_CONFIG_FRAME_RATE,
+ HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO,
+ HFI_PROPERTY_PARAM_FRAME_SIZE,
+ HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
+ HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
+};
+
static const u32 sm8250_dec_ip_int_buf_tbl[] = {
BUF_BIN,
BUF_SCRATCH_1,
@@ -98,10 +308,17 @@ static const u32 sm8250_dec_op_int_buf_tbl[] = {
BUF_DPB,
};
+static const u32 sm8250_enc_ip_int_buf_tbl[] = {
+ BUF_BIN,
+ BUF_SCRATCH_1,
+ BUF_SCRATCH_2,
+};
+
struct iris_platform_data sm8250_data = {
.get_instance = iris_hfi_gen1_get_instance,
.init_hfi_command_ops = &iris_hfi_gen1_command_ops_init,
.init_hfi_response_ops = iris_hfi_gen1_response_ops_init,
+ .get_vpu_buffer_size = iris_vpu_buf_size,
.vpu_ops = &iris_vpu2_ops,
.set_preset_registers = iris_set_sm8250_preset_registers,
.icc_tbl = sm8250_icc_table,
@@ -121,20 +338,29 @@ struct iris_platform_data sm8250_data = {
.fwname = "qcom/vpu-1.0/venus.mbn",
.pas_id = IRIS_PAS_ID,
.inst_caps = &platform_inst_cap_sm8250,
- .inst_fw_caps = inst_fw_cap_sm8250,
- .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8250),
+ .inst_fw_caps_dec = inst_fw_cap_sm8250_dec,
+ .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec),
+ .inst_fw_caps_enc = inst_fw_cap_sm8250_enc,
+ .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc),
.tz_cp_config_data = &tz_cp_config_sm8250,
.hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
.num_vpp_pipe = 4,
.max_session_count = 16,
.max_core_mbpf = NUM_MBS_8K,
- .input_config_params_default =
+ .max_core_mbps = ((7680 * 4320) / 256) * 60,
+ .dec_input_config_params_default =
sm8250_vdec_input_config_param_default,
- .input_config_params_default_size =
+ .dec_input_config_params_default_size =
ARRAY_SIZE(sm8250_vdec_input_config_param_default),
+ .enc_input_config_params = sm8250_venc_input_config_param,
+ .enc_input_config_params_size =
+ ARRAY_SIZE(sm8250_venc_input_config_param),
.dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl,
.dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl),
.dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl,
.dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl),
+
+ .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl,
+ .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl),
};
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8750.h b/drivers/media/platform/qcom/iris/iris_platform_sm8750.h
new file mode 100644
index 000000000000..719056656a5b
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8750.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2025 Linaro Ltd
+ */
+
+#ifndef __MEDIA_IRIS_PLATFORM_SM8750_H__
+#define __MEDIA_IRIS_PLATFORM_SM8750_H__
+
+static const char * const sm8750_clk_reset_table[] = {
+ "bus0", "bus1", "core", "vcodec0_core"
+};
+
+static const struct platform_clk_data sm8750_clk_table[] = {
+ {IRIS_AXI_CLK, "iface" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_HW_CLK, "vcodec0_core" },
+ {IRIS_AXI1_CLK, "iface1" },
+ {IRIS_CTRL_FREERUN_CLK, "core_freerun" },
+ {IRIS_HW_FREERUN_CLK, "vcodec0_core_freerun" },
+};
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
index 4e6e92357968..00e99be16e08 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -146,7 +146,7 @@ static int iris_init_resources(struct iris_core *core)
return iris_init_resets(core);
}
-static int iris_register_video_device(struct iris_core *core)
+static int iris_register_video_device(struct iris_core *core, enum domain_type type)
{
struct video_device *vdev;
int ret;
@@ -155,19 +155,29 @@ static int iris_register_video_device(struct iris_core *core)
if (!vdev)
return -ENOMEM;
- strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name));
vdev->release = video_device_release;
vdev->fops = core->iris_v4l2_file_ops;
- vdev->ioctl_ops = core->iris_v4l2_ioctl_ops;
vdev->vfl_dir = VFL_DIR_M2M;
vdev->v4l2_dev = &core->v4l2_dev;
vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+ if (type == DECODER) {
+ strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name));
+ vdev->ioctl_ops = core->iris_v4l2_ioctl_ops_dec;
+ core->vdev_dec = vdev;
+ } else if (type == ENCODER) {
+ strscpy(vdev->name, "qcom-iris-encoder", sizeof(vdev->name));
+ vdev->ioctl_ops = core->iris_v4l2_ioctl_ops_enc;
+ core->vdev_enc = vdev;
+ } else {
+ ret = -EINVAL;
+ goto err_vdev_release;
+ }
+
ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
if (ret)
goto err_vdev_release;
- core->vdev_dec = vdev;
video_set_drvdata(vdev, core);
return 0;
@@ -189,6 +199,7 @@ static void iris_remove(struct platform_device *pdev)
iris_core_deinit(core);
video_unregister_device(core->vdev_dec);
+ video_unregister_device(core->vdev_enc);
v4l2_device_unregister(&core->v4l2_dev);
@@ -258,17 +269,21 @@ static int iris_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = iris_register_video_device(core);
+ ret = iris_register_video_device(core, DECODER);
if (ret)
goto err_v4l2_unreg;
+ ret = iris_register_video_device(core, ENCODER);
+ if (ret)
+ goto err_vdev_unreg_dec;
+
platform_set_drvdata(pdev, core);
dma_mask = core->iris_platform_data->dma_mask;
ret = dma_set_mask_and_coherent(dev, dma_mask);
if (ret)
- goto err_vdev_unreg;
+ goto err_vdev_unreg_enc;
dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32));
@@ -277,11 +292,13 @@ static int iris_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(core->dev);
ret = devm_pm_runtime_enable(core->dev);
if (ret)
- goto err_vdev_unreg;
+ goto err_vdev_unreg_enc;
return 0;
-err_vdev_unreg:
+err_vdev_unreg_enc:
+ video_unregister_device(core->vdev_enc);
+err_vdev_unreg_dec:
video_unregister_device(core->vdev_dec);
err_v4l2_unreg:
v4l2_device_unregister(&core->v4l2_dev);
@@ -353,6 +370,10 @@ static const struct of_device_id iris_dt_match[] = {
.compatible = "qcom,sm8650-iris",
.data = &sm8650_data,
},
+ {
+ .compatible = "qcom,sm8750-iris",
+ .data = &sm8750_data,
+ },
{ },
};
MODULE_DEVICE_TABLE(of, iris_dt_match);
diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/platform/qcom/iris/iris_state.c
index 104e1687ad39..d14472414750 100644
--- a/drivers/media/platform/qcom/iris/iris_state.c
+++ b/drivers/media/platform/qcom/iris/iris_state.c
@@ -122,7 +122,8 @@ static bool iris_inst_allow_sub_state(struct iris_inst *inst, enum iris_inst_sub
return false;
case IRIS_INST_OUTPUT_STREAMING:
if (sub_state & (IRIS_INST_SUB_DRC_LAST |
- IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE))
+ IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE |
+ IRIS_INST_SUB_LOAD_RESOURCES))
return true;
return false;
case IRIS_INST_STREAMING:
@@ -251,7 +252,7 @@ bool iris_drc_pending(struct iris_inst *inst)
inst->sub_state & IRIS_INST_SUB_DRC_LAST;
}
-static inline bool iris_drain_pending(struct iris_inst *inst)
+bool iris_drain_pending(struct iris_inst *inst)
{
return inst->sub_state & IRIS_INST_SUB_DRAIN &&
inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
@@ -262,11 +263,11 @@ bool iris_allow_cmd(struct iris_inst *inst, u32 cmd)
struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
- if (cmd == V4L2_DEC_CMD_START) {
+ if (cmd == V4L2_DEC_CMD_START || cmd == V4L2_ENC_CMD_START) {
if (vb2_is_streaming(src_q) || vb2_is_streaming(dst_q))
if (iris_drc_pending(inst) || iris_drain_pending(inst))
return true;
- } else if (cmd == V4L2_DEC_CMD_STOP) {
+ } else if (cmd == V4L2_DEC_CMD_STOP || cmd == V4L2_ENC_CMD_STOP) {
if (vb2_is_streaming(src_q))
if (inst->sub_state != IRIS_INST_SUB_DRAIN)
return true;
diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h
index e718386dbe04..b09fa54cf17e 100644
--- a/drivers/media/platform/qcom/iris/iris_state.h
+++ b/drivers/media/platform/qcom/iris/iris_state.h
@@ -141,5 +141,6 @@ int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);
int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane);
bool iris_allow_cmd(struct iris_inst *inst, u32 cmd);
bool iris_drc_pending(struct iris_inst *inst);
+bool iris_drain_pending(struct iris_inst *inst);
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c
index 83c70d6a2d90..85c70a62b1fd 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.c
+++ b/drivers/media/platform/qcom/iris/iris_utils.c
@@ -88,3 +88,39 @@ struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id)
mutex_unlock(&core->lock);
return NULL;
}
+
+int iris_check_core_mbpf(struct iris_inst *inst)
+{
+ struct iris_core *core = inst->core;
+ struct iris_inst *instance;
+ u32 total_mbpf = 0;
+
+ mutex_lock(&core->lock);
+ list_for_each_entry(instance, &core->instances, list)
+ total_mbpf += iris_get_mbpf(instance);
+ mutex_unlock(&core->lock);
+
+ if (total_mbpf > core->iris_platform_data->max_core_mbpf)
+ return -ENOMEM;
+
+ return 0;
+}
+
+int iris_check_core_mbps(struct iris_inst *inst)
+{
+ struct iris_core *core = inst->core;
+ struct iris_inst *instance;
+ u32 total_mbps = 0, fps = 0;
+
+ mutex_lock(&core->lock);
+ list_for_each_entry(instance, &core->instances, list) {
+ fps = max(instance->frame_rate, instance->operating_rate);
+ total_mbps += iris_get_mbpf(instance) * fps;
+ }
+ mutex_unlock(&core->lock);
+
+ if (total_mbps > core->iris_platform_data->max_core_mbps)
+ return -ENOMEM;
+
+ return 0;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/platform/qcom/iris/iris_utils.h
index 49869cf7a376..75740181122f 100644
--- a/drivers/media/platform/qcom/iris/iris_utils.h
+++ b/drivers/media/platform/qcom/iris/iris_utils.h
@@ -49,5 +49,7 @@ struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id);
void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
enum vb2_buffer_state state);
int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush);
+int iris_check_core_mbpf(struct iris_inst *inst);
+int iris_check_core_mbps(struct iris_inst *inst);
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c
index 8b17c7c39487..139b821f7952 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -7,28 +7,13 @@
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
+#include "iris_common.h"
#include "iris_instance.h"
#include "iris_vb2.h"
#include "iris_vdec.h"
+#include "iris_venc.h"
#include "iris_power.h"
-static int iris_check_core_mbpf(struct iris_inst *inst)
-{
- struct iris_core *core = inst->core;
- struct iris_inst *instance;
- u32 total_mbpf = 0;
-
- mutex_lock(&core->lock);
- list_for_each_entry(instance, &core->instances, list)
- total_mbpf += iris_get_mbpf(instance);
- mutex_unlock(&core->lock);
-
- if (total_mbpf > core->iris_platform_data->max_core_mbpf)
- return -ENOMEM;
-
- return 0;
-}
-
static int iris_check_inst_mbpf(struct iris_inst *inst)
{
struct platform_inst_caps *caps;
@@ -173,9 +158,6 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
inst = vb2_get_drv_priv(q);
- if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state == IRIS_INST_INIT)
- return 0;
-
mutex_lock(&inst->lock);
if (inst->state == IRIS_INST_ERROR) {
ret = -EBUSY;
@@ -194,16 +176,35 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
if (ret)
goto error;
- if (V4L2_TYPE_IS_OUTPUT(q->type))
- ret = iris_vdec_streamon_input(inst);
- else if (V4L2_TYPE_IS_CAPTURE(q->type))
- ret = iris_vdec_streamon_output(inst);
+ if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+ if (inst->domain == DECODER)
+ ret = iris_vdec_streamon_input(inst);
+ else
+ ret = iris_venc_streamon_input(inst);
+ } else if (V4L2_TYPE_IS_CAPTURE(q->type)) {
+ if (inst->domain == DECODER)
+ ret = iris_vdec_streamon_output(inst);
+ else
+ ret = iris_venc_streamon_output(inst);
+ }
if (ret)
goto error;
buf_type = iris_v4l2_type_to_driver(q->type);
- ret = iris_queue_deferred_buffers(inst, buf_type);
+ if (inst->domain == DECODER) {
+ if (inst->state == IRIS_INST_STREAMING)
+ ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB);
+ if (!ret)
+ ret = iris_queue_deferred_buffers(inst, buf_type);
+ } else {
+ if (inst->state == IRIS_INST_STREAMING) {
+ ret = iris_queue_deferred_buffers(inst, BUF_INPUT);
+ if (!ret)
+ ret = iris_queue_deferred_buffers(inst, BUF_OUTPUT);
+ }
+ }
+
if (ret)
goto error;
@@ -235,7 +236,7 @@ void iris_vb2_stop_streaming(struct vb2_queue *q)
!V4L2_TYPE_IS_CAPTURE(q->type))
goto exit;
- ret = iris_vdec_session_streamoff(inst, q->type);
+ ret = iris_session_streamoff(inst, q->type);
if (ret)
goto exit;
@@ -326,7 +327,10 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2)
v4l2_m2m_buf_queue(m2m_ctx, vbuf);
- ret = iris_vdec_qbuf(inst, vbuf);
+ if (inst->domain == DECODER)
+ ret = iris_vdec_qbuf(inst, vbuf);
+ else
+ ret = iris_venc_qbuf(inst, vbuf);
exit:
if (ret) {
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
index d670b51c5839..ae13c3e1b426 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -7,14 +7,13 @@
#include <media/v4l2-mem2mem.h>
#include "iris_buffer.h"
+#include "iris_common.h"
#include "iris_ctrls.h"
#include "iris_instance.h"
#include "iris_power.h"
#include "iris_vdec.h"
#include "iris_vpu_buffer.h"
-#define DEFAULT_WIDTH 320
-#define DEFAULT_HEIGHT 240
#define DEFAULT_CODEC_ALIGNMENT 16
int iris_vdec_inst_init(struct iris_inst *inst)
@@ -56,7 +55,7 @@ int iris_vdec_inst_init(struct iris_inst *inst)
inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
- memcpy(&inst->fw_caps[0], &core->inst_fw_caps[0],
+ memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0],
INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
return iris_ctrls_init(inst);
@@ -158,7 +157,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
}
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (!fmt) {
+ if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
f_inst = inst->fmt_dst;
f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
@@ -265,6 +264,19 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
return 0;
}
+int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat)
+{
+ const struct iris_fmt *fmt = NULL;
+
+ if (pixelformat != V4L2_PIX_FMT_NV12) {
+ fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (!fmt)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
{
int ret = 0;
@@ -301,125 +313,6 @@ void iris_vdec_src_change(struct iris_inst *inst)
v4l2_event_queue_fh(&inst->fh, &event);
}
-
-static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,
- enum iris_buffer_type type)
-{
- struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
- struct v4l2_m2m_buffer *buffer, *n;
- struct iris_buffer *buf;
-
- if (type == BUF_INPUT) {
- v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
- buf = to_iris_buffer(&buffer->vb);
- if (buf->attr & BUF_ATTR_DEFERRED) {
- if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
- buf->attr |= BUF_ATTR_BUFFER_DONE;
- buf->data_size = 0;
- iris_vb2_buffer_done(inst, buf);
- }
- }
- }
- } else {
- v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
- buf = to_iris_buffer(&buffer->vb);
- if (buf->attr & BUF_ATTR_DEFERRED) {
- if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
- buf->attr |= BUF_ATTR_BUFFER_DONE;
- buf->data_size = 0;
- iris_vb2_buffer_done(inst, buf);
- }
- }
- }
- }
-}
-
-static void iris_vdec_kill_session(struct iris_inst *inst)
-{
- const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
-
- if (!inst->session_id)
- return;
-
- hfi_ops->session_close(inst);
- iris_inst_change_state(inst, IRIS_INST_ERROR);
-}
-
-int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane)
-{
- const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
- enum iris_buffer_type buffer_type;
- int ret;
-
- switch (plane) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- buffer_type = BUF_INPUT;
- break;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- buffer_type = BUF_OUTPUT;
- break;
- default:
- return -EINVAL;
- }
-
- ret = hfi_ops->session_stop(inst, plane);
- if (ret)
- goto error;
-
- ret = iris_inst_state_change_streamoff(inst, plane);
- if (ret)
- goto error;
-
- iris_vdec_flush_deferred_buffers(inst, buffer_type);
-
- return 0;
-
-error:
- iris_vdec_kill_session(inst);
- iris_vdec_flush_deferred_buffers(inst, buffer_type);
-
- return ret;
-}
-
-static int iris_vdec_process_streamon_input(struct iris_inst *inst)
-{
- const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
- enum iris_inst_sub_state set_sub_state = 0;
- int ret;
-
- iris_scale_power(inst);
-
- ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- if (ret)
- return ret;
-
- if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
- ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
- if (ret)
- return ret;
- }
-
- if (inst->sub_state & IRIS_INST_SUB_DRC ||
- inst->sub_state & IRIS_INST_SUB_DRAIN ||
- inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) {
- if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
- if (hfi_ops->session_pause) {
- ret = hfi_ops->session_pause(inst,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- if (ret)
- return ret;
- }
- set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
- }
- }
-
- ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- if (ret)
- return ret;
-
- return iris_inst_change_sub_state(inst, 0, set_sub_state);
-}
-
int iris_vdec_streamon_input(struct iris_inst *inst)
{
int ret;
@@ -428,7 +321,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
if (ret)
return ret;
- ret = iris_alloc_and_queue_persist_bufs(inst);
+ ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST);
if (ret)
return ret;
@@ -446,71 +339,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst)
if (ret)
return ret;
- return iris_vdec_process_streamon_input(inst);
-}
-
-static int iris_vdec_process_streamon_output(struct iris_inst *inst)
-{
- const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
- bool drain_active = false, drc_active = false;
- enum iris_inst_sub_state clear_sub_state = 0;
- int ret = 0;
-
- iris_scale_power(inst);
-
- drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN &&
- inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
-
- drc_active = inst->sub_state & IRIS_INST_SUB_DRC &&
- inst->sub_state & IRIS_INST_SUB_DRC_LAST;
-
- if (drc_active)
- clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
- else if (drain_active)
- clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
-
- if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
- ret = iris_alloc_and_queue_input_int_bufs(inst);
- if (ret)
- return ret;
- ret = iris_set_stage(inst, STAGE);
- if (ret)
- return ret;
- ret = iris_set_pipe(inst, PIPE);
- if (ret)
- return ret;
- }
-
- if (inst->state == IRIS_INST_INPUT_STREAMING &&
- inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
- if (!drain_active)
- ret = hfi_ops->session_resume_drc(inst,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- else if (hfi_ops->session_resume_drain)
- ret = hfi_ops->session_resume_drain(inst,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- if (ret)
- return ret;
- clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
- }
-
- if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)
- clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC;
-
- ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
- if (ret)
- return ret;
-
- if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
- clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
-
- ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
- if (ret)
- return ret;
-
- inst->last_buffer_dequeued = false;
-
- return iris_inst_change_sub_state(inst, clear_sub_state, 0);
+ return iris_process_streamon_input(inst);
}
int iris_vdec_streamon_output(struct iris_inst *inst)
@@ -532,7 +361,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
if (ret)
return ret;
- ret = iris_vdec_process_streamon_output(inst);
+ ret = iris_process_streamon_output(inst);
if (ret)
goto error;
@@ -543,49 +372,11 @@ int iris_vdec_streamon_output(struct iris_inst *inst)
return ret;
error:
- iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
return ret;
}
-static int
-iris_vdec_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
-
- buf->type = iris_v4l2_type_to_driver(vb2->type);
- buf->index = vb2->index;
- buf->fd = vb2->planes[0].m.fd;
- buf->buffer_size = vb2->planes[0].length;
- buf->data_offset = vb2->planes[0].data_offset;
- buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset;
- buf->flags = vbuf->flags;
- buf->timestamp = vb2->timestamp;
- buf->attr = 0;
-
- return 0;
-}
-
-static void
-iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
-{
- u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- struct vb2_buffer *vb = &vbuf->vb2_buf;
- u64 ts_us = vb->timestamp;
-
- if (inst->metadata_idx >= ARRAY_SIZE(inst->tss))
- inst->metadata_idx = 0;
-
- do_div(ts_us, NSEC_PER_USEC);
-
- inst->tss[inst->metadata_idx].flags = vbuf->flags & mask;
- inst->tss[inst->metadata_idx].tc = vbuf->timecode;
- inst->tss[inst->metadata_idx].ts_us = ts_us;
- inst->tss[inst->metadata_idx].ts_ns = vb->timestamp;
-
- inst->metadata_idx++;
-}
-
int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
{
struct iris_buffer *buf = to_iris_buffer(vbuf);
@@ -593,7 +384,7 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
struct vb2_queue *q;
int ret;
- ret = iris_vdec_vb2_buffer_to_driver(vb2, buf);
+ ret = iris_vb2_buffer_to_driver(vb2, buf);
if (ret)
return ret;
diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h
index cd7aab66dc7c..ec1ce55d1375 100644
--- a/drivers/media/platform/qcom/iris/iris_vdec.h
+++ b/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -8,22 +8,12 @@
struct iris_inst;
-enum iris_fmt_type {
- IRIS_FMT_H264,
- IRIS_FMT_HEVC,
- IRIS_FMT_VP9,
-};
-
-struct iris_fmt {
- u32 pixfmt;
- u32 type;
-};
-
int iris_vdec_inst_init(struct iris_inst *inst);
void iris_vdec_inst_deinit(struct iris_inst *inst);
int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat);
int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub);
void iris_vdec_src_change(struct iris_inst *inst);
int iris_vdec_streamon_input(struct iris_inst *inst);
@@ -31,6 +21,5 @@ int iris_vdec_streamon_output(struct iris_inst *inst);
int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
int iris_vdec_start_cmd(struct iris_inst *inst);
int iris_vdec_stop_cmd(struct iris_inst *inst);
-int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane);
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c
new file mode 100644
index 000000000000..099bd5ed4ae0
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_venc.c
@@ -0,0 +1,579 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "iris_buffer.h"
+#include "iris_common.h"
+#include "iris_ctrls.h"
+#include "iris_instance.h"
+#include "iris_power.h"
+#include "iris_venc.h"
+#include "iris_vpu_buffer.h"
+
+int iris_venc_inst_init(struct iris_inst *inst)
+{
+ struct iris_core *core = inst->core;
+ struct v4l2_format *f;
+
+ inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
+ inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL);
+ if (!inst->fmt_src || !inst->fmt_dst) {
+ kfree(inst->fmt_src);
+ kfree(inst->fmt_dst);
+ return -ENOMEM;
+ }
+
+ f = inst->fmt_dst;
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ f->fmt.pix_mp.width = DEFAULT_WIDTH;
+ f->fmt.pix_mp.height = DEFAULT_HEIGHT;
+ f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+ inst->codec = f->fmt.pix_mp.pixelformat;
+ f->fmt.pix_mp.num_planes = 1;
+ f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+ f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
+ f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+ f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+ inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
+ inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+ f = inst->fmt_src;
+ f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
+ f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128);
+ f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
+ f->fmt.pix_mp.num_planes = 1;
+ f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
+ f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
+ f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+ f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+ inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
+ inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+ inst->crop.left = 0;
+ inst->crop.top = 0;
+ inst->crop.width = f->fmt.pix_mp.width;
+ inst->crop.height = f->fmt.pix_mp.height;
+
+ inst->operating_rate = DEFAULT_FPS;
+ inst->frame_rate = DEFAULT_FPS;
+
+ memcpy(&inst->fw_caps[0], &core->inst_fw_caps_enc[0],
+ INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
+
+ return iris_ctrls_init(inst);
+}
+
+void iris_venc_inst_deinit(struct iris_inst *inst)
+{
+ kfree(inst->fmt_dst);
+ kfree(inst->fmt_src);
+}
+
+static const struct iris_fmt iris_venc_formats[] = {
+ [IRIS_FMT_H264] = {
+ .pixfmt = V4L2_PIX_FMT_H264,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ },
+ [IRIS_FMT_HEVC] = {
+ .pixfmt = V4L2_PIX_FMT_HEVC,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ },
+};
+
+static const struct iris_fmt *
+find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
+{
+ const struct iris_fmt *fmt = iris_venc_formats;
+ unsigned int size = ARRAY_SIZE(iris_venc_formats);
+ unsigned int i;
+
+ for (i = 0; i < size; i++) {
+ if (fmt[i].pixfmt == pixfmt)
+ break;
+ }
+
+ if (i == size || fmt[i].type != type)
+ return NULL;
+
+ return &fmt[i];
+}
+
+static const struct iris_fmt *
+find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
+{
+ const struct iris_fmt *fmt = iris_venc_formats;
+ unsigned int size = ARRAY_SIZE(iris_venc_formats);
+
+ if (index >= size || fmt[index].type != type)
+ return NULL;
+
+ return &fmt[index];
+}
+
+int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
+{
+ const struct iris_fmt *fmt;
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (f->index)
+ return -EINVAL;
+ f->pixelformat = V4L2_PIX_FMT_NV12;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ fmt = find_format_by_index(inst, f->index, f->type);
+ if (!fmt)
+ return -EINVAL;
+
+ f->pixelformat = fmt->pixfmt;
+ f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+ const struct iris_fmt *fmt;
+ struct v4l2_format *f_inst;
+
+ memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
+ fmt = find_format(inst, pixmp->pixelformat, f->type);
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
+ f_inst = inst->fmt_src;
+ f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
+ f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
+ f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
+ }
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ if (!fmt) {
+ f_inst = inst->fmt_dst;
+ f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
+ f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
+ f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (pixmp->field == V4L2_FIELD_ANY)
+ pixmp->field = V4L2_FIELD_NONE;
+
+ pixmp->num_planes = 1;
+
+ return 0;
+}
+
+static int iris_venc_s_fmt_output(struct iris_inst *inst, struct v4l2_format *f)
+{
+ struct v4l2_format *fmt;
+
+ iris_venc_try_fmt(inst, f);
+
+ if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
+ return -EINVAL;
+
+ fmt = inst->fmt_dst;
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt->fmt.pix_mp.num_planes = 1;
+ fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
+
+ if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT &&
+ f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709)
+ f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+ fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
+ fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
+ fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+ fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
+
+ inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
+ inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
+ fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
+ inst->codec = f->fmt.pix_mp.pixelformat;
+ memcpy(f, fmt, sizeof(struct v4l2_format));
+
+ return 0;
+}
+
+static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f)
+{
+ struct v4l2_format *fmt, *output_fmt;
+
+ iris_venc_try_fmt(inst, f);
+
+ if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12)
+ return -EINVAL;
+
+ fmt = inst->fmt_src;
+ fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
+ fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
+ fmt->fmt.pix_mp.num_planes = 1;
+ fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
+ fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128);
+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
+
+ fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
+ fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
+ fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+ fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
+
+ output_fmt = inst->fmt_dst;
+ output_fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.width;
+ output_fmt->fmt.pix_mp.height = fmt->fmt.pix_mp.height;
+ output_fmt->fmt.pix_mp.colorspace = fmt->fmt.pix_mp.colorspace;
+ output_fmt->fmt.pix_mp.xfer_func = fmt->fmt.pix_mp.xfer_func;
+ output_fmt->fmt.pix_mp.ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc;
+ output_fmt->fmt.pix_mp.quantization = fmt->fmt.pix_mp.quantization;
+
+ inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
+ inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+ if (f->fmt.pix_mp.width != inst->crop.width ||
+ f->fmt.pix_mp.height != inst->crop.height) {
+ inst->crop.top = 0;
+ inst->crop.left = 0;
+ inst->crop.width = fmt->fmt.pix_mp.width;
+ inst->crop.height = fmt->fmt.pix_mp.height;
+
+ iris_venc_s_fmt_output(inst, output_fmt);
+ }
+
+ memcpy(f, fmt, sizeof(struct v4l2_format));
+
+ return 0;
+}
+
+int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+ struct vb2_queue *q;
+
+ q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
+ if (!q)
+ return -EINVAL;
+
+ if (vb2_is_busy(q))
+ return -EBUSY;
+
+ switch (f->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ return iris_venc_s_fmt_input(inst, f);
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ return iris_venc_s_fmt_output(inst, f);
+ default:
+ return -EINVAL;
+ }
+}
+
+int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat)
+{
+ const struct iris_fmt *fmt = NULL;
+
+ if (pixelformat != V4L2_PIX_FMT_NV12) {
+ fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (!fmt)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int iris_venc_subscribe_event(struct iris_inst *inst,
+ const struct v4l2_event_subscription *sub)
+{
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(&inst->fh, sub, 0, NULL);
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(&inst->fh, sub);
+ default:
+ return -EINVAL;
+ }
+}
+
+int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s)
+{
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP:
+ s->r.left = 0;
+ s->r.top = 0;
+
+ if (s->r.width > inst->fmt_src->fmt.pix_mp.width ||
+ s->r.height > inst->fmt_src->fmt.pix_mp.height)
+ return -EINVAL;
+
+ inst->crop.left = s->r.left;
+ inst->crop.top = s->r.top;
+ inst->crop.width = s->r.width;
+ inst->crop.height = s->r.height;
+ inst->fmt_dst->fmt.pix_mp.width = inst->crop.width;
+ inst->fmt_dst->fmt.pix_mp.height = inst->crop.height;
+ return iris_venc_s_fmt_output(inst, inst->fmt_dst);
+ default:
+ return -EINVAL;
+ }
+}
+
+int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
+{
+ struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
+ struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+ struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+ struct v4l2_fract *timeperframe = NULL;
+ u32 default_rate = DEFAULT_FPS;
+ bool is_frame_rate = false;
+ u64 us_per_frame, fps;
+ u32 max_rate;
+
+ int ret = 0;
+
+ if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ timeperframe = &s_parm->parm.output.timeperframe;
+ max_rate = caps->max_operating_rate;
+ s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
+ } else {
+ timeperframe = &s_parm->parm.capture.timeperframe;
+ is_frame_rate = true;
+ max_rate = caps->max_frame_rate;
+ s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ }
+
+ if (!timeperframe->denominator || !timeperframe->numerator) {
+ if (!timeperframe->numerator)
+ timeperframe->numerator = 1;
+ if (!timeperframe->denominator)
+ timeperframe->denominator = default_rate;
+ }
+
+ us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
+ do_div(us_per_frame, timeperframe->denominator);
+
+ if (!us_per_frame)
+ return -EINVAL;
+
+ fps = (u64)USEC_PER_SEC;
+ do_div(fps, us_per_frame);
+ if (fps > max_rate) {
+ ret = -ENOMEM;
+ goto reset_rate;
+ }
+
+ if (is_frame_rate)
+ inst->frame_rate = (u32)fps;
+ else
+ inst->operating_rate = (u32)fps;
+
+ if ((s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_streaming(src_q)) ||
+ (s_parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && vb2_is_streaming(dst_q))) {
+ ret = iris_check_core_mbpf(inst);
+ if (ret)
+ goto reset_rate;
+ ret = iris_check_core_mbps(inst);
+ if (ret)
+ goto reset_rate;
+ }
+
+ return 0;
+
+reset_rate:
+ if (ret) {
+ if (is_frame_rate)
+ inst->frame_rate = default_rate;
+ else
+ inst->operating_rate = default_rate;
+ }
+
+ return ret;
+}
+
+int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
+{
+ struct v4l2_fract *timeperframe = NULL;
+
+ if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ timeperframe = &s_parm->parm.output.timeperframe;
+ timeperframe->numerator = 1;
+ timeperframe->denominator = inst->operating_rate;
+ s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
+ } else {
+ timeperframe = &s_parm->parm.capture.timeperframe;
+ timeperframe->numerator = 1;
+ timeperframe->denominator = inst->frame_rate;
+ s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+ }
+
+ return 0;
+}
+
+int iris_venc_streamon_input(struct iris_inst *inst)
+{
+ int ret;
+
+ ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP);
+ if (ret)
+ return ret;
+
+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+ ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ return iris_process_streamon_input(inst);
+}
+
+int iris_venc_streamon_output(struct iris_inst *inst)
+{
+ int ret;
+
+ ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ goto error;
+
+ ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP);
+ if (ret)
+ return ret;
+
+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+ ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ goto error;
+
+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ goto error;
+
+ ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ goto error;
+
+ ret = iris_process_streamon_output(inst);
+ if (ret)
+ goto error;
+
+ return ret;
+
+error:
+ iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+ return ret;
+}
+
+int iris_venc_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+ struct iris_buffer *buf = to_iris_buffer(vbuf);
+ struct vb2_buffer *vb2 = &vbuf->vb2_buf;
+ struct vb2_queue *q;
+ int ret;
+
+ ret = iris_vb2_buffer_to_driver(vb2, buf);
+ if (ret)
+ return ret;
+
+ if (buf->type == BUF_INPUT)
+ iris_set_ts_metadata(inst, vbuf);
+
+ q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type);
+ if (!vb2_is_streaming(q)) {
+ buf->attr |= BUF_ATTR_DEFERRED;
+ return 0;
+ }
+
+ iris_scale_power(inst);
+
+ return iris_queue_buffer(inst, buf);
+}
+
+int iris_venc_start_cmd(struct iris_inst *inst)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ enum iris_inst_sub_state clear_sub_state = 0;
+ struct vb2_queue *dst_vq;
+ int ret;
+
+ dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+ if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
+ inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
+ vb2_clear_last_buffer_dequeued(dst_vq);
+ clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
+ if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+ if (hfi_ops->session_resume_drain) {
+ ret = hfi_ops->session_resume_drain(inst,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+ }
+ clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
+ }
+ if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
+ if (hfi_ops->session_resume_drain) {
+ ret = hfi_ops->session_resume_drain(inst,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (ret)
+ return ret;
+ }
+ clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
+ }
+ } else {
+ dev_err(inst->core->dev, "start called before receiving last_flag\n");
+ iris_inst_change_state(inst, IRIS_INST_ERROR);
+ return -EBUSY;
+ }
+
+ inst->last_buffer_dequeued = false;
+
+ return iris_inst_change_sub_state(inst, clear_sub_state, 0);
+}
+
+int iris_venc_stop_cmd(struct iris_inst *inst)
+{
+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
+ int ret;
+
+ ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (ret)
+ return ret;
+
+ ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
+
+ iris_scale_power(inst);
+
+ return ret;
+}
diff --git a/drivers/media/platform/qcom/iris/iris_venc.h b/drivers/media/platform/qcom/iris/iris_venc.h
new file mode 100644
index 000000000000..c4db7433da53
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_venc.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_VENC_H_
+#define _IRIS_VENC_H_
+
+struct iris_inst;
+
+int iris_venc_inst_init(struct iris_inst *inst);
+void iris_venc_inst_deinit(struct iris_inst *inst);
+int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
+int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat);
+int iris_venc_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub);
+int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s);
+int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm);
+int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm);
+int iris_venc_streamon_input(struct iris_inst *inst);
+int iris_venc_streamon_output(struct iris_inst *inst);
+int iris_venc_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf);
+int iris_venc_start_cmd(struct iris_inst *inst);
+int iris_venc_stop_cmd(struct iris_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c
index c417e8c31f80..d38d0f6961cd 100644
--- a/drivers/media/platform/qcom/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -12,6 +12,7 @@
#include "iris_vidc.h"
#include "iris_instance.h"
#include "iris_vdec.h"
+#include "iris_venc.h"
#include "iris_vb2.h"
#include "iris_vpu_buffer.h"
#include "iris_platform_common.h"
@@ -21,16 +22,19 @@
#define STEP_WIDTH 1
#define STEP_HEIGHT 1
-static void iris_v4l2_fh_init(struct iris_inst *inst)
+static void iris_v4l2_fh_init(struct iris_inst *inst, struct file *filp)
{
- v4l2_fh_init(&inst->fh, inst->core->vdev_dec);
+ if (inst->domain == ENCODER)
+ v4l2_fh_init(&inst->fh, inst->core->vdev_enc);
+ else if (inst->domain == DECODER)
+ v4l2_fh_init(&inst->fh, inst->core->vdev_dec);
inst->fh.ctrl_handler = &inst->ctrl_handler;
- v4l2_fh_add(&inst->fh);
+ v4l2_fh_add(&inst->fh, filp);
}
-static void iris_v4l2_fh_deinit(struct iris_inst *inst)
+static void iris_v4l2_fh_deinit(struct iris_inst *inst, struct file *filp)
{
- v4l2_fh_del(&inst->fh);
+ v4l2_fh_del(&inst->fh, filp);
inst->fh.ctrl_handler = NULL;
v4l2_fh_exit(&inst->fh);
}
@@ -67,9 +71,9 @@ static void iris_remove_session(struct iris_inst *inst)
mutex_unlock(&core->lock);
}
-static inline struct iris_inst *iris_get_inst(struct file *filp, void *fh)
+static inline struct iris_inst *iris_get_inst(struct file *filp)
{
- return container_of(filp->private_data, struct iris_inst, fh);
+ return container_of(file_to_v4l2_fh(filp), struct iris_inst, fh);
}
static void iris_m2m_device_run(void *priv)
@@ -126,9 +130,19 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_
int iris_open(struct file *filp)
{
struct iris_core *core = video_drvdata(filp);
+ struct video_device *vdev;
struct iris_inst *inst;
+ u32 session_type;
int ret;
+ vdev = video_devdata(filp);
+ if (strcmp(vdev->name, "qcom-iris-decoder") == 0)
+ session_type = DECODER;
+ else if (strcmp(vdev->name, "qcom-iris-encoder") == 0)
+ session_type = ENCODER;
+ else
+ return -EINVAL;
+
ret = pm_runtime_resume_and_get(core->dev);
if (ret < 0)
return ret;
@@ -147,6 +161,7 @@ int iris_open(struct file *filp)
return -ENOMEM;
inst->core = core;
+ inst->domain = session_type;
inst->session_id = hash32_ptr(inst);
inst->state = IRIS_INST_DEINIT;
@@ -161,10 +176,12 @@ int iris_open(struct file *filp)
INIT_LIST_HEAD(&inst->buffers[BUF_DPB].list);
INIT_LIST_HEAD(&inst->buffers[BUF_PERSIST].list);
INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list);
+ INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_2].list);
+ INIT_LIST_HEAD(&inst->buffers[BUF_VPSS].list);
init_completion(&inst->completion);
init_completion(&inst->flush_completion);
- iris_v4l2_fh_init(inst);
+ iris_v4l2_fh_init(inst, filp);
inst->m2m_dev = v4l2_m2m_init(&iris_m2m_ops);
if (IS_ERR_OR_NULL(inst->m2m_dev)) {
@@ -178,14 +195,16 @@ int iris_open(struct file *filp)
goto fail_m2m_release;
}
- ret = iris_vdec_inst_init(inst);
+ if (inst->domain == DECODER)
+ ret = iris_vdec_inst_init(inst);
+ else if (inst->domain == ENCODER)
+ ret = iris_venc_inst_init(inst);
if (ret)
goto fail_m2m_ctx_release;
iris_add_session(inst);
inst->fh.m2m_ctx = inst->m2m_ctx;
- filp->private_data = &inst->fh;
return 0;
@@ -194,7 +213,7 @@ fail_m2m_ctx_release:
fail_m2m_release:
v4l2_m2m_release(inst->m2m_dev);
fail_v4l2_fh_deinit:
- iris_v4l2_fh_deinit(inst);
+ iris_v4l2_fh_deinit(inst, filp);
mutex_destroy(&inst->ctx_q_lock);
mutex_destroy(&inst->lock);
kfree(inst);
@@ -240,26 +259,42 @@ static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 p
for (i = 0; i < internal_buffer_count; i++) {
buffers = &inst->buffers[internal_buf_type[i]];
+ count = 0;
list_for_each_entry_safe(buf, next, &buffers->list, list)
count++;
if (count)
dev_err(inst->core->dev, "%d buffer of type %d not released",
count, internal_buf_type[i]);
}
+
+ if (inst->domain == DECODER)
+ buffers = &inst->buffers[BUF_PERSIST];
+ else
+ buffers = &inst->buffers[BUF_ARP];
+
+ count = 0;
+ list_for_each_entry_safe(buf, next, &buffers->list, list)
+ count++;
+ if (count)
+ dev_err(inst->core->dev, "%d buffer of type %d not released",
+ count, inst->domain == DECODER ? BUF_PERSIST : BUF_ARP);
}
int iris_close(struct file *filp)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
+ struct iris_inst *inst = iris_get_inst(filp);
v4l2_ctrl_handler_free(&inst->ctrl_handler);
v4l2_m2m_ctx_release(inst->m2m_ctx);
v4l2_m2m_release(inst->m2m_dev);
mutex_lock(&inst->lock);
- iris_vdec_inst_deinit(inst);
+ if (inst->domain == DECODER)
+ iris_vdec_inst_deinit(inst);
+ else if (inst->domain == ENCODER)
+ iris_venc_inst_deinit(inst);
iris_session_close(inst);
iris_inst_change_state(inst, IRIS_INST_DEINIT);
- iris_v4l2_fh_deinit(inst);
+ iris_v4l2_fh_deinit(inst, filp);
iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
@@ -269,25 +304,34 @@ int iris_close(struct file *filp)
mutex_destroy(&inst->ctx_q_lock);
mutex_destroy(&inst->lock);
kfree(inst);
- filp->private_data = NULL;
return 0;
}
static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
+ struct iris_inst *inst = iris_get_inst(filp);
- return iris_vdec_enum_fmt(inst, f);
+ if (inst->domain == DECODER)
+ return iris_vdec_enum_fmt(inst, f);
+ else if (inst->domain == ENCODER)
+ return iris_venc_enum_fmt(inst, f);
+ else
+ return -EINVAL;
}
static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
- int ret;
+ struct iris_inst *inst = iris_get_inst(filp);
+ int ret = 0;
mutex_lock(&inst->lock);
- ret = iris_vdec_try_fmt(inst, f);
+
+ if (inst->domain == DECODER)
+ ret = iris_vdec_try_fmt(inst, f);
+ else if (inst->domain == ENCODER)
+ ret = iris_venc_try_fmt(inst, f);
+
mutex_unlock(&inst->lock);
return ret;
@@ -295,11 +339,16 @@ static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_form
static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
- int ret;
+ struct iris_inst *inst = iris_get_inst(filp);
+ int ret = 0;
mutex_lock(&inst->lock);
- ret = iris_vdec_s_fmt(inst, f);
+
+ if (inst->domain == DECODER)
+ ret = iris_vdec_s_fmt(inst, f);
+ else if (inst->domain == ENCODER)
+ ret = iris_venc_s_fmt(inst, f);
+
mutex_unlock(&inst->lock);
return ret;
@@ -307,7 +356,7 @@ static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format
static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
+ struct iris_inst *inst = iris_get_inst(filp);
int ret = 0;
mutex_lock(&inst->lock);
@@ -326,15 +375,20 @@ static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format
static int iris_enum_framesizes(struct file *filp, void *fh,
struct v4l2_frmsizeenum *fsize)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
+ struct iris_inst *inst = iris_get_inst(filp);
struct platform_inst_caps *caps;
+ int ret = 0;
if (fsize->index)
return -EINVAL;
- if (fsize->pixel_format != V4L2_PIX_FMT_H264 &&
- fsize->pixel_format != V4L2_PIX_FMT_NV12)
- return -EINVAL;
+ if (inst->domain == DECODER)
+ ret = iris_vdec_validate_format(inst, fsize->pixel_format);
+ else
+ ret = iris_venc_validate_format(inst, fsize->pixel_format);
+
+ if (ret)
+ return ret;
caps = inst->core->iris_platform_data->inst_caps;
@@ -346,55 +400,174 @@ static int iris_enum_framesizes(struct file *filp, void *fh,
fsize->stepwise.max_height = caps->max_frame_height;
fsize->stepwise.step_height = STEP_HEIGHT;
+ return ret;
+}
+
+static int iris_enum_frameintervals(struct file *filp, void *fh,
+ struct v4l2_frmivalenum *fival)
+
+{
+ struct iris_inst *inst = iris_get_inst(filp);
+ struct iris_core *core = inst->core;
+ struct platform_inst_caps *caps;
+ u32 fps, mbpf;
+ int ret = 0;
+
+ if (inst->domain == DECODER)
+ return -ENOTTY;
+
+ if (fival->index)
+ return -EINVAL;
+
+ ret = iris_venc_validate_format(inst, fival->pixel_format);
+ if (ret)
+ return ret;
+
+ if (!fival->width || !fival->height)
+ return -EINVAL;
+
+ caps = inst->core->iris_platform_data->inst_caps;
+ if (fival->width > caps->max_frame_width ||
+ fival->width < caps->min_frame_width ||
+ fival->height > caps->max_frame_height ||
+ fival->height < caps->min_frame_height)
+ return -EINVAL;
+
+ mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width);
+ fps = DIV_ROUND_UP(core->iris_platform_data->max_core_mbps, mbpf);
+
+ fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+ fival->stepwise.min.numerator = 1;
+ fival->stepwise.min.denominator =
+ min_t(u32, fps, MAXIMUM_FPS);
+ fival->stepwise.max.numerator = 1;
+ fival->stepwise.max.denominator = 1;
+ fival->stepwise.step.numerator = 1;
+ fival->stepwise.step.denominator = MAXIMUM_FPS;
+
return 0;
}
static int iris_querycap(struct file *filp, void *fh, struct v4l2_capability *cap)
{
+ struct iris_inst *inst = iris_get_inst(filp);
+
strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver));
- strscpy(cap->card, "Iris Decoder", sizeof(cap->card));
+
+ if (inst->domain == DECODER)
+ strscpy(cap->card, "Iris Decoder", sizeof(cap->card));
+ else
+ strscpy(cap->card, "Iris Encoder", sizeof(cap->card));
return 0;
}
static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
+ struct iris_inst *inst = iris_get_inst(filp);
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ inst->domain == DECODER)
return -EINVAL;
- switch (s->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- case V4L2_SEL_TGT_COMPOSE_PADDED:
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ inst->domain == ENCODER)
+ return -EINVAL;
+
+ if (inst->domain == DECODER) {
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP:
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ case V4L2_SEL_TGT_COMPOSE_PADDED:
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE:
+ s->r.left = inst->crop.left;
+ s->r.top = inst->crop.top;
+ s->r.width = inst->crop.width;
+ s->r.height = inst->crop.height;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (inst->domain == ENCODER) {
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ s->r.width = inst->fmt_src->fmt.pix_mp.width;
+ s->r.height = inst->fmt_src->fmt.pix_mp.height;
+ break;
+ case V4L2_SEL_TGT_CROP:
+ s->r.width = inst->crop.width;
+ s->r.height = inst->crop.height;
+ break;
+ default:
+ return -EINVAL;
+ }
s->r.left = inst->crop.left;
s->r.top = inst->crop.top;
- s->r.width = inst->crop.width;
- s->r.height = inst->crop.height;
- break;
- default:
- return -EINVAL;
}
return 0;
}
+static int iris_s_selection(struct file *filp, void *fh, struct v4l2_selection *s)
+{
+ struct iris_inst *inst = iris_get_inst(filp);
+
+ if (inst->domain == DECODER)
+ return -EINVAL;
+ else if (inst->domain == ENCODER)
+ return iris_venc_s_selection(inst, s);
+
+ return -EINVAL;
+}
+
static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
{
struct iris_inst *inst = container_of(fh, struct iris_inst, fh);
- return iris_vdec_subscribe_event(inst, sub);
+ if (inst->domain == DECODER)
+ return iris_vdec_subscribe_event(inst, sub);
+ else if (inst->domain == ENCODER)
+ return iris_venc_subscribe_event(inst, sub);
+
+ return -EINVAL;
+}
+
+static int iris_s_parm(struct file *filp, void *fh, struct v4l2_streamparm *a)
+{
+ struct iris_inst *inst = iris_get_inst(filp);
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ if (inst->domain == ENCODER)
+ return iris_venc_s_param(inst, a);
+ else
+ return -EINVAL;
+}
+
+static int iris_g_parm(struct file *filp, void *fh, struct v4l2_streamparm *a)
+{
+ struct iris_inst *inst = iris_get_inst(filp);
+
+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ if (inst->domain == ENCODER)
+ return iris_venc_g_param(inst, a);
+ else
+ return -EINVAL;
}
static int iris_dec_cmd(struct file *filp, void *fh,
struct v4l2_decoder_cmd *dec)
{
- struct iris_inst *inst = iris_get_inst(filp, NULL);
+ struct iris_inst *inst = iris_get_inst(filp);
int ret = 0;
mutex_lock(&inst->lock);
@@ -424,6 +597,39 @@ unlock:
return ret;
}
+static int iris_enc_cmd(struct file *filp, void *fh,
+ struct v4l2_encoder_cmd *enc)
+{
+ struct iris_inst *inst = iris_get_inst(filp);
+ int ret = 0;
+
+ mutex_lock(&inst->lock);
+
+ ret = v4l2_m2m_ioctl_encoder_cmd(filp, fh, enc);
+ if (ret)
+ goto unlock;
+
+ if (inst->state == IRIS_INST_DEINIT)
+ goto unlock;
+
+ if (!iris_allow_cmd(inst, enc->cmd)) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+
+ if (enc->cmd == V4L2_ENC_CMD_START)
+ ret = iris_venc_start_cmd(inst);
+ else if (enc->cmd == V4L2_ENC_CMD_STOP)
+ ret = iris_venc_stop_cmd(inst);
+ else
+ ret = -EINVAL;
+
+unlock:
+ mutex_unlock(&inst->lock);
+
+ return ret;
+}
+
static struct v4l2_file_operations iris_v4l2_file_ops = {
.owner = THIS_MODULE,
.open = iris_open,
@@ -443,7 +649,7 @@ static const struct vb2_ops iris_vb2_ops = {
.buf_queue = iris_vb2_buf_queue,
};
-static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = {
+static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_dec = {
.vidioc_enum_fmt_vid_cap = iris_enum_fmt,
.vidioc_enum_fmt_vid_out = iris_enum_fmt,
.vidioc_try_fmt_vid_cap_mplane = iris_try_fmt_vid_mplane,
@@ -471,9 +677,42 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = {
.vidioc_decoder_cmd = iris_dec_cmd,
};
+static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops_enc = {
+ .vidioc_enum_fmt_vid_cap = iris_enum_fmt,
+ .vidioc_enum_fmt_vid_out = iris_enum_fmt,
+ .vidioc_try_fmt_vid_cap_mplane = iris_try_fmt_vid_mplane,
+ .vidioc_try_fmt_vid_out_mplane = iris_try_fmt_vid_mplane,
+ .vidioc_s_fmt_vid_cap_mplane = iris_s_fmt_vid_mplane,
+ .vidioc_s_fmt_vid_out_mplane = iris_s_fmt_vid_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane,
+ .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane,
+ .vidioc_enum_framesizes = iris_enum_framesizes,
+ .vidioc_enum_frameintervals = iris_enum_frameintervals,
+ .vidioc_querycap = iris_querycap,
+ .vidioc_subscribe_event = iris_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_selection = iris_g_selection,
+ .vidioc_s_selection = iris_s_selection,
+ .vidioc_s_parm = iris_s_parm,
+ .vidioc_g_parm = iris_g_parm,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_remove_bufs = v4l2_m2m_ioctl_remove_bufs,
+ .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
+ .vidioc_encoder_cmd = iris_enc_cmd,
+};
+
void iris_init_ops(struct iris_core *core)
{
core->iris_v4l2_file_ops = &iris_v4l2_file_ops;
core->iris_vb2_ops = &iris_vb2_ops;
- core->iris_v4l2_ioctl_ops = &iris_v4l2_ioctl_ops;
+ core->iris_v4l2_ioctl_ops_dec = &iris_v4l2_ioctl_ops_dec;
+ core->iris_v4l2_ioctl_ops_enc = &iris_v4l2_ioctl_ops_enc;
}
diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
index 7cf1bfc352d3..de7d142316d2 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
@@ -34,6 +34,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
const struct vpu_ops iris_vpu2_ops = {
.power_off_hw = iris_vpu_power_off_hw,
+ .power_on_hw = iris_vpu_power_on_hw,
.power_off_controller = iris_vpu_power_off_controller,
+ .power_on_controller = iris_vpu_power_on_controller,
.calc_freq = iris_vpu2_calc_freq,
};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c
index 9b7c9a1495ee..339776a0b467 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2025 Linaro Ltd
*/
#include <linux/iopoll.h>
@@ -19,8 +20,13 @@
#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
#define REQ_POWER_DOWN_PREP BIT(0)
#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
+#define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */
+#define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */
+#define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */
#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
#define CORE_CLK_RUN 0x0
+/* VPU v3.5 */
+#define WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0 (WRAPPER_BASE_OFFS + 0x78)
#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
#define CTL_AXI_CLK_HALT BIT(0)
@@ -52,6 +58,8 @@
#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
#define NOC_HALT BIT(0)
#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
+#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL (AON_BASE_OFFS + 0x2C)
+#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS (AON_BASE_OFFS + 0x30)
static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core)
{
@@ -109,7 +117,9 @@ disable_power:
static void iris_vpu33_power_off_hardware(struct iris_core *core)
{
+ bool handshake_done = false, handshake_busy = false;
u32 reg_val = 0, value, i;
+ u32 count = 0;
int ret;
if (iris_vpu3x_hw_power_collapsed(core))
@@ -128,13 +138,36 @@ static void iris_vpu33_power_off_hardware(struct iris_core *core)
goto disable_power;
}
+ /* Retry up to 1000 times as recommended by hardware documentation */
+ do {
+ /* set MNoC to low power */
+ writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+
+ udelay(15);
+
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
+
+ handshake_done = value & NOC_LPI_STATUS_DONE;
+ handshake_busy = value & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE);
+
+ if (handshake_done || !handshake_busy)
+ break;
+
+ writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+
+ udelay(15);
+
+ } while (++count < 1000);
+
+ if (!handshake_done && handshake_busy)
+ dev_err(core->dev, "LPI handshake timeout\n");
+
ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS,
reg_val, reg_val & BIT(0), 200, 2000);
if (ret)
goto disable_power;
- /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
- writel(BIT(0), core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
@@ -225,6 +258,158 @@ disable_power:
return 0;
}
+static int iris_vpu35_power_on_hw(struct iris_core *core)
+{
+ int ret;
+
+ ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+ if (ret)
+ return ret;
+
+ ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK);
+ if (ret)
+ goto err_disable_power;
+
+ ret = iris_prepare_enable_clock(core, IRIS_HW_FREERUN_CLK);
+ if (ret)
+ goto err_disable_axi_clk;
+
+ ret = iris_prepare_enable_clock(core, IRIS_HW_CLK);
+ if (ret)
+ goto err_disable_hw_free_clk;
+
+ ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true);
+ if (ret)
+ goto err_disable_hw_clk;
+
+ return 0;
+
+err_disable_hw_clk:
+ iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+err_disable_hw_free_clk:
+ iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
+err_disable_axi_clk:
+ iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+err_disable_power:
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
+
+ return ret;
+}
+
+static void iris_vpu35_power_off_hw(struct iris_core *core)
+{
+ iris_vpu33_power_off_hardware(core);
+
+ iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+}
+
+static int iris_vpu35_power_off_controller(struct iris_core *core)
+{
+ u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
+ unsigned int count = 0;
+ u32 val = 0;
+ bool handshake_done, handshake_busy;
+ int ret;
+
+ writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
+
+ writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
+
+ ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
+ val, val & BIT(0), 200, 2000);
+ if (ret)
+ goto disable_power;
+
+ writel(0, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
+
+ /* Retry up to 1000 times as recommended by hardware documentation */
+ do {
+ /* set MNoC to low power */
+ writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
+
+ udelay(15);
+
+ val = readl(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS);
+
+ handshake_done = val & NOC_LPI_STATUS_DONE;
+ handshake_busy = val & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE);
+
+ if (handshake_done || !handshake_busy)
+ break;
+
+ writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
+
+ udelay(15);
+
+ } while (++count < 1000);
+
+ if (!handshake_done && handshake_busy)
+ dev_err(core->dev, "LPI handshake timeout\n");
+
+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS,
+ val, val & BIT(0), 200, 2000);
+ if (ret)
+ goto disable_power;
+
+ writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
+
+ writel(0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
+
+ ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
+ val, val == 0, 200, 2000);
+ if (ret)
+ goto disable_power;
+
+disable_power:
+ iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
+ iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
+ iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
+
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
+
+ reset_control_bulk_reset(clk_rst_tbl_size, core->resets);
+
+ return 0;
+}
+
+static int iris_vpu35_power_on_controller(struct iris_core *core)
+{
+ int ret;
+
+ ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
+ if (ret)
+ return ret;
+
+ ret = iris_prepare_enable_clock(core, IRIS_AXI1_CLK);
+ if (ret)
+ goto err_disable_power;
+
+ ret = iris_prepare_enable_clock(core, IRIS_CTRL_FREERUN_CLK);
+ if (ret)
+ goto err_disable_axi1_clk;
+
+ ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK);
+ if (ret)
+ goto err_disable_ctrl_free_clk;
+
+ return 0;
+
+err_disable_ctrl_free_clk:
+ iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
+err_disable_axi1_clk:
+ iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
+err_disable_power:
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
+
+ return ret;
+}
+
+static void iris_vpu35_program_bootup_registers(struct iris_core *core)
+{
+ writel(0x1, core->reg_base + WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0);
+}
+
static u64 iris_vpu3x_calculate_frequency(struct iris_inst *inst, size_t data_size)
{
struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
@@ -264,12 +449,25 @@ static u64 iris_vpu3x_calculate_frequency(struct iris_inst *inst, size_t data_si
const struct vpu_ops iris_vpu3_ops = {
.power_off_hw = iris_vpu3_power_off_hardware,
+ .power_on_hw = iris_vpu_power_on_hw,
.power_off_controller = iris_vpu_power_off_controller,
+ .power_on_controller = iris_vpu_power_on_controller,
.calc_freq = iris_vpu3x_calculate_frequency,
};
const struct vpu_ops iris_vpu33_ops = {
.power_off_hw = iris_vpu33_power_off_hardware,
+ .power_on_hw = iris_vpu_power_on_hw,
.power_off_controller = iris_vpu33_power_off_controller,
+ .power_on_controller = iris_vpu_power_on_controller,
+ .calc_freq = iris_vpu3x_calculate_frequency,
+};
+
+const struct vpu_ops iris_vpu35_ops = {
+ .power_off_hw = iris_vpu35_power_off_hw,
+ .power_on_hw = iris_vpu35_power_on_hw,
+ .power_off_controller = iris_vpu35_power_off_controller,
+ .power_on_controller = iris_vpu35_power_on_controller,
+ .program_bootup_registers = iris_vpu35_program_bootup_registers,
.calc_freq = iris_vpu3x_calculate_frequency,
};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index f92fd39fe310..4463be05ce16 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -5,6 +5,14 @@
#include "iris_instance.h"
#include "iris_vpu_buffer.h"
+#include "iris_hfi_gen1_defines.h"
+#include "iris_hfi_gen2_defines.h"
+
+#define HFI_MAX_COL_FRAME 6
+
+#ifndef SYSTEM_LAL_TILE10
+#define SYSTEM_LAL_TILE10 192
+#endif
static u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
{
@@ -548,6 +556,858 @@ static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst)
iris_vpu_dec_line_size(inst);
}
+static inline u32 size_bin_bitstream_enc(u32 width, u32 height,
+ u32 rc_type)
+{
+ u32 aligned_height = ALIGN(height, 32);
+ u32 aligned_width = ALIGN(width, 32);
+ u32 frame_size = width * height * 3;
+ u32 mbs_per_frame;
+
+ /*
+ * Encoder output size calculation: 32 Align width/height
+ * For resolution < 720p : YUVsize * 4
+ * For resolution > 720p & <= 4K : YUVsize / 2
+ * For resolution > 4k : YUVsize / 4
+ * Initially frame_size = YUVsize * 2;
+ */
+
+ mbs_per_frame = (ALIGN(aligned_height, 16) * ALIGN(aligned_width, 16)) / 256;
+
+ if (mbs_per_frame < NUM_MBS_720P)
+ frame_size = frame_size << 1;
+ else if (mbs_per_frame <= NUM_MBS_4K)
+ frame_size = frame_size >> 2;
+ else
+ frame_size = frame_size >> 3;
+
+ if (rc_type == HFI_RATE_CONTROL_OFF || rc_type == HFI_RATE_CONTROL_CQ ||
+ rc_type == HFI_RC_OFF || rc_type == HFI_RC_CQ)
+ frame_size = frame_size << 1;
+
+ /*
+ * In case of opaque color format bitdepth will be known
+ * with first ETB, buffers allocated already with 8 bit
+ * won't be sufficient for 10 bit
+ * calculate size considering 10-bit by default
+ * For 10-bit cases size = size * 1.25
+ */
+ frame_size *= 5;
+ frame_size /= 4;
+
+ return ALIGN(frame_size, SZ_4K);
+}
+
+static inline u32 hfi_buffer_bin_enc(u32 width, u32 height,
+ u32 work_mode, u32 lcu_size,
+ u32 num_vpp_pipes, u32 rc_type)
+{
+ u32 sao_bin_buffer_size, padded_bin_size, bitstream_size;
+ u32 total_bitbin_buffers, size_single_pipe, bitbin_size;
+ u32 aligned_height = ALIGN(height, lcu_size);
+ u32 aligned_width = ALIGN(width, lcu_size);
+
+ bitstream_size = size_bin_bitstream_enc(width, height, rc_type);
+ bitstream_size = ALIGN(bitstream_size, 256);
+
+ if (work_mode == STAGE_2) {
+ total_bitbin_buffers = 3;
+ bitbin_size = bitstream_size * 17 / 10;
+ bitbin_size = ALIGN(bitbin_size, 256);
+ } else {
+ total_bitbin_buffers = 1;
+ bitstream_size = aligned_width * aligned_height * 3;
+ bitbin_size = ALIGN(bitstream_size, 256);
+ }
+
+ if (num_vpp_pipes > 2)
+ size_single_pipe = bitbin_size / 2;
+ else
+ size_single_pipe = bitbin_size;
+
+ size_single_pipe = ALIGN(size_single_pipe, 256);
+ sao_bin_buffer_size = (64 * (((width + 32) * (height + 32)) >> 10)) + 384;
+ padded_bin_size = ALIGN(size_single_pipe, 256);
+ size_single_pipe = sao_bin_buffer_size + padded_bin_size;
+ size_single_pipe = ALIGN(size_single_pipe, 256);
+ bitbin_size = size_single_pipe * num_vpp_pipes;
+
+ return ALIGN(bitbin_size, 256) * total_bitbin_buffers + 512;
+}
+
+static u32 iris_vpu_enc_bin_size(struct iris_inst *inst)
+{
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
+ u32 stage = inst->fw_caps[STAGE].value;
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 height = f->fmt.pix_mp.height;
+ u32 width = f->fmt.pix_mp.width;
+ u32 lcu_size;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC)
+ lcu_size = 32;
+ else
+ lcu_size = 16;
+
+ return hfi_buffer_bin_enc(width, height, stage, lcu_size,
+ num_vpp_pipes, inst->hfi_rc_type);
+}
+
+static inline
+u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
+ u32 num_recon, u32 standard)
+{
+ u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+ u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+ u32 num_lcu_in_frame = width_in_lcus * height_in_lcus;
+ u32 mb_height = ((frame_height) + 15) >> 4;
+ u32 mb_width = ((frame_width) + 15) >> 4;
+ u32 size_colloc_mv, size_colloc_rc;
+
+ size_colloc_mv = (standard == HFI_CODEC_ENCODE_HEVC) ?
+ (16 * ((num_lcu_in_frame << 2) + 32)) :
+ (3 * 16 * (width_in_lcus * height_in_lcus + 32));
+ size_colloc_mv = ALIGN(size_colloc_mv, 256) * num_recon;
+ size_colloc_rc = (((mb_width + 7) >> 3) * 16 * 2 * mb_height);
+ size_colloc_rc = ALIGN(size_colloc_rc, 256) * HFI_MAX_COL_FRAME;
+
+ return size_colloc_mv + size_colloc_rc;
+}
+
+static u32 iris_vpu_enc_comv_size(struct iris_inst *inst)
+{
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 height = f->fmt.pix_mp.height;
+ u32 width = f->fmt.pix_mp.width;
+ u32 num_recon = 1;
+ u32 lcu_size = 16;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ lcu_size = 32;
+ return hfi_buffer_comv_enc(width, height, lcu_size,
+ num_recon + 1, HFI_CODEC_ENCODE_HEVC);
+ }
+
+ return hfi_buffer_comv_enc(width, height, lcu_size,
+ num_recon + 1, HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 size_frame_rc_buf_size(u32 standard, u32 frame_height_coded,
+ u32 num_vpp_pipes_enc)
+{
+ u32 size = 0;
+
+ size = (standard == HFI_CODEC_ENCODE_HEVC) ?
+ (256 + 16 * (14 + ((((frame_height_coded) >> 5) + 7) >> 3))) :
+ (256 + 16 * (14 + ((((frame_height_coded) >> 4) + 7) >> 3)));
+ size *= 11;
+
+ if (num_vpp_pipes_enc > 1)
+ size = ALIGN(size, 256) * num_vpp_pipes_enc;
+
+ return ALIGN(size, 512) * HFI_MAX_COL_FRAME;
+}
+
+static inline
+u32 size_enc_slice_info_buf(u32 num_lcu_in_frame)
+{
+ return ALIGN((256 + (num_lcu_in_frame << 4)), 256);
+}
+
+static inline u32 enc_bitcnt_buf_size(u32 num_lcu_in_frame)
+{
+ return ALIGN((256 + (4 * (num_lcu_in_frame))), 256);
+}
+
+static inline u32 enc_bitmap_buf_size(u32 num_lcu_in_frame)
+{
+ return ALIGN((256 + ((num_lcu_in_frame) >> 3)), 256);
+}
+
+static inline u32 size_override_buf(u32 num_lcumb)
+{
+ return ALIGN(((16 * (((num_lcumb) + 7) >> 3))), 256) * 2;
+}
+
+static inline u32 size_ir_buf(u32 num_lcu_in_frame)
+{
+ return ALIGN((((((num_lcu_in_frame) << 1) + 7) & (~7)) * 3), 256);
+}
+
+static inline
+u32 size_linebuff_data(bool is_ten_bit, u32 frame_width_coded)
+{
+ return is_ten_bit ?
+ (((((10 * (frame_width_coded) + 1024) + (256 - 1)) &
+ (~(256 - 1))) * 1) +
+ (((((10 * (frame_width_coded) + 1024) >> 1) + (256 - 1)) &
+ (~(256 - 1))) * 2)) :
+ (((((8 * (frame_width_coded) + 1024) + (256 - 1)) &
+ (~(256 - 1))) * 1) +
+ (((((8 * (frame_width_coded) + 1024) >> 1) + (256 - 1)) &
+ (~(256 - 1))) * 2));
+}
+
+static inline
+u32 size_left_linebuff_ctrl(u32 standard, u32 frame_height_coded,
+ u32 num_vpp_pipes_enc)
+{
+ u32 size = 0;
+
+ size = standard == HFI_CODEC_ENCODE_HEVC ?
+ (((frame_height_coded) +
+ (32)) / 32 * 4 * 16) :
+ (((frame_height_coded) + 15) / 16 * 5 * 16);
+
+ if ((num_vpp_pipes_enc) > 1) {
+ size += 512;
+ size = ALIGN(size, 512) *
+ num_vpp_pipes_enc;
+ }
+
+ return ALIGN(size, 256);
+}
+
+static inline
+u32 size_left_linebuff_recon_pix(bool is_ten_bit, u32 frame_height_coded,
+ u32 num_vpp_pipes_enc)
+{
+ return (((is_ten_bit + 1) * 2 * (frame_height_coded) + 256) +
+ (256 << (num_vpp_pipes_enc - 1)) - 1) &
+ (~((256 << (num_vpp_pipes_enc - 1)) - 1)) * 1;
+}
+
+static inline
+u32 size_top_linebuff_ctrl_fe(u32 frame_width_coded, u32 standard)
+{
+ return standard == HFI_CODEC_ENCODE_HEVC ?
+ ALIGN((64 * ((frame_width_coded) >> 5)), 256) :
+ ALIGN((256 + 16 * ((frame_width_coded) >> 4)), 256);
+}
+
+static inline
+u32 size_left_linebuff_ctrl_fe(u32 frame_height_coded, u32 num_vpp_pipes_enc)
+{
+ return (((256 + 64 * ((frame_height_coded) >> 4)) +
+ (256 << (num_vpp_pipes_enc - 1)) - 1) &
+ (~((256 << (num_vpp_pipes_enc - 1)) - 1)) * 1) *
+ num_vpp_pipes_enc;
+}
+
+static inline
+u32 size_left_linebuff_metadata_recon_y(u32 frame_height_coded,
+ bool is_ten_bit,
+ u32 num_vpp_pipes_enc)
+{
+ return ALIGN(((256 + 64 * ((frame_height_coded) /
+ (8 * (is_ten_bit ? 4 : 8))))), 256) * num_vpp_pipes_enc;
+}
+
+static inline
+u32 size_left_linebuff_metadata_recon_uv(u32 frame_height_coded,
+ bool is_ten_bit,
+ u32 num_vpp_pipes_enc)
+{
+ return ALIGN(((256 + 64 * ((frame_height_coded) /
+ (4 * (is_ten_bit ? 4 : 8))))), 256) * num_vpp_pipes_enc;
+}
+
+static inline
+u32 size_linebuff_recon_pix(bool is_ten_bit, u32 frame_width_coded)
+{
+ return ALIGN(((is_ten_bit ? 3 : 2) * (frame_width_coded)), 256);
+}
+
+static inline
+u32 size_line_buf_ctrl(u32 frame_width_coded)
+{
+ return ALIGN(frame_width_coded, 256);
+}
+
+static inline
+u32 size_line_buf_ctrl_id2(u32 frame_width_coded)
+{
+ return ALIGN(frame_width_coded, 256);
+}
+
+static inline u32 size_line_buf_sde(u32 frame_width_coded)
+{
+ return ALIGN((256 + (16 * ((frame_width_coded) >> 4))), 256);
+}
+
+static inline
+u32 size_vpss_line_buf(u32 num_vpp_pipes_enc, u32 frame_height_coded,
+ u32 frame_width_coded)
+{
+ return ALIGN(((((((8192) >> 2) << 5) * (num_vpp_pipes_enc)) + 64) +
+ (((((max_t(u32, (frame_width_coded),
+ (frame_height_coded)) + 3) >> 2) << 5) + 256) * 16)), 256);
+}
+static inline
+u32 size_vpss_line_buf_vpu33(u32 num_vpp_pipes_enc, u32 frame_height_coded,
+ u32 frame_width_coded)
+{
+ u32 vpss_4tap_top, vpss_4tap_left, vpss_div2_top;
+ u32 vpss_div2_left, vpss_top_lb, vpss_left_lb;
+ u32 size_left, size_top;
+ u32 max_width_height;
+
+ max_width_height = max_t(u32, frame_width_coded, frame_height_coded);
+ vpss_4tap_top = ((((max_width_height * 2) + 3) >> 2) << 4) + 256;
+ vpss_4tap_left = (((8192 + 3) >> 2) << 5) + 64;
+ vpss_div2_top = (((max_width_height + 3) >> 2) << 4) + 256;
+ vpss_div2_left = ((((max_width_height * 2) + 3) >> 2) << 5) + 64;
+ vpss_top_lb = (frame_width_coded + 1) << 3;
+ vpss_left_lb = (frame_height_coded << 3) * num_vpp_pipes_enc;
+ size_left = (vpss_4tap_left + vpss_div2_left) * 2 * num_vpp_pipes_enc;
+ size_top = (vpss_4tap_top + vpss_div2_top) * 2;
+
+ return ALIGN(size_left + size_top + vpss_top_lb + vpss_left_lb, DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_top_line_buf_first_stg_sao(u32 frame_width_coded)
+{
+ return ALIGN((16 * ((frame_width_coded) >> 5)), 256);
+}
+
+static inline
+u32 size_enc_ref_buffer(u32 frame_width, u32 frame_height)
+{
+ u32 u_chroma_buffer_height = ALIGN(frame_height >> 1, 32);
+ u32 u_buffer_height = ALIGN(frame_height, 32);
+ u32 u_buffer_width = ALIGN(frame_width, 32);
+
+ return (u_buffer_height + u_chroma_buffer_height) * u_buffer_width;
+}
+
+static inline
+u32 size_enc_ten_bit_ref_buffer(u32 frame_width, u32 frame_height)
+{
+ u32 ref_luma_stride_in_bytes = ((frame_width + SYSTEM_LAL_TILE10 - 1) / SYSTEM_LAL_TILE10) *
+ SYSTEM_LAL_TILE10;
+ u32 ref_buf_height = (frame_height + (32 - 1)) & (~(32 - 1));
+ u32 u_ref_stride, luma_size;
+ u32 ref_chrm_height_in_bytes;
+ u32 chroma_size;
+
+ u_ref_stride = 4 * (ref_luma_stride_in_bytes / 3);
+ u_ref_stride = (u_ref_stride + (128 - 1)) & (~(128 - 1));
+ luma_size = ref_buf_height * u_ref_stride;
+ luma_size = (luma_size + (4096 - 1)) & (~(4096 - 1));
+
+ ref_chrm_height_in_bytes = (((frame_height + 1) >> 1) + (32 - 1)) & (~(32 - 1));
+ chroma_size = u_ref_stride * ref_chrm_height_in_bytes;
+ chroma_size = (chroma_size + (4096 - 1)) & (~(4096 - 1));
+
+ return luma_size + chroma_size;
+}
+
+static inline
+u32 hfi_ubwc_calc_metadata_plane_stride(u32 frame_width,
+ u32 metadata_stride_multiple,
+ u32 tile_width_in_pels)
+{
+ return ALIGN(((frame_width + (tile_width_in_pels - 1)) / tile_width_in_pels),
+ metadata_stride_multiple);
+}
+
+static inline
+u32 hfi_ubwc_metadata_plane_bufheight(u32 frame_height,
+ u32 metadata_height_multiple,
+ u32 tile_height_in_pels)
+{
+ return ALIGN(((frame_height + (tile_height_in_pels - 1)) / tile_height_in_pels),
+ metadata_height_multiple);
+}
+
+static inline
+u32 hfi_ubwc_metadata_plane_buffer_size(u32 _metadata_tride, u32 _metadata_buf_height)
+{
+ return ALIGN(_metadata_tride * _metadata_buf_height, 4096);
+}
+
+static inline
+u32 hfi_buffer_non_comv_enc(u32 frame_width, u32 frame_height,
+ u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+ u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+ u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+ u32 num_lcu_in_frame = width_in_lcus * height_in_lcus;
+ u32 frame_height_coded = height_in_lcus * (lcu_size);
+ u32 frame_width_coded = width_in_lcus * (lcu_size);
+ u32 num_lcumb, frame_rc_buf_size;
+
+ num_lcumb = (frame_height_coded / lcu_size) *
+ ((frame_width_coded + lcu_size * 8) / lcu_size);
+ frame_rc_buf_size = size_frame_rc_buf_size(standard, frame_height_coded,
+ num_vpp_pipes_enc);
+ return size_enc_slice_info_buf(num_lcu_in_frame) +
+ SIZE_SLICE_CMD_BUFFER +
+ SIZE_SPS_PPS_SLICE_HDR +
+ frame_rc_buf_size +
+ enc_bitcnt_buf_size(num_lcu_in_frame) +
+ enc_bitmap_buf_size(num_lcu_in_frame) +
+ SIZE_BSE_SLICE_CMD_BUF +
+ SIZE_LAMBDA_LUT +
+ size_override_buf(num_lcumb) +
+ size_ir_buf(num_lcu_in_frame);
+}
+
+static u32 iris_vpu_enc_non_comv_size(struct iris_inst *inst)
+{
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 height = f->fmt.pix_mp.height;
+ u32 width = f->fmt.pix_mp.width;
+ u32 lcu_size = 16;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ lcu_size = 32;
+ return hfi_buffer_non_comv_enc(width, height, num_vpp_pipes,
+ lcu_size, HFI_CODEC_ENCODE_HEVC) +
+ SIZE_ONE_SLICE_BUF;
+ }
+
+ return hfi_buffer_non_comv_enc(width, height, num_vpp_pipes,
+ lcu_size, HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_line_enc_base(u32 frame_width, u32 frame_height, bool is_ten_bit,
+ u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+ u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+ u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+ u32 frame_height_coded = height_in_lcus * (lcu_size);
+ u32 frame_width_coded = width_in_lcus * (lcu_size);
+ u32 line_buff_data_size, left_line_buff_ctrl_size;
+ u32 left_line_buff_metadata_recon__uv__size;
+ u32 left_line_buff_metadata_recon__y__size;
+ u32 left_line_buff_recon_pix_size;
+ u32 top_line_buff_ctrl_fe_size;
+ u32 line_buff_recon_pix_size;
+
+ line_buff_data_size = size_linebuff_data(is_ten_bit, frame_width_coded);
+ left_line_buff_ctrl_size =
+ size_left_linebuff_ctrl(standard, frame_height_coded, num_vpp_pipes_enc);
+ left_line_buff_recon_pix_size =
+ size_left_linebuff_recon_pix(is_ten_bit, frame_height_coded,
+ num_vpp_pipes_enc);
+ top_line_buff_ctrl_fe_size =
+ size_top_linebuff_ctrl_fe(frame_width_coded, standard);
+ left_line_buff_metadata_recon__y__size =
+ size_left_linebuff_metadata_recon_y(frame_height_coded, is_ten_bit,
+ num_vpp_pipes_enc);
+ left_line_buff_metadata_recon__uv__size =
+ size_left_linebuff_metadata_recon_uv(frame_height_coded, is_ten_bit,
+ num_vpp_pipes_enc);
+ line_buff_recon_pix_size = size_linebuff_recon_pix(is_ten_bit, frame_width_coded);
+
+ return size_line_buf_ctrl(frame_width_coded) +
+ size_line_buf_ctrl_id2(frame_width_coded) +
+ line_buff_data_size +
+ left_line_buff_ctrl_size +
+ left_line_buff_recon_pix_size +
+ top_line_buff_ctrl_fe_size +
+ left_line_buff_metadata_recon__y__size +
+ left_line_buff_metadata_recon__uv__size +
+ line_buff_recon_pix_size +
+ size_left_linebuff_ctrl_fe(frame_height_coded, num_vpp_pipes_enc) +
+ size_line_buf_sde(frame_width_coded) +
+ size_top_line_buf_first_stg_sao(frame_width_coded);
+}
+
+static inline
+u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit,
+ u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+ u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+ u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+ u32 frame_height_coded = height_in_lcus * (lcu_size);
+ u32 frame_width_coded = width_in_lcus * (lcu_size);
+
+ return hfi_buffer_line_enc_base(frame_width, frame_height, is_ten_bit,
+ num_vpp_pipes_enc, lcu_size, standard) +
+ size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded, frame_width_coded);
+}
+
+static inline
+u32 hfi_buffer_line_enc_vpu33(u32 frame_width, u32 frame_height, bool is_ten_bit,
+ u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+ u32 width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+ u32 height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+ u32 frame_height_coded = height_in_lcus * (lcu_size);
+ u32 frame_width_coded = width_in_lcus * (lcu_size);
+
+ return hfi_buffer_line_enc_base(frame_width, frame_height, is_ten_bit,
+ num_vpp_pipes_enc, lcu_size, standard) +
+ size_vpss_line_buf_vpu33(num_vpp_pipes_enc, frame_height_coded,
+ frame_width_coded);
+}
+
+static u32 iris_vpu_enc_line_size(struct iris_inst *inst)
+{
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 height = f->fmt.pix_mp.height;
+ u32 width = f->fmt.pix_mp.width;
+ u32 lcu_size = 16;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ lcu_size = 32;
+ return hfi_buffer_line_enc(width, height, 0, num_vpp_pipes,
+ lcu_size, HFI_CODEC_ENCODE_HEVC);
+ }
+
+ return hfi_buffer_line_enc(width, height, 0, num_vpp_pipes,
+ lcu_size, HFI_CODEC_ENCODE_AVC);
+}
+
+static u32 iris_vpu33_enc_line_size(struct iris_inst *inst)
+{
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 height = f->fmt.pix_mp.height;
+ u32 width = f->fmt.pix_mp.width;
+ u32 lcu_size = 16;
+
+ if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ lcu_size = 32;
+ return hfi_buffer_line_enc_vpu33(width, height, 0, num_vpp_pipes,
+ lcu_size, HFI_CODEC_ENCODE_HEVC);
+ }
+
+ return hfi_buffer_line_enc_vpu33(width, height, 0, num_vpp_pipes,
+ lcu_size, HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_dpb_enc(u32 frame_width, u32 frame_height, bool is_ten_bit)
+{
+ u32 metadata_stride, metadata_buf_height, meta_size_y, meta_size_c;
+ u32 ten_bit_ref_buf_size = 0, ref_buf_size = 0;
+ u32 size;
+
+ if (!is_ten_bit) {
+ ref_buf_size = size_enc_ref_buffer(frame_width, frame_height);
+ metadata_stride =
+ hfi_ubwc_calc_metadata_plane_stride(frame_width, 64,
+ HFI_COL_FMT_NV12C_Y_TILE_WIDTH);
+ metadata_buf_height =
+ hfi_ubwc_metadata_plane_bufheight(frame_height, 16,
+ HFI_COL_FMT_NV12C_Y_TILE_HEIGHT);
+ meta_size_y =
+ hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+ meta_size_c =
+ hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+ size = ref_buf_size + meta_size_y + meta_size_c;
+ } else {
+ ten_bit_ref_buf_size = size_enc_ten_bit_ref_buffer(frame_width, frame_height);
+ metadata_stride =
+ hfi_ubwc_calc_metadata_plane_stride(frame_width,
+ IRIS_METADATA_STRIDE_MULTIPLE,
+ HFI_COL_FMT_TP10C_Y_TILE_WIDTH);
+ metadata_buf_height =
+ hfi_ubwc_metadata_plane_bufheight(frame_height,
+ IRIS_METADATA_HEIGHT_MULTIPLE,
+ HFI_COL_FMT_TP10C_Y_TILE_HEIGHT);
+ meta_size_y =
+ hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+ meta_size_c =
+ hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+ size = ten_bit_ref_buf_size + meta_size_y + meta_size_c;
+ }
+
+ return size;
+}
+
+static u32 iris_vpu_enc_arp_size(struct iris_inst *inst)
+{
+ return HFI_BUFFER_ARP_ENC;
+}
+
+inline bool is_scaling_enabled(struct iris_inst *inst)
+{
+ return inst->crop.left != inst->compose.left ||
+ inst->crop.top != inst->compose.top ||
+ inst->crop.width != inst->compose.width ||
+ inst->crop.height != inst->compose.height;
+}
+
+static inline
+u32 hfi_buffer_vpss_enc(u32 dswidth, u32 dsheight, bool ds_enable,
+ u32 blur, bool is_ten_bit)
+{
+ if (ds_enable || blur)
+ return hfi_buffer_dpb_enc(dswidth, dsheight, is_ten_bit);
+
+ return 0;
+}
+
+static inline u32 hfi_buffer_scratch1_enc(u32 frame_width, u32 frame_height,
+ u32 lcu_size, u32 num_ref,
+ bool ten_bit, u32 num_vpp_pipes,
+ bool is_h265)
+{
+ u32 line_buf_ctrl_size, line_buf_data_size, leftline_buf_ctrl_size;
+ u32 line_buf_sde_size, sps_pps_slice_hdr, topline_buf_ctrl_size_FE;
+ u32 leftline_buf_ctrl_size_FE, line_buf_recon_pix_size;
+ u32 leftline_buf_recon_pix_size, lambda_lut_size, override_buffer_size;
+ u32 col_mv_buf_size, vpp_reg_buffer_size, ir_buffer_size;
+ u32 vpss_line_buf, leftline_buf_meta_recony, h265e_colrcbuf_size;
+ u32 h265e_framerc_bufsize, h265e_lcubitcnt_bufsize;
+ u32 h265e_lcubitmap_bufsize, se_stats_bufsize;
+ u32 bse_reg_buffer_size, bse_slice_cmd_buffer_size, slice_info_bufsize;
+ u32 line_buf_ctrl_size_buffid2, slice_cmd_buffer_size;
+ u32 width_lcu_num, height_lcu_num, width_coded, height_coded;
+ u32 frame_num_lcu, linebuf_meta_recon_uv, topline_bufsize_fe_1stg_sao;
+ u32 vpss_line_buffer_size_1;
+ u32 bit_depth, num_lcu_mb;
+
+ width_lcu_num = (frame_width + lcu_size - 1) / lcu_size;
+ height_lcu_num = (frame_height + lcu_size - 1) / lcu_size;
+ frame_num_lcu = width_lcu_num * height_lcu_num;
+ width_coded = width_lcu_num * lcu_size;
+ height_coded = height_lcu_num * lcu_size;
+ num_lcu_mb = (height_coded / lcu_size) *
+ ((width_coded + lcu_size * 8) / lcu_size);
+ slice_info_bufsize = 256 + (frame_num_lcu << 4);
+ slice_info_bufsize = ALIGN(slice_info_bufsize, 256);
+ line_buf_ctrl_size = ALIGN(width_coded, 256);
+ line_buf_ctrl_size_buffid2 = ALIGN(width_coded, 256);
+
+ bit_depth = ten_bit ? 10 : 8;
+ line_buf_data_size =
+ (((((bit_depth * width_coded + 1024) + (256 - 1)) &
+ (~(256 - 1))) * 1) +
+ (((((bit_depth * width_coded + 1024) >> 1) + (256 - 1)) &
+ (~(256 - 1))) * 2));
+
+ leftline_buf_ctrl_size = is_h265 ? ((height_coded + 32) / 32 * 4 * 16) :
+ ((height_coded + 15) / 16 * 5 * 16);
+
+ if (num_vpp_pipes > 1) {
+ leftline_buf_ctrl_size += 512;
+ leftline_buf_ctrl_size =
+ ALIGN(leftline_buf_ctrl_size, 512) * num_vpp_pipes;
+ }
+
+ leftline_buf_ctrl_size = ALIGN(leftline_buf_ctrl_size, 256);
+ leftline_buf_recon_pix_size =
+ (((ten_bit + 1) * 2 * (height_coded) + 256) +
+ (256 << (num_vpp_pipes - 1)) - 1) &
+ (~((256 << (num_vpp_pipes - 1)) - 1)) * 1;
+
+ topline_buf_ctrl_size_FE = is_h265 ? (64 * (width_coded >> 5)) :
+ (256 + 16 * (width_coded >> 4));
+ topline_buf_ctrl_size_FE = ALIGN(topline_buf_ctrl_size_FE, 256);
+ leftline_buf_ctrl_size_FE =
+ (((256 + 64 * (height_coded >> 4)) +
+ (256 << (num_vpp_pipes - 1)) - 1) &
+ (~((256 << (num_vpp_pipes - 1)) - 1)) * 1) *
+ num_vpp_pipes;
+ leftline_buf_meta_recony =
+ (256 + 64 * ((height_coded) / (8 * (ten_bit ? 4 : 8))));
+ leftline_buf_meta_recony = ALIGN(leftline_buf_meta_recony, 256);
+ leftline_buf_meta_recony = leftline_buf_meta_recony * num_vpp_pipes;
+ linebuf_meta_recon_uv =
+ (256 + 64 * ((height_coded) / (4 * (ten_bit ? 4 : 8))));
+ linebuf_meta_recon_uv = ALIGN(linebuf_meta_recon_uv, 256);
+ linebuf_meta_recon_uv = linebuf_meta_recon_uv * num_vpp_pipes;
+ line_buf_recon_pix_size = ((ten_bit ? 3 : 2) * width_coded);
+ line_buf_recon_pix_size = ALIGN(line_buf_recon_pix_size, 256);
+ slice_cmd_buffer_size = ALIGN(20480, 256);
+ sps_pps_slice_hdr = 2048 + 4096;
+ col_mv_buf_size =
+ is_h265 ? (16 * ((frame_num_lcu << 2) + 32)) :
+ (3 * 16 * (width_lcu_num * height_lcu_num + 32));
+ col_mv_buf_size = ALIGN(col_mv_buf_size, 256) * (num_ref + 1);
+ h265e_colrcbuf_size =
+ (((width_lcu_num + 7) >> 3) * 16 * 2 * height_lcu_num);
+ if (num_vpp_pipes > 1)
+ h265e_colrcbuf_size =
+ ALIGN(h265e_colrcbuf_size, 256) * num_vpp_pipes;
+
+ h265e_colrcbuf_size =
+ ALIGN(h265e_colrcbuf_size, 256) * HFI_MAX_COL_FRAME;
+ h265e_framerc_bufsize =
+ (is_h265) ?
+ (256 + 16 * (14 + (((height_coded >> 5) + 7) >> 3))) :
+ (256 + 16 * (14 + (((height_coded >> 4) + 7) >> 3)));
+ h265e_framerc_bufsize *= 6;
+ if (num_vpp_pipes > 1)
+ h265e_framerc_bufsize =
+ ALIGN(h265e_framerc_bufsize, 256) * num_vpp_pipes;
+
+ h265e_framerc_bufsize =
+ ALIGN(h265e_framerc_bufsize, 512) * HFI_MAX_COL_FRAME;
+ h265e_lcubitcnt_bufsize = 256 + 4 * frame_num_lcu;
+ h265e_lcubitcnt_bufsize = ALIGN(h265e_lcubitcnt_bufsize, 256);
+ h265e_lcubitmap_bufsize = 256 + (frame_num_lcu >> 3);
+ h265e_lcubitmap_bufsize = ALIGN(h265e_lcubitmap_bufsize, 256);
+ line_buf_sde_size = 256 + 16 * (width_coded >> 4);
+ line_buf_sde_size = ALIGN(line_buf_sde_size, 256);
+ if ((width_coded * height_coded) > (4096 * 2160))
+ se_stats_bufsize = 0;
+ else if ((width_coded * height_coded) > (1920 * 1088))
+ se_stats_bufsize = (40 * 4 * frame_num_lcu + 256 + 256);
+ else
+ se_stats_bufsize = (1024 * frame_num_lcu + 256 + 256);
+
+ se_stats_bufsize = ALIGN(se_stats_bufsize, 256) * 2;
+ bse_slice_cmd_buffer_size = (((8192 << 2) + 7) & (~7)) * 6;
+ bse_reg_buffer_size = (((512 << 3) + 7) & (~7)) * 4;
+ vpp_reg_buffer_size = (((2048 << 3) + 31) & (~31)) * 10;
+ lambda_lut_size = 256 * 11;
+ override_buffer_size = 16 * ((num_lcu_mb + 7) >> 3);
+ override_buffer_size = ALIGN(override_buffer_size, 256) * 2;
+ ir_buffer_size = (((frame_num_lcu << 1) + 7) & (~7)) * 3;
+ vpss_line_buffer_size_1 = (((8192 >> 2) << 5) * num_vpp_pipes) + 64;
+ vpss_line_buf =
+ (((((max(width_coded, height_coded) + 3) >> 2) << 5) + 256) *
+ 16) +
+ vpss_line_buffer_size_1;
+ topline_bufsize_fe_1stg_sao = 16 * (width_coded >> 5);
+ topline_bufsize_fe_1stg_sao = ALIGN(topline_bufsize_fe_1stg_sao, 256);
+
+ return line_buf_ctrl_size + line_buf_data_size +
+ line_buf_ctrl_size_buffid2 + leftline_buf_ctrl_size +
+ vpss_line_buf + col_mv_buf_size + topline_buf_ctrl_size_FE +
+ leftline_buf_ctrl_size_FE + line_buf_recon_pix_size +
+ leftline_buf_recon_pix_size + leftline_buf_meta_recony +
+ linebuf_meta_recon_uv + h265e_colrcbuf_size +
+ h265e_framerc_bufsize + h265e_lcubitcnt_bufsize +
+ h265e_lcubitmap_bufsize + line_buf_sde_size +
+ topline_bufsize_fe_1stg_sao + override_buffer_size +
+ bse_reg_buffer_size + vpp_reg_buffer_size + sps_pps_slice_hdr +
+ slice_cmd_buffer_size + bse_slice_cmd_buffer_size +
+ ir_buffer_size + slice_info_bufsize + lambda_lut_size +
+ se_stats_bufsize + 1024;
+}
+
+static u32 iris_vpu_enc_scratch1_size(struct iris_inst *inst)
+{
+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe;
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 frame_height = f->fmt.pix_mp.height;
+ u32 frame_width = f->fmt.pix_mp.width;
+ u32 num_ref = 1;
+ u32 lcu_size;
+ bool is_h265;
+
+ if (inst->codec == V4L2_PIX_FMT_H264) {
+ lcu_size = 16;
+ is_h265 = false;
+ } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
+ lcu_size = 32;
+ is_h265 = true;
+ } else {
+ return 0;
+ }
+
+ return hfi_buffer_scratch1_enc(frame_width, frame_height, lcu_size,
+ num_ref, false, num_vpp_pipes, is_h265);
+}
+
+static inline u32 ubwc_metadata_plane_stride(u32 width,
+ u32 metadata_stride_multi,
+ u32 tile_width_pels)
+{
+ return ALIGN(((width + (tile_width_pels - 1)) / tile_width_pels),
+ metadata_stride_multi);
+}
+
+static inline u32 ubwc_metadata_plane_bufheight(u32 height,
+ u32 metadata_height_multi,
+ u32 tile_height_pels)
+{
+ return ALIGN(((height + (tile_height_pels - 1)) / tile_height_pels),
+ metadata_height_multi);
+}
+
+static inline u32 ubwc_metadata_plane_buffer_size(u32 metadata_stride,
+ u32 metadata_buf_height)
+{
+ return ALIGN(metadata_stride * metadata_buf_height, SZ_4K);
+}
+
+static inline u32 hfi_buffer_scratch2_enc(u32 frame_width, u32 frame_height,
+ u32 num_ref, bool ten_bit)
+{
+ u32 aligned_width, aligned_height, chroma_height, ref_buf_height;
+ u32 metadata_stride, meta_buf_height, meta_size_y, meta_size_c;
+ u32 ref_luma_stride_bytes, ref_chroma_height_bytes;
+ u32 ref_buf_size, ref_stride;
+ u32 luma_size, chroma_size;
+ u32 size;
+
+ if (!ten_bit) {
+ aligned_height = ALIGN(frame_height, 32);
+ chroma_height = frame_height >> 1;
+ chroma_height = ALIGN(chroma_height, 32);
+ aligned_width = ALIGN(frame_width, 128);
+ metadata_stride =
+ ubwc_metadata_plane_stride(frame_width, 64, 32);
+ meta_buf_height =
+ ubwc_metadata_plane_bufheight(frame_height, 16, 8);
+ meta_size_y = ubwc_metadata_plane_buffer_size(metadata_stride,
+ meta_buf_height);
+ meta_size_c = ubwc_metadata_plane_buffer_size(metadata_stride,
+ meta_buf_height);
+ size = (aligned_height + chroma_height) * aligned_width +
+ meta_size_y + meta_size_c;
+ size = (size * (num_ref + 3)) + 4096;
+ } else {
+ ref_buf_height = (frame_height + (32 - 1)) & (~(32 - 1));
+ ref_luma_stride_bytes = ((frame_width + 192 - 1) / 192) * 192;
+ ref_stride = 4 * (ref_luma_stride_bytes / 3);
+ ref_stride = (ref_stride + (128 - 1)) & (~(128 - 1));
+ luma_size = ref_buf_height * ref_stride;
+ ref_chroma_height_bytes =
+ (((frame_height + 1) >> 1) + (32 - 1)) & (~(32 - 1));
+ chroma_size = ref_stride * ref_chroma_height_bytes;
+ luma_size = (luma_size + (SZ_4K - 1)) & (~(SZ_4K - 1));
+ chroma_size = (chroma_size + (SZ_4K - 1)) & (~(SZ_4K - 1));
+ ref_buf_size = luma_size + chroma_size;
+ metadata_stride =
+ ubwc_metadata_plane_stride(frame_width, 64, 48);
+ meta_buf_height =
+ ubwc_metadata_plane_bufheight(frame_height, 16, 4);
+ meta_size_y = ubwc_metadata_plane_buffer_size(metadata_stride,
+ meta_buf_height);
+ meta_size_c = ubwc_metadata_plane_buffer_size(metadata_stride,
+ meta_buf_height);
+ size = ref_buf_size + meta_size_y + meta_size_c;
+ size = (size * (num_ref + 3)) + 4096;
+ }
+
+ return size;
+}
+
+static u32 iris_vpu_enc_scratch2_size(struct iris_inst *inst)
+{
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 frame_width = f->fmt.pix_mp.width;
+ u32 frame_height = f->fmt.pix_mp.height;
+ u32 num_ref = 1;
+
+ return hfi_buffer_scratch2_enc(frame_width, frame_height, num_ref,
+ false);
+}
+
+static u32 iris_vpu_enc_vpss_size(struct iris_inst *inst)
+{
+ u32 ds_enable = is_scaling_enabled(inst);
+ struct v4l2_format *f = inst->fmt_dst;
+ u32 height = f->fmt.pix_mp.height;
+ u32 width = f->fmt.pix_mp.width;
+
+ return hfi_buffer_vpss_enc(width, height, ds_enable, 0, 0);
+}
+
static int output_min_count(struct iris_inst *inst)
{
int output_min_count = 4;
@@ -571,10 +1431,10 @@ struct iris_vpu_buf_type_handle {
u32 (*handle)(struct iris_inst *inst);
};
-int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
+u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
{
- const struct iris_vpu_buf_type_handle *buf_type_handle_arr;
- u32 size = 0, buf_type_handle_size, i;
+ const struct iris_vpu_buf_type_handle *buf_type_handle_arr = NULL;
+ u32 size = 0, buf_type_handle_size = 0, i;
static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle[] = {
{BUF_BIN, iris_vpu_dec_bin_size },
@@ -586,8 +1446,24 @@ int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
{BUF_SCRATCH_1, iris_vpu_dec_scratch1_size },
};
- buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle);
- buf_type_handle_arr = dec_internal_buf_type_handle;
+ static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = {
+ {BUF_BIN, iris_vpu_enc_bin_size },
+ {BUF_COMV, iris_vpu_enc_comv_size },
+ {BUF_NON_COMV, iris_vpu_enc_non_comv_size },
+ {BUF_LINE, iris_vpu_enc_line_size },
+ {BUF_ARP, iris_vpu_enc_arp_size },
+ {BUF_VPSS, iris_vpu_enc_vpss_size },
+ {BUF_SCRATCH_1, iris_vpu_enc_scratch1_size },
+ {BUF_SCRATCH_2, iris_vpu_enc_scratch2_size },
+ };
+
+ if (inst->domain == DECODER) {
+ buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle);
+ buf_type_handle_arr = dec_internal_buf_type_handle;
+ } else if (inst->domain == ENCODER) {
+ buf_type_handle_size = ARRAY_SIZE(enc_internal_buf_type_handle);
+ buf_type_handle_arr = enc_internal_buf_type_handle;
+ }
for (i = 0; i < buf_type_handle_size; i++) {
if (buf_type_handle_arr[i].type == buffer_type) {
@@ -599,6 +1475,34 @@ int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
return size;
}
+u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type)
+{
+ u32 size = 0, i;
+
+ static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = {
+ {BUF_BIN, iris_vpu_enc_bin_size },
+ {BUF_COMV, iris_vpu_enc_comv_size },
+ {BUF_NON_COMV, iris_vpu_enc_non_comv_size },
+ {BUF_LINE, iris_vpu33_enc_line_size },
+ {BUF_ARP, iris_vpu_enc_arp_size },
+ {BUF_VPSS, iris_vpu_enc_vpss_size },
+ {BUF_SCRATCH_1, iris_vpu_enc_scratch1_size },
+ {BUF_SCRATCH_2, iris_vpu_enc_scratch2_size },
+ };
+
+ if (inst->domain == DECODER)
+ return iris_vpu_buf_size(inst, buffer_type);
+
+ for (i = 0; i < ARRAY_SIZE(enc_internal_buf_type_handle); i++) {
+ if (enc_internal_buf_type_handle[i].type == buffer_type) {
+ size = enc_internal_buf_type_handle[i].handle(inst);
+ break;
+ }
+ }
+
+ return size;
+}
+
static u32 internal_buffer_count(struct iris_inst *inst,
enum iris_buffer_type buffer_type)
{
@@ -628,7 +1532,10 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type
case BUF_INPUT:
return MIN_BUFFERS;
case BUF_OUTPUT:
- return output_min_count(inst);
+ if (inst->domain == ENCODER)
+ return MIN_BUFFERS;
+ else
+ return output_min_count(inst);
case BUF_BIN:
case BUF_COMV:
case BUF_NON_COMV:
@@ -636,6 +1543,9 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type
case BUF_PERSIST:
return internal_buffer_count(inst, buffer_type);
case BUF_SCRATCH_1:
+ case BUF_SCRATCH_2:
+ case BUF_VPSS:
+ case BUF_ARP:
return 1; /* internal buffer count needed by firmware is 1 */
case BUF_DPB:
return iris_vpu_dpb_count(inst);
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
index ee95fd20b794..04f0b7400a1e 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h
@@ -41,6 +41,7 @@ struct iris_inst;
#define SIZE_SLIST_BUF_H265 (BIT(10))
#define H265_DISPLAY_BUF_SIZE (3072)
#define H265_NUM_FRM_INFO (48)
+#define SIZE_ONE_SLICE_BUF 256
#define VP9_NUM_FRAME_INFO_BUF 32
#define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4)
@@ -80,6 +81,26 @@ struct iris_inst;
#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE 384
#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640
+#define SIZE_SLICE_CMD_BUFFER (ALIGN(20480, 256))
+#define SIZE_SPS_PPS_SLICE_HDR (2048 + 4096)
+#define SIZE_BSE_SLICE_CMD_BUF ((((8192 << 2) + 7) & (~7)) * 3)
+#define SIZE_LAMBDA_LUT (256 * 11)
+
+#define HFI_COL_FMT_NV12C_Y_TILE_HEIGHT (8)
+#define HFI_COL_FMT_NV12C_Y_TILE_WIDTH (32)
+#define HFI_COL_FMT_TP10C_Y_TILE_HEIGHT (4)
+#define HFI_COL_FMT_TP10C_Y_TILE_WIDTH (48)
+
+#define IRIS_METADATA_STRIDE_MULTIPLE 64
+#define IRIS_METADATA_HEIGHT_MULTIPLE 16
+
+#define HFI_BUFFER_ARP_ENC 204800
+
+#define MAX_WIDTH 4096
+#define MAX_HEIGHT 2304
+#define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT, 16))
+#define NUM_MBS_720P (((ALIGN(1280, 16)) >> 4) * ((ALIGN(736, 16)) >> 4))
+
static inline u32 size_h264d_lb_fe_top_data(u32 frame_width)
{
return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3;
@@ -125,7 +146,8 @@ static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height)
return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 128;
}
-int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
+u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
+u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type);
int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type);
#endif
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index 268e45acaa7c..bb98950e018f 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -84,6 +84,7 @@ static void iris_vpu_interrupt_init(struct iris_core *core)
static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core)
{
u32 queue_size, value;
+ const struct vpu_ops *vpu_ops = core->iris_platform_data->vpu_ops;
/* Iris hardware requires 4K queue alignment */
queue_size = ALIGN(sizeof(struct iris_hfi_queue_table_header) +
@@ -105,6 +106,9 @@ static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core)
value = (u32)core->sfr_daddr + core->iris_platform_data->core_arch;
writel(value, core->reg_base + SFR_ADDR);
}
+
+ if (vpu_ops->program_bootup_registers)
+ vpu_ops->program_bootup_registers(core);
}
int iris_vpu_boot_firmware(struct iris_core *core)
@@ -271,7 +275,7 @@ void iris_vpu_power_off(struct iris_core *core)
disable_irq_nosync(core->irq);
}
-static int iris_vpu_power_on_controller(struct iris_core *core)
+int iris_vpu_power_on_controller(struct iris_core *core)
{
u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
int ret;
@@ -302,7 +306,7 @@ err_disable_power:
return ret;
}
-static int iris_vpu_power_on_hw(struct iris_core *core)
+int iris_vpu_power_on_hw(struct iris_core *core)
{
int ret;
@@ -337,11 +341,11 @@ int iris_vpu_power_on(struct iris_core *core)
if (ret)
goto err;
- ret = iris_vpu_power_on_controller(core);
+ ret = core->iris_platform_data->vpu_ops->power_on_controller(core);
if (ret)
goto err_unvote_icc;
- ret = iris_vpu_power_on_hw(core);
+ ret = core->iris_platform_data->vpu_ops->power_on_hw(core);
if (ret)
goto err_power_off_ctrl;
@@ -359,7 +363,7 @@ int iris_vpu_power_on(struct iris_core *core)
return 0;
err_power_off_ctrl:
- iris_vpu_power_off_controller(core);
+ core->iris_platform_data->vpu_ops->power_off_controller(core);
err_unvote_icc:
iris_unset_icc_bw(core);
err:
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
index 93b7fa27be3b..d636e287457a 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -11,10 +11,14 @@ struct iris_core;
extern const struct vpu_ops iris_vpu2_ops;
extern const struct vpu_ops iris_vpu3_ops;
extern const struct vpu_ops iris_vpu33_ops;
+extern const struct vpu_ops iris_vpu35_ops;
struct vpu_ops {
void (*power_off_hw)(struct iris_core *core);
+ int (*power_on_hw)(struct iris_core *core);
int (*power_off_controller)(struct iris_core *core);
+ int (*power_on_controller)(struct iris_core *core);
+ void (*program_bootup_registers)(struct iris_core *core);
u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
};
@@ -23,6 +27,8 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
void iris_vpu_clear_interrupt(struct iris_core *core);
int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
int iris_vpu_prepare_pc(struct iris_core *core);
+int iris_vpu_power_on_controller(struct iris_core *core);
+int iris_vpu_power_on_hw(struct iris_core *core);
int iris_vpu_power_on(struct iris_core *core);
int iris_vpu_power_off_controller(struct iris_core *core);
void iris_vpu_power_off_hw(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 4c049c694d9c..abf959b8f3a6 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -254,14 +254,19 @@ err:
static void venus_assign_register_offsets(struct venus_core *core)
{
- if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
- core->vbif_base = core->base + VBIF_BASE;
+ if (IS_IRIS2(core) || IS_IRIS2_1(core) || IS_AR50_LITE(core)) {
core->cpu_base = core->base + CPU_BASE_V6;
core->cpu_cs_base = core->base + CPU_CS_BASE_V6;
core->cpu_ic_base = core->base + CPU_IC_BASE_V6;
core->wrapper_base = core->base + WRAPPER_BASE_V6;
core->wrapper_tz_base = core->base + WRAPPER_TZ_BASE_V6;
- core->aon_base = core->base + AON_BASE_V6;
+ if (IS_AR50_LITE(core)) {
+ core->vbif_base = NULL;
+ core->aon_base = NULL;
+ } else {
+ core->vbif_base = core->base + VBIF_BASE;
+ core->aon_base = core->base + AON_BASE_V6;
+ }
} else {
core->vbif_base = core->base + VBIF_BASE;
core->cpu_base = core->base + CPU_BASE;
@@ -448,24 +453,18 @@ static int venus_probe(struct platform_device *pdev)
if (ret < 0)
goto err_runtime_disable;
- if (core->res->dec_nodename || core->res->enc_nodename) {
- ret = venus_add_dynamic_nodes(core);
- if (ret)
- goto err_runtime_disable;
- }
-
- ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
- if (ret)
- goto err_remove_dynamic_nodes;
-
ret = venus_firmware_init(core);
if (ret)
- goto err_of_depopulate;
+ goto err_runtime_disable;
ret = venus_boot(core);
if (ret)
goto err_firmware_deinit;
+ ret = venus_firmware_cfg(core);
+ if (ret)
+ goto err_venus_shutdown;
+
ret = hfi_core_resume(core, true);
if (ret)
goto err_venus_shutdown;
@@ -474,34 +473,48 @@ static int venus_probe(struct platform_device *pdev)
if (ret)
goto err_venus_shutdown;
- ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
+ ret = venus_firmware_check(core);
if (ret)
goto err_core_deinit;
+ if (core->res->dec_nodename || core->res->enc_nodename) {
+ ret = venus_add_dynamic_nodes(core);
+ if (ret)
+ goto err_core_deinit;
+ }
+
+ ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+ if (ret)
+ goto err_remove_dynamic_nodes;
+
+ ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
+ if (ret)
+ goto err_of_depopulate;
+
ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
if (ret)
- goto err_core_deinit;
+ goto err_of_depopulate;
ret = pm_runtime_put_sync(dev);
if (ret) {
pm_runtime_get_noresume(dev);
- goto err_core_deinit;
+ goto err_of_depopulate;
}
venus_dbgfs_init(core);
return 0;
+err_of_depopulate:
+ of_platform_depopulate(dev);
+err_remove_dynamic_nodes:
+ venus_remove_dynamic_nodes(core);
err_core_deinit:
hfi_core_deinit(core, false);
err_venus_shutdown:
venus_shutdown(core);
err_firmware_deinit:
venus_firmware_deinit(core);
-err_of_depopulate:
- of_platform_depopulate(dev);
-err_remove_dynamic_nodes:
- venus_remove_dynamic_nodes(core);
err_runtime_disable:
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
@@ -596,7 +609,7 @@ err_cpucfg_path:
return ret;
}
-void venus_close_common(struct venus_inst *inst)
+void venus_close_common(struct venus_inst *inst, struct file *filp)
{
/*
* Make sure we don't have IRQ/IRQ-thread currently running
@@ -607,7 +620,7 @@ void venus_close_common(struct venus_inst *inst)
v4l2_m2m_ctx_release(inst->m2m_ctx);
v4l2_m2m_release(inst->m2m_dev);
hfi_session_destroy(inst);
- v4l2_fh_del(&inst->fh);
+ v4l2_fh_del(&inst->fh, filp);
v4l2_fh_exit(&inst->fh);
v4l2_ctrl_handler_free(&inst->ctrl_handler);
@@ -1057,15 +1070,65 @@ static const struct venus_resources sc7280_res = {
.enc_nodename = "video-encoder",
};
+static const struct bw_tbl qcm2290_bw_table_dec[] = {
+ { 352800, 597000, 0, 746000, 0 }, /* 1080p@30 + 720p@30 */
+ { 244800, 413000, 0, 516000, 0 }, /* 1080p@30 */
+ { 216000, 364000, 0, 454000, 0 }, /* 720p@60 */
+ { 108000, 182000, 0, 227000, 0 }, /* 720p@30 */
+};
+
+static const struct bw_tbl qcm2290_bw_table_enc[] = {
+ { 352800, 396000, 0, 0, 0 }, /* 1080p@30 + 720p@30 */
+ { 244800, 275000, 0, 0, 0 }, /* 1080p@30 */
+ { 216000, 242000, 0, 0, 0 }, /* 720p@60 */
+ { 108000, 121000, 0, 0, 0 }, /* 720p@30 */
+};
+
+static const struct firmware_version min_fw = {
+ .major = 6, .minor = 0, .rev = 55,
+};
+
+static const struct venus_resources qcm2290_res = {
+ .bw_tbl_dec = qcm2290_bw_table_dec,
+ .bw_tbl_dec_size = ARRAY_SIZE(qcm2290_bw_table_dec),
+ .bw_tbl_enc = qcm2290_bw_table_enc,
+ .bw_tbl_enc_size = ARRAY_SIZE(qcm2290_bw_table_enc),
+ .clks = { "core", "iface", "bus", "throttle" },
+ .clks_num = 4,
+ .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
+ .vcodec_clks_num = 2,
+ .vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
+ .vcodec_pmdomains_num = 2,
+ .opp_pmdomain = (const char *[]) { "cx" },
+ .vcodec_num = 1,
+ .hfi_version = HFI_VERSION_4XX,
+ .vpu_version = VPU_VERSION_AR50_LITE,
+ .max_load = 352800,
+ .num_vpp_pipes = 1,
+ .vmem_id = VIDC_RESOURCE_NONE,
+ .vmem_size = 0,
+ .vmem_addr = 0,
+ .cp_start = 0,
+ .cp_size = 0x70800000,
+ .cp_nonpixel_start = 0x1000000,
+ .cp_nonpixel_size = 0x24800000,
+ .dma_mask = 0xe0000000 - 1,
+ .fwname = "qcom/venus-6.0/venus.mbn",
+ .dec_nodename = "video-decoder",
+ .enc_nodename = "video-encoder",
+ .min_fw = &min_fw,
+};
+
static const struct of_device_id venus_dt_match[] = {
{ .compatible = "qcom,msm8916-venus", .data = &msm8916_res, },
{ .compatible = "qcom,msm8996-venus", .data = &msm8996_res, },
{ .compatible = "qcom,msm8998-venus", .data = &msm8998_res, },
+ { .compatible = "qcom,qcm2290-venus", .data = &qcm2290_res, },
+ { .compatible = "qcom,sc7180-venus", .data = &sc7180_res, },
+ { .compatible = "qcom,sc7280-venus", .data = &sc7280_res, },
{ .compatible = "qcom,sdm660-venus", .data = &sdm660_res, },
{ .compatible = "qcom,sdm845-venus", .data = &sdm845_res, },
{ .compatible = "qcom,sdm845-venus-v2", .data = &sdm845_res_v2, },
- { .compatible = "qcom,sc7180-venus", .data = &sc7180_res, },
- { .compatible = "qcom,sc7280-venus", .data = &sc7280_res, },
{ .compatible = "qcom,sm8250-venus", .data = &sm8250_res, },
{ }
};
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 5b1ba1c69adb..7506f5d0f609 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -58,6 +58,12 @@ enum vpu_version {
VPU_VERSION_IRIS2_1,
};
+struct firmware_version {
+ u32 major;
+ u32 minor;
+ u32 rev;
+};
+
struct venus_resources {
u64 dma_mask;
const struct freq_tbl *freq_tbl;
@@ -94,6 +100,7 @@ struct venus_resources {
const char *fwname;
const char *enc_nodename;
const char *dec_nodename;
+ const struct firmware_version *min_fw;
};
enum venus_fmt {
@@ -231,11 +238,7 @@ struct venus_core {
unsigned int core0_usage_count;
unsigned int core1_usage_count;
struct dentry *root;
- struct venus_img_version {
- u32 major;
- u32 minor;
- u32 rev;
- } venus_ver;
+ struct firmware_version venus_ver;
unsigned long dump_core;
struct of_changeset *ocs;
bool hwmode_dev;
@@ -530,12 +533,17 @@ struct venus_inst {
#define IS_IRIS2(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2)
#define IS_IRIS2_1(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2_1)
+static inline bool is_lite(struct venus_core *core)
+{
+ return IS_AR50_LITE(core);
+}
+
#define ctrl_to_inst(ctrl) \
container_of((ctrl)->handler, struct venus_inst, ctrl_handler)
static inline struct venus_inst *to_inst(struct file *filp)
{
- return container_of(filp->private_data, struct venus_inst, fh);
+ return container_of(file_to_v4l2_fh(filp), struct venus_inst, fh);
}
static inline void *to_hfi_priv(struct venus_core *core)
@@ -573,5 +581,5 @@ is_fw_rev_or_older(struct venus_core *core, u32 vmajor, u32 vminor, u32 vrev)
(core)->venus_ver.rev <= vrev);
}
-void venus_close_common(struct venus_inst *inst);
+void venus_close_common(struct venus_inst *inst, struct file *filp);
#endif
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c
index 66a18830e66d..af0ac40bec9b 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -30,7 +30,7 @@ static void venus_reset_cpu(struct venus_core *core)
u32 fw_size = core->fw.mapped_mem_size;
void __iomem *wrapper_base;
- if (IS_IRIS2_1(core))
+ if (IS_IRIS2(core) || IS_IRIS2_1(core))
wrapper_base = core->wrapper_tz_base;
else
wrapper_base = core->wrapper_base;
@@ -42,7 +42,7 @@ static void venus_reset_cpu(struct venus_core *core)
writel(fw_size, wrapper_base + WRAPPER_NONPIX_START_ADDR);
writel(fw_size, wrapper_base + WRAPPER_NONPIX_END_ADDR);
- if (IS_IRIS2_1(core)) {
+ if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
/* Bring XTSS out of reset */
writel(0, wrapper_base + WRAPPER_TZ_XTSS_SW_RESET);
} else {
@@ -68,7 +68,7 @@ int venus_set_hw_state(struct venus_core *core, bool resume)
if (resume) {
venus_reset_cpu(core);
} else {
- if (IS_IRIS2_1(core))
+ if (IS_IRIS2(core) || IS_IRIS2_1(core))
writel(WRAPPER_XTSS_SW_RESET_BIT,
core->wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET);
else
@@ -136,8 +136,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname,
ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID,
mem_va, *mem_phys, *mem_size, NULL);
else
- ret = qcom_mdt_load_no_init(dev, mdt, fwname, VENUS_PAS_ID,
- mem_va, *mem_phys, *mem_size, NULL);
+ ret = qcom_mdt_load_no_init(dev, mdt, fwname, mem_va,
+ *mem_phys, *mem_size, NULL);
memunmap(mem_va);
err_release_fw:
@@ -181,7 +181,7 @@ static int venus_shutdown_no_tz(struct venus_core *core)
void __iomem *wrapper_base = core->wrapper_base;
void __iomem *wrapper_tz_base = core->wrapper_tz_base;
- if (IS_IRIS2_1(core)) {
+ if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
/* Assert the reset to XTSS */
reg = readl(wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET);
reg |= WRAPPER_XTSS_SW_RESET_BIT;
@@ -207,6 +207,16 @@ static int venus_shutdown_no_tz(struct venus_core *core)
return 0;
}
+int venus_firmware_cfg(struct venus_core *core)
+{
+ void __iomem *cpu_cs_base = core->cpu_cs_base;
+
+ if (IS_AR50_LITE(core))
+ writel(CPU_CS_VCICMD_ARP_OFF, cpu_cs_base + CPU_CS_VCICMD);
+
+ return 0;
+}
+
int venus_boot(struct venus_core *core)
{
struct device *dev = core->dev;
@@ -280,6 +290,26 @@ int venus_shutdown(struct venus_core *core)
return ret;
}
+int venus_firmware_check(struct venus_core *core)
+{
+ const struct firmware_version *req = core->res->min_fw;
+ const struct firmware_version *run = &core->venus_ver;
+
+ if (!req)
+ return 0;
+
+ if (!is_fw_rev_or_newer(core, req->major, req->minor, req->rev))
+ goto error;
+
+ return 0;
+error:
+ dev_err(core->dev, "Firmware v%d.%d.%d < v%d.%d.%d\n",
+ run->major, run->minor, run->rev,
+ req->major, req->minor, req->rev);
+
+ return -EINVAL;
+}
+
int venus_firmware_init(struct venus_core *core)
{
struct platform_device_info info;
diff --git a/drivers/media/platform/qcom/venus/firmware.h b/drivers/media/platform/qcom/venus/firmware.h
index aaccd847fa30..87e1d922b369 100644
--- a/drivers/media/platform/qcom/venus/firmware.h
+++ b/drivers/media/platform/qcom/venus/firmware.h
@@ -9,6 +9,8 @@ struct device;
int venus_firmware_init(struct venus_core *core);
void venus_firmware_deinit(struct venus_core *core);
+int venus_firmware_check(struct venus_core *core);
+int venus_firmware_cfg(struct venus_core *core);
int venus_boot(struct venus_core *core);
int venus_shutdown(struct venus_core *core);
int venus_set_hw_state(struct venus_core *core, bool suspend);
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index 8295542e1a7c..2e4363f82231 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -1715,11 +1715,17 @@ int venus_helper_session_init(struct venus_inst *inst)
if (ret)
return ret;
- inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec,
+ inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(inst->core,
+ version,
+ codec,
session_type);
- inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec,
+ inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(inst->core,
+ version,
+ codec,
session_type);
- inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(version, codec,
+ inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(inst->core,
+ version,
+ codec,
session_type);
return 0;
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c
index cf0d97cbc463..47b99d5b5af7 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -277,7 +277,12 @@ static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst,
done:
core->error = error;
- complete(&core->done);
+ /*
+ * Since core_init could ask for the firmware version to be validated,
+ * completion might have to wait until the version is retrieved.
+ */
+ if (!core->res->min_fw)
+ complete(&core->done);
}
static void
@@ -328,6 +333,10 @@ done:
if (!IS_ERR(smem_tbl_ptr) && smem_blk_sz >= SMEM_IMG_OFFSET_VENUS + VER_STR_SZ)
memcpy(smem_tbl_ptr + SMEM_IMG_OFFSET_VENUS,
img_ver, VER_STR_SZ);
+
+ /* core_init could have had to wait for a version check */
+ if (core->res->min_fw)
+ complete(&core->done);
}
static void hfi_sys_property_info(struct venus_core *core,
diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
index 1b3db2caa99f..92765f9c8873 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -282,7 +282,7 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
return ret;
if (plat->capabilities)
- caps = plat->capabilities(&entries);
+ caps = plat->capabilities(core, &entries);
if (!caps || !entries || !count)
return -EINVAL;
diff --git a/drivers/media/platform/qcom/venus/hfi_platform.c b/drivers/media/platform/qcom/venus/hfi_platform.c
index 643e5aa138f5..cde7f93045ac 100644
--- a/drivers/media/platform/qcom/venus/hfi_platform.c
+++ b/drivers/media/platform/qcom/venus/hfi_platform.c
@@ -21,7 +21,9 @@ const struct hfi_platform *hfi_platform_get(enum hfi_version version)
}
unsigned long
-hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec, u32 session_type)
+hfi_platform_get_codec_vpp_freq(struct venus_core *core,
+ enum hfi_version version, u32 codec,
+ u32 session_type)
{
const struct hfi_platform *plat;
unsigned long freq = 0;
@@ -31,13 +33,15 @@ hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec, u32 session
return 0;
if (plat->codec_vpp_freq)
- freq = plat->codec_vpp_freq(session_type, codec);
+ freq = plat->codec_vpp_freq(core, session_type, codec);
return freq;
}
unsigned long
-hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session_type)
+hfi_platform_get_codec_vsp_freq(struct venus_core *core,
+ enum hfi_version version, u32 codec,
+ u32 session_type)
{
const struct hfi_platform *plat;
unsigned long freq = 0;
@@ -47,13 +51,15 @@ hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session
return 0;
if (plat->codec_vpp_freq)
- freq = plat->codec_vsp_freq(session_type, codec);
+ freq = plat->codec_vsp_freq(core, session_type, codec);
return freq;
}
unsigned long
-hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec, u32 session_type)
+hfi_platform_get_codec_lp_freq(struct venus_core *core,
+ enum hfi_version version, u32 codec,
+ u32 session_type)
{
const struct hfi_platform *plat;
unsigned long freq = 0;
@@ -63,13 +69,14 @@ hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec, u32 session_
return 0;
if (plat->codec_lp_freq)
- freq = plat->codec_lp_freq(session_type, codec);
+ freq = plat->codec_lp_freq(core, session_type, codec);
return freq;
}
int
-hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count)
{
const struct hfi_platform *plat;
@@ -78,7 +85,7 @@ hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codec
return -EINVAL;
if (plat->codecs)
- plat->codecs(enc_codecs, dec_codecs, count);
+ plat->codecs(core, enc_codecs, dec_codecs, count);
if (IS_IRIS2_1(core)) {
*enc_codecs &= ~HFI_VIDEO_CODEC_VP8;
diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h
index ec89a90a8129..5e4f8013a6b1 100644
--- a/drivers/media/platform/qcom/venus/hfi_platform.h
+++ b/drivers/media/platform/qcom/venus/hfi_platform.h
@@ -47,11 +47,16 @@ struct hfi_platform_codec_freq_data {
};
struct hfi_platform {
- unsigned long (*codec_vpp_freq)(u32 session_type, u32 codec);
- unsigned long (*codec_vsp_freq)(u32 session_type, u32 codec);
- unsigned long (*codec_lp_freq)(u32 session_type, u32 codec);
- void (*codecs)(u32 *enc_codecs, u32 *dec_codecs, u32 *count);
- const struct hfi_plat_caps *(*capabilities)(unsigned int *entries);
+ unsigned long (*codec_vpp_freq)(struct venus_core *core,
+ u32 session_type, u32 codec);
+ unsigned long (*codec_vsp_freq)(struct venus_core *core,
+ u32 session_type, u32 codec);
+ unsigned long (*codec_lp_freq)(struct venus_core *core,
+ u32 session_type, u32 codec);
+ void (*codecs)(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count);
+ const struct hfi_plat_caps *(*capabilities)(struct venus_core *core,
+ unsigned int *entries);
int (*bufreq)(struct hfi_plat_buffers_params *params, u32 session_type,
u32 buftype, struct hfi_buffer_requirements *bufreq);
};
@@ -60,12 +65,15 @@ extern const struct hfi_platform hfi_plat_v4;
extern const struct hfi_platform hfi_plat_v6;
const struct hfi_platform *hfi_platform_get(enum hfi_version version);
-unsigned long hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec,
- u32 session_type);
-unsigned long hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec,
- u32 session_type);
-unsigned long hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec,
- u32 session_type);
-int hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codecs,
- u32 *count);
+unsigned long hfi_platform_get_codec_vpp_freq(struct venus_core *core,
+ enum hfi_version version,
+ u32 codec, u32 session_type);
+unsigned long hfi_platform_get_codec_vsp_freq(struct venus_core *core,
+ enum hfi_version version,
+ u32 codec, u32 session_type);
+unsigned long hfi_platform_get_codec_lp_freq(struct venus_core *core,
+ enum hfi_version version,
+ u32 codec, u32 session_type);
+int hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count);
#endif
diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v4.c b/drivers/media/platform/qcom/venus/hfi_platform_v4.c
index e3f0a90a567b..cda888b56b5d 100644
--- a/drivers/media/platform/qcom/venus/hfi_platform_v4.c
+++ b/drivers/media/platform/qcom/venus/hfi_platform_v4.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
+#include "core.h"
#include "hfi_platform.h"
static const struct hfi_plat_caps caps[] = {
@@ -245,20 +246,150 @@ static const struct hfi_plat_caps caps[] = {
.num_fmts = 4,
} };
-static const struct hfi_plat_caps *get_capabilities(unsigned int *entries)
+static const struct hfi_plat_caps caps_lite[] = {
{
- *entries = ARRAY_SIZE(caps);
- return caps;
+ .codec = HFI_VIDEO_CODEC_H264,
+ .domain = VIDC_SESSION_TYPE_DEC,
+ .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 1920, 1},
+ .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 1920, 1},
+ .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 8160, 1},
+ .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 60000000, 1 },
+ .caps[4] = {HFI_CAPABILITY_MBS_PER_SECOND, 64, 244800, 1},
+ .caps[5] = {HFI_CAPABILITY_FRAMERATE, 1, 120, 1},
+ .caps[6] = {HFI_CAPABILITY_MAX_VIDEOCORES, 0, 1, 1},
+ .num_caps = 7,
+ .pl[0] = { HFI_H264_PROFILE_BASELINE, HFI_H264_LEVEL_5},
+ .pl[1] = {HFI_H264_PROFILE_MAIN, HFI_H264_LEVEL_5},
+ .pl[2] = {HFI_H264_PROFILE_HIGH, HFI_H264_LEVEL_5},
+ .pl[3] = {HFI_H264_PROFILE_CONSTRAINED_BASE, HFI_H264_LEVEL_5},
+ .pl[4] = {HFI_H264_PROFILE_CONSTRAINED_HIGH, HFI_H264_LEVEL_5},
+ .num_pl = 5,
+ .fmts[0] = {HFI_BUFFER_OUTPUT, HFI_COLOR_FORMAT_NV12_UBWC},
+ .fmts[1] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV12_UBWC},
+ .fmts[2] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV12},
+ .fmts[3] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV21},
+ .num_fmts = 4,
+}, {
+ .codec = HFI_VIDEO_CODEC_HEVC,
+ .domain = VIDC_SESSION_TYPE_DEC,
+ .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 1920, 1},
+ .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 1920, 1},
+ .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 8160, 1},
+ .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 60000000, 1 },
+ .caps[4] = {HFI_CAPABILITY_MBS_PER_SECOND, 64, 244800, 1},
+ .caps[5] = {HFI_CAPABILITY_FRAMERATE, 1, 120, 1},
+ .caps[6] = {HFI_CAPABILITY_MAX_VIDEOCORES, 0, 1, 1},
+ .num_caps = 7,
+ .pl[0] = {HFI_HEVC_PROFILE_MAIN, HFI_HEVC_LEVEL_5 | HFI_HEVC_TIER_HIGH0 << 28 },
+ .pl[1] = {HFI_HEVC_PROFILE_MAIN10, HFI_HEVC_LEVEL_5 | HFI_HEVC_TIER_HIGH0 << 28 },
+ .num_pl = 2,
+ .fmts[0] = {HFI_BUFFER_OUTPUT, HFI_COLOR_FORMAT_NV12_UBWC},
+ .fmts[1] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV12_UBWC},
+ .fmts[2] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV12},
+ .fmts[3] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV21},
+ .num_fmts = 4,
+}, {
+ .codec = HFI_VIDEO_CODEC_VP9,
+ .domain = VIDC_SESSION_TYPE_DEC,
+ .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 1920, 1},
+ .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 1920, 1},
+ .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 8160, 1},
+ .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 60000000, 1 },
+ .caps[4] = {HFI_CAPABILITY_MBS_PER_SECOND, 64, 244800, 1},
+ .caps[5] = {HFI_CAPABILITY_FRAMERATE, 1, 120, 1},
+ .caps[6] = {HFI_CAPABILITY_MAX_VIDEOCORES, 0, 1, 1},
+ .num_caps = 7,
+ .pl[0] = {HFI_VP9_PROFILE_P0, 200},
+ .pl[1] = {HFI_VP9_PROFILE_P2_10B, 200},
+ .num_pl = 2,
+ .fmts[0] = {HFI_BUFFER_OUTPUT, HFI_COLOR_FORMAT_NV12_UBWC},
+ .fmts[1] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV12_UBWC},
+ .fmts[2] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV12},
+ .fmts[3] = {HFI_BUFFER_OUTPUT2, HFI_COLOR_FORMAT_NV21},
+ .num_fmts = 4,
+}, {
+ .codec = HFI_VIDEO_CODEC_H264,
+ .domain = VIDC_SESSION_TYPE_ENC,
+ .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 1920, 1},
+ .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 1920, 1},
+ .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 8160, 1},
+ .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 60000000, 1 },
+ .caps[4] = {HFI_CAPABILITY_MBS_PER_SECOND, 64, 244800, 1},
+ .caps[5] = {HFI_CAPABILITY_FRAMERATE, 1, 120, 1},
+ .caps[6] = {HFI_CAPABILITY_MAX_VIDEOCORES, 0, 1, 1},
+ .caps[7] = {HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS, 0, 6, 1},
+ .caps[8] = {HFI_CAPABILITY_ENC_LTR_COUNT, 0, 4, 1},
+ .caps[9] = {HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE, 0, 244800, 1},
+ .caps[10] = {HFI_CAPABILITY_I_FRAME_QP, 0, 51, 1},
+ .caps[11] = {HFI_CAPABILITY_P_FRAME_QP, 0, 51, 1},
+ .caps[12] = {HFI_CAPABILITY_B_FRAME_QP, 0, 51, 1},
+ .caps[13] = {HFI_CAPABILITY_SLICE_BYTE, 1, 10, 1},
+ .caps[14] = {HFI_CAPABILITY_SLICE_MB, 1, 10, 1},
+ .num_caps = 15,
+ .pl[0] = {HFI_H264_PROFILE_BASELINE, HFI_H264_LEVEL_5},
+ .pl[1] = {HFI_H264_PROFILE_MAIN, HFI_H264_LEVEL_5},
+ .pl[2] = {HFI_H264_PROFILE_HIGH, HFI_H264_LEVEL_5},
+ .pl[3] = {HFI_H264_PROFILE_CONSTRAINED_BASE, HFI_H264_LEVEL_5},
+ .pl[4] = {HFI_H264_PROFILE_CONSTRAINED_HIGH, HFI_H264_LEVEL_5},
+ .num_pl = 5,
+ .fmts[0] = {HFI_BUFFER_INPUT, HFI_COLOR_FORMAT_NV12},
+ .fmts[1] = {HFI_BUFFER_INPUT, HFI_COLOR_FORMAT_NV12_UBWC},
+ .num_fmts = 2,
+}, {
+ .codec = HFI_VIDEO_CODEC_HEVC,
+ .domain = VIDC_SESSION_TYPE_ENC,
+ .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 1920, 1},
+ .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 1920, 1},
+ .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 8160, 1},
+ .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 60000000, 1 },
+ .caps[4] = {HFI_CAPABILITY_MBS_PER_SECOND, 64, 244800, 1},
+ .caps[5] = {HFI_CAPABILITY_FRAMERATE, 1, 120, 1},
+ .caps[6] = {HFI_CAPABILITY_MAX_VIDEOCORES, 0, 1, 1},
+ .caps[7] = {HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS, 0, 6, 1},
+ .caps[8] = {HFI_CAPABILITY_ENC_LTR_COUNT, 0, 4, 1},
+ .caps[9] = {HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE, 0, 244800, 1},
+ .caps[10] = {HFI_CAPABILITY_I_FRAME_QP, 0, 51, 1},
+ .caps[11] = {HFI_CAPABILITY_P_FRAME_QP, 0, 51, 1},
+ .caps[12] = {HFI_CAPABILITY_B_FRAME_QP, 0, 51, 1},
+ .caps[13] = {HFI_CAPABILITY_SLICE_BYTE, 1, 10, 1},
+ .caps[14] = {HFI_CAPABILITY_SLICE_MB, 1, 10, 1},
+ .num_caps = 15,
+ .pl[0] = {HFI_HEVC_PROFILE_MAIN, HFI_HEVC_LEVEL_5 | HFI_HEVC_TIER_HIGH0},
+ .pl[1] = {HFI_HEVC_PROFILE_MAIN10, HFI_HEVC_LEVEL_5 | HFI_HEVC_TIER_HIGH0},
+ .num_pl = 2,
+ .fmts[0] = {HFI_BUFFER_INPUT, HFI_COLOR_FORMAT_NV12},
+ .fmts[1] = {HFI_BUFFER_INPUT, HFI_COLOR_FORMAT_NV12_UBWC},
+ .num_fmts = 2,
+} };
+
+static const struct hfi_plat_caps *get_capabilities(struct venus_core *core,
+ unsigned int *entries)
+{
+ *entries = is_lite(core) ? ARRAY_SIZE(caps_lite) : ARRAY_SIZE(caps);
+
+ return is_lite(core) ? caps_lite : caps;
}
-static void get_codecs(u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+static void get_codecs(struct venus_core *core,
+ u32 *enc_codecs, u32 *dec_codecs, u32 *count)
{
- *enc_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
- HFI_VIDEO_CODEC_VP8;
- *dec_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
- HFI_VIDEO_CODEC_VP8 | HFI_VIDEO_CODEC_VP9 |
- HFI_VIDEO_CODEC_MPEG2;
- *count = 8;
+ const struct hfi_plat_caps *caps;
+ unsigned int num;
+ size_t i;
+
+ *enc_codecs = 0;
+ *dec_codecs = 0;
+
+ caps = get_capabilities(core, &num);
+
+ for (i = 0; i < num; caps++, i++) {
+ if (caps->domain == VIDC_SESSION_TYPE_ENC)
+ *enc_codecs |= caps->codec;
+ else
+ *dec_codecs |= caps->codec;
+ }
+
+ *count = num;
}
static const struct hfi_platform_codec_freq_data codec_freq_data[] = {
@@ -272,13 +403,29 @@ static const struct hfi_platform_codec_freq_data codec_freq_data[] = {
{ V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10, 200 },
};
+static const struct hfi_platform_codec_freq_data codec_freq_data_lite[] = {
+ { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 440, 0, 440 },
+ { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 440, 0, 440 },
+ { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 440, 0, 440 },
+ { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 0, 675 },
+ { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 0, 675 },
+};
+
static const struct hfi_platform_codec_freq_data *
-get_codec_freq_data(u32 session_type, u32 pixfmt)
+get_codec_freq_data(struct venus_core *core, u32 session_type, u32 pixfmt)
{
- const struct hfi_platform_codec_freq_data *data = codec_freq_data;
- unsigned int i, data_size = ARRAY_SIZE(codec_freq_data);
+ const struct hfi_platform_codec_freq_data *data;
+ unsigned int i, data_size;
const struct hfi_platform_codec_freq_data *found = NULL;
+ if (is_lite(core)) {
+ data = codec_freq_data_lite;
+ data_size = ARRAY_SIZE(codec_freq_data_lite);
+ } else {
+ data = codec_freq_data;
+ data_size = ARRAY_SIZE(codec_freq_data);
+ }
+
for (i = 0; i < data_size; i++) {
if (data[i].pixfmt == pixfmt && data[i].session_type == session_type) {
found = &data[i];
@@ -289,33 +436,36 @@ get_codec_freq_data(u32 session_type, u32 pixfmt)
return found;
}
-static unsigned long codec_vpp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vpp_freq(struct venus_core *core,
+ u32 session_type, u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vpp_freq;
return 0;
}
-static unsigned long codec_vsp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vsp_freq(struct venus_core *core,
+ u32 session_type, u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vsp_freq;
return 0;
}
-static unsigned long codec_lp_freq(u32 session_type, u32 codec)
+static unsigned long codec_lp_freq(struct venus_core *core,
+ u32 session_type, u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->low_power_freq;
diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v6.c b/drivers/media/platform/qcom/venus/hfi_platform_v6.c
index 4e8af645f8b9..d8568c08cc36 100644
--- a/drivers/media/platform/qcom/venus/hfi_platform_v6.c
+++ b/drivers/media/platform/qcom/venus/hfi_platform_v6.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
+#include "core.h"
#include "hfi_platform.h"
static const struct hfi_plat_caps caps[] = {
@@ -245,14 +246,22 @@ static const struct hfi_plat_caps caps[] = {
.num_fmts = 4,
} };
-static const struct hfi_plat_caps *get_capabilities(unsigned int *entries)
+static const struct hfi_plat_caps *get_capabilities(struct venus_core *core,
+ unsigned int *entries)
{
+ if (is_lite(core))
+ return NULL;
+
*entries = ARRAY_SIZE(caps);
return caps;
}
-static void get_codecs(u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+static void get_codecs(struct venus_core *core, u32 *enc_codecs,
+ u32 *dec_codecs, u32 *count)
{
+ if (is_lite(core))
+ return;
+
*enc_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
HFI_VIDEO_CODEC_VP8;
*dec_codecs = HFI_VIDEO_CODEC_H264 | HFI_VIDEO_CODEC_HEVC |
@@ -273,12 +282,15 @@ static const struct hfi_platform_codec_freq_data codec_freq_data[] = {
};
static const struct hfi_platform_codec_freq_data *
-get_codec_freq_data(u32 session_type, u32 pixfmt)
+get_codec_freq_data(struct venus_core *core, u32 session_type, u32 pixfmt)
{
const struct hfi_platform_codec_freq_data *data = codec_freq_data;
unsigned int i, data_size = ARRAY_SIZE(codec_freq_data);
const struct hfi_platform_codec_freq_data *found = NULL;
+ if (is_lite(core))
+ return NULL;
+
for (i = 0; i < data_size; i++) {
if (data[i].pixfmt == pixfmt && data[i].session_type == session_type) {
found = &data[i];
@@ -289,33 +301,36 @@ get_codec_freq_data(u32 session_type, u32 pixfmt)
return found;
}
-static unsigned long codec_vpp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vpp_freq(struct venus_core *core, u32 session_type,
+ u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vpp_freq;
return 0;
}
-static unsigned long codec_vsp_freq(u32 session_type, u32 codec)
+static unsigned long codec_vsp_freq(struct venus_core *core, u32 session_type,
+ u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->vsp_freq;
return 0;
}
-static unsigned long codec_lp_freq(u32 session_type, u32 codec)
+static unsigned long codec_lp_freq(struct venus_core *core, u32 session_type,
+ u32 codec)
{
const struct hfi_platform_codec_freq_data *data;
- data = get_codec_freq_data(session_type, codec);
+ data = get_codec_freq_data(core, session_type, codec);
if (data)
return data->low_power_freq;
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index cec7f5964d3d..d3da35f67fd5 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -380,7 +380,7 @@ static void venus_soft_int(struct venus_hfi_device *hdev)
void __iomem *cpu_ic_base = hdev->core->cpu_ic_base;
u32 clear_bit;
- if (IS_V6(hdev->core))
+ if (IS_V6(hdev->core) || (IS_V4(hdev->core) && is_lite(hdev->core)))
clear_bit = BIT(CPU_IC_SOFTINT_H2A_SHIFT_V6);
else
clear_bit = BIT(CPU_IC_SOFTINT_H2A_SHIFT);
@@ -501,9 +501,11 @@ static int venus_boot_core(struct venus_hfi_device *hdev)
if (count >= max_tries)
ret = -ETIMEDOUT;
- if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) {
+ if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core)) {
writel(0x1, cpu_cs_base + CPU_CS_H2XSOFTINTEN_V6);
- writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
+
+ if (!IS_AR50_LITE(hdev->core))
+ writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
}
return ret;
@@ -569,6 +571,9 @@ static int venus_halt_axi(struct venus_hfi_device *hdev)
u32 mask_val;
int ret;
+ if (IS_AR50_LITE(hdev->core))
+ return 0;
+
if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) {
writel(0x3, cpu_cs_base + CPU_CS_X2RPMH_V6);
@@ -1138,7 +1143,13 @@ static irqreturn_t venus_isr(struct venus_core *core)
wrapper_base = hdev->core->wrapper_base;
status = readl(wrapper_base + WRAPPER_INTR_STATUS);
- if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
+
+ if (IS_AR50_LITE(core)) {
+ if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
+ status & WRAPPER_INTR_STATUS_A2HWD_MASK_V4_LITE ||
+ status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
+ hdev->irq_status = status;
+ } else if (IS_IRIS2(core) || IS_IRIS2_1(core)) {
if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
status & WRAPPER_INTR_STATUS_A2HWD_MASK_V6 ||
status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
@@ -1150,7 +1161,7 @@ static irqreturn_t venus_isr(struct venus_core *core)
hdev->irq_status = status;
}
writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR);
- if (!(IS_IRIS2(core) || IS_IRIS2_1(core)))
+ if (!(IS_IRIS2(core) || IS_IRIS2_1(core) || IS_AR50_LITE(core)))
writel(status, wrapper_base + WRAPPER_INTR_CLEAR);
return IRQ_WAKE_THREAD;
@@ -1535,7 +1546,7 @@ static bool venus_cpu_and_video_core_idle(struct venus_hfi_device *hdev)
void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status, cpu_status;
- if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core))
+ if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core))
cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6);
else
cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
@@ -1555,7 +1566,7 @@ static bool venus_cpu_idle_and_pc_ready(struct venus_hfi_device *hdev)
void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status, cpu_status;
- if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core))
+ if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core))
cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6);
else
cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
diff --git a/drivers/media/platform/qcom/venus/hfi_venus_io.h b/drivers/media/platform/qcom/venus/hfi_venus_io.h
index 9735a246ce36..f2c3064c44ae 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus_io.h
+++ b/drivers/media/platform/qcom/venus/hfi_venus_io.h
@@ -51,6 +51,9 @@
/* Venus cpu */
#define CPU_CS_SCIACMDARG3 0x58
+#define CPU_CS_VCICMD 0x20
+#define CPU_CS_VCICMD_ARP_OFF BIT(0)
+
#define SFR_ADDR 0x5c
#define MMAP_ADDR 0x60
#define UC_REGION_ADDR 0x64
@@ -100,6 +103,7 @@
#define WRAPPER_INTR_MASK_A2HCPU_MASK 0x4
#define WRAPPER_INTR_MASK_A2HCPU_SHIFT 0x2
+#define WRAPPER_INTR_STATUS_A2HWD_MASK_V4_LITE 0x10
#define WRAPPER_INTR_STATUS_A2HWD_MASK_V6 0x8
#define WRAPPER_INTR_MASK_A2HWD_BASK_V6 0x8
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
index e32f8862a9f9..f0269524ac70 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -40,6 +40,8 @@ static int core_clks_get(struct venus_core *core)
static int core_clks_enable(struct venus_core *core)
{
+ const struct freq_tbl *freq_tbl = core->res->freq_tbl;
+ unsigned int freq_tbl_size = core->res->freq_tbl_size;
const struct venus_resources *res = core->res;
struct device *dev = core->dev;
unsigned long freq = 0;
@@ -48,11 +50,16 @@ static int core_clks_enable(struct venus_core *core)
int ret;
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
- if (!IS_ERR(opp))
+ if (IS_ERR(opp)) {
+ if (!freq_tbl)
+ return -ENODEV;
+ freq = freq_tbl[freq_tbl_size - 1].freq;
+ } else {
dev_pm_opp_put(opp);
+ }
for (i = 0; i < res->clks_num; i++) {
- if (IS_V6(core)) {
+ if (IS_V6(core) || (IS_V4(core) && is_lite(core))) {
ret = clk_set_rate(core->clks[i], freq);
if (ret)
goto err;
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 29b0d6a5303d..55c27345b7d8 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1732,9 +1732,8 @@ static int vdec_open(struct file *file)
v4l2_fh_init(&inst->fh, core->vdev_dec);
inst->fh.ctrl_handler = &inst->ctrl_handler;
- v4l2_fh_add(&inst->fh);
+ v4l2_fh_add(&inst->fh, file);
inst->fh.m2m_ctx = inst->m2m_ctx;
- file->private_data = &inst->fh;
return 0;
@@ -1755,7 +1754,7 @@ static int vdec_close(struct file *file)
vdec_pm_get(inst);
cancel_work_sync(&inst->delayed_process_work);
- venus_close_common(inst);
+ venus_close_common(inst, file);
ida_destroy(&inst->dpb_ids);
vdec_pm_put(inst, false);
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index c0a0ccdded80..fba07557a399 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1515,9 +1515,8 @@ static int venc_open(struct file *file)
v4l2_fh_init(&inst->fh, core->vdev_enc);
inst->fh.ctrl_handler = &inst->ctrl_handler;
- v4l2_fh_add(&inst->fh);
+ v4l2_fh_add(&inst->fh, file);
inst->fh.m2m_ctx = inst->m2m_ctx;
- file->private_data = &inst->fh;
return 0;
@@ -1537,7 +1536,7 @@ static int venc_close(struct file *file)
struct venus_inst *inst = to_inst(file);
venc_pm_get(inst);
- venus_close_common(inst);
+ venus_close_common(inst, file);
inst->enc_state = VENUS_ENC_STATE_DEINIT;
venc_pm_put(inst, false);
diff --git a/drivers/media/platform/raspberrypi/rp1-cfe/csi2.c b/drivers/media/platform/raspberrypi/rp1-cfe/csi2.c
index 35c2ab1e2cd4..2c5b4d24b4e6 100644
--- a/drivers/media/platform/raspberrypi/rp1-cfe/csi2.c
+++ b/drivers/media/platform/raspberrypi/rp1-cfe/csi2.c
@@ -525,7 +525,7 @@ static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
int csi2_init(struct csi2_device *csi2, struct dentry *debugfs)
{
- unsigned int ret;
+ int ret;
spin_lock_init(&csi2->errors_lock);
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
index f73729f59671..100105b620e3 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
@@ -849,7 +849,7 @@ static int rvin_isp_init(struct rvin_dev *vin)
* Suspend / Resume
*/
-static int __maybe_unused rvin_suspend(struct device *dev)
+static int rvin_suspend(struct device *dev)
{
struct rvin_dev *vin = dev_get_drvdata(dev);
@@ -861,7 +861,7 @@ static int __maybe_unused rvin_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused rvin_resume(struct device *dev)
+static int rvin_resume(struct device *dev)
{
struct rvin_dev *vin = dev_get_drvdata(dev);
@@ -1276,13 +1276,13 @@ static void rcar_vin_remove(struct platform_device *pdev)
rvin_dma_unregister(vin);
}
-static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
static struct platform_driver rcar_vin_driver = {
.driver = {
.name = "rcar-vin",
.suppress_bind_attrs = true,
- .pm = &rvin_pm_ops,
+ .pm = pm_sleep_ptr(&rvin_pm_ops),
.of_match_table = rvin_of_id_table,
},
.probe = rcar_vin_probe,
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c b/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
index 62eddf3a35fc..079dbaf016c2 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
@@ -588,8 +588,6 @@ static int rvin_open(struct file *file)
if (ret)
goto err_pm;
- file->private_data = vin;
-
ret = v4l2_fh_open(file);
if (ret)
goto err_unlock;
diff --git a/drivers/media/platform/renesas/rcar_drif.c b/drivers/media/platform/renesas/rcar_drif.c
index fc8b6bbef793..11bf47fb8266 100644
--- a/drivers/media/platform/renesas/rcar_drif.c
+++ b/drivers/media/platform/renesas/rcar_drif.c
@@ -1446,18 +1446,18 @@ static void rcar_drif_remove(struct platform_device *pdev)
}
/* FIXME: Implement suspend/resume support */
-static int __maybe_unused rcar_drif_suspend(struct device *dev)
+static int rcar_drif_suspend(struct device *dev)
{
return 0;
}
-static int __maybe_unused rcar_drif_resume(struct device *dev)
+static int rcar_drif_resume(struct device *dev)
{
return 0;
}
-static SIMPLE_DEV_PM_OPS(rcar_drif_pm_ops, rcar_drif_suspend,
- rcar_drif_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(rcar_drif_pm_ops, rcar_drif_suspend,
+ rcar_drif_resume);
static const struct of_device_id rcar_drif_of_table[] = {
{ .compatible = "renesas,rcar-gen3-drif" },
@@ -1470,8 +1470,8 @@ static struct platform_driver rcar_drif_driver = {
.driver = {
.name = RCAR_DRIF_DRV_NAME,
.of_match_table = rcar_drif_of_table,
- .pm = &rcar_drif_pm_ops,
- },
+ .pm = pm_sleep_ptr(&rcar_drif_pm_ops),
+ },
.probe = rcar_drif_probe,
.remove = rcar_drif_remove,
};
diff --git a/drivers/media/platform/renesas/rcar_fdp1.c b/drivers/media/platform/renesas/rcar_fdp1.c
index 5d453a7a8988..e615c56083f1 100644
--- a/drivers/media/platform/renesas/rcar_fdp1.c
+++ b/drivers/media/platform/renesas/rcar_fdp1.c
@@ -630,9 +630,9 @@ struct fdp1_ctx {
struct fdp1_field_buffer *previous;
};
-static inline struct fdp1_ctx *fh_to_ctx(struct v4l2_fh *fh)
+static inline struct fdp1_ctx *file_to_ctx(struct file *filp)
{
- return container_of(fh, struct fdp1_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct fdp1_ctx, fh);
}
static struct fdp1_q_data *get_q_data(struct fdp1_ctx *ctx,
@@ -1406,8 +1406,8 @@ static int fdp1_enum_fmt_vid_out(struct file *file, void *priv,
static int fdp1_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
+ struct fdp1_ctx *ctx = file_to_ctx(file);
struct fdp1_q_data *q_data;
- struct fdp1_ctx *ctx = fh_to_ctx(priv);
if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
return -EINVAL;
@@ -1584,7 +1584,7 @@ static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx,
static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct fdp1_ctx *ctx = fh_to_ctx(priv);
+ struct fdp1_ctx *ctx = file_to_ctx(file);
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp);
@@ -1655,7 +1655,7 @@ static void fdp1_set_format(struct fdp1_ctx *ctx,
static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct fdp1_ctx *ctx = fh_to_ctx(priv);
+ struct fdp1_ctx *ctx = file_to_ctx(file);
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
struct vb2_queue *vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
@@ -2088,7 +2088,6 @@ static int fdp1_open(struct file *file)
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->fdp1 = fdp1;
/* Initialise Queues */
@@ -2137,7 +2136,7 @@ static int fdp1_open(struct file *file)
if (ret < 0)
goto error_pm;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n",
ctx, ctx->fh.m2m_ctx);
@@ -2158,11 +2157,11 @@ done:
static int fdp1_release(struct file *file)
{
struct fdp1_dev *fdp1 = video_drvdata(file);
- struct fdp1_ctx *ctx = fh_to_ctx(file->private_data);
+ struct fdp1_ctx *ctx = file_to_ctx(file);
dprintk(fdp1, "Releasing instance %p\n", ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
mutex_lock(&fdp1->dev_mutex);
@@ -2409,7 +2408,7 @@ static void fdp1_remove(struct platform_device *pdev)
rcar_fcp_put(fdp1->fcp);
}
-static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev)
+static int fdp1_pm_runtime_suspend(struct device *dev)
{
struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
@@ -2418,7 +2417,7 @@ static int __maybe_unused fdp1_pm_runtime_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev)
+static int fdp1_pm_runtime_resume(struct device *dev)
{
struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
@@ -2429,9 +2428,7 @@ static int __maybe_unused fdp1_pm_runtime_resume(struct device *dev)
}
static const struct dev_pm_ops fdp1_pm_ops = {
- SET_RUNTIME_PM_OPS(fdp1_pm_runtime_suspend,
- fdp1_pm_runtime_resume,
- NULL)
+ RUNTIME_PM_OPS(fdp1_pm_runtime_suspend, fdp1_pm_runtime_resume, NULL)
};
static const struct of_device_id fdp1_dt_ids[] = {
@@ -2446,7 +2443,7 @@ static struct platform_driver fdp1_pdrv = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = fdp1_dt_ids,
- .pm = &fdp1_pm_ops,
+ .pm = pm_ptr(&fdp1_pm_ops),
},
};
diff --git a/drivers/media/platform/renesas/rcar_jpu.c b/drivers/media/platform/renesas/rcar_jpu.c
index 81038df71bb5..46ea259a2bb9 100644
--- a/drivers/media/platform/renesas/rcar_jpu.c
+++ b/drivers/media/platform/renesas/rcar_jpu.c
@@ -480,9 +480,9 @@ static struct jpu_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
return container_of(c->handler, struct jpu_ctx, ctrl_handler);
}
-static struct jpu_ctx *fh_to_ctx(struct v4l2_fh *fh)
+static struct jpu_ctx *file_to_ctx(struct file *filp)
{
- return container_of(fh, struct jpu_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct jpu_ctx, fh);
}
static void jpu_set_tbl(struct jpu *jpu, u32 reg, const unsigned int *tbl,
@@ -656,7 +656,7 @@ static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width,
static int jpu_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct jpu_ctx *ctx = fh_to_ctx(priv);
+ struct jpu_ctx *ctx = file_to_ctx(file);
if (ctx->encoder)
strscpy(cap->card, DRV_NAME " encoder", sizeof(cap->card));
@@ -714,7 +714,7 @@ static int jpu_enum_fmt(struct v4l2_fmtdesc *f, u32 type)
static int jpu_enum_fmt_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct jpu_ctx *ctx = fh_to_ctx(priv);
+ struct jpu_ctx *ctx = file_to_ctx(file);
return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_CAPTURE :
JPU_DEC_CAPTURE);
@@ -723,7 +723,7 @@ static int jpu_enum_fmt_cap(struct file *file, void *priv,
static int jpu_enum_fmt_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct jpu_ctx *ctx = fh_to_ctx(priv);
+ struct jpu_ctx *ctx = file_to_ctx(file);
return jpu_enum_fmt(f, ctx->encoder ? JPU_ENC_OUTPUT : JPU_DEC_OUTPUT);
}
@@ -823,7 +823,7 @@ static int __jpu_try_fmt(struct jpu_ctx *ctx, struct jpu_fmt **fmtinfo,
static int jpu_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct jpu_ctx *ctx = fh_to_ctx(priv);
+ struct jpu_ctx *ctx = file_to_ctx(file);
if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
return -EINVAL;
@@ -834,7 +834,7 @@ static int jpu_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int jpu_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct vb2_queue *vq;
- struct jpu_ctx *ctx = fh_to_ctx(priv);
+ struct jpu_ctx *ctx = file_to_ctx(file);
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
struct jpu_fmt *fmtinfo;
struct jpu_q_data *q_data;
@@ -863,8 +863,8 @@ static int jpu_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int jpu_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
+ struct jpu_ctx *ctx = file_to_ctx(file);
struct jpu_q_data *q_data;
- struct jpu_ctx *ctx = fh_to_ctx(priv);
if (!v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type))
return -EINVAL;
@@ -897,8 +897,8 @@ static const struct v4l2_ctrl_ops jpu_ctrl_ops = {
static int jpu_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
{
- struct jpu_ctx *ctx = fh_to_ctx(priv);
struct jpu_q_data *src_q_data, *dst_q_data, *orig, adj, *ref;
+ struct jpu_ctx *ctx = file_to_ctx(file);
enum v4l2_buf_type adj_type;
src_q_data = jpu_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
@@ -1226,8 +1226,7 @@ static int jpu_open(struct file *file)
v4l2_fh_init(&ctx->fh, vfd);
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->jpu = jpu;
ctx->encoder = vfd == &jpu->vfd_encoder;
@@ -1272,7 +1271,7 @@ jpu_reset_rollback:
device_prepare_rollback:
mutex_unlock(&jpu->mutex);
v4l_prepare_rollback:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
return ret;
@@ -1280,12 +1279,12 @@ v4l_prepare_rollback:
static int jpu_release(struct file *file)
{
+ struct jpu_ctx *ctx = file_to_ctx(file);
struct jpu *jpu = video_drvdata(file);
- struct jpu_ctx *ctx = fh_to_ctx(file->private_data);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
@@ -1745,6 +1744,6 @@ static struct platform_driver jpu_driver = {
module_platform_driver(jpu_driver);
MODULE_ALIAS("platform:" DRV_NAME);
-MODULE_AUTHOR("Mikhail Ulianov <mikhail.ulyanov@cogentembedded.com>");
+MODULE_AUTHOR("Mikhail Ulianov");
MODULE_DESCRIPTION("Renesas R-Car JPEG processing unit driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/renesas/renesas-ceu.c b/drivers/media/platform/renesas/renesas-ceu.c
index 8cceafe491b1..deed49d0fb10 100644
--- a/drivers/media/platform/renesas/renesas-ceu.c
+++ b/drivers/media/platform/renesas/renesas-ceu.c
@@ -1048,7 +1048,7 @@ static int ceu_init_mbus_fmt(struct ceu_device *ceudev)
/*
* ceu_runtime_resume() - soft-reset the interface and turn sensor power on.
*/
-static int __maybe_unused ceu_runtime_resume(struct device *dev)
+static int ceu_runtime_resume(struct device *dev)
{
struct ceu_device *ceudev = dev_get_drvdata(dev);
struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd;
@@ -1064,7 +1064,7 @@ static int __maybe_unused ceu_runtime_resume(struct device *dev)
* ceu_runtime_suspend() - disable capture and interrupts and soft-reset.
* Turn sensor power off.
*/
-static int __maybe_unused ceu_runtime_suspend(struct device *dev)
+static int ceu_runtime_suspend(struct device *dev)
{
struct ceu_device *ceudev = dev_get_drvdata(dev);
struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd;
@@ -1709,15 +1709,13 @@ static void ceu_remove(struct platform_device *pdev)
}
static const struct dev_pm_ops ceu_pm_ops = {
- SET_RUNTIME_PM_OPS(ceu_runtime_suspend,
- ceu_runtime_resume,
- NULL)
+ RUNTIME_PM_OPS(ceu_runtime_suspend, ceu_runtime_resume, NULL)
};
static struct platform_driver ceu_driver = {
.driver = {
.name = DRIVER_NAME,
- .pm = &ceu_pm_ops,
+ .pm = pm_ptr(&ceu_pm_ops),
.of_match_table = of_match_ptr(ceu_of_match),
},
.probe = ceu_probe,
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
index 806acc8f9728..3c5fbd857371 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c
@@ -367,7 +367,6 @@ static const struct rzg2l_cru_info rzg3e_cru_info = {
.enable_interrupts = rzg3e_cru_enable_interrupts,
.disable_interrupts = rzg3e_cru_disable_interrupts,
.fifo_empty = rzg3e_fifo_empty,
- .csi_setup = rzg3e_cru_csi2_setup,
};
static const u16 rzg2l_cru_regs[] = {
@@ -412,7 +411,6 @@ static const struct rzg2l_cru_info rzg2l_cru_info = {
.enable_interrupts = rzg2l_cru_enable_interrupts,
.disable_interrupts = rzg2l_cru_disable_interrupts,
.fifo_empty = rzg2l_fifo_empty,
- .csi_setup = rzg2l_cru_csi2_setup,
};
static const struct of_device_id rzg2l_cru_of_id_table[] = {
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
index be95b41c37df..3a200db15730 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
@@ -92,9 +92,6 @@ struct rzg2l_cru_info {
void (*enable_interrupts)(struct rzg2l_cru_dev *cru);
void (*disable_interrupts)(struct rzg2l_cru_dev *cru);
bool (*fifo_empty)(struct rzg2l_cru_dev *cru);
- void (*csi_setup)(struct rzg2l_cru_dev *cru,
- const struct rzg2l_cru_ip_format *ip_fmt,
- u8 csi_vc);
};
/**
@@ -204,11 +201,5 @@ void rzg3e_cru_disable_interrupts(struct rzg2l_cru_dev *cru);
bool rzg2l_fifo_empty(struct rzg2l_cru_dev *cru);
bool rzg3e_fifo_empty(struct rzg2l_cru_dev *cru);
-void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru,
- const struct rzg2l_cru_ip_format *ip_fmt,
- u8 csi_vc);
-void rzg3e_cru_csi2_setup(struct rzg2l_cru_dev *cru,
- const struct rzg2l_cru_ip_format *ip_fmt,
- u8 csi_vc);
#endif
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index a8817a7066b2..162e2ace6931 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -257,30 +257,18 @@ static void rzg2l_cru_initialize_axi(struct rzg2l_cru_dev *cru)
rzg2l_cru_write(cru, AMnAXIATTR, amnaxiattr);
}
-void rzg3e_cru_csi2_setup(struct rzg2l_cru_dev *cru,
- const struct rzg2l_cru_ip_format *ip_fmt,
- u8 csi_vc)
+static void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru,
+ const struct rzg2l_cru_ip_format *ip_fmt,
+ u8 csi_vc)
{
const struct rzg2l_cru_info *info = cru->info;
u32 icnmc = ICnMC_INF(ip_fmt->datatype);
- icnmc |= rzg2l_cru_read(cru, info->image_conv) & ~ICnMC_INF_MASK;
-
- /* Set virtual channel CSI2 */
- icnmc |= ICnMC_VCSEL(csi_vc);
-
- rzg2l_cru_write(cru, ICnSVCNUM, csi_vc);
- rzg2l_cru_write(cru, ICnSVC, ICnSVC_SVC0(0) | ICnSVC_SVC1(1) |
- ICnSVC_SVC2(2) | ICnSVC_SVC3(3));
- rzg2l_cru_write(cru, info->image_conv, icnmc);
-}
-
-void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru,
- const struct rzg2l_cru_ip_format *ip_fmt,
- u8 csi_vc)
-{
- const struct rzg2l_cru_info *info = cru->info;
- u32 icnmc = ICnMC_INF(ip_fmt->datatype);
+ if (cru->info->regs[ICnSVC]) {
+ rzg2l_cru_write(cru, ICnSVCNUM, csi_vc);
+ rzg2l_cru_write(cru, ICnSVC, ICnSVC_SVC0(0) | ICnSVC_SVC1(1) |
+ ICnSVC_SVC2(2) | ICnSVC_SVC3(3));
+ }
icnmc |= rzg2l_cru_read(cru, info->image_conv) & ~ICnMC_INF_MASK;
@@ -299,7 +287,7 @@ static int rzg2l_cru_initialize_image_conv(struct rzg2l_cru_dev *cru,
const struct rzg2l_cru_ip_format *cru_ip_fmt;
cru_ip_fmt = rzg2l_cru_ip_code_to_fmt(ip_sd_fmt->code);
- info->csi_setup(cru, cru_ip_fmt, csi_vc);
+ rzg2l_cru_csi2_setup(cru, cru_ip_fmt, csi_vc);
/* Output format */
cru_video_fmt = rzg2l_cru_ip_format_to_fmt(cru->format.pixelformat);
@@ -1078,7 +1066,6 @@ static int rzg2l_cru_open(struct file *file)
if (ret)
return ret;
- file->private_data = cru;
ret = v4l2_fh_open(file);
if (ret)
goto err_unlock;
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_drv.c b/drivers/media/platform/renesas/vsp1/vsp1_drv.c
index b8d06e88c475..6c64657fc4f3 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_drv.c
@@ -618,7 +618,7 @@ void vsp1_device_put(struct vsp1_device *vsp1)
* Power Management
*/
-static int __maybe_unused vsp1_pm_suspend(struct device *dev)
+static int vsp1_pm_suspend(struct device *dev)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
@@ -634,7 +634,7 @@ static int __maybe_unused vsp1_pm_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused vsp1_pm_resume(struct device *dev)
+static int vsp1_pm_resume(struct device *dev)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
@@ -650,7 +650,7 @@ static int __maybe_unused vsp1_pm_resume(struct device *dev)
return 0;
}
-static int __maybe_unused vsp1_pm_runtime_suspend(struct device *dev)
+static int vsp1_pm_runtime_suspend(struct device *dev)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
@@ -660,7 +660,7 @@ static int __maybe_unused vsp1_pm_runtime_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused vsp1_pm_runtime_resume(struct device *dev)
+static int vsp1_pm_runtime_resume(struct device *dev)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
int ret;
@@ -693,8 +693,8 @@ done:
}
static const struct dev_pm_ops vsp1_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume)
- SET_RUNTIME_PM_OPS(vsp1_pm_runtime_suspend, vsp1_pm_runtime_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume)
+ RUNTIME_PM_OPS(vsp1_pm_runtime_suspend, vsp1_pm_runtime_resume, NULL)
};
/* -----------------------------------------------------------------------------
@@ -1042,7 +1042,7 @@ static struct platform_driver vsp1_platform_driver = {
.remove = vsp1_remove,
.driver = {
.name = "vsp1",
- .pm = &vsp1_pm_ops,
+ .pm = pm_ptr(&vsp1_pm_ops),
.of_match_table = vsp1_of_match,
},
};
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_histo.c b/drivers/media/platform/renesas/vsp1/vsp1_histo.c
index c762202877ba..390ea50f1595 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_histo.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_histo.c
@@ -392,7 +392,7 @@ static const struct v4l2_subdev_ops histo_ops = {
static int histo_v4l2_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_histogram *histo = vdev_to_histo(vfh->vdev);
cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
@@ -409,7 +409,7 @@ static int histo_v4l2_querycap(struct file *file, void *fh,
static int histo_v4l2_enum_format(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_histogram *histo = vdev_to_histo(vfh->vdev);
if (f->index > 0 || f->type != histo->queue.type)
@@ -423,7 +423,7 @@ static int histo_v4l2_enum_format(struct file *file, void *fh,
static int histo_v4l2_get_format(struct file *file, void *fh,
struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_histogram *histo = vdev_to_histo(vfh->vdev);
struct v4l2_meta_format *meta = &format->fmt.meta;
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c
index bc66fbdde3cc..75f9a1a85d55 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_video.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c
@@ -896,7 +896,7 @@ static const struct vb2_ops vsp1_video_queue_qops = {
static int
vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_video *video = to_vsp1_video(vfh->vdev);
cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
@@ -912,7 +912,7 @@ vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
static int vsp1_video_enum_format(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_video *video = to_vsp1_video(vfh->vdev);
const struct vsp1_format_info *info;
@@ -933,7 +933,7 @@ static int vsp1_video_enum_format(struct file *file, void *fh,
static int
vsp1_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_video *video = to_vsp1_video(vfh->vdev);
if (format->type != video->queue.type)
@@ -949,7 +949,7 @@ vsp1_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
static int
vsp1_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_video *video = to_vsp1_video(vfh->vdev);
if (format->type != video->queue.type)
@@ -961,7 +961,7 @@ vsp1_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
static int
vsp1_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_video *video = to_vsp1_video(vfh->vdev);
const struct vsp1_format_info *info;
int ret;
@@ -991,7 +991,7 @@ done:
static int
vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct vsp1_video *video = to_vsp1_video(vfh->vdev);
struct media_device *mdev = &video->vsp1->media_dev;
struct vsp1_pipeline *pipe;
@@ -1079,13 +1079,11 @@ static int vsp1_video_open(struct file *file)
return -ENOMEM;
v4l2_fh_init(vfh, &video->video);
- v4l2_fh_add(vfh);
-
- file->private_data = vfh;
+ v4l2_fh_add(vfh, file);
ret = vsp1_device_get(video->vsp1);
if (ret < 0) {
- v4l2_fh_del(vfh);
+ v4l2_fh_del(vfh, file);
v4l2_fh_exit(vfh);
kfree(vfh);
}
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_vspx.c b/drivers/media/platform/renesas/vsp1/vsp1_vspx.c
index a754b92232bd..1673479be0ff 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_vspx.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_vspx.c
@@ -286,6 +286,7 @@ void vsp1_isp_free_buffer(struct device *dev,
dma_free_coherent(bus_master, buffer_desc->size, buffer_desc->cpu_addr,
buffer_desc->dma_addr);
}
+EXPORT_SYMBOL_GPL(vsp1_isp_free_buffer);
/**
* vsp1_isp_start_streaming - Start processing VSPX jobs
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 3dccab5fa4a1..776046de979a 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -395,8 +395,7 @@ static int rga_open(struct file *file)
return ret;
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
rga_setup_ctrls(ctx);
@@ -411,8 +410,7 @@ static int rga_open(struct file *file)
static int rga_release(struct file *file)
{
- struct rga_ctx *ctx =
- container_of(file->private_data, struct rga_ctx, fh);
+ struct rga_ctx *ctx = file_to_rga_ctx(file);
struct rockchip_rga *rga = ctx->rga;
mutex_lock(&rga->mutex);
@@ -420,7 +418,7 @@ static int rga_release(struct file *file)
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
@@ -448,7 +446,7 @@ vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
return 0;
}
-static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
+static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
{
struct rga_fmt *fmt;
@@ -461,10 +459,10 @@ static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
return 0;
}
-static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
- struct rga_ctx *ctx = prv;
+ struct rga_ctx *ctx = file_to_rga_ctx(file);
struct vb2_queue *vq;
struct rga_frame *frm;
@@ -483,7 +481,7 @@ static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
struct rga_fmt *fmt;
@@ -503,10 +501,10 @@ static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
- struct rga_ctx *ctx = prv;
+ struct rga_ctx *ctx = file_to_rga_ctx(file);
struct rockchip_rga *rga = ctx->rga;
struct vb2_queue *vq;
struct rga_frame *frm;
@@ -516,7 +514,7 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
/* Adjust all values accordingly to the hardware capabilities
* and chosen format.
*/
- ret = vidioc_try_fmt(file, prv, f);
+ ret = vidioc_try_fmt(file, priv, f);
if (ret)
return ret;
vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
@@ -560,10 +558,10 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_g_selection(struct file *file, void *prv,
+static int vidioc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct rga_ctx *ctx = prv;
+ struct rga_ctx *ctx = file_to_rga_ctx(file);
struct rga_frame *f;
bool use_frame = false;
@@ -608,10 +606,10 @@ static int vidioc_g_selection(struct file *file, void *prv,
return 0;
}
-static int vidioc_s_selection(struct file *file, void *prv,
+static int vidioc_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct rga_ctx *ctx = prv;
+ struct rga_ctx *ctx = file_to_rga_ctx(file);
struct rockchip_rga *rga = ctx->rga;
struct rga_frame *f;
int ret = 0;
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index 530e12de73c4..72a28b120fab 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -68,6 +68,11 @@ struct rga_ctx {
u32 fill_color;
};
+static inline struct rga_ctx *file_to_rga_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct rga_ctx, fh);
+}
+
struct rockchip_rga {
struct v4l2_device v4l2_dev;
struct v4l2_m2m_dev *m2m_dev;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index 5f187f9efc7b..6028ecdd23de 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -24,6 +24,7 @@
#include "rkisp1-regs.h"
struct dentry;
+struct dev_pm_domain_list;
struct regmap;
/*
@@ -55,7 +56,7 @@ struct regmap;
#define RKISP1_BUS_INFO "platform:" RKISP1_DRIVER_NAME
/* maximum number of clocks */
-#define RKISP1_MAX_BUS_CLK 8
+#define RKISP1_MAX_BUS_CLK 4
/* a bitmask of the ready stats */
#define RKISP1_STATS_MEAS_MASK (RKISP1_CIF_ISP_AWB_DONE | \
@@ -139,27 +140,31 @@ enum rkisp1_feature {
/*
* struct rkisp1_info - Model-specific ISP Information
*
- * @clks: array of ISP clock names
- * @clk_size: number of entries in the @clks array
+ * @num_clocks: number of clocks
* @isrs: array of ISP interrupt descriptors
* @isr_size: number of entries in the @isrs array
* @isp_ver: ISP version
* @features: bitmask of rkisp1_feature features implemented by the ISP
* @max_width: maximum input frame width
* @max_height: maximum input frame height
+ * @pm_domains.names: name of the power domains
+ * @pm_domains.count: number of power domains
*
* This structure contains information about the ISP specific to a particular
* ISP model, version, or integration in a particular SoC.
*/
struct rkisp1_info {
- const char * const *clks;
- unsigned int clk_size;
+ unsigned int num_clocks;
const struct rkisp1_isr_data *isrs;
unsigned int isr_size;
enum rkisp1_cif_isp_version isp_ver;
unsigned int features;
unsigned int max_width;
unsigned int max_height;
+ struct {
+ const char * const *names;
+ unsigned int count;
+ } pm_domains;
};
/*
@@ -483,6 +488,7 @@ struct rkisp1_debug {
* @dev: a pointer to the struct device
* @clk_size: number of clocks
* @clks: array of clocks
+ * @pm_domains: power domains
* @gasket: the gasket - i.MX8MP only
* @gasket_id: the gasket ID (0 or 1) - i.MX8MP only
* @v4l2_dev: v4l2_device variable
@@ -507,6 +513,7 @@ struct rkisp1_device {
struct device *dev;
unsigned int clk_size;
struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
+ struct dev_pm_domain_list *pm_domains;
struct regmap *gasket;
unsigned int gasket_id;
struct v4l2_device v4l2_dev;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index dc65a7924f8a..1791c02a40ae 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -8,6 +8,7 @@
* Copyright (C) 2017 Rockchip Electronics Co., Ltd.
*/
+#include <linux/build_bug.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
@@ -16,6 +17,7 @@
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
@@ -491,13 +493,6 @@ static irqreturn_t rkisp1_isr(int irq, void *ctx)
return ret;
}
-static const char * const px30_isp_clks[] = {
- "isp",
- "aclk",
- "hclk",
- "pclk",
-};
-
static const struct rkisp1_isr_data px30_isp_isrs[] = {
{ "isp", rkisp1_isp_isr, BIT(RKISP1_IRQ_ISP) },
{ "mi", rkisp1_capture_isr, BIT(RKISP1_IRQ_MI) },
@@ -505,8 +500,7 @@ static const struct rkisp1_isr_data px30_isp_isrs[] = {
};
static const struct rkisp1_info px30_isp_info = {
- .clks = px30_isp_clks,
- .clk_size = ARRAY_SIZE(px30_isp_clks),
+ .num_clocks = 4,
.isrs = px30_isp_isrs,
.isr_size = ARRAY_SIZE(px30_isp_isrs),
.isp_ver = RKISP1_V12,
@@ -518,19 +512,12 @@ static const struct rkisp1_info px30_isp_info = {
.max_height = 2448,
};
-static const char * const rk3399_isp_clks[] = {
- "isp",
- "aclk",
- "hclk",
-};
-
static const struct rkisp1_isr_data rk3399_isp_isrs[] = {
{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) },
};
static const struct rkisp1_info rk3399_isp_info = {
- .clks = rk3399_isp_clks,
- .clk_size = ARRAY_SIZE(rk3399_isp_clks),
+ .num_clocks = 3,
.isrs = rk3399_isp_isrs,
.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
.isp_ver = RKISP1_V10,
@@ -542,19 +529,17 @@ static const struct rkisp1_info rk3399_isp_info = {
.max_height = 3312,
};
-static const char * const imx8mp_isp_clks[] = {
- "isp",
- "hclk",
- "aclk",
-};
-
static const struct rkisp1_isr_data imx8mp_isp_isrs[] = {
{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) },
};
+static const char * const imx8mp_isp_pm_domains[] = {
+ "isp",
+ "csi2",
+};
+
static const struct rkisp1_info imx8mp_isp_info = {
- .clks = imx8mp_isp_clks,
- .clk_size = ARRAY_SIZE(imx8mp_isp_clks),
+ .num_clocks = 3,
.isrs = imx8mp_isp_isrs,
.isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
.isp_ver = RKISP1_V_IMX8MP,
@@ -563,6 +548,10 @@ static const struct rkisp1_info imx8mp_isp_info = {
| RKISP1_FEATURE_COMPAND,
.max_width = 4096,
.max_height = 3072,
+ .pm_domains = {
+ .names = imx8mp_isp_pm_domains,
+ .count = ARRAY_SIZE(imx8mp_isp_pm_domains),
+ },
};
static const struct of_device_id rkisp1_of_match[] = {
@@ -582,6 +571,81 @@ static const struct of_device_id rkisp1_of_match[] = {
};
MODULE_DEVICE_TABLE(of, rkisp1_of_match);
+static const char * const rkisp1_clk_names[] = {
+ "isp",
+ "aclk",
+ "hclk",
+ "pclk",
+};
+
+static int rkisp1_init_clocks(struct rkisp1_device *rkisp1)
+{
+ const struct rkisp1_info *info = rkisp1->info;
+ unsigned int i;
+ int ret;
+
+ static_assert(ARRAY_SIZE(rkisp1_clk_names) == ARRAY_SIZE(rkisp1->clks));
+
+ for (i = 0; i < info->num_clocks; i++)
+ rkisp1->clks[i].id = rkisp1_clk_names[i];
+
+ ret = devm_clk_bulk_get(rkisp1->dev, info->num_clocks, rkisp1->clks);
+ if (ret)
+ return ret;
+
+ rkisp1->clk_size = info->num_clocks;
+
+ /*
+ * On i.MX8MP the pclk clock is needed to access the HDR stitching
+ * registers, but wasn't required by DT bindings. Try to acquire it as
+ * an optional clock to avoid breaking backward compatibility.
+ */
+ if (info->isp_ver == RKISP1_V_IMX8MP) {
+ struct clk *clk;
+
+ clk = devm_clk_get_optional(rkisp1->dev, "pclk");
+ if (IS_ERR(clk))
+ return dev_err_probe(rkisp1->dev, PTR_ERR(clk),
+ "Failed to acquire pclk clock\n");
+
+ if (clk)
+ rkisp1->clks[rkisp1->clk_size++].clk = clk;
+ }
+
+ return 0;
+}
+
+static int rkisp1_init_pm_domains(struct rkisp1_device *rkisp1)
+{
+ const struct rkisp1_info *info = rkisp1->info;
+ struct dev_pm_domain_attach_data pm_domain_data = {
+ .pd_names = info->pm_domains.names,
+ .num_pd_names = info->pm_domains.count,
+ };
+ int ret;
+
+ /*
+ * Most platforms have a single power domain, which the PM domain core
+ * automatically attaches at probe time. When that's the case there's
+ * nothing to do here.
+ */
+ if (rkisp1->dev->pm_domain)
+ return 0;
+
+ if (!pm_domain_data.num_pd_names)
+ return 0;
+
+ ret = devm_pm_domain_attach_list(rkisp1->dev, &pm_domain_data,
+ &rkisp1->pm_domains);
+ if (ret < 0) {
+ dev_err_probe(rkisp1->dev, ret,
+ "Failed to attach power domains\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int rkisp1_probe(struct platform_device *pdev)
{
const struct rkisp1_info *info;
@@ -639,12 +703,13 @@ static int rkisp1_probe(struct platform_device *pdev)
}
}
- for (i = 0; i < info->clk_size; i++)
- rkisp1->clks[i].id = info->clks[i];
- ret = devm_clk_bulk_get(dev, info->clk_size, rkisp1->clks);
+ ret = rkisp1_init_clocks(rkisp1);
+ if (ret)
+ return ret;
+
+ ret = rkisp1_init_pm_domains(rkisp1);
if (ret)
return ret;
- rkisp1->clk_size = info->clk_size;
if (info->isp_ver == RKISP1_V_IMX8MP) {
unsigned int id;
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index d3b31f461194..6e606d73ff51 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -354,7 +354,7 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
const struct rkvdec_coded_fmt_desc *coded_desc;
/*
@@ -387,7 +387,7 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
const struct rkvdec_coded_fmt_desc *desc;
desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat);
@@ -418,7 +418,7 @@ static int rkvdec_try_output_fmt(struct file *file, void *priv,
static int rkvdec_s_capture_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
struct vb2_queue *vq;
int ret;
@@ -439,7 +439,7 @@ static int rkvdec_s_capture_fmt(struct file *file, void *priv,
static int rkvdec_s_output_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
const struct rkvdec_coded_fmt_desc *desc;
struct v4l2_format *cap_fmt;
@@ -504,7 +504,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
static int rkvdec_g_output_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
*f = ctx->coded_fmt;
return 0;
@@ -513,7 +513,7 @@ static int rkvdec_g_output_fmt(struct file *file, void *priv,
static int rkvdec_g_capture_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
*f = ctx->decoded_fmt;
return 0;
@@ -532,7 +532,7 @@ static int rkvdec_enum_output_fmt(struct file *file, void *priv,
static int rkvdec_enum_capture_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
u32 fourcc;
fourcc = rkvdec_enum_decoded_fmt(ctx, f->index, ctx->image_fmt);
@@ -937,8 +937,7 @@ static int rkvdec_open(struct file *filp)
if (ret)
goto err_cleanup_m2m_ctx;
- filp->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, filp);
return 0;
@@ -952,9 +951,9 @@ err_free_ctx:
static int rkvdec_release(struct file *filp)
{
- struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(filp->private_data);
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(filp);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, filp);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
v4l2_fh_exit(&ctx->fh);
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index f6e8bf38add3..481aaa4bffe9 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -124,9 +124,9 @@ struct rkvdec_ctx {
void *priv;
};
-static inline struct rkvdec_ctx *fh_to_rkvdec_ctx(struct v4l2_fh *fh)
+static inline struct rkvdec_ctx *file_to_rkvdec_ctx(struct file *filp)
{
- return container_of(fh, struct rkvdec_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct rkvdec_ctx, fh);
}
struct rkvdec_aux_buf {
diff --git a/drivers/media/platform/samsung/exynos-gsc/gsc-core.h b/drivers/media/platform/samsung/exynos-gsc/gsc-core.h
index b9777e07fb6d..265221abf4dc 100644
--- a/drivers/media/platform/samsung/exynos-gsc/gsc-core.h
+++ b/drivers/media/platform/samsung/exynos-gsc/gsc-core.h
@@ -85,7 +85,6 @@ enum gsc_yuv_fmt {
GSC_CRCB,
};
-#define fh_to_ctx(__fh) container_of(__fh, struct gsc_ctx, fh)
#define is_rgb(x) (!!((x) & 0x1))
#define is_yuv420(x) (!!((x) & 0x2))
#define is_yuv422(x) (!!((x) & 0x4))
@@ -381,6 +380,11 @@ struct gsc_ctx {
enum v4l2_colorspace out_colorspace;
};
+static inline struct gsc_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct gsc_ctx, fh);
+}
+
void gsc_set_prefbuf(struct gsc_dev *gsc, struct gsc_frame *frm);
int gsc_register_m2m_device(struct gsc_dev *gsc);
void gsc_unregister_m2m_device(struct gsc_dev *gsc);
diff --git a/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c b/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c
index 4bda1c369c44..722e2531e23f 100644
--- a/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c
+++ b/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c
@@ -297,7 +297,7 @@ static int gsc_m2m_enum_fmt(struct file *file, void *priv,
static int gsc_m2m_g_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return gsc_g_fmt_mplane(ctx, f);
}
@@ -305,7 +305,7 @@ static int gsc_m2m_g_fmt_mplane(struct file *file, void *fh,
static int gsc_m2m_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return gsc_try_fmt_mplane(ctx, f);
}
@@ -313,7 +313,7 @@ static int gsc_m2m_try_fmt_mplane(struct file *file, void *fh,
static int gsc_m2m_s_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct vb2_queue *vq;
struct gsc_frame *frame;
struct v4l2_pix_format_mplane *pix;
@@ -359,7 +359,7 @@ static int gsc_m2m_s_fmt_mplane(struct file *file, void *fh,
static int gsc_m2m_reqbufs(struct file *file, void *fh,
struct v4l2_requestbuffers *reqbufs)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct gsc_dev *gsc = ctx->gsc_dev;
u32 max_cnt;
@@ -374,35 +374,35 @@ static int gsc_m2m_reqbufs(struct file *file, void *fh,
static int gsc_m2m_expbuf(struct file *file, void *fh,
struct v4l2_exportbuffer *eb)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
}
static int gsc_m2m_querybuf(struct file *file, void *fh,
struct v4l2_buffer *buf)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
}
static int gsc_m2m_qbuf(struct file *file, void *fh,
struct v4l2_buffer *buf)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
}
static int gsc_m2m_dqbuf(struct file *file, void *fh,
struct v4l2_buffer *buf)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
}
static int gsc_m2m_streamon(struct file *file, void *fh,
enum v4l2_buf_type type)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
/* The source and target color format need to be set */
if (V4L2_TYPE_IS_OUTPUT(type)) {
@@ -418,7 +418,7 @@ static int gsc_m2m_streamon(struct file *file, void *fh,
static int gsc_m2m_streamoff(struct file *file, void *fh,
enum v4l2_buf_type type)
{
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
}
@@ -440,8 +440,8 @@ static int is_rectangle_enclosed(struct v4l2_rect *a, struct v4l2_rect *b)
static int gsc_m2m_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct gsc_frame *frame;
- struct gsc_ctx *ctx = fh_to_ctx(fh);
if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
(s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
@@ -478,7 +478,7 @@ static int gsc_m2m_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct gsc_frame *frame;
- struct gsc_ctx *ctx = fh_to_ctx(fh);
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct gsc_variant *variant = ctx->gsc_dev->variant;
struct v4l2_selection sel = *s;
int ret;
@@ -625,8 +625,7 @@ static int gsc_m2m_open(struct file *file)
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->gsc_dev = gsc;
/* Default color format */
@@ -655,7 +654,7 @@ static int gsc_m2m_open(struct file *file)
error_ctrls:
gsc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
error_fh:
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
@@ -666,7 +665,7 @@ unlock:
static int gsc_m2m_release(struct file *file)
{
- struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct gsc_dev *gsc = ctx->gsc_dev;
pr_debug("pid: %d, state: 0x%lx, refcnt= %d",
@@ -676,7 +675,7 @@ static int gsc_m2m_release(struct file *file)
v4l2_m2m_ctx_release(ctx->m2m_ctx);
gsc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
if (--gsc->m2m.refcnt <= 0)
@@ -690,7 +689,7 @@ static int gsc_m2m_release(struct file *file)
static __poll_t gsc_m2m_poll(struct file *file,
struct poll_table_struct *wait)
{
- struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct gsc_dev *gsc = ctx->gsc_dev;
__poll_t ret;
@@ -705,7 +704,7 @@ static __poll_t gsc_m2m_poll(struct file *file,
static int gsc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct gsc_ctx *ctx = file_to_ctx(file);
struct gsc_dev *gsc = ctx->gsc_dev;
int ret;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.h b/drivers/media/platform/samsung/exynos4-is/fimc-core.h
index 63385152a2ff..c23cbdee7afc 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.h
@@ -496,7 +496,10 @@ struct fimc_ctx {
struct fimc_ctrls ctrls;
};
-#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
+static inline struct fimc_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct fimc_ctx, fh);
+}
static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height)
{
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c
index 951433c8e92a..562c57f186c6 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c
@@ -249,7 +249,7 @@ static int fimc_m2m_enum_fmt(struct file *file, void *priv,
static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
+ struct fimc_ctx *ctx = file_to_ctx(file);
const struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
if (IS_ERR(frame))
@@ -308,7 +308,7 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
+ struct fimc_ctx *ctx = file_to_ctx(file);
return fimc_try_fmt_mplane(ctx, f);
}
@@ -337,7 +337,7 @@ static void __set_frame_format(struct fimc_frame *frame,
static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
+ struct fimc_ctx *ctx = file_to_ctx(file);
struct fimc_dev *fimc = ctx->fimc_dev;
const struct fimc_fmt *fmt;
struct vb2_queue *vq;
@@ -376,7 +376,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
static int fimc_m2m_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
+ struct fimc_ctx *ctx = file_to_ctx(file);
const struct fimc_frame *frame;
frame = ctx_get_frame(ctx, s->type);
@@ -484,7 +484,7 @@ static int fimc_m2m_try_selection(struct fimc_ctx *ctx,
static int fimc_m2m_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
+ struct fimc_ctx *ctx = file_to_ctx(file);
struct fimc_dev *fimc = ctx->fimc_dev;
struct fimc_frame *f;
int ret;
@@ -634,8 +634,7 @@ static int fimc_m2m_open(struct file *file)
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrls.handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
/* Setup the device context for memory-to-memory mode */
ctx->state = FIMC_CTX_M2M;
@@ -664,7 +663,7 @@ error_m2m_ctx:
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
error_c:
fimc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
error_fh:
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
@@ -675,7 +674,7 @@ unlock:
static int fimc_m2m_release(struct file *file)
{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct fimc_ctx *ctx = file_to_ctx(file);
struct fimc_dev *fimc = ctx->fimc_dev;
dbg("pid: %d, state: 0x%lx, refcnt= %d",
@@ -685,7 +684,7 @@ static int fimc_m2m_release(struct file *file)
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
fimc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
if (--fimc->m2m.refcnt <= 0)
diff --git a/drivers/media/platform/samsung/s3c-camif/camif-capture.c b/drivers/media/platform/samsung/s3c-camif/camif-capture.c
index 3e566b65f417..ed1a1d693293 100644
--- a/drivers/media/platform/samsung/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/samsung/s3c-camif/camif-capture.c
@@ -572,7 +572,7 @@ static int s3c_camif_close(struct file *file)
mutex_lock(&camif->lock);
- if (vp->owner == file->private_data) {
+ if (vp->owner == file_to_v4l2_fh(file)) {
camif_stop_capture(vp);
vb2_queue_release(&vp->vb_queue);
vp->owner = NULL;
@@ -595,7 +595,7 @@ static __poll_t s3c_camif_poll(struct file *file,
__poll_t ret;
mutex_lock(&camif->lock);
- if (vp->owner && vp->owner != file->private_data)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
ret = EPOLLERR;
else
ret = vb2_poll(&vp->vb_queue, file, wait);
@@ -609,7 +609,7 @@ static int s3c_camif_mmap(struct file *file, struct vm_area_struct *vma)
struct camif_vp *vp = video_drvdata(file);
int ret;
- if (vp->owner && vp->owner != file->private_data)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
ret = -EBUSY;
else
ret = vb2_mmap(&vp->vb_queue, vma);
@@ -791,7 +791,7 @@ static int s3c_camif_vidioc_s_fmt(struct file *file, void *priv,
out_frame->rect.top = 0;
if (vp->owner == NULL)
- vp->owner = priv;
+ vp->owner = file_to_v4l2_fh(file);
pr_debug("%ux%u. payload: %u. fmt: 0x%08x. %d %d. sizeimage: %d. bpl: %d\n",
out_frame->f_width, out_frame->f_height, vp->payload,
@@ -841,7 +841,7 @@ static int s3c_camif_streamon(struct file *file, void *priv,
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- if (vp->owner && vp->owner != priv)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
return -EBUSY;
if (s3c_vp_active(vp))
@@ -872,7 +872,7 @@ static int s3c_camif_streamoff(struct file *file, void *priv,
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- if (vp->owner && vp->owner != priv)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
return -EBUSY;
ret = vb2_streamoff(&vp->vb_queue, type);
@@ -888,9 +888,9 @@ static int s3c_camif_reqbufs(struct file *file, void *priv,
int ret;
pr_debug("[vp%d] rb count: %d, owner: %p, priv: %p\n",
- vp->id, rb->count, vp->owner, priv);
+ vp->id, rb->count, vp->owner, file_to_v4l2_fh(file));
- if (vp->owner && vp->owner != priv)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
return -EBUSY;
if (rb->count)
@@ -910,7 +910,7 @@ static int s3c_camif_reqbufs(struct file *file, void *priv,
vp->reqbufs_count = rb->count;
if (vp->owner == NULL && rb->count > 0)
- vp->owner = priv;
+ vp->owner = file_to_v4l2_fh(file);
return ret;
}
@@ -929,7 +929,7 @@ static int s3c_camif_qbuf(struct file *file, void *priv,
pr_debug("[vp%d]\n", vp->id);
- if (vp->owner && vp->owner != priv)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
return -EBUSY;
return vb2_qbuf(&vp->vb_queue, vp->vdev.v4l2_dev->mdev, buf);
@@ -942,7 +942,7 @@ static int s3c_camif_dqbuf(struct file *file, void *priv,
pr_debug("[vp%d] sequence: %d\n", vp->id, vp->frame_sequence);
- if (vp->owner && vp->owner != priv)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
return -EBUSY;
return vb2_dqbuf(&vp->vb_queue, buf, file->f_flags & O_NONBLOCK);
@@ -954,14 +954,14 @@ static int s3c_camif_create_bufs(struct file *file, void *priv,
struct camif_vp *vp = video_drvdata(file);
int ret;
- if (vp->owner && vp->owner != priv)
+ if (vp->owner && vp->owner != file_to_v4l2_fh(file))
return -EBUSY;
create->count = max_t(u32, 1, create->count);
ret = vb2_create_bufs(&vp->vb_queue, create);
if (!ret && vp->owner == NULL)
- vp->owner = priv;
+ vp->owner = file_to_v4l2_fh(file);
return ret;
}
diff --git a/drivers/media/platform/samsung/s5p-g2d/g2d.c b/drivers/media/platform/samsung/s5p-g2d/g2d.c
index ffed16a34493..ffb9bee6cb9d 100644
--- a/drivers/media/platform/samsung/s5p-g2d/g2d.c
+++ b/drivers/media/platform/samsung/s5p-g2d/g2d.c
@@ -25,7 +25,10 @@
#include "g2d.h"
#include "g2d-regs.h"
-#define fh2ctx(__fh) container_of(__fh, struct g2d_ctx, fh)
+static inline struct g2d_ctx *file2ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct g2d_ctx, fh);
+}
static struct g2d_fmt formats[] = {
{
@@ -254,8 +257,7 @@ static int g2d_open(struct file *file)
return ret;
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
g2d_setup_ctrls(ctx);
@@ -272,13 +274,13 @@ static int g2d_open(struct file *file)
static int g2d_release(struct file *file)
{
struct g2d_dev *dev = video_drvdata(file);
- struct g2d_ctx *ctx = fh2ctx(file->private_data);
+ struct g2d_ctx *ctx = file2ctx(file);
mutex_lock(&dev->mutex);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
mutex_unlock(&dev->mutex);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
v4l2_info(&dev->v4l2_dev, "instance closed\n");
@@ -295,7 +297,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
+static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
{
if (f->index >= NUM_FORMATS)
return -EINVAL;
@@ -303,9 +305,9 @@ static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
return 0;
}
-static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct g2d_ctx *ctx = prv;
+ struct g2d_ctx *ctx = file2ctx(file);
struct vb2_queue *vq;
struct g2d_frame *frm;
@@ -325,7 +327,7 @@ static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct g2d_fmt *fmt;
enum v4l2_field *field;
@@ -355,9 +357,9 @@ static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct g2d_ctx *ctx = prv;
+ struct g2d_ctx *ctx = file2ctx(file);
struct g2d_dev *dev = ctx->dev;
struct vb2_queue *vq;
struct g2d_frame *frm;
@@ -366,7 +368,7 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
/* Adjust all values accordingly to the hardware capabilities
* and chosen format. */
- ret = vidioc_try_fmt(file, prv, f);
+ ret = vidioc_try_fmt(file, priv, f);
if (ret)
return ret;
vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
@@ -395,10 +397,10 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_g_selection(struct file *file, void *prv,
+static int vidioc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct g2d_ctx *ctx = prv;
+ struct g2d_ctx *ctx = file2ctx(file);
struct g2d_frame *f;
f = get_frame(ctx, s->type);
@@ -445,10 +447,10 @@ static int vidioc_g_selection(struct file *file, void *prv,
return 0;
}
-static int vidioc_try_selection(struct file *file, void *prv,
+static int vidioc_try_selection(struct file *file, void *priv,
const struct v4l2_selection *s)
{
- struct g2d_ctx *ctx = prv;
+ struct g2d_ctx *ctx = file2ctx(file);
struct g2d_dev *dev = ctx->dev;
struct g2d_frame *f;
@@ -473,14 +475,14 @@ static int vidioc_try_selection(struct file *file, void *prv,
return 0;
}
-static int vidioc_s_selection(struct file *file, void *prv,
+static int vidioc_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct g2d_ctx *ctx = prv;
+ struct g2d_ctx *ctx = file2ctx(file);
struct g2d_frame *f;
int ret;
- ret = vidioc_try_selection(file, prv, s);
+ ret = vidioc_try_selection(file, priv, s);
if (ret)
return ret;
f = get_frame(ctx, s->type);
diff --git a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
index ac4cf269456a..81792f7f8b16 100644
--- a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
@@ -580,9 +580,9 @@ static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
}
-static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
+static inline struct s5p_jpeg_ctx *file_to_ctx(struct file *filp)
{
- return container_of(fh, struct s5p_jpeg_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct s5p_jpeg_ctx, fh);
}
static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
@@ -965,8 +965,7 @@ static int s5p_jpeg_open(struct file *file)
v4l2_fh_init(&ctx->fh, vfd);
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->jpeg = jpeg;
if (vfd == jpeg->vfd_encoder) {
@@ -1001,7 +1000,7 @@ static int s5p_jpeg_open(struct file *file)
return 0;
error:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
mutex_unlock(&jpeg->lock);
free:
@@ -1011,13 +1010,13 @@ free:
static int s5p_jpeg_release(struct file *file)
{
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
struct s5p_jpeg *jpeg = video_drvdata(file);
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
mutex_lock(&jpeg->lock);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
mutex_unlock(&jpeg->lock);
@@ -1249,7 +1248,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
static int s5p_jpeg_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
if (ctx->mode == S5P_JPEG_ENCODE) {
strscpy(cap->driver, S5P_JPEG_M2M_NAME,
@@ -1297,7 +1296,7 @@ static int enum_fmt(struct s5p_jpeg_ctx *ctx,
static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
if (ctx->mode == S5P_JPEG_ENCODE)
return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
@@ -1310,7 +1309,7 @@ static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
if (ctx->mode == S5P_JPEG_ENCODE)
return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
@@ -1336,7 +1335,7 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
struct vb2_queue *vq;
struct s5p_jpeg_q_data *q_data = NULL;
struct v4l2_pix_format *pix = &f->fmt.pix;
- struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ct = file_to_ctx(file);
vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
if (!vq)
@@ -1476,7 +1475,7 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
struct v4l2_pix_format *pix = &f->fmt.pix;
struct s5p_jpeg_fmt *fmt;
int ret;
@@ -1535,7 +1534,7 @@ exit:
static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
struct s5p_jpeg_fmt *fmt;
fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
@@ -1682,7 +1681,7 @@ static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
if (ret)
return ret;
- return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
+ return s5p_jpeg_s_fmt(file_to_ctx(file), f);
}
static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
@@ -1694,7 +1693,7 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
if (ret)
return ret;
- return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
+ return s5p_jpeg_s_fmt(file_to_ctx(file), f);
}
static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
@@ -1791,7 +1790,7 @@ static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
static int s5p_jpeg_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1828,7 +1827,7 @@ static int s5p_jpeg_g_selection(struct file *file, void *priv,
static int s5p_jpeg_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+ struct s5p_jpeg_ctx *ctx = file_to_ctx(file);
struct v4l2_rect *rect = &s->r;
int ret = -EINVAL;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index 73fdcd362265..4948d734eb02 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -801,8 +801,7 @@ static int s5p_mfc_open(struct file *file)
}
init_waitqueue_head(&ctx->queue);
v4l2_fh_init(&ctx->fh, vdev);
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ctx->dev = dev;
INIT_LIST_HEAD(&ctx->src_queue);
INIT_LIST_HEAD(&ctx->dst_queue);
@@ -877,7 +876,7 @@ static int s5p_mfc_open(struct file *file)
/* Init videobuf2 queue for CAPTURE */
q = &ctx->vq_dst;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->drv_priv = &ctx->fh;
+ q->drv_priv = ctx;
q->lock = &dev->mfc_mutex;
if (vdev == dev->vfd_dec) {
q->io_modes = VB2_MMAP;
@@ -904,7 +903,7 @@ static int s5p_mfc_open(struct file *file)
/* Init videobuf2 queue for OUTPUT */
q = &ctx->vq_src;
q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- q->drv_priv = &ctx->fh;
+ q->drv_priv = ctx;
q->lock = &dev->mfc_mutex;
if (vdev == dev->vfd_dec) {
q->io_modes = VB2_MMAP;
@@ -956,7 +955,7 @@ err_ctrls_setup:
err_bad_node:
dev->ctx[ctx->num] = NULL;
err_no_ctx:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
err_alloc:
@@ -970,7 +969,7 @@ err_enter:
/* Release MFC context */
static int s5p_mfc_release(struct file *file)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct s5p_mfc_dev *dev = ctx->dev;
/* if dev is null, do cleanup that doesn't need dev */
@@ -1011,7 +1010,7 @@ static int s5p_mfc_release(struct file *file)
if (dev)
dev->ctx[ctx->num] = NULL;
s5p_mfc_dec_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
/* vdev is gone if dev is null */
if (dev)
v4l2_fh_exit(&ctx->fh);
@@ -1027,7 +1026,7 @@ static int s5p_mfc_release(struct file *file)
static __poll_t s5p_mfc_poll(struct file *file,
struct poll_table_struct *wait)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct s5p_mfc_dev *dev = ctx->dev;
struct vb2_queue *src_q, *dst_q;
struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
@@ -1078,7 +1077,7 @@ end:
/* Mmap */
static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
int ret;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c
index 47bc3014b5d8..f7c682fca645 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c
@@ -14,8 +14,7 @@
#include "s5p_mfc_opr.h"
#include "s5p_mfc_cmd_v6.h"
-static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
- const struct s5p_mfc_cmd_args *args)
+static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd)
{
mfc_debug(2, "Issue the command: %d\n", cmd);
@@ -31,7 +30,6 @@ static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
{
- struct s5p_mfc_cmd_args h2r_args;
const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
int ret;
@@ -41,33 +39,23 @@ static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
- return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6,
- &h2r_args);
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6);
}
static int s5p_mfc_sleep_cmd_v6(struct s5p_mfc_dev *dev)
{
- struct s5p_mfc_cmd_args h2r_args;
-
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6,
- &h2r_args);
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SLEEP_V6);
}
static int s5p_mfc_wakeup_cmd_v6(struct s5p_mfc_dev *dev)
{
- struct s5p_mfc_cmd_args h2r_args;
-
- memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
- return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6,
- &h2r_args);
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_WAKEUP_V6);
}
/* Open a new instance and get its number */
static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_cmd_args h2r_args;
int codec_type;
mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);
@@ -129,23 +117,20 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
mfc_write(dev, ctx->ctx.size, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
mfc_write(dev, 0, S5P_FIMV_D_CRC_CTRL_V6); /* no crc */
- return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6,
- &h2r_args);
+ return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE_V6);
}
/* Close instance */
static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_cmd_args h2r_args;
int ret = 0;
dev->curr_ctx = ctx->num;
if (ctx->state != MFCINST_FREE) {
mfc_write(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
ret = s5p_mfc_cmd_host2risc_v6(dev,
- S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6,
- &h2r_args);
+ S5P_FIMV_H2R_CMD_CLOSE_INSTANCE_V6);
} else {
ret = -EINVAL;
}
@@ -153,9 +138,15 @@ static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
return ret;
}
+static int s5p_mfc_cmd_host2risc_v6_args(struct s5p_mfc_dev *dev, int cmd,
+ const struct s5p_mfc_cmd_args *ignored)
+{
+ return s5p_mfc_cmd_host2risc_v6(dev, cmd);
+}
+
/* Initialize cmd function pointers for MFC v6 */
static const struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
- .cmd_host2risc = s5p_mfc_cmd_host2risc_v6,
+ .cmd_host2risc = s5p_mfc_cmd_host2risc_v6_args,
.sys_init_cmd = s5p_mfc_sys_init_cmd_v6,
.sleep_cmd = s5p_mfc_sleep_cmd_v6,
.wakeup_cmd = s5p_mfc_wakeup_cmd_v6,
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index 86c316c1ff8f..58dc1768082c 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -767,7 +767,11 @@ struct mfc_control {
#define s5p_mfc_hw_call(f, op, args...) \
((f && f->op) ? f->op(args) : (typeof(f->op(args)))(-ENODEV))
-#define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh)
+static inline struct s5p_mfc_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct s5p_mfc_ctx, fh);
+}
+
#define ctrl_to_ctx(__ctrl) \
container_of((__ctrl)->handler, struct s5p_mfc_ctx, ctrl_handler)
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
index 3efbc3367906..afd28beabfde 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
@@ -330,7 +330,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
return 0;
}
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
return vidioc_enum_fmt(file, f, false);
@@ -345,7 +345,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
/* Get format */
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct v4l2_pix_format_mplane *pix_mp;
mfc_debug_enter();
@@ -442,7 +442,7 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
int ret = 0;
struct v4l2_pix_format_mplane *pix_mp;
const struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
@@ -598,7 +598,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *reqbufs)
{
struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (reqbufs->memory != V4L2_MEMORY_MMAP) {
mfc_debug(2, "Only V4L2_MEMORY_MMAP is supported\n");
@@ -619,7 +619,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
static int vidioc_querybuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
int ret;
int i;
@@ -647,7 +647,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
/* Queue a buffer */
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (ctx->state == MFCINST_ERROR) {
mfc_err("Call on QBUF after unrecoverable error\n");
@@ -666,7 +666,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
const struct v4l2_event ev = {
.type = V4L2_EVENT_EOS
};
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
int ret;
if (ctx->state == MFCINST_ERROR) {
@@ -695,7 +695,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
static int vidioc_expbuf(struct file *file, void *priv,
struct v4l2_exportbuffer *eb)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return vb2_expbuf(&ctx->vq_src, eb);
@@ -708,7 +708,7 @@ static int vidioc_expbuf(struct file *file, void *priv,
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
int ret = -EINVAL;
mfc_debug_enter();
@@ -724,7 +724,7 @@ static int vidioc_streamon(struct file *file, void *priv,
static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return vb2_streamoff(&ctx->vq_src, type);
@@ -801,7 +801,7 @@ static const struct v4l2_ctrl_ops s5p_mfc_dec_ctrl_ops = {
static int vidioc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct s5p_mfc_dev *dev = ctx->dev;
u32 left, right, top, bottom;
u32 width, height;
@@ -856,7 +856,7 @@ static int vidioc_g_selection(struct file *file, void *priv,
static int vidioc_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *cmd)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *buf;
unsigned long flags;
@@ -937,7 +937,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
unsigned int *plane_count, unsigned int psize[],
struct device *alloc_devs[])
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
struct s5p_mfc_dev *dev = ctx->dev;
const struct v4l2_format_info *format;
@@ -1006,7 +1006,7 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
unsigned int i;
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
@@ -1068,7 +1068,7 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(q);
struct s5p_mfc_dev *dev = ctx->dev;
v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
@@ -1085,7 +1085,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
static void s5p_mfc_stop_streaming(struct vb2_queue *q)
{
unsigned long flags;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(q);
struct s5p_mfc_dev *dev = ctx->dev;
int aborted = 0;
@@ -1130,7 +1130,7 @@ static void s5p_mfc_stop_streaming(struct vb2_queue *q)
static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
{
struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
struct s5p_mfc_dev *dev = ctx->dev;
unsigned long flags;
struct s5p_mfc_buf *mfc_buf;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index 6c603dcd5664..3f8701e5614f 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -1375,7 +1375,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
return -EINVAL;
}
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
return vidioc_enum_fmt(file, f, false);
@@ -1389,8 +1389,8 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
mfc_debug(2, "f->type = %d ctx->state = %d\n", f->type, ctx->state);
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
@@ -1472,8 +1472,8 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
int ret = 0;
@@ -1531,7 +1531,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *reqbufs)
{
struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
int ret = 0;
/* if memory is not mmp or userptr or dmabuf return error */
@@ -1601,7 +1601,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
static int vidioc_querybuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
int ret = 0;
/* if memory is not mmp or userptr or dmabuf return error */
@@ -1636,7 +1636,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
/* Queue a buffer */
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (ctx->state == MFCINST_ERROR) {
mfc_err("Call on QBUF after unrecoverable error\n");
@@ -1657,10 +1657,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
/* Dequeue a buffer */
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
const struct v4l2_event ev = {
.type = V4L2_EVENT_EOS
};
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
int ret;
if (ctx->state == MFCINST_ERROR) {
@@ -1685,7 +1685,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
static int vidioc_expbuf(struct file *file, void *priv,
struct v4l2_exportbuffer *eb)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return vb2_expbuf(&ctx->vq_src, eb);
@@ -1698,7 +1698,7 @@ static int vidioc_expbuf(struct file *file, void *priv,
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return vb2_streamon(&ctx->vq_src, type);
@@ -1711,7 +1711,7 @@ static int vidioc_streamon(struct file *file, void *priv,
static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
return vb2_streamoff(&ctx->vq_src, type);
@@ -2284,7 +2284,7 @@ static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = {
static int vidioc_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *a)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
ctx->enc_params.rc_framerate_num =
@@ -2301,7 +2301,7 @@ static int vidioc_s_parm(struct file *file, void *priv,
static int vidioc_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *a)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
a->parm.output.timeperframe.denominator =
@@ -2318,7 +2318,7 @@ static int vidioc_g_parm(struct file *file, void *priv,
static int vidioc_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *cmd)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+ struct s5p_mfc_ctx *ctx = file_to_ctx(file);
struct s5p_mfc_dev *dev = ctx->dev;
struct s5p_mfc_buf *buf;
unsigned long flags;
@@ -2418,7 +2418,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
unsigned int *buf_count, unsigned int *plane_count,
unsigned int psize[], struct device *alloc_devs[])
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
struct s5p_mfc_dev *dev = ctx->dev;
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
@@ -2477,7 +2477,7 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
unsigned int i;
int ret;
@@ -2516,7 +2516,7 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb)
static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
{
struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
int ret;
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
@@ -2557,7 +2557,7 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
{
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(q);
struct s5p_mfc_dev *dev = ctx->dev;
if (IS_MFCV6_PLUS(dev) &&
@@ -2588,7 +2588,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
static void s5p_mfc_stop_streaming(struct vb2_queue *q)
{
unsigned long flags;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(q);
struct s5p_mfc_dev *dev = ctx->dev;
if ((ctx->state == MFCINST_FINISHING ||
@@ -2617,7 +2617,7 @@ static void s5p_mfc_stop_streaming(struct vb2_queue *q)
static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
{
struct vb2_queue *vq = vb->vb2_queue;
- struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
+ struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq);
struct s5p_mfc_dev *dev = ctx->dev;
unsigned long flags;
struct s5p_mfc_buf *mfc_buf;
diff --git a/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
index 1eb934490c0b..56169b70652d 100644
--- a/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
@@ -33,7 +33,10 @@
#define BDISP_MIN_H 1
#define BDISP_MAX_H 8191
-#define fh_to_ctx(__fh) container_of(__fh, struct bdisp_ctx, fh)
+static inline struct bdisp_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct bdisp_ctx, fh);
+}
enum bdisp_dev_flags {
ST_M2M_OPEN, /* Driver opened */
@@ -603,8 +606,7 @@ static int bdisp_open(struct file *file)
/* Use separate control handler per file handle */
ctx->fh.ctrl_handler = &ctx->ctrl_handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
/* Default format */
ctx->src = bdisp_dflt_fmt;
@@ -630,7 +632,7 @@ static int bdisp_open(struct file *file)
error_ctrls:
bdisp_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
error_fh:
v4l2_fh_exit(&ctx->fh);
bdisp_hw_free_nodes(ctx);
@@ -644,7 +646,7 @@ unlock:
static int bdisp_release(struct file *file)
{
- struct bdisp_ctx *ctx = fh_to_ctx(file->private_data);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct bdisp_dev *bdisp = ctx->bdisp_dev;
dev_dbg(bdisp->dev, "%s\n", __func__);
@@ -655,7 +657,7 @@ static int bdisp_release(struct file *file)
bdisp_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
if (--bdisp->m2m.refcnt <= 0)
@@ -682,7 +684,7 @@ static const struct v4l2_file_operations bdisp_fops = {
static int bdisp_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct bdisp_dev *bdisp = ctx->bdisp_dev;
strscpy(cap->driver, bdisp->pdev->name, sizeof(cap->driver));
@@ -694,7 +696,7 @@ static int bdisp_querycap(struct file *file, void *fh,
static int bdisp_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
const struct bdisp_fmt *fmt;
if (f->index >= ARRAY_SIZE(bdisp_formats))
@@ -714,7 +716,7 @@ static int bdisp_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
static int bdisp_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
{
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct v4l2_pix_format *pix;
struct bdisp_frame *frame = ctx_get_frame(ctx, f->type);
@@ -738,7 +740,7 @@ static int bdisp_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
static int bdisp_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
{
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct v4l2_pix_format *pix = &f->fmt.pix;
const struct bdisp_fmt *format;
u32 in_w, in_h;
@@ -788,7 +790,7 @@ static int bdisp_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
static int bdisp_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
{
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct vb2_queue *vq;
struct bdisp_frame *frame;
struct v4l2_pix_format *pix;
@@ -841,8 +843,8 @@ static int bdisp_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
static int bdisp_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct bdisp_frame *frame;
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
frame = ctx_get_frame(ctx, s->type);
if (IS_ERR(frame)) {
@@ -919,8 +921,8 @@ static int is_rect_enclosed(struct v4l2_rect *a, struct v4l2_rect *b)
static int bdisp_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
+ struct bdisp_ctx *ctx = file_to_ctx(file);
struct bdisp_frame *frame;
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
struct v4l2_rect *in, out;
bool valid = false;
@@ -997,7 +999,7 @@ static int bdisp_s_selection(struct file *file, void *fh,
static int bdisp_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
{
- struct bdisp_ctx *ctx = fh_to_ctx(fh);
+ struct bdisp_ctx *ctx = file_to_ctx(file);
if ((type == V4L2_BUF_TYPE_VIDEO_OUTPUT) &&
!bdisp_ctx_state_is_set(BDISP_SRC_FMT, ctx)) {
diff --git a/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c
index 0533d4a083d2..a078f1107300 100644
--- a/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c
+++ b/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c
@@ -239,7 +239,7 @@ static int delta_mjpeg_ipc_open(struct delta_ctx *pctx)
return 0;
}
-static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au)
+static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, dma_addr_t pstart, dma_addr_t pend)
{
struct delta_dev *delta = pctx->dev;
struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
@@ -256,8 +256,8 @@ static int delta_mjpeg_ipc_decode(struct delta_ctx *pctx, struct delta_au *au)
memset(params, 0, sizeof(*params));
- params->picture_start_addr_p = (u32)(au->paddr);
- params->picture_end_addr_p = (u32)(au->paddr + au->size - 1);
+ params->picture_start_addr_p = pstart;
+ params->picture_end_addr_p = pend;
/*
* !WARNING!
@@ -374,12 +374,14 @@ static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau)
struct delta_dev *delta = pctx->dev;
struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
int ret;
- struct delta_au au = *pau;
+ void *au_vaddr = pau->vaddr;
+ dma_addr_t au_dma = pau->paddr;
+ size_t au_size = pau->size;
unsigned int data_offset = 0;
struct mjpeg_header *header = &ctx->header_struct;
if (!ctx->header) {
- ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
+ ret = delta_mjpeg_read_header(pctx, au_vaddr, au_size,
header, &data_offset);
if (ret) {
pctx->stream_errors++;
@@ -405,17 +407,17 @@ static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau)
goto err;
}
- ret = delta_mjpeg_read_header(pctx, au.vaddr, au.size,
+ ret = delta_mjpeg_read_header(pctx, au_vaddr, au_size,
ctx->header, &data_offset);
if (ret) {
pctx->stream_errors++;
goto err;
}
- au.paddr += data_offset;
- au.vaddr += data_offset;
+ au_dma += data_offset;
+ au_vaddr += data_offset;
- ret = delta_mjpeg_ipc_decode(pctx, &au);
+ ret = delta_mjpeg_ipc_decode(pctx, au_dma, au_dma + au_size - 1);
if (ret)
goto err;
diff --git a/drivers/media/platform/st/sti/delta/delta-v4l2.c b/drivers/media/platform/st/sti/delta/delta-v4l2.c
index 196e6a40335d..6c1a53c771f7 100644
--- a/drivers/media/platform/st/sti/delta/delta-v4l2.c
+++ b/drivers/media/platform/st/sti/delta/delta-v4l2.c
@@ -24,7 +24,11 @@
#define DELTA_PREFIX "[---:----]"
-#define to_ctx(__fh) container_of(__fh, struct delta_ctx, fh)
+static inline struct delta_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct delta_ctx, fh);
+}
+
#define to_au(__vbuf) container_of(__vbuf, struct delta_au, vbuf)
#define to_frame(__vbuf) container_of(__vbuf, struct delta_frame, vbuf)
@@ -382,7 +386,7 @@ static int delta_open_decoder(struct delta_ctx *ctx, u32 streamformat,
static int delta_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
strscpy(cap->driver, DELTA_NAME, sizeof(cap->driver));
@@ -396,7 +400,7 @@ static int delta_querycap(struct file *file, void *priv,
static int delta_enum_fmt_stream(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
if (unlikely(f->index >= delta->nb_of_streamformats))
@@ -410,7 +414,7 @@ static int delta_enum_fmt_stream(struct file *file, void *priv,
static int delta_enum_fmt_frame(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
if (unlikely(f->index >= delta->nb_of_pixelformats))
@@ -424,7 +428,7 @@ static int delta_enum_fmt_frame(struct file *file, void *priv,
static int delta_g_fmt_stream(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct delta_streaminfo *streaminfo = &ctx->streaminfo;
@@ -452,7 +456,7 @@ static int delta_g_fmt_stream(struct file *file, void *fh,
static int delta_g_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct delta_frameinfo *frameinfo = &ctx->frameinfo;
@@ -491,7 +495,7 @@ static int delta_g_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
static int delta_try_fmt_stream(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
struct v4l2_pix_format *pix = &f->fmt.pix;
u32 streamformat = pix->pixelformat;
@@ -545,7 +549,7 @@ static int delta_try_fmt_stream(struct file *file, void *priv,
static int delta_try_fmt_frame(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
struct v4l2_pix_format *pix = &f->fmt.pix;
u32 pixelformat = pix->pixelformat;
@@ -605,7 +609,7 @@ static int delta_try_fmt_frame(struct file *file, void *priv,
static int delta_s_fmt_stream(struct file *file, void *fh,
struct v4l2_format *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
struct vb2_queue *vq;
struct v4l2_pix_format *pix = &f->fmt.pix;
@@ -641,7 +645,7 @@ static int delta_s_fmt_stream(struct file *file, void *fh,
static int delta_s_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
const struct delta_dec *dec = ctx->dec;
struct v4l2_pix_format *pix = &f->fmt.pix;
@@ -721,7 +725,7 @@ static int delta_s_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
static int delta_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct delta_ctx *ctx = to_ctx(fh);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_frameinfo *frameinfo = &ctx->frameinfo;
struct v4l2_rect crop;
@@ -803,7 +807,7 @@ static int delta_try_decoder_cmd(struct file *file, void *fh,
return 0;
}
-static int delta_decoder_stop_cmd(struct delta_ctx *ctx, void *fh)
+static int delta_decoder_stop_cmd(struct delta_ctx *ctx)
{
const struct delta_dec *dec = ctx->dec;
struct delta_dev *delta = ctx->dev;
@@ -866,14 +870,14 @@ delay_eos:
static int delta_decoder_cmd(struct file *file, void *fh,
struct v4l2_decoder_cmd *cmd)
{
- struct delta_ctx *ctx = to_ctx(fh);
+ struct delta_ctx *ctx = file_to_ctx(file);
int ret = 0;
ret = delta_try_decoder_cmd(file, fh, cmd);
if (ret)
return ret;
- return delta_decoder_stop_cmd(ctx, fh);
+ return delta_decoder_stop_cmd(ctx);
}
static int delta_subscribe_event(struct v4l2_fh *fh,
@@ -1633,8 +1637,7 @@ static int delta_open(struct file *file)
ctx->dev = delta;
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
INIT_WORK(&ctx->run_work, delta_run_work);
mutex_init(&ctx->lock);
@@ -1679,7 +1682,7 @@ static int delta_open(struct file *file)
return 0;
err_fh_del:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
err:
@@ -1690,7 +1693,7 @@ err:
static int delta_release(struct file *file)
{
- struct delta_ctx *ctx = to_ctx(file->private_data);
+ struct delta_ctx *ctx = file_to_ctx(file);
struct delta_dev *delta = ctx->dev;
const struct delta_dec *dec = ctx->dec;
@@ -1707,7 +1710,7 @@ static int delta_release(struct file *file)
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
/* disable ST231 clocks */
diff --git a/drivers/media/platform/st/sti/hva/hva-v4l2.c b/drivers/media/platform/st/sti/hva/hva-v4l2.c
index 5366c0f92549..3581b73a99b8 100644
--- a/drivers/media/platform/st/sti/hva/hva-v4l2.c
+++ b/drivers/media/platform/st/sti/hva/hva-v4l2.c
@@ -36,7 +36,10 @@
#define to_type_str(type) (type == V4L2_BUF_TYPE_VIDEO_OUTPUT ? \
"frame" : "stream")
-#define fh_to_ctx(f) (container_of(f, struct hva_ctx, fh))
+static inline struct hva_ctx *file_to_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct hva_ctx, fh);
+}
/* registry of available encoders */
static const struct hva_enc *hva_encoders[] = {
@@ -254,7 +257,7 @@ static void hva_dbg_summary(struct hva_ctx *ctx)
static int hva_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct hva_dev *hva = ctx_to_hdev(ctx);
strscpy(cap->driver, HVA_NAME, sizeof(cap->driver));
@@ -268,7 +271,7 @@ static int hva_querycap(struct file *file, void *priv,
static int hva_enum_fmt_stream(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct hva_dev *hva = ctx_to_hdev(ctx);
if (unlikely(f->index >= hva->nb_of_streamformats))
@@ -282,7 +285,7 @@ static int hva_enum_fmt_stream(struct file *file, void *priv,
static int hva_enum_fmt_frame(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct hva_dev *hva = ctx_to_hdev(ctx);
if (unlikely(f->index >= hva->nb_of_pixelformats))
@@ -295,7 +298,7 @@ static int hva_enum_fmt_frame(struct file *file, void *priv,
static int hva_g_fmt_stream(struct file *file, void *fh, struct v4l2_format *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct hva_streaminfo *streaminfo = &ctx->streaminfo;
f->fmt.pix.width = streaminfo->width;
@@ -314,7 +317,7 @@ static int hva_g_fmt_stream(struct file *file, void *fh, struct v4l2_format *f)
static int hva_g_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct hva_frameinfo *frameinfo = &ctx->frameinfo;
f->fmt.pix.width = frameinfo->width;
@@ -335,7 +338,7 @@ static int hva_g_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
static int hva_try_fmt_stream(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct device *dev = ctx_to_dev(ctx);
struct v4l2_pix_format *pix = &f->fmt.pix;
u32 streamformat = pix->pixelformat;
@@ -399,7 +402,7 @@ static int hva_try_fmt_stream(struct file *file, void *priv,
static int hva_try_fmt_frame(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct device *dev = ctx_to_dev(ctx);
struct v4l2_pix_format *pix = &f->fmt.pix;
u32 pixelformat = pix->pixelformat;
@@ -449,7 +452,7 @@ static int hva_try_fmt_frame(struct file *file, void *priv,
static int hva_s_fmt_stream(struct file *file, void *fh, struct v4l2_format *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct device *dev = ctx_to_dev(ctx);
struct vb2_queue *vq;
int ret;
@@ -479,7 +482,7 @@ static int hva_s_fmt_stream(struct file *file, void *fh, struct v4l2_format *f)
static int hva_s_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct device *dev = ctx_to_dev(ctx);
struct v4l2_pix_format *pix = &f->fmt.pix;
struct vb2_queue *vq;
@@ -517,7 +520,7 @@ static int hva_s_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
static int hva_g_parm(struct file *file, void *fh, struct v4l2_streamparm *sp)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct v4l2_fract *time_per_frame = &ctx->ctrls.time_per_frame;
if (sp->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -533,7 +536,7 @@ static int hva_g_parm(struct file *file, void *fh, struct v4l2_streamparm *sp)
static int hva_s_parm(struct file *file, void *fh, struct v4l2_streamparm *sp)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct v4l2_fract *time_per_frame = &ctx->ctrls.time_per_frame;
if (sp->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -553,7 +556,7 @@ static int hva_s_parm(struct file *file, void *fh, struct v4l2_streamparm *sp)
static int hva_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct device *dev = ctx_to_dev(ctx);
if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
@@ -1171,8 +1174,7 @@ static int hva_open(struct file *file)
INIT_WORK(&ctx->run_work, hva_run_work);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ret = hva_ctrls_setup(ctx);
if (ret) {
@@ -1216,7 +1218,7 @@ static int hva_open(struct file *file)
err_ctrls:
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
err_fh:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
out:
@@ -1225,7 +1227,7 @@ out:
static int hva_release(struct file *file)
{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
+ struct hva_ctx *ctx = file_to_ctx(file);
struct hva_dev *hva = ctx_to_hdev(ctx);
struct device *dev = ctx_to_dev(ctx);
const struct hva_enc *enc = ctx->enc;
@@ -1247,7 +1249,7 @@ static int hva_release(struct file *file)
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
diff --git a/drivers/media/platform/st/sti/hva/hva.h b/drivers/media/platform/st/sti/hva/hva.h
index ba6b893416ec..1fe561082a74 100644
--- a/drivers/media/platform/st/sti/hva/hva.h
+++ b/drivers/media/platform/st/sti/hva/hva.h
@@ -13,8 +13,6 @@
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-mem2mem.h>
-#define fh_to_ctx(f) (container_of(f, struct hva_ctx, fh))
-
#define hva_to_dev(h) (h->dev)
#define ctx_to_dev(c) (c->hva_dev->dev)
diff --git a/drivers/media/platform/st/stm32/dma2d/dma2d.c b/drivers/media/platform/st/stm32/dma2d/dma2d.c
index 48fa781aab06..468c247ba328 100644
--- a/drivers/media/platform/st/stm32/dma2d/dma2d.c
+++ b/drivers/media/platform/st/stm32/dma2d/dma2d.c
@@ -45,7 +45,10 @@
* whole of a destination image with a pixel format conversion.
*/
-#define fh2ctx(__fh) container_of(__fh, struct dma2d_ctx, fh)
+static inline struct dma2d_ctx *file2ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct dma2d_ctx, fh);
+}
static const struct dma2d_fmt formats[] = {
{
@@ -301,8 +304,7 @@ static int dma2d_open(struct file *file)
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
dma2d_setup_ctrls(ctx);
@@ -318,13 +320,13 @@ static int dma2d_open(struct file *file)
static int dma2d_release(struct file *file)
{
struct dma2d_dev *dev = video_drvdata(file);
- struct dma2d_ctx *ctx = fh2ctx(file->private_data);
+ struct dma2d_ctx *ctx = file2ctx(file);
mutex_lock(&dev->mutex);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
mutex_unlock(&dev->mutex);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
@@ -341,7 +343,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
+static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
{
if (f->index >= NUM_FORMATS)
return -EINVAL;
@@ -350,9 +352,9 @@ static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
return 0;
}
-static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct dma2d_ctx *ctx = prv;
+ struct dma2d_ctx *ctx = file2ctx(file);
struct vb2_queue *vq;
struct dma2d_frame *frm;
@@ -375,9 +377,9 @@ static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct dma2d_ctx *ctx = prv;
+ struct dma2d_ctx *ctx = file2ctx(file);
struct dma2d_fmt *fmt;
enum v4l2_field *field;
u32 fourcc = f->fmt.pix.pixelformat;
@@ -418,9 +420,9 @@ static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
return 0;
}
-static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
+static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct dma2d_ctx *ctx = prv;
+ struct dma2d_ctx *ctx = file2ctx(file);
struct vb2_queue *vq;
struct dma2d_frame *frm;
struct dma2d_fmt *fmt;
@@ -429,7 +431,7 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
/* Adjust all values accordingly to the hardware capabilities
* and chosen format.
*/
- ret = vidioc_try_fmt(file, prv, f);
+ ret = vidioc_try_fmt(file, priv, f);
if (ret)
return ret;
diff --git a/drivers/media/platform/st/stm32/stm32-csi.c b/drivers/media/platform/st/stm32/stm32-csi.c
index b69048144cc1..fd2b6dfbd44c 100644
--- a/drivers/media/platform/st/stm32/stm32-csi.c
+++ b/drivers/media/platform/st/stm32/stm32-csi.c
@@ -443,8 +443,7 @@ static void stm32_csi_phy_reg_write(struct stm32_csi_dev *csidev,
static int stm32_csi_start(struct stm32_csi_dev *csidev,
struct v4l2_subdev_state *state)
{
- struct media_pad *src_pad =
- &csidev->s_subdev->entity.pads[csidev->s_subdev_pad_nb];
+ struct media_pad *src_pad;
const struct stm32_csi_mbps_phy_reg *phy_regs = NULL;
struct v4l2_mbus_framefmt *sink_fmt;
const struct stm32_csi_fmts *fmt;
@@ -466,6 +465,7 @@ static int stm32_csi_start(struct stm32_csi_dev *csidev,
if (!csidev->s_subdev)
return -EIO;
+ src_pad = &csidev->s_subdev->entity.pads[csidev->s_subdev_pad_nb];
link_freq = v4l2_get_link_freq(src_pad,
fmt->bpp, 2 * csidev->num_lanes);
if (link_freq < 0)
diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index d94c61b8569d..13762861b769 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -1701,8 +1701,8 @@ static int dcmi_framesizes_init(struct stm32_dcmi *dcmi)
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.code = dcmi->sd_format->mbus_code,
};
- unsigned int ret;
unsigned int i;
+ int ret;
/* Allocate discrete framesizes array */
while (!v4l2_subdev_call(subdev, pad, enum_frame_size,
@@ -1808,8 +1808,8 @@ static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier,
struct v4l2_async_connection *asd)
{
struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
- unsigned int ret;
int src_pad;
+ int ret;
dev_dbg(dcmi->dev, "Subdev \"%s\" bound\n", subdev->name);
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index 76356bc7f10e..65879f4802c0 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -711,7 +711,7 @@ static void sun6i_csi_capture_format_prepare(struct v4l2_format *format)
pix_format->xfer_func = V4L2_XFER_FUNC_DEFAULT;
}
-static int sun6i_csi_capture_querycap(struct file *file, void *private,
+static int sun6i_csi_capture_querycap(struct file *file, void *priv,
struct v4l2_capability *capability)
{
struct sun6i_csi_device *csi_dev = video_drvdata(file);
@@ -725,7 +725,7 @@ static int sun6i_csi_capture_querycap(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_enum_fmt(struct file *file, void *private,
+static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtdesc)
{
u32 index = fmtdesc->index;
@@ -738,7 +738,7 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_g_fmt(struct file *file, void *private,
+static int sun6i_csi_capture_g_fmt(struct file *file, void *priv,
struct v4l2_format *format)
{
struct sun6i_csi_device *csi_dev = video_drvdata(file);
@@ -748,7 +748,7 @@ static int sun6i_csi_capture_g_fmt(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_s_fmt(struct file *file, void *private,
+static int sun6i_csi_capture_s_fmt(struct file *file, void *priv,
struct v4l2_format *format)
{
struct sun6i_csi_device *csi_dev = video_drvdata(file);
@@ -764,7 +764,7 @@ static int sun6i_csi_capture_s_fmt(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_try_fmt(struct file *file, void *private,
+static int sun6i_csi_capture_try_fmt(struct file *file, void *priv,
struct v4l2_format *format)
{
sun6i_csi_capture_format_prepare(format);
@@ -772,7 +772,7 @@ static int sun6i_csi_capture_try_fmt(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_enum_input(struct file *file, void *private,
+static int sun6i_csi_capture_enum_input(struct file *file, void *priv,
struct v4l2_input *input)
{
if (input->index != 0)
@@ -784,7 +784,7 @@ static int sun6i_csi_capture_enum_input(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_g_input(struct file *file, void *private,
+static int sun6i_csi_capture_g_input(struct file *file, void *priv,
unsigned int *index)
{
*index = 0;
@@ -792,7 +792,7 @@ static int sun6i_csi_capture_g_input(struct file *file, void *private,
return 0;
}
-static int sun6i_csi_capture_s_input(struct file *file, void *private,
+static int sun6i_csi_capture_s_input(struct file *file, void *priv,
unsigned int index)
{
if (index != 0)
diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
index 3e7f2df70408..eb519afb30ca 100644
--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
@@ -309,7 +309,7 @@ static void deinterlace_init(struct deinterlace_dev *dev)
static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file)
{
- return container_of(file->private_data, struct deinterlace_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct deinterlace_ctx, fh);
}
static bool deinterlace_check_format(u32 pixelformat)
@@ -730,7 +730,6 @@ static int deinterlace_open(struct file *file)
deinterlace_prepare_format(&ctx->dst_fmt);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = dev;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
@@ -740,7 +739,7 @@ static int deinterlace_open(struct file *file)
goto err_free;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
mutex_unlock(&dev->dev_mutex);
@@ -756,12 +755,11 @@ err_free:
static int deinterlace_release(struct file *file)
{
struct deinterlace_dev *dev = video_drvdata(file);
- struct deinterlace_ctx *ctx = container_of(file->private_data,
- struct deinterlace_ctx, fh);
+ struct deinterlace_ctx *ctx = deinterlace_file2ctx(file);
mutex_lock(&dev->dev_mutex);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c
index abd10b218aa1..89992feaab60 100644
--- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c
+++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c
@@ -170,7 +170,7 @@ static irqreturn_t rotate_irq(int irq, void *data)
static inline struct rotate_ctx *rotate_file2ctx(struct file *file)
{
- return container_of(file->private_data, struct rotate_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct rotate_ctx, fh);
}
static void rotate_prepare_format(struct v4l2_pix_format *pix_fmt)
@@ -659,7 +659,6 @@ static int rotate_open(struct file *file)
rotate_set_cap_format(ctx, &ctx->dst_fmt, ctx->rotate);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = dev;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
@@ -669,7 +668,7 @@ static int rotate_open(struct file *file)
goto err_free;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
ret = rotate_setup_ctrls(ctx);
if (ret)
@@ -691,13 +690,12 @@ err_free:
static int rotate_release(struct file *file)
{
struct rotate_dev *dev = video_drvdata(file);
- struct rotate_ctx *ctx = container_of(file->private_data,
- struct rotate_ctx, fh);
+ struct rotate_ctx *ctx = rotate_file2ctx(file);
mutex_lock(&dev->dev_mutex);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
index 7af6765532e3..b7d278b3889f 100644
--- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
@@ -459,7 +459,7 @@ static bool port_no_link(struct snps_hdmirx_dev *hdmirx_dev)
return !tx_5v_power_present(hdmirx_dev);
}
-static int hdmirx_query_dv_timings(struct file *file, void *_fh,
+static int hdmirx_query_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct hdmirx_stream *stream = video_drvdata(file);
@@ -751,7 +751,7 @@ static int hdmirx_dv_timings_cap(struct file *file, void *fh,
return 0;
}
-static int hdmirx_enum_dv_timings(struct file *file, void *_fh,
+static int hdmirx_enum_dv_timings(struct file *file, void *priv,
struct v4l2_enum_dv_timings *timings)
{
return v4l2_enum_dv_timings_cap(timings, &hdmirx_timings_cap, NULL, NULL);
@@ -1323,7 +1323,7 @@ static int hdmirx_g_fmt_vid_cap_mplane(struct file *file, void *fh,
return 0;
}
-static int hdmirx_g_dv_timings(struct file *file, void *_fh,
+static int hdmirx_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct hdmirx_stream *stream = video_drvdata(file);
@@ -1339,7 +1339,7 @@ static int hdmirx_g_dv_timings(struct file *file, void *_fh,
return 0;
}
-static int hdmirx_s_dv_timings(struct file *file, void *_fh,
+static int hdmirx_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct hdmirx_stream *stream = video_drvdata(file);
diff --git a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
index 220ab99ca611..b13f58e31944 100644
--- a/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
+++ b/drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
@@ -8,10 +8,12 @@
#ifndef DW_HDMIRX_H
#define DW_HDMIRX_H
+#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/hw_bitfield.h>
-#define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
-#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
+#define UPDATE(x, h, l) FIELD_PREP(GENMASK((h), (l)), (x))
+#define HIWORD_UPDATE(v, h, l) FIELD_PREP_WM16(GENMASK((h), (l)), (v))
/* SYS_GRF */
#define SYS_GRF_SOC_CON1 0x0304
diff --git a/drivers/media/platform/ti/Kconfig b/drivers/media/platform/ti/Kconfig
index bab998c4179a..3bc4aa35887e 100644
--- a/drivers/media/platform/ti/Kconfig
+++ b/drivers/media/platform/ti/Kconfig
@@ -67,7 +67,8 @@ config VIDEO_TI_J721E_CSI2RX
tristate "TI J721E CSI2RX wrapper layer driver"
depends on VIDEO_DEV && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_SUPPORT && MEDIA_CONTROLLER
- depends on (PHY_CADENCE_DPHY_RX && VIDEO_CADENCE_CSI2RX) || COMPILE_TEST
+ depends on VIDEO_CADENCE_CSI2RX
+ depends on PHY_CADENCE_DPHY_RX || COMPILE_TEST
depends on ARCH_K3 || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select V4L2_FWNODE
diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
index b628d6e081db..b75aa363d1bf 100644
--- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
+++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
@@ -13,7 +13,9 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <media/cadence/cdns-csi2rx.h>
#include <media/mipi-csi2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
@@ -28,6 +30,7 @@
#define SHIM_DMACNTX 0x20
#define SHIM_DMACNTX_EN BIT(31)
#define SHIM_DMACNTX_YUV422 GENMASK(27, 26)
+#define SHIM_DMACNTX_DUAL_PCK_CFG BIT(24)
#define SHIM_DMACNTX_SIZE GENMASK(21, 20)
#define SHIM_DMACNTX_FMT GENMASK(5, 0)
#define SHIM_DMACNTX_YUV422_MODE_11 3
@@ -39,6 +42,7 @@
#define SHIM_PSI_CFG0_SRC_TAG GENMASK(15, 0)
#define SHIM_PSI_CFG0_DST_TAG GENMASK(31, 16)
+#define TI_CSI2RX_MAX_PIX_PER_CLK 4
#define PSIL_WORD_SIZE_BYTES 16
/*
* There are no hard limits on the width or height. The DMA engine can handle
@@ -52,6 +56,8 @@
#define DRAIN_TIMEOUT_MS 50
#define DRAIN_BUFFER_SIZE SZ_32K
+#define CSI2RX_BRIDGE_SOURCE_PAD 1
+
struct ti_csi2rx_fmt {
u32 fourcc; /* Four character code. */
u32 code; /* Mbus code. */
@@ -107,6 +113,7 @@ struct ti_csi2rx_dev {
struct v4l2_format v_fmt;
struct ti_csi2rx_dma dma;
u32 sequence;
+ u8 pix_per_clk;
};
static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = {
@@ -299,7 +306,7 @@ static int ti_csi2rx_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int ti_csi2rx_g_fmt_vid_cap(struct file *file, void *prov,
+static int ti_csi2rx_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct ti_csi2rx_dev *csi = video_drvdata(file);
@@ -426,8 +433,9 @@ static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier)
if (ret)
return ret;
- ret = v4l2_create_fwnode_links_to_pad(csi->source, &csi->pad,
- MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
+ ret = media_create_pad_link(&csi->source->entity, CSI2RX_BRIDGE_SOURCE_PAD,
+ &vdev->entity, csi->pad.index,
+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
if (ret) {
video_unregister_device(vdev);
@@ -450,25 +458,23 @@ static int ti_csi2rx_notifier_register(struct ti_csi2rx_dev *csi)
{
struct fwnode_handle *fwnode;
struct v4l2_async_connection *asc;
- struct device_node *node;
int ret;
- node = of_get_child_by_name(csi->dev->of_node, "csi-bridge");
- if (!node)
+ fwnode = fwnode_get_named_child_node(csi->dev->fwnode, "csi-bridge");
+ if (!fwnode)
return -EINVAL;
- fwnode = of_fwnode_handle(node);
- if (!fwnode) {
- of_node_put(node);
- return -EINVAL;
- }
-
v4l2_async_nf_init(&csi->notifier, &csi->v4l2_dev);
csi->notifier.ops = &csi_async_notifier_ops;
asc = v4l2_async_nf_add_fwnode(&csi->notifier, fwnode,
struct v4l2_async_connection);
- of_node_put(node);
+ /*
+ * Calling v4l2_async_nf_add_fwnode grabs a refcount,
+ * so drop the one we got in fwnode_get_named_child_node
+ */
+ fwnode_handle_put(fwnode);
+
if (IS_ERR(asc)) {
v4l2_async_nf_cleanup(&csi->notifier);
return PTR_ERR(asc);
@@ -483,6 +489,26 @@ static int ti_csi2rx_notifier_register(struct ti_csi2rx_dev *csi)
return 0;
}
+/* Request maximum possible pixels per clock from the bridge */
+static void ti_csi2rx_request_max_ppc(struct ti_csi2rx_dev *csi)
+{
+ u8 ppc = TI_CSI2RX_MAX_PIX_PER_CLK;
+ struct media_pad *pad;
+ int ret;
+
+ pad = media_entity_remote_source_pad_unique(&csi->vdev.entity);
+ if (IS_ERR(pad))
+ return;
+
+ ret = cdns_csi2rx_negotiate_ppc(csi->source, pad->index, &ppc);
+ if (ret) {
+ dev_warn(csi->dev, "NUM_PIXELS negotiation failed: %d\n", ret);
+ csi->pix_per_clk = 1;
+ } else {
+ csi->pix_per_clk = ppc;
+ }
+}
+
static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi)
{
const struct ti_csi2rx_fmt *fmt;
@@ -494,6 +520,9 @@ static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi)
reg = SHIM_CNTL_PIX_RST;
writel(reg, csi->shim + SHIM_CNTL);
+ /* Negotiate pixel count from the source */
+ ti_csi2rx_request_max_ppc(csi);
+
reg = SHIM_DMACNTX_EN;
reg |= FIELD_PREP(SHIM_DMACNTX_FMT, fmt->csi_dt);
@@ -522,14 +551,18 @@ static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi)
case V4L2_PIX_FMT_YVYU:
reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
SHIM_DMACNTX_YUV422_MODE_11);
+ /* Multiple pixels are handled differently for packed YUV */
+ if (csi->pix_per_clk == 2)
+ reg |= SHIM_DMACNTX_DUAL_PCK_CFG;
+ reg |= FIELD_PREP(SHIM_DMACNTX_SIZE, fmt->size);
break;
default:
- /* Ignore if not YUV 4:2:2 */
+ /* By default we change the shift size for multiple pixels */
+ reg |= FIELD_PREP(SHIM_DMACNTX_SIZE,
+ fmt->size + (csi->pix_per_clk >> 1));
break;
}
- reg |= FIELD_PREP(SHIM_DMACNTX_SIZE, fmt->size);
-
writel(reg, csi->shim + SHIM_DMACNTX);
reg = FIELD_PREP(SHIM_PSI_CFG0_SRC_TAG, 0) |
@@ -1120,7 +1153,7 @@ static int ti_csi2rx_probe(struct platform_device *pdev)
if (ret)
goto err_vb2q;
- ret = of_platform_populate(csi->dev->of_node, NULL, NULL, csi->dev);
+ ret = devm_of_platform_populate(csi->dev);
if (ret) {
dev_err(csi->dev, "Failed to create children: %d\n", ret);
goto err_subdev;
diff --git a/drivers/media/platform/ti/omap/omap_vout.c b/drivers/media/platform/ti/omap/omap_vout.c
index a87d5030ac35..22782e9f1f4e 100644
--- a/drivers/media/platform/ti/omap/omap_vout.c
+++ b/drivers/media/platform/ti/omap/omap_vout.c
@@ -1236,7 +1236,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
return 0;
}
-static int vidioc_enum_output(struct file *file, void *priv_fh,
+static int vidioc_enum_output(struct file *file, void *priv,
struct v4l2_output *out)
{
if (out->index)
@@ -1246,13 +1246,13 @@ static int vidioc_enum_output(struct file *file, void *priv_fh,
return 0;
}
-static int vidioc_g_output(struct file *file, void *priv_fh, unsigned int *i)
+static int vidioc_g_output(struct file *file, void *priv, unsigned int *i)
{
*i = 0;
return 0;
}
-static int vidioc_s_output(struct file *file, void *priv_fh, unsigned int i)
+static int vidioc_s_output(struct file *file, void *priv, unsigned int i)
{
return i ? -EINVAL : 0;
}
diff --git a/drivers/media/platform/ti/omap3isp/ispccdc.c b/drivers/media/platform/ti/omap3isp/ispccdc.c
index 7d0c723dcd11..55ee14e8b449 100644
--- a/drivers/media/platform/ti/omap3isp/ispccdc.c
+++ b/drivers/media/platform/ti/omap3isp/ispccdc.c
@@ -1873,12 +1873,6 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
}
-static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- return v4l2_event_unsubscribe(fh, sub);
-}
-
/*
* ccdc_set_stream - Enable/Disable streaming on the CCDC module
* @sd: ISP CCDC V4L2 subdevice
@@ -2487,7 +2481,7 @@ static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
.ioctl = ccdc_ioctl,
.subscribe_event = ccdc_subscribe_event,
- .unsubscribe_event = ccdc_unsubscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
/* V4L2 subdev video operations */
diff --git a/drivers/media/platform/ti/omap3isp/isph3a_aewb.c b/drivers/media/platform/ti/omap3isp/isph3a_aewb.c
index e6c54c4bbfca..ae93da9c4542 100644
--- a/drivers/media/platform/ti/omap3isp/isph3a_aewb.c
+++ b/drivers/media/platform/ti/omap3isp/isph3a_aewb.c
@@ -269,7 +269,7 @@ static const struct ispstat_ops h3a_aewb_ops = {
static const struct v4l2_subdev_core_ops h3a_aewb_subdev_core_ops = {
.ioctl = h3a_aewb_ioctl,
.subscribe_event = omap3isp_stat_subscribe_event,
- .unsubscribe_event = omap3isp_stat_unsubscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops h3a_aewb_subdev_video_ops = {
diff --git a/drivers/media/platform/ti/omap3isp/isph3a_af.c b/drivers/media/platform/ti/omap3isp/isph3a_af.c
index de7b116d0122..ca478da4ad34 100644
--- a/drivers/media/platform/ti/omap3isp/isph3a_af.c
+++ b/drivers/media/platform/ti/omap3isp/isph3a_af.c
@@ -334,7 +334,7 @@ static const struct ispstat_ops h3a_af_ops = {
static const struct v4l2_subdev_core_ops h3a_af_subdev_core_ops = {
.ioctl = h3a_af_ioctl,
.subscribe_event = omap3isp_stat_subscribe_event,
- .unsubscribe_event = omap3isp_stat_unsubscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops h3a_af_subdev_video_ops = {
diff --git a/drivers/media/platform/ti/omap3isp/isphist.c b/drivers/media/platform/ti/omap3isp/isphist.c
index 0ef78aace6da..7851ad13d84f 100644
--- a/drivers/media/platform/ti/omap3isp/isphist.c
+++ b/drivers/media/platform/ti/omap3isp/isphist.c
@@ -456,7 +456,7 @@ static const struct ispstat_ops hist_ops = {
static const struct v4l2_subdev_core_ops hist_subdev_core_ops = {
.ioctl = hist_ioctl,
.subscribe_event = omap3isp_stat_subscribe_event,
- .unsubscribe_event = omap3isp_stat_unsubscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops hist_subdev_video_ops = {
diff --git a/drivers/media/platform/ti/omap3isp/ispstat.c b/drivers/media/platform/ti/omap3isp/ispstat.c
index d3da68408ecb..07bd62a93d99 100644
--- a/drivers/media/platform/ti/omap3isp/ispstat.c
+++ b/drivers/media/platform/ti/omap3isp/ispstat.c
@@ -1010,13 +1010,6 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
}
-int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- return v4l2_event_unsubscribe(fh, sub);
-}
-
void omap3isp_stat_unregister_entities(struct ispstat *stat)
{
v4l2_device_unregister_subdev(&stat->subdev);
diff --git a/drivers/media/platform/ti/omap3isp/ispstat.h b/drivers/media/platform/ti/omap3isp/ispstat.h
index b548e617cf62..59842c4a9c33 100644
--- a/drivers/media/platform/ti/omap3isp/ispstat.h
+++ b/drivers/media/platform/ti/omap3isp/ispstat.h
@@ -135,9 +135,6 @@ void omap3isp_stat_cleanup(struct ispstat *stat);
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub);
-int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
- struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub);
int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
int omap3isp_stat_busy(struct ispstat *stat);
diff --git a/drivers/media/platform/ti/omap3isp/ispvideo.c b/drivers/media/platform/ti/omap3isp/ispvideo.c
index 78e30298c7ad..0e7f0bf2b346 100644
--- a/drivers/media/platform/ti/omap3isp/ispvideo.c
+++ b/drivers/media/platform/ti/omap3isp/ispvideo.c
@@ -657,7 +657,7 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
static int
isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
if (format->type != video->type)
@@ -673,7 +673,7 @@ isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
static int
isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
struct v4l2_mbus_framefmt fmt;
@@ -858,7 +858,7 @@ isp_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel)
static int
isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
@@ -876,7 +876,7 @@ isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
static int
isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
@@ -894,7 +894,7 @@ isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
static int
isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
int ret;
@@ -908,7 +908,7 @@ isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
static int
isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
int ret;
@@ -922,7 +922,7 @@ isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
static int
isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
int ret;
@@ -936,7 +936,7 @@ isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
static int
isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
int ret;
@@ -1074,7 +1074,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
static int
isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
enum isp_pipeline_state state;
struct isp_pipeline *pipe;
@@ -1180,7 +1180,7 @@ err_enum_init:
static int
isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
{
- struct isp_video_fh *vfh = to_isp_video_fh(fh);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
enum isp_pipeline_state state;
@@ -1297,7 +1297,7 @@ static int isp_video_open(struct file *file)
return -ENOMEM;
v4l2_fh_init(&handle->vfh, &video->video);
- v4l2_fh_add(&handle->vfh);
+ v4l2_fh_add(&handle->vfh, file);
/* If this is the first user, initialise the pipeline. */
if (omap3isp_get(video->isp) == NULL) {
@@ -1333,11 +1333,10 @@ static int isp_video_open(struct file *file)
handle->timeperframe.denominator = 1;
handle->video = video;
- file->private_data = &handle->vfh;
done:
if (ret < 0) {
- v4l2_fh_del(&handle->vfh);
+ v4l2_fh_del(&handle->vfh, file);
v4l2_fh_exit(&handle->vfh);
kfree(handle);
}
@@ -1348,8 +1347,8 @@ done:
static int isp_video_release(struct file *file)
{
struct isp_video *video = video_drvdata(file);
- struct v4l2_fh *vfh = file->private_data;
- struct isp_video_fh *handle = to_isp_video_fh(vfh);
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
+ struct isp_video_fh *handle = file_to_isp_video_fh(file);
/* Disable streaming and free the buffers queue resources. */
isp_video_streamoff(file, vfh, video->type);
@@ -1361,10 +1360,9 @@ static int isp_video_release(struct file *file)
v4l2_pipeline_pm_put(&video->video.entity);
/* Release the file handle. */
- v4l2_fh_del(vfh);
+ v4l2_fh_del(vfh, file);
v4l2_fh_exit(vfh);
kfree(handle);
- file->private_data = NULL;
omap3isp_put(video->isp);
@@ -1373,7 +1371,7 @@ static int isp_video_release(struct file *file)
static __poll_t isp_video_poll(struct file *file, poll_table *wait)
{
- struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
struct isp_video *video = video_drvdata(file);
__poll_t ret;
@@ -1386,7 +1384,7 @@ static __poll_t isp_video_poll(struct file *file, poll_table *wait)
static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
+ struct isp_video_fh *vfh = file_to_isp_video_fh(file);
return vb2_mmap(&vfh->queue, vma);
}
diff --git a/drivers/media/platform/ti/omap3isp/ispvideo.h b/drivers/media/platform/ti/omap3isp/ispvideo.h
index 1d23df576e6b..537da59cff62 100644
--- a/drivers/media/platform/ti/omap3isp/ispvideo.h
+++ b/drivers/media/platform/ti/omap3isp/ispvideo.h
@@ -194,7 +194,11 @@ struct isp_video_fh {
struct v4l2_fract timeperframe;
};
-#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
+static inline struct isp_video_fh *file_to_isp_video_fh(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct isp_video_fh, vfh);
+}
+
#define isp_video_queue_to_isp_video_fh(q) \
container_of(q, struct isp_video_fh, queue)
diff --git a/drivers/media/platform/ti/vpe/vpe.c b/drivers/media/platform/ti/vpe/vpe.c
index 636d76ecebcd..6029d4e8e0bd 100644
--- a/drivers/media/platform/ti/vpe/vpe.c
+++ b/drivers/media/platform/ti/vpe/vpe.c
@@ -422,6 +422,10 @@ struct vpe_ctx {
unsigned int src_mv_buf_selector;
};
+static inline struct vpe_ctx *to_vpe_ctx(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct vpe_ctx, fh);
+}
/*
* M2M devices get 2 queues.
@@ -1562,7 +1566,7 @@ static int vpe_enum_fmt(struct file *file, void *priv,
static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct vpe_ctx *ctx = file->private_data;
+ struct vpe_ctx *ctx = to_vpe_ctx(file);
struct vb2_queue *vq;
struct vpe_q_data *q_data;
@@ -1719,7 +1723,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
- struct vpe_ctx *ctx = file->private_data;
+ struct vpe_ctx *ctx = to_vpe_ctx(file);
struct vpe_fmt *fmt = find_format(f);
if (V4L2_TYPE_IS_OUTPUT(f->type))
@@ -1783,7 +1787,7 @@ static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
int ret;
- struct vpe_ctx *ctx = file->private_data;
+ struct vpe_ctx *ctx = to_vpe_ctx(file);
ret = vpe_try_fmt(file, priv, f);
if (ret)
@@ -1871,7 +1875,7 @@ static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
static int vpe_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct vpe_ctx *ctx = file->private_data;
+ struct vpe_ctx *ctx = to_vpe_ctx(file);
struct vpe_q_data *q_data;
struct v4l2_pix_format_mplane *pix;
bool use_c_rect = false;
@@ -1935,7 +1939,7 @@ static int vpe_g_selection(struct file *file, void *fh,
static int vpe_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
- struct vpe_ctx *ctx = file->private_data;
+ struct vpe_ctx *ctx = to_vpe_ctx(file);
struct vpe_q_data *q_data;
struct v4l2_selection sel = *s;
int ret;
@@ -2306,7 +2310,6 @@ static int vpe_open(struct file *file)
init_adb_hdrs(ctx);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = ctx;
hdl = &ctx->hdl;
v4l2_ctrl_handler_init(hdl, 1);
@@ -2360,7 +2363,7 @@ static int vpe_open(struct file *file)
goto exit_fh;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
/*
* for now, just report the creation of the first instance, we can later
@@ -2400,7 +2403,7 @@ free_ctx:
static int vpe_release(struct file *file)
{
struct vpe_dev *dev = video_drvdata(file);
- struct vpe_ctx *ctx = file->private_data;
+ struct vpe_ctx *ctx = to_vpe_ctx(file);
vpe_dbg(dev, "releasing instance %p\n", ctx);
@@ -2418,7 +2421,7 @@ static int vpe_release(struct file *file)
vpdma_free_desc_buf(&ctx->sc_coeff_v);
vpdma_free_desc_buf(&ctx->sc_coeff_h);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h
index 81328c63b796..e0fdc4535b2d 100644
--- a/drivers/media/platform/verisilicon/hantro.h
+++ b/drivers/media/platform/verisilicon/hantro.h
@@ -382,9 +382,9 @@ extern int hantro_debug;
pr_err("%s:%d: " fmt, __func__, __LINE__, ##args)
/* Structure access helpers. */
-static __always_inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh)
+static __always_inline struct hantro_ctx *file_to_ctx(struct file *filp)
{
- return container_of(fh, struct hantro_ctx, fh);
+ return container_of(file_to_v4l2_fh(filp), struct hantro_ctx, fh);
}
/* Register accessors. */
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index fa972effd4a2..e0c11fe8b55c 100644
--- a/drivers/media/platform/verisilicon/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
@@ -662,8 +662,7 @@ static int hantro_open(struct file *filp)
}
v4l2_fh_init(&ctx->fh, vdev);
- filp->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, filp);
hantro_reset_fmts(ctx);
@@ -677,7 +676,7 @@ static int hantro_open(struct file *filp)
return 0;
err_fh_free:
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, filp);
v4l2_fh_exit(&ctx->fh);
err_ctx_free:
kfree(ctx);
@@ -686,15 +685,14 @@ err_ctx_free:
static int hantro_release(struct file *filp)
{
- struct hantro_ctx *ctx =
- container_of(filp->private_data, struct hantro_ctx, fh);
+ struct hantro_ctx *ctx = file_to_ctx(filp);
/*
* No need for extra locking because this was the last reference
* to this file.
*/
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, filp);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_handler);
kfree(ctx);
@@ -917,6 +915,8 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid)
vpu->decoder = func;
v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
+ v4l2_disable_ioctl(vfd, VIDIOC_G_SELECTION);
+ v4l2_disable_ioctl(vfd, VIDIOC_S_SELECTION);
}
video_set_drvdata(vfd, vpu);
diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
index 7c3515cf7d64..fcf3bd9bcda2 100644
--- a/drivers/media/platform/verisilicon/hantro_v4l2.c
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
@@ -185,7 +185,7 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
const struct hantro_fmt *fmt;
fmt = hantro_find_format(ctx, fsize->pixel_format);
@@ -217,7 +217,7 @@ static int vidioc_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f, bool capture)
{
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
const struct hantro_fmt *fmt, *formats;
unsigned int num_fmts, i, j = 0;
bool skip_mode_none, enum_all_formats;
@@ -297,7 +297,7 @@ static int vidioc_g_fmt_out_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
vpu_debug(4, "f->type = %d\n", f->type);
@@ -310,7 +310,7 @@ static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
vpu_debug(4, "f->type = %d\n", f->type);
@@ -398,13 +398,13 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
- return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type);
+ return hantro_try_fmt(file_to_ctx(file), &f->fmt.pix_mp, f->type);
}
static int vidioc_try_fmt_out_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
- return hantro_try_fmt(fh_to_ctx(priv), &f->fmt.pix_mp, f->type);
+ return hantro_try_fmt(file_to_ctx(file), &f->fmt.pix_mp, f->type);
}
static void
@@ -648,23 +648,22 @@ static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
static int
vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
{
- return hantro_set_fmt_out(fh_to_ctx(priv), &f->fmt.pix_mp, HANTRO_AUTO_POSTPROC);
+ return hantro_set_fmt_out(file_to_ctx(file), &f->fmt.pix_mp, HANTRO_AUTO_POSTPROC);
}
static int
vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f)
{
- return hantro_set_fmt_cap(fh_to_ctx(priv), &f->fmt.pix_mp);
+ return hantro_set_fmt_cap(file_to_ctx(file), &f->fmt.pix_mp);
}
static int vidioc_g_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
/* Crop only supported on source. */
- if (!ctx->is_encoder ||
- sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
switch (sel->target) {
@@ -691,13 +690,12 @@ static int vidioc_g_selection(struct file *file, void *priv,
static int vidioc_s_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
struct v4l2_rect *rect = &sel->r;
struct vb2_queue *vq;
/* Crop only supported on source. */
- if (!ctx->is_encoder ||
- sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
/* Change not allowed if the queue is streaming. */
@@ -738,7 +736,7 @@ static const struct v4l2_event hantro_eos_event = {
static int vidioc_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *ec)
{
- struct hantro_ctx *ctx = fh_to_ctx(priv);
+ struct hantro_ctx *ctx = file_to_ctx(file);
int ret;
ret = v4l2_m2m_ioctl_try_encoder_cmd(file, priv, ec);
diff --git a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
index 35799da534ed..f9f276385c11 100644
--- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
@@ -234,24 +234,6 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
},
};
-static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
-{
- struct hantro_dev *vpu = dev_id;
- enum vb2_buffer_state state;
- u32 status;
-
- status = vdpu_read(vpu, G1_REG_INTERRUPT);
- state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?
- VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
-
- vdpu_write(vpu, 0, G1_REG_INTERRUPT);
- vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
-
- hantro_irq_done(vpu, state);
-
- return IRQ_HANDLED;
-}
-
static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)
{
vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];
@@ -328,7 +310,7 @@ static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
*/
static const struct hantro_irq imx8mq_irqs[] = {
- { "g1", imx8m_vpu_g1_irq },
+ { "g1", hantro_g1_irq },
};
static const struct hantro_irq imx8mq_g2_irqs[] = {
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 18bfa6001909..fcfe0883aba5 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -469,7 +469,7 @@ static const struct vb2_ops xvip_dma_queue_qops = {
static int
xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
cap->capabilities = dma->xdev->v4l2_caps | V4L2_CAP_STREAMING |
@@ -491,7 +491,7 @@ xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
static int
xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
if (f->index > 0)
@@ -505,7 +505,7 @@ xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
static int
xvip_dma_get_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
format->fmt.pix = dma->format;
@@ -565,7 +565,7 @@ __xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix,
static int
xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
__xvip_dma_try_format(dma, &format->fmt.pix, NULL);
@@ -575,7 +575,7 @@ xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format)
static int
xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
const struct xvip_video_format *info;
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 72776d08046a..bbbdd054ba64 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -141,23 +141,6 @@ config RADIO_TIMBERDALE
found behind the Timberdale FPGA on the Russellville board.
Enabling this driver will automatically select the DSP and tuner.
-config RADIO_WL1273
- tristate "Texas Instruments WL1273 I2C FM Radio"
- depends on I2C
- select MFD_CORE
- select MFD_WL1273_CORE
- select FW_LOADER
- help
- Choose Y here if you have this FM radio chip.
-
- In order to control your radio card, you will need to use programs
- that are compatible with the Video For Linux 2 API. Information on
- this API and pointers to "v4l2" programs may be found at
- <file:Documentation/userspace-api/media/index.rst>.
-
- To compile this driver as a module, choose M here: the
- module will be called radio-wl1273.
-
config USB_DSBR
tristate "D-Link/GemTek USB FM radio support"
depends on USB
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 1ff46f3a6ed3..f54693ebdb30 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -30,7 +30,6 @@ obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o
obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
obj-$(CONFIG_RADIO_TYPHOON) += radio-typhoon.o
-obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 3c8c17d64821..2c1d413e8636 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -4,7 +4,7 @@
*
* Copyright 1997 M. Kirkwood
*
- * Converted to the radio-isa framework by Hans Verkuil <hansverk@cisco.com>
+ * Converted to the radio-isa framework by Hans Verkuil <hverkuil@kernel.org>
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
* Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index d989c0b3966f..0a4667bb7034 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -2,7 +2,7 @@
/*
* radio-aztech.c - Aztech radio card driver
*
- * Converted to the radio-isa framework by Hans Verkuil <hverkuil@xs4all.nl>
+ * Converted to the radio-isa framework by Hans Verkuil <hverkuil@kernel.org>
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
* Adapted to support the Video for Linux API by
* Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 5ca6274c45bd..a3265f1dd189 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -15,7 +15,7 @@
* Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
*
- * Converted to the radio-isa framework by Hans Verkuil <hansverk@cisco.com>
+ * Converted to the radio-isa framework by Hans Verkuil <hverkuil@kernel.org>
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
*
* Note: this card seems to swap the left and right audio channels!
diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c
index 4f87c76a2a96..1a144536ffa7 100644
--- a/drivers/media/radio/radio-isa.c
+++ b/drivers/media/radio/radio-isa.c
@@ -4,7 +4,7 @@
* This takes care of all the V4L2 scaffolding, allowing the ISA drivers
* to concentrate on the actual hardware operation.
*
- * Copyright (C) 2012 Hans Verkuil <hansverk@cisco.com>
+ * Copyright (C) 2012 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/module.h>
diff --git a/drivers/media/radio/radio-isa.h b/drivers/media/radio/radio-isa.h
index 0f3db473da5e..62ff5c3fb5d5 100644
--- a/drivers/media/radio/radio-isa.h
+++ b/drivers/media/radio/radio-isa.h
@@ -4,7 +4,7 @@
* This takes care of all the V4L2 scaffolding, allowing the ISA drivers
* to concentrate on the actual hardware operation.
*
- * Copyright (C) 2012 Hans Verkuil <hansverk@cisco.com>
+ * Copyright (C) 2012 Hans Verkuil <hverkuil@kernel.org>
*/
#ifndef _RADIO_ISA_H_
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index a35648316aa8..f3b57f0cb1ec 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2012 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (c) 2012 Hans Verkuil <hverkuil@kernel.org>
*/
/* kernel includes */
@@ -18,7 +18,7 @@
#include <linux/mutex.h>
/* driver and module definitions */
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_DESCRIPTION("Keene FM Transmitter driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
index 27f058c5e677..67712ab3d564 100644
--- a/drivers/media/radio/radio-miropcm20.c
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -23,7 +23,7 @@
* This code has been reintroduced and converted to use
* the new V4L2 RDS API by:
*
- * Hans Verkuil <hansverk@cisco.com>
+ * Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/module.h>
diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c
index 64c7452c05b5..f60775b005e1 100644
--- a/drivers/media/radio/radio-raremono.c
+++ b/drivers/media/radio/radio-raremono.c
@@ -25,14 +25,14 @@
*
* The USB protocol has been reversed engineered using wireshark, initially
* by Dinesh Ram <dinesh.ram@cern.ch> and finished by Hans Verkuil
- * <hverkuil@xs4all.nl>.
+ * <hverkuil@kernel.org>.
*
* Sadly the firmware used in this product hides lots of goodies since the
* si4734 has more features than are supported by the firmware. Oh well...
*/
/* driver and module definitions */
-MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_DESCRIPTION("Thanko's Raremono AM/FM/SW Receiver USB driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 16b13a63bfed..efc02069bf9d 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -7,7 +7,7 @@
* Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
* Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
*
- * Converted to the radio-isa framework by Hans Verkuil <hansverk@cisco.com>
+ * Converted to the radio-isa framework by Hans Verkuil <hverkuil@kernel.org>
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
*
* Fully tested with actual hardware and the v4l2-compliance tool.
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 720080634454..43817dd0a0fe 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -17,7 +17,7 @@
* Frequency control is done digitally -- ie out(port,encodefreq(95.8));
* Volume Control is done digitally
*
- * Converted to the radio-isa framework by Hans Verkuil <hansverk@cisco.com>
+ * Converted to the radio-isa framework by Hans Verkuil <hverkuil@kernel.org>
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
*/
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
deleted file mode 100644
index f55217ccf2b8..000000000000
--- a/drivers/media/radio/radio-wl1273.c
+++ /dev/null
@@ -1,2159 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Driver for the Texas Instruments WL1273 FM radio.
- *
- * Copyright (C) 2011 Nokia Corporation
- * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
- */
-
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/wl1273-core.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-
-#define DRIVER_DESC "Wl1273 FM Radio"
-
-#define WL1273_POWER_SET_OFF 0
-#define WL1273_POWER_SET_FM BIT(0)
-#define WL1273_POWER_SET_RDS BIT(1)
-#define WL1273_POWER_SET_RETENTION BIT(4)
-
-#define WL1273_PUPD_SET_OFF 0x00
-#define WL1273_PUPD_SET_ON 0x01
-#define WL1273_PUPD_SET_RETENTION 0x10
-
-#define WL1273_FREQ(x) (x * 10000 / 625)
-#define WL1273_INV_FREQ(x) (x * 625 / 10000)
-
-/*
- * static int radio_nr - The number of the radio device
- *
- * The default is 0.
- */
-static int radio_nr;
-module_param(radio_nr, int, 0);
-MODULE_PARM_DESC(radio_nr, "The number of the radio device. Default = 0");
-
-struct wl1273_device {
- char *bus_type;
-
- u8 forbidden;
- unsigned int preemphasis;
- unsigned int spacing;
- unsigned int tx_power;
- unsigned int rx_frequency;
- unsigned int tx_frequency;
- unsigned int rangelow;
- unsigned int rangehigh;
- unsigned int band;
- bool stereo;
-
- /* RDS */
- unsigned int rds_on;
-
- wait_queue_head_t read_queue;
- struct mutex lock; /* for serializing fm radio operations */
- struct completion busy;
-
- unsigned char *buffer;
- unsigned int buf_size;
- unsigned int rd_index;
- unsigned int wr_index;
-
- /* Selected interrupts */
- u16 irq_flags;
- u16 irq_received;
-
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_device v4l2dev;
- struct video_device videodev;
- struct device *dev;
- struct wl1273_core *core;
- struct file *owner;
- char *write_buf;
- unsigned int rds_users;
-};
-
-#define WL1273_IRQ_MASK (WL1273_FR_EVENT | \
- WL1273_POW_ENB_EVENT)
-
-/*
- * static unsigned int rds_buf - the number of RDS buffer blocks used.
- *
- * The default number is 100.
- */
-static unsigned int rds_buf = 100;
-module_param(rds_buf, uint, 0);
-MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");
-
-static int wl1273_fm_write_fw(struct wl1273_core *core,
- __u8 *fw, int len)
-{
- struct i2c_client *client = core->client;
- struct i2c_msg msg;
- int i, r = 0;
-
- msg.addr = client->addr;
- msg.flags = 0;
-
- for (i = 0; i <= len; i++) {
- msg.len = fw[0];
- msg.buf = fw + 1;
-
- fw += msg.len + 1;
- dev_dbg(&client->dev, "%s:len[%d]: %d\n", __func__, i, msg.len);
-
- r = i2c_transfer(client->adapter, &msg, 1);
- if (r < 0 && i < len + 1)
- break;
- }
-
- dev_dbg(&client->dev, "%s: i: %d\n", __func__, i);
- dev_dbg(&client->dev, "%s: len + 1: %d\n", __func__, len + 1);
-
- /* Last transfer always fails. */
- if (i == len || r == 1)
- r = 0;
-
- return r;
-}
-
-#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)
-#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)
-#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)
-
-static int wl1273_fm_rds(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- struct i2c_client *client = core->client;
- u16 val;
- u8 b0 = WL1273_RDS_DATA_GET, status;
- struct v4l2_rds_data rds = { 0, 0, 0 };
- struct i2c_msg msg[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .buf = &b0,
- .len = 1,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .buf = (u8 *) &rds,
- .len = sizeof(rds),
- }
- };
- int r;
-
- if (core->mode != WL1273_MODE_RX)
- return 0;
-
- r = core->read(core, WL1273_RDS_SYNC_GET, &val);
- if (r)
- return r;
-
- if ((val & 0x01) == 0) {
- /* RDS decoder not synchronized */
- return -EAGAIN;
- }
-
- /* copy all four RDS blocks to internal buffer */
- do {
- r = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
- if (r != ARRAY_SIZE(msg)) {
- dev_err(radio->dev, WL1273_FM_DRIVER_NAME
- ": %s: read_rds error r == %i)\n",
- __func__, r);
- }
-
- status = rds.block;
-
- if (!WL1273_FIFO_HAS_DATA(status))
- break;
-
- /* copy bits 0-2 (the block ID) to bits 3-5 */
- rds.block = V4L2_RDS_BLOCK_MSK & status;
- rds.block |= rds.block << 3;
-
- /* copy the error bits to standard positions */
- if (WL1273_RDS_UNCORRECTABLE_ERROR & status) {
- rds.block |= V4L2_RDS_BLOCK_ERROR;
- rds.block &= ~V4L2_RDS_BLOCK_CORRECTED;
- } else if (WL1273_RDS_CORRECTABLE_ERROR & status) {
- rds.block &= ~V4L2_RDS_BLOCK_ERROR;
- rds.block |= V4L2_RDS_BLOCK_CORRECTED;
- }
-
- /* copy RDS block to internal buffer */
- memcpy(&radio->buffer[radio->wr_index], &rds, RDS_BLOCK_SIZE);
- radio->wr_index += 3;
-
- /* wrap write pointer */
- if (radio->wr_index >= radio->buf_size)
- radio->wr_index = 0;
-
- /* check for overflow & start over */
- if (radio->wr_index == radio->rd_index) {
- dev_dbg(radio->dev, "RDS OVERFLOW");
-
- radio->rd_index = 0;
- radio->wr_index = 0;
- break;
- }
- } while (WL1273_FIFO_HAS_DATA(status));
-
- /* wake up read queue */
- if (radio->wr_index != radio->rd_index)
- wake_up_interruptible(&radio->read_queue);
-
- return 0;
-}
-
-static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
-{
- struct wl1273_device *radio = dev_id;
- struct wl1273_core *core = radio->core;
- u16 flags;
- int r;
-
- r = core->read(core, WL1273_FLAG_GET, &flags);
- if (r)
- goto out;
-
- if (flags & WL1273_BL_EVENT) {
- radio->irq_received = flags;
- dev_dbg(radio->dev, "IRQ: BL\n");
- }
-
- if (flags & WL1273_RDS_EVENT) {
- msleep(200);
-
- wl1273_fm_rds(radio);
- }
-
- if (flags & WL1273_BBLK_EVENT)
- dev_dbg(radio->dev, "IRQ: BBLK\n");
-
- if (flags & WL1273_LSYNC_EVENT)
- dev_dbg(radio->dev, "IRQ: LSYNC\n");
-
- if (flags & WL1273_LEV_EVENT) {
- u16 level;
-
- r = core->read(core, WL1273_RSSI_LVL_GET, &level);
- if (r)
- goto out;
-
- if (level > 14)
- dev_dbg(radio->dev, "IRQ: LEV: 0x%x04\n", level);
- }
-
- if (flags & WL1273_IFFR_EVENT)
- dev_dbg(radio->dev, "IRQ: IFFR\n");
-
- if (flags & WL1273_PI_EVENT)
- dev_dbg(radio->dev, "IRQ: PI\n");
-
- if (flags & WL1273_PD_EVENT)
- dev_dbg(radio->dev, "IRQ: PD\n");
-
- if (flags & WL1273_STIC_EVENT)
- dev_dbg(radio->dev, "IRQ: STIC\n");
-
- if (flags & WL1273_MAL_EVENT)
- dev_dbg(radio->dev, "IRQ: MAL\n");
-
- if (flags & WL1273_POW_ENB_EVENT) {
- complete(&radio->busy);
- dev_dbg(radio->dev, "NOT BUSY\n");
- dev_dbg(radio->dev, "IRQ: POW_ENB\n");
- }
-
- if (flags & WL1273_SCAN_OVER_EVENT)
- dev_dbg(radio->dev, "IRQ: SCAN_OVER\n");
-
- if (flags & WL1273_ERROR_EVENT)
- dev_dbg(radio->dev, "IRQ: ERROR\n");
-
- if (flags & WL1273_FR_EVENT) {
- u16 freq;
-
- dev_dbg(radio->dev, "IRQ: FR:\n");
-
- if (core->mode == WL1273_MODE_RX) {
- r = core->write(core, WL1273_TUNER_MODE_SET,
- TUNER_MODE_STOP_SEARCH);
- if (r) {
- dev_err(radio->dev,
- "%s: TUNER_MODE_SET fails: %d\n",
- __func__, r);
- goto out;
- }
-
- r = core->read(core, WL1273_FREQ_SET, &freq);
- if (r)
- goto out;
-
- if (radio->band == WL1273_BAND_JAPAN)
- radio->rx_frequency = WL1273_BAND_JAPAN_LOW +
- freq * 50;
- else
- radio->rx_frequency = WL1273_BAND_OTHER_LOW +
- freq * 50;
- /*
- * The driver works better with this msleep,
- * the documentation doesn't mention it.
- */
- usleep_range(10000, 15000);
-
- dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);
-
- } else {
- r = core->read(core, WL1273_CHANL_SET, &freq);
- if (r)
- goto out;
-
- dev_dbg(radio->dev, "%dkHz\n", freq);
- }
- dev_dbg(radio->dev, "%s: NOT BUSY\n", __func__);
- }
-
-out:
- core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
- complete(&radio->busy);
-
- return IRQ_HANDLED;
-}
-
-static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
-{
- struct wl1273_core *core = radio->core;
- int r = 0;
- unsigned long t;
-
- if (freq < WL1273_BAND_TX_LOW) {
- dev_err(radio->dev,
- "Frequency out of range: %d < %d\n", freq,
- WL1273_BAND_TX_LOW);
- return -ERANGE;
- }
-
- if (freq > WL1273_BAND_TX_HIGH) {
- dev_err(radio->dev,
- "Frequency out of range: %d > %d\n", freq,
- WL1273_BAND_TX_HIGH);
- return -ERANGE;
- }
-
- /*
- * The driver works better with this sleep,
- * the documentation doesn't mention it.
- */
- usleep_range(5000, 10000);
-
- dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);
-
- /* Set the current tx channel */
- r = core->write(core, WL1273_CHANL_SET, freq / 10);
- if (r)
- return r;
-
- reinit_completion(&radio->busy);
-
- /* wait for the FR IRQ */
- t = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000));
- if (!t)
- return -ETIMEDOUT;
-
- dev_dbg(radio->dev, "WL1273_CHANL_SET: %lu\n", t);
-
- /* Enable the output power */
- r = core->write(core, WL1273_POWER_ENB_SET, 1);
- if (r)
- return r;
-
- reinit_completion(&radio->busy);
-
- /* wait for the POWER_ENB IRQ */
- t = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));
- if (!t)
- return -ETIMEDOUT;
-
- radio->tx_frequency = freq;
- dev_dbg(radio->dev, "WL1273_POWER_ENB_SET: %lu\n", t);
-
- return 0;
-}
-
-static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)
-{
- struct wl1273_core *core = radio->core;
- int r, f;
- unsigned long t;
-
- if (freq < radio->rangelow) {
- dev_err(radio->dev,
- "Frequency out of range: %d < %d\n", freq,
- radio->rangelow);
- r = -ERANGE;
- goto err;
- }
-
- if (freq > radio->rangehigh) {
- dev_err(radio->dev,
- "Frequency out of range: %d > %d\n", freq,
- radio->rangehigh);
- r = -ERANGE;
- goto err;
- }
-
- dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);
-
- core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
-
- if (radio->band == WL1273_BAND_JAPAN)
- f = (freq - WL1273_BAND_JAPAN_LOW) / 50;
- else
- f = (freq - WL1273_BAND_OTHER_LOW) / 50;
-
- r = core->write(core, WL1273_FREQ_SET, f);
- if (r) {
- dev_err(radio->dev, "FREQ_SET fails\n");
- goto err;
- }
-
- r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
- if (r) {
- dev_err(radio->dev, "TUNER_MODE_SET fails\n");
- goto err;
- }
-
- reinit_completion(&radio->busy);
-
- t = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000));
- if (!t) {
- dev_err(radio->dev, "%s: TIMEOUT\n", __func__);
- return -ETIMEDOUT;
- }
-
- radio->rd_index = 0;
- radio->wr_index = 0;
- radio->rx_frequency = freq;
- return 0;
-err:
- return r;
-}
-
-static int wl1273_fm_get_freq(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- unsigned int freq;
- u16 f;
- int r;
-
- if (core->mode == WL1273_MODE_RX) {
- r = core->read(core, WL1273_FREQ_SET, &f);
- if (r)
- return r;
-
- dev_dbg(radio->dev, "Freq get: 0x%04x\n", f);
- if (radio->band == WL1273_BAND_JAPAN)
- freq = WL1273_BAND_JAPAN_LOW + 50 * f;
- else
- freq = WL1273_BAND_OTHER_LOW + 50 * f;
- } else {
- r = core->read(core, WL1273_CHANL_SET, &f);
- if (r)
- return r;
-
- freq = f * 10;
- }
-
- return freq;
-}
-
-/**
- * wl1273_fm_upload_firmware_patch() - Upload the firmware.
- * @radio: A pointer to the device struct.
- *
- * The firmware file consists of arrays of bytes where the first byte
- * gives the array length. The first byte in the file gives the
- * number of these arrays.
- */
-static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- unsigned int packet_num;
- const struct firmware *fw_p;
- const char *fw_name = "radio-wl1273-fw.bin";
- struct device *dev = radio->dev;
- __u8 *ptr;
- int r;
-
- dev_dbg(dev, "%s:\n", __func__);
-
- /*
- * Uploading the firmware patch is not always necessary,
- * so we only print an info message.
- */
- if (request_firmware(&fw_p, fw_name, dev)) {
- dev_info(dev, "%s - %s not found\n", __func__, fw_name);
-
- return 0;
- }
-
- ptr = (__u8 *) fw_p->data;
- packet_num = ptr[0];
- dev_dbg(dev, "%s: packets: %d\n", __func__, packet_num);
-
- r = wl1273_fm_write_fw(core, ptr + 1, packet_num);
- if (r) {
- dev_err(dev, "FW upload error: %d\n", r);
- goto out;
- }
-
- /* ignore possible error here */
- core->write(core, WL1273_RESET, 0);
-
- dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);
-out:
- release_firmware(fw_p);
- return r;
-}
-
-static int wl1273_fm_stop(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
-
- if (core->mode == WL1273_MODE_RX) {
- int r = core->write(core, WL1273_POWER_SET,
- WL1273_POWER_SET_OFF);
- if (r)
- dev_err(radio->dev, "%s: POWER_SET fails: %d\n",
- __func__, r);
- } else if (core->mode == WL1273_MODE_TX) {
- int r = core->write(core, WL1273_PUPD_SET,
- WL1273_PUPD_SET_OFF);
- if (r)
- dev_err(radio->dev,
- "%s: PUPD_SET fails: %d\n", __func__, r);
- }
-
- if (core->pdata->disable) {
- core->pdata->disable();
- dev_dbg(radio->dev, "Back to reset\n");
- }
-
- return 0;
-}
-
-static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
-{
- struct wl1273_core *core = radio->core;
- struct wl1273_fm_platform_data *pdata = core->pdata;
- struct device *dev = radio->dev;
- int r = -EINVAL;
-
- if (pdata->enable && core->mode == WL1273_MODE_OFF) {
- dev_dbg(radio->dev, "Out of reset\n");
-
- pdata->enable();
- msleep(250);
- }
-
- if (new_mode == WL1273_MODE_RX) {
- u16 val = WL1273_POWER_SET_FM;
-
- if (radio->rds_on)
- val |= WL1273_POWER_SET_RDS;
-
- /* If this fails try again */
- r = core->write(core, WL1273_POWER_SET, val);
- if (r) {
- msleep(100);
-
- r = core->write(core, WL1273_POWER_SET, val);
- if (r) {
- dev_err(dev, "%s: POWER_SET fails\n", __func__);
- goto fail;
- }
- }
-
- /* rds buffer configuration */
- radio->wr_index = 0;
- radio->rd_index = 0;
-
- } else if (new_mode == WL1273_MODE_TX) {
- /* If this fails try again once */
- r = core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON);
- if (r) {
- msleep(100);
- r = core->write(core, WL1273_PUPD_SET,
- WL1273_PUPD_SET_ON);
- if (r) {
- dev_err(dev, "%s: PUPD_SET fails\n", __func__);
- goto fail;
- }
- }
-
- if (radio->rds_on) {
- r = core->write(core, WL1273_RDS_DATA_ENB, 1);
- if (r) {
- dev_err(dev, "%s: RDS_DATA_ENB ON fails\n",
- __func__);
- goto fail;
- }
- } else {
- r = core->write(core, WL1273_RDS_DATA_ENB, 0);
- if (r) {
- dev_err(dev, "%s: RDS_DATA_ENB OFF fails\n",
- __func__);
- goto fail;
- }
- }
- } else {
- dev_warn(dev, "%s: Illegal mode.\n", __func__);
- }
-
- if (core->mode == WL1273_MODE_OFF) {
- r = wl1273_fm_upload_firmware_patch(radio);
- if (r)
- dev_warn(dev, "Firmware upload failed.\n");
-
- /*
- * Sometimes the chip is in a wrong power state at this point.
- * So we set the power once again.
- */
- if (new_mode == WL1273_MODE_RX) {
- u16 val = WL1273_POWER_SET_FM;
-
- if (radio->rds_on)
- val |= WL1273_POWER_SET_RDS;
-
- r = core->write(core, WL1273_POWER_SET, val);
- if (r) {
- dev_err(dev, "%s: POWER_SET fails\n", __func__);
- goto fail;
- }
- } else if (new_mode == WL1273_MODE_TX) {
- r = core->write(core, WL1273_PUPD_SET,
- WL1273_PUPD_SET_ON);
- if (r) {
- dev_err(dev, "%s: PUPD_SET fails\n", __func__);
- goto fail;
- }
- }
- }
-
- return 0;
-fail:
- if (pdata->disable)
- pdata->disable();
-
- dev_dbg(dev, "%s: return: %d\n", __func__, r);
- return r;
-}
-
-static int wl1273_fm_suspend(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- int r;
-
- /* Cannot go from OFF to SUSPENDED */
- if (core->mode == WL1273_MODE_RX)
- r = core->write(core, WL1273_POWER_SET,
- WL1273_POWER_SET_RETENTION);
- else if (core->mode == WL1273_MODE_TX)
- r = core->write(core, WL1273_PUPD_SET,
- WL1273_PUPD_SET_RETENTION);
- else
- r = -EINVAL;
-
- if (r) {
- dev_err(radio->dev, "%s: POWER_SET fails: %d\n", __func__, r);
- goto out;
- }
-
-out:
- return r;
-}
-
-static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)
-{
- struct wl1273_core *core = radio->core;
- struct device *dev = radio->dev;
- int old_mode;
- int r;
-
- dev_dbg(dev, "%s\n", __func__);
- dev_dbg(dev, "Forbidden modes: 0x%02x\n", radio->forbidden);
-
- old_mode = core->mode;
- if (mode & radio->forbidden) {
- r = -EPERM;
- goto out;
- }
-
- switch (mode) {
- case WL1273_MODE_RX:
- case WL1273_MODE_TX:
- r = wl1273_fm_start(radio, mode);
- if (r) {
- dev_err(dev, "%s: Cannot start.\n", __func__);
- wl1273_fm_stop(radio);
- goto out;
- }
-
- core->mode = mode;
- r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
- if (r) {
- dev_err(dev, "INT_MASK_SET fails.\n");
- goto out;
- }
-
- /* remember previous settings */
- if (mode == WL1273_MODE_RX) {
- r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);
- if (r) {
- dev_err(dev, "set freq fails: %d.\n", r);
- goto out;
- }
-
- r = core->set_volume(core, core->volume);
- if (r) {
- dev_err(dev, "set volume fails: %d.\n", r);
- goto out;
- }
-
- dev_dbg(dev, "%s: Set vol: %d.\n", __func__,
- core->volume);
- } else {
- r = wl1273_fm_set_tx_freq(radio, radio->tx_frequency);
- if (r) {
- dev_err(dev, "set freq fails: %d.\n", r);
- goto out;
- }
- }
-
- dev_dbg(radio->dev, "%s: Set audio mode.\n", __func__);
-
- r = core->set_audio(core, core->audio_mode);
- if (r)
- dev_err(dev, "Cannot set audio mode.\n");
- break;
-
- case WL1273_MODE_OFF:
- r = wl1273_fm_stop(radio);
- if (r)
- dev_err(dev, "%s: Off fails: %d\n", __func__, r);
- else
- core->mode = WL1273_MODE_OFF;
-
- break;
-
- case WL1273_MODE_SUSPENDED:
- r = wl1273_fm_suspend(radio);
- if (r)
- dev_err(dev, "%s: Suspend fails: %d\n", __func__, r);
- else
- core->mode = WL1273_MODE_SUSPENDED;
-
- break;
-
- default:
- dev_err(dev, "%s: Unknown mode: %d\n", __func__, mode);
- r = -EINVAL;
- break;
- }
-out:
- if (r)
- core->mode = old_mode;
-
- return r;
-}
-
-static int wl1273_fm_set_seek(struct wl1273_device *radio,
- unsigned int wrap_around,
- unsigned int seek_upward,
- int level)
-{
- struct wl1273_core *core = radio->core;
- int r = 0;
- unsigned int dir = (seek_upward == 0) ? 0 : 1;
- unsigned int f;
-
- f = radio->rx_frequency;
- dev_dbg(radio->dev, "rx_frequency: %d\n", f);
-
- if (dir && f + radio->spacing <= radio->rangehigh)
- r = wl1273_fm_set_rx_freq(radio, f + radio->spacing);
- else if (dir && wrap_around)
- r = wl1273_fm_set_rx_freq(radio, radio->rangelow);
- else if (f - radio->spacing >= radio->rangelow)
- r = wl1273_fm_set_rx_freq(radio, f - radio->spacing);
- else if (wrap_around)
- r = wl1273_fm_set_rx_freq(radio, radio->rangehigh);
-
- if (r)
- goto out;
-
- if (level < SCHAR_MIN || level > SCHAR_MAX)
- return -EINVAL;
-
- reinit_completion(&radio->busy);
- dev_dbg(radio->dev, "%s: BUSY\n", __func__);
-
- r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
- if (r)
- goto out;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- r = core->write(core, WL1273_SEARCH_LVL_SET, level);
- if (r)
- goto out;
-
- r = core->write(core, WL1273_SEARCH_DIR_SET, dir);
- if (r)
- goto out;
-
- r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
- if (r)
- goto out;
-
- /* wait for the FR IRQ */
- wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000));
- if (!(radio->irq_received & WL1273_BL_EVENT)) {
- r = -ETIMEDOUT;
- goto out;
- }
-
- radio->irq_received &= ~WL1273_BL_EVENT;
-
- if (!wrap_around)
- goto out;
-
- /* Wrap around */
- dev_dbg(radio->dev, "Wrap around in HW seek.\n");
-
- if (seek_upward)
- f = radio->rangelow;
- else
- f = radio->rangehigh;
-
- r = wl1273_fm_set_rx_freq(radio, f);
- if (r)
- goto out;
-
- reinit_completion(&radio->busy);
- dev_dbg(radio->dev, "%s: BUSY\n", __func__);
-
- r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
- if (r)
- goto out;
-
- /* wait for the FR IRQ */
- if (!wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)))
- r = -ETIMEDOUT;
-out:
- dev_dbg(radio->dev, "%s: Err: %d\n", __func__, r);
- return r;
-}
-
-/**
- * wl1273_fm_get_tx_ctune() - Get the TX tuning capacitor value.
- * @radio: A pointer to the device struct.
- */
-static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- struct device *dev = radio->dev;
- u16 val;
- int r;
-
- if (core->mode == WL1273_MODE_OFF ||
- core->mode == WL1273_MODE_SUSPENDED)
- return -EPERM;
-
- r = core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
- if (r) {
- dev_err(dev, "%s: read error: %d\n", __func__, r);
- goto out;
- }
-
-out:
- return val;
-}
-
-/**
- * wl1273_fm_set_preemphasis() - Set the TX pre-emphasis value.
- * @radio: A pointer to the device struct.
- * @preemphasis: The new pre-amphasis value.
- *
- * Possible pre-emphasis values are: V4L2_PREEMPHASIS_DISABLED,
- * V4L2_PREEMPHASIS_50_uS and V4L2_PREEMPHASIS_75_uS.
- */
-static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,
- unsigned int preemphasis)
-{
- struct wl1273_core *core = radio->core;
- int r;
- u16 em;
-
- if (core->mode == WL1273_MODE_OFF ||
- core->mode == WL1273_MODE_SUSPENDED)
- return -EPERM;
-
- mutex_lock(&core->lock);
-
- switch (preemphasis) {
- case V4L2_PREEMPHASIS_DISABLED:
- em = 1;
- break;
- case V4L2_PREEMPHASIS_50_uS:
- em = 0;
- break;
- case V4L2_PREEMPHASIS_75_uS:
- em = 2;
- break;
- default:
- r = -EINVAL;
- goto out;
- }
-
- r = core->write(core, WL1273_PREMPH_SET, em);
- if (r)
- goto out;
-
- radio->preemphasis = preemphasis;
-
-out:
- mutex_unlock(&core->lock);
- return r;
-}
-
-static int wl1273_fm_rds_on(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- int r;
-
- dev_dbg(radio->dev, "%s\n", __func__);
- if (radio->rds_on)
- return 0;
-
- r = core->write(core, WL1273_POWER_SET,
- WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);
- if (r)
- goto out;
-
- r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);
- if (r)
- dev_err(radio->dev, "set freq fails: %d.\n", r);
-out:
- return r;
-}
-
-static int wl1273_fm_rds_off(struct wl1273_device *radio)
-{
- struct wl1273_core *core = radio->core;
- int r;
-
- if (!radio->rds_on)
- return 0;
-
- radio->irq_flags &= ~WL1273_RDS_EVENT;
-
- r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
- if (r)
- goto out;
-
- /* Service pending read */
- wake_up_interruptible(&radio->read_queue);
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- r = core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
- if (r)
- goto out;
-
- r = wl1273_fm_set_rx_freq(radio, radio->rx_frequency);
- if (r)
- dev_err(radio->dev, "set freq fails: %d.\n", r);
-out:
- dev_dbg(radio->dev, "%s: exiting...\n", __func__);
-
- return r;
-}
-
-static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)
-{
- int r = 0;
- struct wl1273_core *core = radio->core;
-
- if (core->mode == WL1273_MODE_OFF ||
- core->mode == WL1273_MODE_SUSPENDED)
- return -EPERM;
-
- if (new_mode == WL1273_RDS_RESET) {
- r = core->write(core, WL1273_RDS_CNTRL_SET, 1);
- return r;
- }
-
- if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {
- r = core->write(core, WL1273_RDS_DATA_ENB, 0);
- } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {
- r = core->write(core, WL1273_RDS_DATA_ENB, 1);
- } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {
- r = wl1273_fm_rds_off(radio);
- } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {
- r = wl1273_fm_rds_on(radio);
- } else {
- dev_err(radio->dev, "%s: Unknown mode: %d\n",
- __func__, new_mode);
- r = -EINVAL;
- }
-
- if (!r)
- radio->rds_on = new_mode == WL1273_RDS_ON;
-
- return r;
-}
-
-static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- u16 val;
- int r;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (core->mode != WL1273_MODE_TX)
- return count;
-
- if (radio->rds_users == 0) {
- dev_warn(radio->dev, "%s: RDS not on.\n", __func__);
- return 0;
- }
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
- /*
- * Multiple processes can open the device, but only
- * one gets to write to it.
- */
- if (radio->owner && radio->owner != file) {
- r = -EBUSY;
- goto out;
- }
- radio->owner = file;
-
- /* Manual Mode */
- if (count > 255)
- val = 255;
- else
- val = count;
-
- core->write(core, WL1273_RDS_CONFIG_DATA_SET, val);
-
- if (copy_from_user(radio->write_buf + 1, buf, val)) {
- r = -EFAULT;
- goto out;
- }
-
- dev_dbg(radio->dev, "Count: %d\n", val);
- dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);
-
- radio->write_buf[0] = WL1273_RDS_DATA_SET;
- core->write_data(core, radio->write_buf, val + 1);
-
- r = val;
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static __poll_t wl1273_fm_fops_poll(struct file *file,
- struct poll_table_struct *pts)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
-
- if (radio->owner && radio->owner != file)
- return EPOLLERR;
-
- radio->owner = file;
-
- if (core->mode == WL1273_MODE_RX) {
- poll_wait(file, &radio->read_queue, pts);
-
- if (radio->rd_index != radio->wr_index)
- return EPOLLIN | EPOLLRDNORM;
-
- } else if (core->mode == WL1273_MODE_TX) {
- return EPOLLOUT | EPOLLWRNORM;
- }
-
- return 0;
-}
-
-static int wl1273_fm_fops_open(struct file *file)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- int r = 0;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (core->mode == WL1273_MODE_RX && radio->rds_on &&
- !radio->rds_users) {
- dev_dbg(radio->dev, "%s: Mode: %d\n", __func__, core->mode);
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- radio->irq_flags |= WL1273_RDS_EVENT;
-
- r = core->write(core, WL1273_INT_MASK_SET,
- radio->irq_flags);
- if (r) {
- mutex_unlock(&core->lock);
- goto out;
- }
-
- radio->rds_users++;
-
- mutex_unlock(&core->lock);
- }
-out:
- return r;
-}
-
-static int wl1273_fm_fops_release(struct file *file)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- int r = 0;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (radio->rds_users > 0) {
- radio->rds_users--;
- if (radio->rds_users == 0) {
- mutex_lock(&core->lock);
-
- radio->irq_flags &= ~WL1273_RDS_EVENT;
-
- if (core->mode == WL1273_MODE_RX) {
- r = core->write(core,
- WL1273_INT_MASK_SET,
- radio->irq_flags);
- if (r) {
- mutex_unlock(&core->lock);
- goto out;
- }
- }
- mutex_unlock(&core->lock);
- }
- }
-
- if (file == radio->owner)
- radio->owner = NULL;
-out:
- return r;
-}
-
-static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- int r = 0;
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- unsigned int block_count = 0;
- u16 val;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (core->mode != WL1273_MODE_RX)
- return 0;
-
- if (radio->rds_users == 0) {
- dev_warn(radio->dev, "%s: RDS not on.\n", __func__);
- return 0;
- }
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- /*
- * Multiple processes can open the device, but only
- * one at a time gets read access.
- */
- if (radio->owner && radio->owner != file) {
- r = -EBUSY;
- goto out;
- }
- radio->owner = file;
-
- r = core->read(core, WL1273_RDS_SYNC_GET, &val);
- if (r) {
- dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);
- goto out;
- } else if (val == 0) {
- dev_info(radio->dev, "RDS_SYNC: Not synchronized\n");
- r = -ENODATA;
- goto out;
- }
-
- /* block if no new data available */
- while (radio->wr_index == radio->rd_index) {
- if (file->f_flags & O_NONBLOCK) {
- r = -EWOULDBLOCK;
- goto out;
- }
-
- dev_dbg(radio->dev, "%s: Wait for RDS data.\n", __func__);
- if (wait_event_interruptible(radio->read_queue,
- radio->wr_index !=
- radio->rd_index) < 0) {
- r = -EINTR;
- goto out;
- }
- }
-
- /* calculate block count from byte count */
- count /= RDS_BLOCK_SIZE;
-
- /* copy RDS blocks from the internal buffer and to user buffer */
- while (block_count < count) {
- if (radio->rd_index == radio->wr_index)
- break;
-
- /* always transfer complete RDS blocks */
- if (copy_to_user(buf, &radio->buffer[radio->rd_index],
- RDS_BLOCK_SIZE))
- break;
-
- /* increment and wrap the read pointer */
- radio->rd_index += RDS_BLOCK_SIZE;
- if (radio->rd_index >= radio->buf_size)
- radio->rd_index = 0;
-
- /* increment counters */
- block_count++;
- buf += RDS_BLOCK_SIZE;
- r += RDS_BLOCK_SIZE;
- }
-
-out:
- dev_dbg(radio->dev, "%s: exit\n", __func__);
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static const struct v4l2_file_operations wl1273_fops = {
- .owner = THIS_MODULE,
- .read = wl1273_fm_fops_read,
- .write = wl1273_fm_fops_write,
- .poll = wl1273_fm_fops_poll,
- .unlocked_ioctl = video_ioctl2,
- .open = wl1273_fm_fops_open,
- .release = wl1273_fm_fops_release,
-};
-
-static int wl1273_fm_vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *capability)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- strscpy(capability->driver, WL1273_FM_DRIVER_NAME,
- sizeof(capability->driver));
- strscpy(capability->card, "TI Wl1273 FM Radio",
- sizeof(capability->card));
- strscpy(capability->bus_info, radio->bus_type,
- sizeof(capability->bus_info));
- return 0;
-}
-
-static int wl1273_fm_vidioc_g_input(struct file *file, void *priv,
- unsigned int *i)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- *i = 0;
-
- return 0;
-}
-
-static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
- unsigned int i)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (i != 0)
- return -EINVAL;
-
- return 0;
-}
-
-/**
- * wl1273_fm_set_tx_power() - Set the transmission power value.
- * @radio: A pointer to the device struct.
- * @power: The new power value.
- */
-static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
-{
- struct wl1273_core *core = radio->core;
- int r;
-
- if (core->mode == WL1273_MODE_OFF ||
- core->mode == WL1273_MODE_SUSPENDED)
- return -EPERM;
-
- mutex_lock(&core->lock);
-
- /* Convert the dBuV value to chip presentation */
- r = core->write(core, WL1273_POWER_LEV_SET, 122 - power);
- if (r)
- goto out;
-
- radio->tx_power = power;
-
-out:
- mutex_unlock(&core->lock);
- return r;
-}
-
-#define WL1273_SPACING_50kHz 1
-#define WL1273_SPACING_100kHz 2
-#define WL1273_SPACING_200kHz 4
-
-static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,
- unsigned int spacing)
-{
- struct wl1273_core *core = radio->core;
- int r;
-
- if (spacing == 0) {
- r = core->write(core, WL1273_SCAN_SPACING_SET,
- WL1273_SPACING_100kHz);
- radio->spacing = 100;
- } else if (spacing - 50000 < 25000) {
- r = core->write(core, WL1273_SCAN_SPACING_SET,
- WL1273_SPACING_50kHz);
- radio->spacing = 50;
- } else if (spacing - 100000 < 50000) {
- r = core->write(core, WL1273_SCAN_SPACING_SET,
- WL1273_SPACING_100kHz);
- radio->spacing = 100;
- } else {
- r = core->write(core, WL1273_SCAN_SPACING_SET,
- WL1273_SPACING_200kHz);
- radio->spacing = 200;
- }
-
- return r;
-}
-
-static int wl1273_fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct wl1273_device *radio = ctrl->priv;
- struct wl1273_core *core = radio->core;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- switch (ctrl->id) {
- case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
- ctrl->val = wl1273_fm_get_tx_ctune(radio);
- break;
-
- default:
- dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n",
- __func__, ctrl->id);
- break;
- }
-
- mutex_unlock(&core->lock);
-
- return 0;
-}
-
-#define WL1273_MUTE_SOFT_ENABLE (1 << 0)
-#define WL1273_MUTE_AC (1 << 1)
-#define WL1273_MUTE_HARD_LEFT (1 << 2)
-#define WL1273_MUTE_HARD_RIGHT (1 << 3)
-#define WL1273_MUTE_SOFT_FORCE (1 << 4)
-
-static inline struct wl1273_device *to_radio(struct v4l2_ctrl *ctrl)
-{
- return container_of(ctrl->handler, struct wl1273_device, ctrl_handler);
-}
-
-static int wl1273_fm_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct wl1273_device *radio = to_radio(ctrl);
- struct wl1273_core *core = radio->core;
- int r = 0;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- if (core->mode == WL1273_MODE_RX && ctrl->val)
- r = core->write(core,
- WL1273_MUTE_STATUS_SET,
- WL1273_MUTE_HARD_LEFT |
- WL1273_MUTE_HARD_RIGHT);
- else if (core->mode == WL1273_MODE_RX)
- r = core->write(core,
- WL1273_MUTE_STATUS_SET, 0x0);
- else if (core->mode == WL1273_MODE_TX && ctrl->val)
- r = core->write(core, WL1273_MUTE, 1);
- else if (core->mode == WL1273_MODE_TX)
- r = core->write(core, WL1273_MUTE, 0);
-
- mutex_unlock(&core->lock);
- break;
-
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->val == 0)
- r = wl1273_fm_set_mode(radio, WL1273_MODE_OFF);
- else
- r = core->set_volume(core, core->volume);
- break;
-
- case V4L2_CID_TUNE_PREEMPHASIS:
- r = wl1273_fm_set_preemphasis(radio, ctrl->val);
- break;
-
- case V4L2_CID_TUNE_POWER_LEVEL:
- r = wl1273_fm_set_tx_power(radio, ctrl->val);
- break;
-
- default:
- dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n",
- __func__, ctrl->id);
- break;
- }
-
- dev_dbg(radio->dev, "%s\n", __func__);
- return r;
-}
-
-static int wl1273_fm_vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *audio)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (audio->index > 1)
- return -EINVAL;
-
- strscpy(audio->name, "Radio", sizeof(audio->name));
- audio->capability = V4L2_AUDCAP_STEREO;
-
- return 0;
-}
-
-static int wl1273_fm_vidioc_s_audio(struct file *file, void *priv,
- const struct v4l2_audio *audio)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (audio->index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-#define WL1273_RDS_NOT_SYNCHRONIZED 0
-#define WL1273_RDS_SYNCHRONIZED 1
-
-static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *tuner)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- u16 val;
- int r;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (tuner->index > 0)
- return -EINVAL;
-
- strscpy(tuner->name, WL1273_FM_DRIVER_NAME, sizeof(tuner->name));
- tuner->type = V4L2_TUNER_RADIO;
-
- tuner->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);
- tuner->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);
-
- tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO |
- V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP;
-
- if (radio->stereo)
- tuner->audmode = V4L2_TUNER_MODE_STEREO;
- else
- tuner->audmode = V4L2_TUNER_MODE_MONO;
-
- if (core->mode != WL1273_MODE_RX)
- return 0;
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- r = core->read(core, WL1273_STEREO_GET, &val);
- if (r)
- goto out;
-
- if (val == 1)
- tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
- else
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
-
- r = core->read(core, WL1273_RSSI_LVL_GET, &val);
- if (r)
- goto out;
-
- tuner->signal = (s16) val;
- dev_dbg(radio->dev, "Signal: %d\n", tuner->signal);
-
- tuner->afc = 0;
-
- r = core->read(core, WL1273_RDS_SYNC_GET, &val);
- if (r)
- goto out;
-
- if (val == WL1273_RDS_SYNCHRONIZED)
- tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
- const struct v4l2_tuner *tuner)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- int r = 0;
-
- dev_dbg(radio->dev, "%s\n", __func__);
- dev_dbg(radio->dev, "tuner->index: %d\n", tuner->index);
- dev_dbg(radio->dev, "tuner->name: %s\n", tuner->name);
- dev_dbg(radio->dev, "tuner->capability: 0x%04x\n", tuner->capability);
- dev_dbg(radio->dev, "tuner->rxsubchans: 0x%04x\n", tuner->rxsubchans);
- dev_dbg(radio->dev, "tuner->rangelow: %d\n", tuner->rangelow);
- dev_dbg(radio->dev, "tuner->rangehigh: %d\n", tuner->rangehigh);
-
- if (tuner->index > 0)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- r = wl1273_fm_set_mode(radio, WL1273_MODE_RX);
- if (r)
- goto out;
-
- if (tuner->rxsubchans & V4L2_TUNER_SUB_RDS)
- r = wl1273_fm_set_rds(radio, WL1273_RDS_ON);
- else
- r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
-
- if (r)
- dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);
-
- if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
- r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
- if (r < 0) {
- dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
- __func__, r);
- goto out;
- }
- radio->stereo = false;
- } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {
- r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
- if (r < 0) {
- dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
- __func__, r);
- goto out;
- }
- radio->stereo = true;
- } else {
- dev_err(radio->dev, "%s: tuner->audmode: %d\n",
- __func__, tuner->audmode);
- r = -EINVAL;
- goto out;
- }
-
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int wl1273_fm_vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *freq)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- freq->type = V4L2_TUNER_RADIO;
- freq->frequency = WL1273_FREQ(wl1273_fm_get_freq(radio));
-
- mutex_unlock(&core->lock);
-
- return 0;
-}
-
-static int wl1273_fm_vidioc_s_frequency(struct file *file, void *priv,
- const struct v4l2_frequency *freq)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- int r;
-
- dev_dbg(radio->dev, "%s: %d\n", __func__, freq->frequency);
-
- if (freq->type != V4L2_TUNER_RADIO) {
- dev_dbg(radio->dev,
- "freq->type != V4L2_TUNER_RADIO: %d\n", freq->type);
- return -EINVAL;
- }
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- if (core->mode == WL1273_MODE_RX) {
- dev_dbg(radio->dev, "freq: %d\n", freq->frequency);
-
- r = wl1273_fm_set_rx_freq(radio,
- WL1273_INV_FREQ(freq->frequency));
- if (r)
- dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
- ": set frequency failed with %d\n", r);
- } else {
- r = wl1273_fm_set_tx_freq(radio,
- WL1273_INV_FREQ(freq->frequency));
- if (r)
- dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
- ": set frequency failed with %d\n", r);
- }
-
- mutex_unlock(&core->lock);
-
- dev_dbg(radio->dev, "wl1273_vidioc_s_frequency: DONE\n");
- return r;
-}
-
-#define WL1273_DEFAULT_SEEK_LEVEL 7
-
-static int wl1273_fm_vidioc_s_hw_freq_seek(struct file *file, void *priv,
- const struct v4l2_hw_freq_seek *seek)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- int r;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (seek->tuner != 0 || seek->type != V4L2_TUNER_RADIO)
- return -EINVAL;
-
- if (file->f_flags & O_NONBLOCK)
- return -EWOULDBLOCK;
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- r = wl1273_fm_set_mode(radio, WL1273_MODE_RX);
- if (r)
- goto out;
-
- r = wl1273_fm_tx_set_spacing(radio, seek->spacing);
- if (r)
- dev_warn(radio->dev, "HW seek failed: %d\n", r);
-
- r = wl1273_fm_set_seek(radio, seek->wrap_around, seek->seek_upward,
- WL1273_DEFAULT_SEEK_LEVEL);
- if (r)
- dev_warn(radio->dev, "HW seek failed: %d\n", r);
-
-out:
- mutex_unlock(&core->lock);
- return r;
-}
-
-static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
- const struct v4l2_modulator *modulator)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- int r = 0;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- if (modulator->index > 0)
- return -EINVAL;
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- r = wl1273_fm_set_mode(radio, WL1273_MODE_TX);
- if (r)
- goto out;
-
- if (modulator->txsubchans & V4L2_TUNER_SUB_RDS)
- r = wl1273_fm_set_rds(radio, WL1273_RDS_ON);
- else
- r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
-
- if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
- r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
- else
- r = core->write(core, WL1273_MONO_SET,
- WL1273_RX_STEREO);
- if (r < 0)
- dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
- "MONO_SET fails: %d\n", r);
-out:
- mutex_unlock(&core->lock);
-
- return r;
-}
-
-static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
- struct v4l2_modulator *modulator)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- u16 val;
- int r;
-
- dev_dbg(radio->dev, "%s\n", __func__);
-
- strscpy(modulator->name, WL1273_FM_DRIVER_NAME,
- sizeof(modulator->name));
-
- modulator->rangelow = WL1273_FREQ(WL1273_BAND_JAPAN_LOW);
- modulator->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);
-
- modulator->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO;
-
- if (core->mode != WL1273_MODE_TX)
- return 0;
-
- if (mutex_lock_interruptible(&core->lock))
- return -EINTR;
-
- r = core->read(core, WL1273_MONO_SET, &val);
- if (r)
- goto out;
-
- if (val == WL1273_TX_STEREO)
- modulator->txsubchans = V4L2_TUNER_SUB_STEREO;
- else
- modulator->txsubchans = V4L2_TUNER_SUB_MONO;
-
- if (radio->rds_on)
- modulator->txsubchans |= V4L2_TUNER_SUB_RDS;
-out:
- mutex_unlock(&core->lock);
-
- return 0;
-}
-
-static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
-{
- struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
- struct wl1273_core *core = radio->core;
- struct device *dev = radio->dev;
- u16 val;
- int r;
-
- dev_info(dev, DRIVER_DESC);
-
- if (core->mode == WL1273_MODE_OFF) {
- dev_info(dev, "Mode: Off\n");
- return 0;
- }
-
- if (core->mode == WL1273_MODE_SUSPENDED) {
- dev_info(dev, "Mode: Suspended\n");
- return 0;
- }
-
- r = core->read(core, WL1273_ASIC_ID_GET, &val);
- if (r)
- dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);
- else
- dev_info(dev, "ASIC_ID: 0x%04x\n", val);
-
- r = core->read(core, WL1273_ASIC_VER_GET, &val);
- if (r)
- dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);
- else
- dev_info(dev, "ASIC Version: 0x%04x\n", val);
-
- r = core->read(core, WL1273_FIRM_VER_GET, &val);
- if (r)
- dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);
- else
- dev_info(dev, "FW version: %d(0x%04x)\n", val, val);
-
- r = core->read(core, WL1273_BAND_SET, &val);
- if (r)
- dev_err(dev, "%s: Get BAND fails.\n", __func__);
- else
- dev_info(dev, "BAND: %d\n", val);
-
- if (core->mode == WL1273_MODE_TX) {
- r = core->read(core, WL1273_PUPD_SET, &val);
- if (r)
- dev_err(dev, "%s: Get PUPD fails.\n", __func__);
- else
- dev_info(dev, "PUPD: 0x%04x\n", val);
-
- r = core->read(core, WL1273_CHANL_SET, &val);
- if (r)
- dev_err(dev, "%s: Get CHANL fails.\n", __func__);
- else
- dev_info(dev, "Tx frequency: %dkHz\n", val*10);
- } else if (core->mode == WL1273_MODE_RX) {
- int bf = radio->rangelow;
-
- r = core->read(core, WL1273_FREQ_SET, &val);
- if (r)
- dev_err(dev, "%s: Get FREQ fails.\n", __func__);
- else
- dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);
-
- r = core->read(core, WL1273_MOST_MODE_SET, &val);
- if (r)
- dev_err(dev, "%s: Get MOST_MODE fails.\n",
- __func__);
- else if (val == 0)
- dev_info(dev, "MOST_MODE: Stereo according to blend\n");
- else if (val == 1)
- dev_info(dev, "MOST_MODE: Force mono output\n");
- else
- dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);
-
- r = core->read(core, WL1273_MOST_BLEND_SET, &val);
- if (r)
- dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);
- else if (val == 0)
- dev_info(dev,
- "MOST_BLEND: Switched blend & hysteresis.\n");
- else if (val == 1)
- dev_info(dev, "MOST_BLEND: Soft blend.\n");
- else
- dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);
-
- r = core->read(core, WL1273_STEREO_GET, &val);
- if (r)
- dev_err(dev, "%s: Get STEREO fails.\n", __func__);
- else if (val == 0)
- dev_info(dev, "STEREO: Not detected\n");
- else if (val == 1)
- dev_info(dev, "STEREO: Detected\n");
- else
- dev_info(dev, "STEREO: Unexpected value: %d\n", val);
-
- r = core->read(core, WL1273_RSSI_LVL_GET, &val);
- if (r)
- dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);
- else
- dev_info(dev, "RX signal strength: %d\n", (s16) val);
-
- r = core->read(core, WL1273_POWER_SET, &val);
- if (r)
- dev_err(dev, "%s: Get POWER fails.\n", __func__);
- else
- dev_info(dev, "POWER: 0x%04x\n", val);
-
- r = core->read(core, WL1273_INT_MASK_SET, &val);
- if (r)
- dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);
- else
- dev_info(dev, "INT_MASK: 0x%04x\n", val);
-
- r = core->read(core, WL1273_RDS_SYNC_GET, &val);
- if (r)
- dev_err(dev, "%s: Get RDS_SYNC fails.\n",
- __func__);
- else if (val == 0)
- dev_info(dev, "RDS_SYNC: Not synchronized\n");
-
- else if (val == 1)
- dev_info(dev, "RDS_SYNC: Synchronized\n");
- else
- dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);
-
- r = core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val);
- if (r)
- dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",
- __func__);
- else
- dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);
-
- r = core->read(core, WL1273_VOLUME_SET, &val);
- if (r)
- dev_err(dev, "%s: Get VOLUME fails.\n", __func__);
- else
- dev_info(dev, "VOLUME: 0x%04x\n", val);
- }
-
- return 0;
-}
-
-static void wl1273_vdev_release(struct video_device *dev)
-{
-}
-
-static const struct v4l2_ctrl_ops wl1273_ctrl_ops = {
- .s_ctrl = wl1273_fm_s_ctrl,
- .g_volatile_ctrl = wl1273_fm_g_volatile_ctrl,
-};
-
-static const struct v4l2_ioctl_ops wl1273_ioctl_ops = {
- .vidioc_querycap = wl1273_fm_vidioc_querycap,
- .vidioc_g_input = wl1273_fm_vidioc_g_input,
- .vidioc_s_input = wl1273_fm_vidioc_s_input,
- .vidioc_g_audio = wl1273_fm_vidioc_g_audio,
- .vidioc_s_audio = wl1273_fm_vidioc_s_audio,
- .vidioc_g_tuner = wl1273_fm_vidioc_g_tuner,
- .vidioc_s_tuner = wl1273_fm_vidioc_s_tuner,
- .vidioc_g_frequency = wl1273_fm_vidioc_g_frequency,
- .vidioc_s_frequency = wl1273_fm_vidioc_s_frequency,
- .vidioc_s_hw_freq_seek = wl1273_fm_vidioc_s_hw_freq_seek,
- .vidioc_g_modulator = wl1273_fm_vidioc_g_modulator,
- .vidioc_s_modulator = wl1273_fm_vidioc_s_modulator,
- .vidioc_log_status = wl1273_fm_vidioc_log_status,
-};
-
-static const struct video_device wl1273_viddev_template = {
- .fops = &wl1273_fops,
- .ioctl_ops = &wl1273_ioctl_ops,
- .name = WL1273_FM_DRIVER_NAME,
- .release = wl1273_vdev_release,
- .vfl_dir = VFL_DIR_TX,
- .device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
- V4L2_CAP_RADIO | V4L2_CAP_AUDIO |
- V4L2_CAP_RDS_CAPTURE | V4L2_CAP_MODULATOR |
- V4L2_CAP_RDS_OUTPUT,
-};
-
-static void wl1273_fm_radio_remove(struct platform_device *pdev)
-{
- struct wl1273_device *radio = platform_get_drvdata(pdev);
- struct wl1273_core *core = radio->core;
-
- dev_info(&pdev->dev, "%s.\n", __func__);
-
- free_irq(core->client->irq, radio);
- core->pdata->free_resources();
-
- v4l2_ctrl_handler_free(&radio->ctrl_handler);
- video_unregister_device(&radio->videodev);
- v4l2_device_unregister(&radio->v4l2dev);
-}
-
-static int wl1273_fm_radio_probe(struct platform_device *pdev)
-{
- struct wl1273_core **core = pdev->dev.platform_data;
- struct wl1273_device *radio;
- struct v4l2_ctrl *ctrl;
- int r = 0;
-
- pr_debug("%s\n", __func__);
-
- if (!core) {
- dev_err(&pdev->dev, "No platform data.\n");
- r = -EINVAL;
- goto pdata_err;
- }
-
- radio = devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL);
- if (!radio) {
- r = -ENOMEM;
- goto pdata_err;
- }
-
- /* RDS buffer allocation */
- radio->buf_size = rds_buf * RDS_BLOCK_SIZE;
- radio->buffer = devm_kzalloc(&pdev->dev, radio->buf_size, GFP_KERNEL);
- if (!radio->buffer) {
- pr_err("Cannot allocate memory for RDS buffer.\n");
- r = -ENOMEM;
- goto pdata_err;
- }
-
- radio->core = *core;
- radio->irq_flags = WL1273_IRQ_MASK;
- radio->dev = &radio->core->client->dev;
- radio->rds_on = false;
- radio->core->mode = WL1273_MODE_OFF;
- radio->tx_power = 118;
- radio->core->audio_mode = WL1273_AUDIO_ANALOG;
- radio->band = WL1273_BAND_OTHER;
- radio->core->i2s_mode = WL1273_I2S_DEF_MODE;
- radio->core->channel_number = 2;
- radio->core->volume = WL1273_DEFAULT_VOLUME;
- radio->rx_frequency = WL1273_BAND_OTHER_LOW;
- radio->tx_frequency = WL1273_BAND_OTHER_HIGH;
- radio->rangelow = WL1273_BAND_OTHER_LOW;
- radio->rangehigh = WL1273_BAND_OTHER_HIGH;
- radio->stereo = true;
- radio->bus_type = "I2C";
-
- if (radio->core->pdata->request_resources) {
- r = radio->core->pdata->request_resources(radio->core->client);
- if (r) {
- dev_err(radio->dev, WL1273_FM_DRIVER_NAME
- ": Cannot get platform data\n");
- goto pdata_err;
- }
-
- dev_dbg(radio->dev, "irq: %d\n", radio->core->client->irq);
-
- r = request_threaded_irq(radio->core->client->irq, NULL,
- wl1273_fm_irq_thread_handler,
- IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
- "wl1273-fm", radio);
- if (r < 0) {
- dev_err(radio->dev, WL1273_FM_DRIVER_NAME
- ": Unable to register IRQ handler: %d\n", r);
- goto err_request_irq;
- }
- } else {
- dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ not configured");
- r = -EINVAL;
- goto pdata_err;
- }
-
- init_completion(&radio->busy);
- init_waitqueue_head(&radio->read_queue);
-
- radio->write_buf = devm_kzalloc(&pdev->dev, 256, GFP_KERNEL);
- if (!radio->write_buf) {
- r = -ENOMEM;
- goto write_buf_err;
- }
-
- radio->dev = &pdev->dev;
- radio->v4l2dev.ctrl_handler = &radio->ctrl_handler;
- radio->rds_users = 0;
-
- r = v4l2_device_register(&pdev->dev, &radio->v4l2dev);
- if (r) {
- dev_err(&pdev->dev, "Cannot register v4l2_device.\n");
- goto write_buf_err;
- }
-
- /* V4L2 configuration */
- radio->videodev = wl1273_viddev_template;
-
- radio->videodev.v4l2_dev = &radio->v4l2dev;
-
- v4l2_ctrl_handler_init(&radio->ctrl_handler, 6);
-
- /* add in ascending ID order */
- v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
- V4L2_CID_AUDIO_VOLUME, 0, WL1273_MAX_VOLUME, 1,
- WL1273_DEFAULT_VOLUME);
-
- v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
-
- v4l2_ctrl_new_std_menu(&radio->ctrl_handler, &wl1273_ctrl_ops,
- V4L2_CID_TUNE_PREEMPHASIS,
- V4L2_PREEMPHASIS_75_uS, 0x03,
- V4L2_PREEMPHASIS_50_uS);
-
- v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
- V4L2_CID_TUNE_POWER_LEVEL, 91, 122, 1, 118);
-
- ctrl = v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops,
- V4L2_CID_TUNE_ANTENNA_CAPACITOR,
- 0, 255, 1, 255);
- if (ctrl)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- if (radio->ctrl_handler.error) {
- r = radio->ctrl_handler.error;
- dev_err(&pdev->dev, "Ctrl handler error: %d\n", r);
- goto handler_init_err;
- }
-
- video_set_drvdata(&radio->videodev, radio);
- platform_set_drvdata(pdev, radio);
-
- /* register video device */
- r = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr);
- if (r) {
- dev_err(&pdev->dev, WL1273_FM_DRIVER_NAME
- ": Could not register video device\n");
- goto handler_init_err;
- }
-
- return 0;
-
-handler_init_err:
- v4l2_ctrl_handler_free(&radio->ctrl_handler);
- v4l2_device_unregister(&radio->v4l2dev);
-write_buf_err:
- free_irq(radio->core->client->irq, radio);
-err_request_irq:
- radio->core->pdata->free_resources();
-pdata_err:
- return r;
-}
-
-static struct platform_driver wl1273_fm_radio_driver = {
- .probe = wl1273_fm_radio_probe,
- .remove = wl1273_fm_radio_remove,
- .driver = {
- .name = "wl1273_fm_radio",
- },
-};
-
-module_platform_driver(wl1273_fm_radio_driver);
-
-MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:wl1273_fm_radio");
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 099b7af6a410..e043bee52384 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -30,7 +30,7 @@
* 2006-07-24 - Converted to V4L2 API
* by Mauro Carvalho Chehab <mchehab@kernel.org>
*
- * Converted to the radio-isa framework by Hans Verkuil <hansverk@cisco.com>
+ * Converted to the radio-isa framework by Hans Verkuil <hverkuil@kernel.org>
*
* Note that this is the driver for the Zoltrix Radio Plus.
* This driver does not work for the Zoltrix Radio Plus 108 or the
diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c
index 67b4afadc95a..4132968110e3 100644
--- a/drivers/media/radio/si4713/radio-platform-si4713.c
+++ b/drivers/media/radio/si4713/radio-platform-si4713.c
@@ -75,35 +75,35 @@ static inline struct v4l2_device *get_v4l2_dev(struct file *file)
return &((struct radio_si4713_device *)video_drvdata(file))->v4l2_dev;
}
-static int radio_si4713_g_modulator(struct file *file, void *p,
+static int radio_si4713_g_modulator(struct file *file, void *priv,
struct v4l2_modulator *vm)
{
return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
g_modulator, vm);
}
-static int radio_si4713_s_modulator(struct file *file, void *p,
+static int radio_si4713_s_modulator(struct file *file, void *priv,
const struct v4l2_modulator *vm)
{
return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
s_modulator, vm);
}
-static int radio_si4713_g_frequency(struct file *file, void *p,
+static int radio_si4713_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *vf)
{
return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
g_frequency, vf);
}
-static int radio_si4713_s_frequency(struct file *file, void *p,
+static int radio_si4713_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *vf)
{
return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
s_frequency, vf);
}
-static long radio_si4713_default(struct file *file, void *p,
+static long radio_si4713_default(struct file *file, void *priv,
bool valid_prio, unsigned int cmd, void *arg)
{
return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index f5221b018808..35b9e07003d8 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -39,11 +39,6 @@
#define DISPLAY_MINOR_BASE 144
#define DEVICE_NAME "lcd%d"
-#define BUF_CHUNK_SIZE 8
-#define BUF_SIZE 128
-
-#define BIT_DURATION 250 /* each bit received is 250us */
-
#define IMON_CLOCK_ENABLE_PACKETS 2
/*** P R O T O T Y P E S ***/
@@ -536,7 +531,9 @@ static int display_open(struct inode *inode, struct file *file)
mutex_lock(&ictx->lock);
- if (!ictx->display_supported) {
+ if (ictx->disconnected) {
+ retval = -ENODEV;
+ } else if (!ictx->display_supported) {
pr_err("display not supported by device\n");
retval = -ENODEV;
} else if (ictx->display_isopen) {
@@ -598,6 +595,11 @@ static int send_packet(struct imon_context *ictx)
int retval = 0;
struct usb_ctrlrequest *control_req = NULL;
+ lockdep_assert_held(&ictx->lock);
+
+ if (ictx->disconnected)
+ return -ENODEV;
+
/* Check if we need to use control or interrupt urb */
if (!ictx->tx_control) {
pipe = usb_sndintpipe(ictx->usbdev_intf0,
@@ -645,12 +647,15 @@ static int send_packet(struct imon_context *ictx)
smp_rmb(); /* ensure later readers know we're not busy */
pr_err_ratelimited("error submitting urb(%d)\n", retval);
} else {
- /* Wait for transmission to complete (or abort) */
- retval = wait_for_completion_interruptible(
- &ictx->tx.finished);
- if (retval) {
+ /* Wait for transmission to complete (or abort or timeout) */
+ retval = wait_for_completion_interruptible_timeout(&ictx->tx.finished, 10 * HZ);
+ if (retval <= 0) {
usb_kill_urb(ictx->tx_urb);
pr_err_ratelimited("task interrupted\n");
+ if (retval < 0)
+ ictx->tx.status = retval;
+ else
+ ictx->tx.status = -ETIMEDOUT;
}
ictx->tx.busy = false;
@@ -949,12 +954,14 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
static const unsigned char vfd_packet6[] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
- if (ictx->disconnected)
- return -ENODEV;
-
if (mutex_lock_interruptible(&ictx->lock))
return -ERESTARTSYS;
+ if (ictx->disconnected) {
+ retval = -ENODEV;
+ goto exit;
+ }
+
if (!ictx->dev_present_intf0) {
pr_err_ratelimited("no iMON device present\n");
retval = -ENODEV;
@@ -1029,11 +1036,13 @@ static ssize_t lcd_write(struct file *file, const char __user *buf,
int retval = 0;
struct imon_context *ictx = file->private_data;
- if (ictx->disconnected)
- return -ENODEV;
-
mutex_lock(&ictx->lock);
+ if (ictx->disconnected) {
+ retval = -ENODEV;
+ goto exit;
+ }
+
if (!ictx->display_supported) {
pr_err_ratelimited("no iMON display present\n");
retval = -ENODEV;
@@ -1121,7 +1130,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)
int retval;
struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev;
- bool unlock = false;
+ const bool unlock = mutex_trylock(&ictx->lock);
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
@@ -1148,8 +1157,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)
memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
- unlock = mutex_trylock(&ictx->lock);
-
retval = send_packet(ictx);
if (retval)
goto out;
@@ -1745,14 +1752,6 @@ static void usb_rx_callback_intf0(struct urb *urb)
if (!ictx)
return;
- /*
- * if we get a callback before we're done configuring the hardware, we
- * can't yet process the data, as there's nowhere to send it, but we
- * still need to submit a new rx URB to avoid wedging the hardware
- */
- if (!ictx->dev_present_intf0)
- goto out;
-
switch (urb->status) {
case -ENOENT: /* usbcore unlink successful! */
return;
@@ -1761,16 +1760,29 @@ static void usb_rx_callback_intf0(struct urb *urb)
break;
case 0:
- imon_incoming_packet(ictx, urb, intfnum);
+ /*
+ * if we get a callback before we're done configuring the hardware, we
+ * can't yet process the data, as there's nowhere to send it, but we
+ * still need to submit a new rx URB to avoid wedging the hardware
+ */
+ if (ictx->dev_present_intf0)
+ imon_incoming_packet(ictx, urb, intfnum);
break;
+ case -ECONNRESET:
+ case -EILSEQ:
+ case -EPROTO:
+ case -EPIPE:
+ dev_warn(ictx->dev, "imon %s: status(%d)\n",
+ __func__, urb->status);
+ return;
+
default:
dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
__func__, urb->status);
break;
}
-out:
usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
}
@@ -1786,14 +1798,6 @@ static void usb_rx_callback_intf1(struct urb *urb)
if (!ictx)
return;
- /*
- * if we get a callback before we're done configuring the hardware, we
- * can't yet process the data, as there's nowhere to send it, but we
- * still need to submit a new rx URB to avoid wedging the hardware
- */
- if (!ictx->dev_present_intf1)
- goto out;
-
switch (urb->status) {
case -ENOENT: /* usbcore unlink successful! */
return;
@@ -1802,16 +1806,29 @@ static void usb_rx_callback_intf1(struct urb *urb)
break;
case 0:
- imon_incoming_packet(ictx, urb, intfnum);
+ /*
+ * if we get a callback before we're done configuring the hardware, we
+ * can't yet process the data, as there's nowhere to send it, but we
+ * still need to submit a new rx URB to avoid wedging the hardware
+ */
+ if (ictx->dev_present_intf1)
+ imon_incoming_packet(ictx, urb, intfnum);
break;
+ case -ECONNRESET:
+ case -EILSEQ:
+ case -EPROTO:
+ case -EPIPE:
+ dev_warn(ictx->dev, "imon %s: status(%d)\n",
+ __func__, urb->status);
+ return;
+
default:
dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
__func__, urb->status);
break;
}
-out:
usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
}
@@ -2499,7 +2516,11 @@ static void imon_disconnect(struct usb_interface *interface)
int ifnum;
ictx = usb_get_intfdata(interface);
+
+ mutex_lock(&ictx->lock);
ictx->disconnected = true;
+ mutex_unlock(&ictx->lock);
+
dev = ictx->dev;
ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index a2257dc2f25d..7d4942925993 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -736,11 +736,11 @@ int lirc_register(struct rc_dev *dev)
cdev_init(&dev->lirc_cdev, &lirc_fops);
+ get_device(&dev->dev);
+
err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);
if (err)
- goto out_ida;
-
- get_device(&dev->dev);
+ goto out_put_device;
switch (dev->driver_type) {
case RC_DRIVER_SCANCODE:
@@ -764,7 +764,8 @@ int lirc_register(struct rc_dev *dev)
return 0;
-out_ida:
+out_put_device:
+ put_device(&dev->lirc_dev);
ida_free(&lirc_ida, minor);
return err;
}
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index d89a4cfe3c89..a49173f54a4d 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -422,7 +422,7 @@ static int redrat3_send_cmd(int cmd, struct redrat3_dev *rr3)
static int redrat3_enable_detector(struct redrat3_dev *rr3)
{
struct device *dev = rr3->dev;
- u8 ret;
+ int ret;
ret = redrat3_send_cmd(RR3_RC_DET_ENABLE, rr3);
if (ret != 0)
diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c
index c45f5cf12ded..a3df3a33237e 100644
--- a/drivers/media/test-drivers/vicodec/vicodec-core.c
+++ b/drivers/media/test-drivers/vicodec/vicodec-core.c
@@ -26,7 +26,7 @@
#include "codec-v4l2-fwht.h"
MODULE_DESCRIPTION("Virtual codec device");
-MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
MODULE_LICENSE("GPL v2");
static bool multiplanar;
@@ -144,7 +144,7 @@ static const struct v4l2_event vicodec_eos_event = {
static inline struct vicodec_ctx *file2ctx(struct file *file)
{
- return container_of(file->private_data, struct vicodec_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct vicodec_ctx, fh);
}
static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx,
@@ -1207,20 +1207,20 @@ static int vidioc_s_selection(struct file *file, void *priv,
return 0;
}
-static int vicodec_encoder_cmd(struct file *file, void *fh,
+static int vicodec_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *ec)
{
struct vicodec_ctx *ctx = file2ctx(file);
int ret;
- ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec);
+ ret = v4l2_m2m_ioctl_try_encoder_cmd(file, priv, ec);
if (ret < 0)
return ret;
if (!vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
return 0;
- ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec);
+ ret = v4l2_m2m_ioctl_encoder_cmd(file, priv, ec);
if (ret < 0)
return ret;
@@ -1235,7 +1235,7 @@ static int vicodec_encoder_cmd(struct file *file, void *fh,
return 0;
}
-static int vicodec_decoder_cmd(struct file *file, void *fh,
+static int vicodec_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *dc)
{
struct vicodec_ctx *ctx = file2ctx(file);
@@ -1247,14 +1247,14 @@ static int vicodec_decoder_cmd(struct file *file, void *fh,
*/
WARN_ON(ctx->is_stateless);
- ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, dc);
+ ret = v4l2_m2m_ioctl_try_decoder_cmd(file, priv, dc);
if (ret < 0)
return ret;
if (!vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
return 0;
- ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc);
+ ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, dc);
if (ret < 0)
return ret;
@@ -1269,7 +1269,7 @@ static int vicodec_decoder_cmd(struct file *file, void *fh,
return 0;
}
-static int vicodec_enum_framesizes(struct file *file, void *fh,
+static int vicodec_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
switch (fsize->pixel_format) {
@@ -1848,7 +1848,6 @@ static int vicodec_open(struct file *file)
ctx->is_stateless = true;
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = dev;
hdl = &ctx->hdl;
v4l2_ctrl_handler_init(hdl, 5);
@@ -1932,7 +1931,7 @@ static int vicodec_open(struct file *file)
goto open_unlock;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
open_unlock:
mutex_unlock(vfd->lock);
@@ -1947,7 +1946,7 @@ static int vicodec_release(struct file *file)
mutex_lock(vfd->lock);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
mutex_unlock(vfd->lock);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
kvfree(ctx->state.compressed_frame);
diff --git a/drivers/media/test-drivers/vim2m.c b/drivers/media/test-drivers/vim2m.c
index 1d1a9e768505..86c32699111a 100644
--- a/drivers/media/test-drivers/vim2m.c
+++ b/drivers/media/test-drivers/vim2m.c
@@ -191,9 +191,7 @@ static void get_alignment(u32 fourcc,
struct vim2m_dev {
struct v4l2_device v4l2_dev;
struct video_device vfd;
-#ifdef CONFIG_MEDIA_CONTROLLER
struct media_device mdev;
-#endif
atomic_t num_inst;
struct mutex dev_mutex;
@@ -236,7 +234,7 @@ struct vim2m_ctx {
static inline struct vim2m_ctx *file2ctx(struct file *file)
{
- return container_of(file->private_data, struct vim2m_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct vim2m_ctx, fh);
}
static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx,
@@ -268,9 +266,6 @@ static const char *type_name(enum v4l2_buf_type type)
}
}
-#define CLIP(__color) \
- (u8)(((__color) > 0xff) ? 0xff : (((__color) < 0) ? 0 : (__color)))
-
static void copy_line(struct vim2m_q_data *q_data_out,
u8 *src, u8 *dst, bool reverse)
{
@@ -1389,7 +1384,6 @@ static int vim2m_open(struct file *file)
}
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = dev;
hdl = &ctx->hdl;
v4l2_ctrl_handler_init(hdl, 4);
@@ -1433,7 +1427,7 @@ static int vim2m_open(struct file *file)
goto open_unlock;
}
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
atomic_inc(&dev->num_inst);
dprintk(dev, 1, "Created instance: %p, m2m_ctx: %p\n",
@@ -1451,7 +1445,7 @@ static int vim2m_release(struct file *file)
dprintk(dev, 1, "Releasing instance %p\n", ctx);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
mutex_lock(&dev->dev_mutex);
@@ -1470,9 +1464,7 @@ static void vim2m_device_release(struct video_device *vdev)
v4l2_device_unregister(&dev->v4l2_dev);
v4l2_m2m_release(dev->m2m_dev);
-#ifdef CONFIG_MEDIA_CONTROLLER
media_device_cleanup(&dev->mdev);
-#endif
kfree(dev);
}
@@ -1543,7 +1535,6 @@ static int vim2m_probe(struct platform_device *pdev)
goto error_dev;
}
-#ifdef CONFIG_MEDIA_CONTROLLER
dev->mdev.dev = &pdev->dev;
strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
strscpy(dev->mdev.bus_info, "platform:vim2m",
@@ -1551,7 +1542,6 @@ static int vim2m_probe(struct platform_device *pdev)
media_device_init(&dev->mdev);
dev->mdev.ops = &m2m_media_ops;
dev->v4l2_dev.mdev = &dev->mdev;
-#endif
ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
if (ret) {
@@ -1562,7 +1552,6 @@ static int vim2m_probe(struct platform_device *pdev)
v4l2_info(&dev->v4l2_dev,
"Device registered as /dev/video%d\n", vfd->num);
-#ifdef CONFIG_MEDIA_CONTROLLER
ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
MEDIA_ENT_F_PROC_VIDEO_SCALER);
if (ret) {
@@ -1575,13 +1564,11 @@ static int vim2m_probe(struct platform_device *pdev)
v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
goto error_m2m_mc;
}
-#endif
+
return 0;
-#ifdef CONFIG_MEDIA_CONTROLLER
error_m2m_mc:
v4l2_m2m_unregister_media_controller(dev->m2m_dev);
-#endif
error_v4l2:
video_unregister_device(&dev->vfd);
/* vim2m_device_release called by video_unregister_device to release various objects */
@@ -1602,10 +1589,8 @@ static void vim2m_remove(struct platform_device *pdev)
v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME);
-#ifdef CONFIG_MEDIA_CONTROLLER
media_device_unregister(&dev->mdev);
v4l2_m2m_unregister_media_controller(dev->m2m_dev);
-#endif
video_unregister_device(&dev->vfd);
}
diff --git a/drivers/media/test-drivers/vimc/vimc-capture.c b/drivers/media/test-drivers/vimc/vimc-capture.c
index 10df039278e7..7f6124025fc9 100644
--- a/drivers/media/test-drivers/vimc/vimc-capture.c
+++ b/drivers/media/test-drivers/vimc/vimc-capture.c
@@ -57,8 +57,6 @@ static int vimc_capture_querycap(struct file *file, void *priv,
{
strscpy(cap->driver, VIMC_PDEV_NAME, sizeof(cap->driver));
strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info),
- "platform:%s", VIMC_PDEV_NAME);
return 0;
}
@@ -169,7 +167,7 @@ static int vimc_capture_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int vimc_capture_enum_framesizes(struct file *file, void *fh,
+static int vimc_capture_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
const struct vimc_pix_map *vpix;
diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c
index c812fa9f0650..f632c77e52f5 100644
--- a/drivers/media/test-drivers/vimc/vimc-core.c
+++ b/drivers/media/test-drivers/vimc/vimc-core.c
@@ -366,8 +366,6 @@ static int vimc_probe(struct platform_device *pdev)
/* Initialize media device */
strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
sizeof(vimc->mdev.model));
- snprintf(vimc->mdev.bus_info, sizeof(vimc->mdev.bus_info),
- "platform:%s", VIMC_PDEV_NAME);
vimc->mdev.dev = &pdev->dev;
media_device_init(&vimc->mdev);
diff --git a/drivers/media/test-drivers/visl/visl-core.c b/drivers/media/test-drivers/visl/visl-core.c
index 5bf3136b36eb..26c6c6835f79 100644
--- a/drivers/media/test-drivers/visl/visl-core.c
+++ b/drivers/media/test-drivers/visl/visl-core.c
@@ -341,7 +341,6 @@ static int visl_open(struct file *file)
ctx->tpg_str_buf = kzalloc(TPG_STR_BUF_SZ, GFP_KERNEL);
v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
ctx->dev = dev;
rc = visl_init_ctrls(ctx);
@@ -361,7 +360,7 @@ static int visl_open(struct file *file)
if (rc)
goto free_m2m_ctx;
- v4l2_fh_add(&ctx->fh);
+ v4l2_fh_add(&ctx->fh, file);
dprintk(dev, "Created instance: %p, m2m_ctx: %p\n",
ctx, ctx->fh.m2m_ctx);
@@ -390,7 +389,7 @@ static int visl_release(struct file *file)
dprintk(dev, "Releasing instance %p\n", ctx);
tpg_free(&ctx->tpg);
- v4l2_fh_del(&ctx->fh);
+ v4l2_fh_del(&ctx->fh, file);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->hdl);
mutex_lock(&dev->dev_mutex);
diff --git a/drivers/media/test-drivers/visl/visl.h b/drivers/media/test-drivers/visl/visl.h
index 434e9efbf9b2..2971e8b37ff6 100644
--- a/drivers/media/test-drivers/visl/visl.h
+++ b/drivers/media/test-drivers/visl/visl.h
@@ -163,12 +163,7 @@ struct visl_ctrl_desc {
static inline struct visl_ctx *visl_file_to_ctx(struct file *file)
{
- return container_of(file->private_data, struct visl_ctx, fh);
-}
-
-static inline struct visl_ctx *visl_v4l2fh_to_ctx(struct v4l2_fh *v4l2_fh)
-{
- return container_of(v4l2_fh, struct visl_ctx, fh);
+ return container_of(file_to_v4l2_fh(file), struct visl_ctx, fh);
}
void *visl_find_control_data(struct visl_ctx *ctx, u32 id);
diff --git a/drivers/media/test-drivers/vivid/vivid-cec.c b/drivers/media/test-drivers/vivid/vivid-cec.c
index 356a988dd6a1..2d15fdd5d999 100644
--- a/drivers/media/test-drivers/vivid/vivid-cec.c
+++ b/drivers/media/test-drivers/vivid/vivid-cec.c
@@ -327,7 +327,7 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
char osd[14];
if (!cec_is_sink(adap))
- return -ENOMSG;
+ break;
cec_ops_set_osd_string(msg, &disp_ctl, osd);
switch (disp_ctl) {
case CEC_OP_DISP_CTL_DEFAULT:
@@ -348,7 +348,7 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
cec_transmit_msg(adap, &reply, false);
break;
}
- break;
+ return 0;
}
case CEC_MSG_VENDOR_COMMAND_WITH_ID: {
u32 vendor_id;
@@ -379,7 +379,7 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
if (size == 1) {
// Ignore even op values
if (!(vendor_cmd[0] & 1))
- break;
+ return 0;
reply.len = msg->len;
memcpy(reply.msg + 1, msg->msg + 1, msg->len - 1);
reply.msg[msg->len - 1]++;
@@ -388,12 +388,10 @@ static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
CEC_OP_ABORT_INVALID_OP);
}
cec_transmit_msg(adap, &reply, false);
- break;
+ return 0;
}
- default:
- return -ENOMSG;
}
- return 0;
+ return -ENOMSG;
}
static const struct cec_adap_ops vivid_cec_adap_ops = {
diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
index 8d56168c72aa..86506be36acb 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.c
+++ b/drivers/media/test-drivers/vivid/vivid-core.c
@@ -277,49 +277,49 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a)
+static int vidioc_s_hw_freq_seek(struct file *file, void *priv, const struct v4l2_hw_freq_seek *a)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_type == VFL_TYPE_RADIO)
- return vivid_radio_rx_s_hw_freq_seek(file, fh, a);
+ return vivid_radio_rx_s_hw_freq_seek(file, priv, a);
return -ENOTTY;
}
-static int vidioc_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
+static int vidioc_enum_freq_bands(struct file *file, void *priv, struct v4l2_frequency_band *band)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_type == VFL_TYPE_RADIO)
- return vivid_radio_rx_enum_freq_bands(file, fh, band);
+ return vivid_radio_rx_enum_freq_bands(file, priv, band);
if (vdev->vfl_type == VFL_TYPE_SDR)
- return vivid_sdr_enum_freq_bands(file, fh, band);
+ return vivid_sdr_enum_freq_bands(file, priv, band);
return -ENOTTY;
}
-static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_type == VFL_TYPE_RADIO)
- return vivid_radio_rx_g_tuner(file, fh, vt);
+ return vivid_radio_rx_g_tuner(file, priv, vt);
if (vdev->vfl_type == VFL_TYPE_SDR)
- return vivid_sdr_g_tuner(file, fh, vt);
- return vivid_video_g_tuner(file, fh, vt);
+ return vivid_sdr_g_tuner(file, priv, vt);
+ return vivid_video_g_tuner(file, priv, vt);
}
-static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+static int vidioc_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_type == VFL_TYPE_RADIO)
- return vivid_radio_rx_s_tuner(file, fh, vt);
+ return vivid_radio_rx_s_tuner(file, priv, vt);
if (vdev->vfl_type == VFL_TYPE_SDR)
- return vivid_sdr_s_tuner(file, fh, vt);
- return vivid_video_s_tuner(file, fh, vt);
+ return vivid_sdr_s_tuner(file, priv, vt);
+ return vivid_video_s_tuner(file, priv, vt);
}
-static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
@@ -329,11 +329,11 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency
vdev->vfl_dir == VFL_DIR_RX ?
&dev->radio_rx_freq : &dev->radio_tx_freq, vf);
if (vdev->vfl_type == VFL_TYPE_SDR)
- return vivid_sdr_g_frequency(file, fh, vf);
- return vivid_video_g_frequency(file, fh, vf);
+ return vivid_sdr_g_frequency(file, priv, vf);
+ return vivid_video_g_frequency(file, priv, vf);
}
-static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
+static int vidioc_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
@@ -343,113 +343,113 @@ static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_fre
vdev->vfl_dir == VFL_DIR_RX ?
&dev->radio_rx_freq : &dev->radio_tx_freq, vf);
if (vdev->vfl_type == VFL_TYPE_SDR)
- return vivid_sdr_s_frequency(file, fh, vf);
- return vivid_video_s_frequency(file, fh, vf);
+ return vivid_sdr_s_frequency(file, priv, vf);
+ return vivid_video_s_frequency(file, priv, vf);
}
-static int vidioc_overlay(struct file *file, void *fh, unsigned i)
+static int vidioc_overlay(struct file *file, void *priv, unsigned i)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
return -ENOTTY;
- return vivid_vid_out_overlay(file, fh, i);
+ return vivid_vid_out_overlay(file, priv, i);
}
-static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a)
+static int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *a)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
return -ENOTTY;
- return vivid_vid_out_g_fbuf(file, fh, a);
+ return vivid_vid_out_g_fbuf(file, priv, a);
}
-static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
+static int vidioc_s_fbuf(struct file *file, void *priv, const struct v4l2_framebuffer *a)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
return -ENOTTY;
- return vivid_vid_out_s_fbuf(file, fh, a);
+ return vivid_vid_out_s_fbuf(file, priv, a);
}
-static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_s_std(file, fh, id);
- return vivid_vid_out_s_std(file, fh, id);
+ return vivid_vid_cap_s_std(file, priv, id);
+ return vivid_vid_out_s_std(file, priv, id);
}
-static int vidioc_s_dv_timings(struct file *file, void *fh, struct v4l2_dv_timings *timings)
+static int vidioc_s_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *timings)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_s_dv_timings(file, fh, timings);
- return vivid_vid_out_s_dv_timings(file, fh, timings);
+ return vivid_vid_cap_s_dv_timings(file, priv, timings);
+ return vivid_vid_out_s_dv_timings(file, priv, timings);
}
-static int vidioc_g_pixelaspect(struct file *file, void *fh,
+static int vidioc_g_pixelaspect(struct file *file, void *priv,
int type, struct v4l2_fract *f)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_g_pixelaspect(file, fh, type, f);
- return vivid_vid_out_g_pixelaspect(file, fh, type, f);
+ return vivid_vid_cap_g_pixelaspect(file, priv, type, f);
+ return vivid_vid_out_g_pixelaspect(file, priv, type, f);
}
-static int vidioc_g_selection(struct file *file, void *fh,
+static int vidioc_g_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_g_selection(file, fh, sel);
- return vivid_vid_out_g_selection(file, fh, sel);
+ return vivid_vid_cap_g_selection(file, priv, sel);
+ return vivid_vid_out_g_selection(file, priv, sel);
}
-static int vidioc_s_selection(struct file *file, void *fh,
+static int vidioc_s_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_s_selection(file, fh, sel);
- return vivid_vid_out_s_selection(file, fh, sel);
+ return vivid_vid_cap_s_selection(file, priv, sel);
+ return vivid_vid_out_s_selection(file, priv, sel);
}
-static int vidioc_g_parm(struct file *file, void *fh,
+static int vidioc_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_type == VFL_TYPE_TOUCH)
- return vivid_g_parm_tch(file, fh, parm);
+ return vivid_g_parm_tch(file, priv, parm);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_g_parm(file, fh, parm);
- return vivid_vid_out_g_parm(file, fh, parm);
+ return vivid_vid_cap_g_parm(file, priv, parm);
+ return vivid_vid_out_g_parm(file, priv, parm);
}
-static int vidioc_s_parm(struct file *file, void *fh,
+static int vidioc_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
struct video_device *vdev = video_devdata(file);
if (vdev->vfl_dir == VFL_DIR_RX)
- return vivid_vid_cap_s_parm(file, fh, parm);
+ return vivid_vid_cap_s_parm(file, priv, parm);
return -ENOTTY;
}
-static int vidioc_log_status(struct file *file, void *fh)
+static int vidioc_log_status(struct file *file, void *priv)
{
struct vivid_dev *dev = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
- v4l2_ctrl_log_status(file, fh);
+ v4l2_ctrl_log_status(file, priv);
if (vdev->vfl_dir == VFL_DIR_RX && vdev->vfl_type == VFL_TYPE_VIDEO)
tpg_log_status(&dev->tpg);
return 0;
@@ -654,11 +654,11 @@ static int vivid_fop_release(struct file *file)
v4l2_info(&dev->v4l2_dev, "reconnect\n");
vivid_reconnect(dev);
}
- if (file->private_data == dev->radio_rx_rds_owner) {
+ if (file_to_v4l2_fh(file) == dev->radio_rx_rds_owner) {
dev->radio_rx_rds_last_block = 0;
dev->radio_rx_rds_owner = NULL;
}
- if (file->private_data == dev->radio_tx_rds_owner) {
+ if (file_to_v4l2_fh(file) == dev->radio_tx_rds_owner) {
dev->radio_tx_rds_last_block = 0;
dev->radio_tx_rds_owner = NULL;
}
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-rx.c b/drivers/media/test-drivers/vivid/vivid-radio-rx.c
index 79c1723bd84c..b5e3026f883e 100644
--- a/drivers/media/test-drivers/vivid/vivid-radio-rx.c
+++ b/drivers/media/test-drivers/vivid/vivid-radio-rx.c
@@ -42,13 +42,13 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
if (mutex_lock_interruptible(&dev->mutex))
return -ERESTARTSYS;
if (dev->radio_rx_rds_owner &&
- file->private_data != dev->radio_rx_rds_owner) {
+ file_to_v4l2_fh(file) != dev->radio_rx_rds_owner) {
mutex_unlock(&dev->mutex);
return -EBUSY;
}
if (dev->radio_rx_rds_owner == NULL) {
vivid_radio_rds_init(dev);
- dev->radio_rx_rds_owner = file->private_data;
+ dev->radio_rx_rds_owner = file_to_v4l2_fh(file);
}
retry:
@@ -133,7 +133,7 @@ __poll_t vivid_radio_rx_poll(struct file *file, struct poll_table_struct *wait)
return EPOLLIN | EPOLLRDNORM | v4l2_ctrl_poll(file, wait);
}
-int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
+int vivid_radio_rx_enum_freq_bands(struct file *file, void *priv, struct v4l2_frequency_band *band)
{
if (band->tuner != 0)
return -EINVAL;
@@ -145,7 +145,7 @@ int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_freq
return 0;
}
-int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a)
+int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *priv, const struct v4l2_hw_freq_seek *a)
{
struct vivid_dev *dev = video_drvdata(file);
unsigned low, high;
@@ -214,7 +214,7 @@ int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2
return 0;
}
-int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+int vivid_radio_rx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
{
struct vivid_dev *dev = video_drvdata(file);
int delta = 800;
@@ -267,7 +267,7 @@ int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
return 0;
}
-int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+int vivid_radio_rx_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
{
struct vivid_dev *dev = video_drvdata(file);
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-rx.h b/drivers/media/test-drivers/vivid/vivid-radio-rx.h
index c9c7849f6f99..a2ae17c78ece 100644
--- a/drivers/media/test-drivers/vivid/vivid-radio-rx.h
+++ b/drivers/media/test-drivers/vivid/vivid-radio-rx.h
@@ -11,9 +11,9 @@
ssize_t vivid_radio_rx_read(struct file *, char __user *, size_t, loff_t *);
__poll_t vivid_radio_rx_poll(struct file *file, struct poll_table_struct *wait);
-int vivid_radio_rx_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band);
-int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *fh, const struct v4l2_hw_freq_seek *a);
-int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
-int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
+int vivid_radio_rx_enum_freq_bands(struct file *file, void *priv, struct v4l2_frequency_band *band);
+int vivid_radio_rx_s_hw_freq_seek(struct file *file, void *priv, const struct v4l2_hw_freq_seek *a);
+int vivid_radio_rx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt);
+int vivid_radio_rx_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt);
#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-tx.c b/drivers/media/test-drivers/vivid/vivid-radio-tx.c
index 049d40b948bb..ada60722066e 100644
--- a/drivers/media/test-drivers/vivid/vivid-radio-tx.c
+++ b/drivers/media/test-drivers/vivid/vivid-radio-tx.c
@@ -39,11 +39,11 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
if (mutex_lock_interruptible(&dev->mutex))
return -ERESTARTSYS;
if (dev->radio_tx_rds_owner &&
- file->private_data != dev->radio_tx_rds_owner) {
+ file_to_v4l2_fh(file) != dev->radio_tx_rds_owner) {
mutex_unlock(&dev->mutex);
return -EBUSY;
}
- dev->radio_tx_rds_owner = file->private_data;
+ dev->radio_tx_rds_owner = file_to_v4l2_fh(file);
retry:
timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
@@ -96,7 +96,7 @@ __poll_t vivid_radio_tx_poll(struct file *file, struct poll_table_struct *wait)
return EPOLLOUT | EPOLLWRNORM | v4l2_ctrl_poll(file, wait);
}
-int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a)
+int vidioc_g_modulator(struct file *file, void *priv, struct v4l2_modulator *a)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -115,7 +115,7 @@ int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a)
return 0;
}
-int vidioc_s_modulator(struct file *file, void *fh, const struct v4l2_modulator *a)
+int vidioc_s_modulator(struct file *file, void *priv, const struct v4l2_modulator *a)
{
struct vivid_dev *dev = video_drvdata(file);
diff --git a/drivers/media/test-drivers/vivid/vivid-radio-tx.h b/drivers/media/test-drivers/vivid/vivid-radio-tx.h
index c2bf1e7e634a..20cb6f1363ff 100644
--- a/drivers/media/test-drivers/vivid/vivid-radio-tx.h
+++ b/drivers/media/test-drivers/vivid/vivid-radio-tx.h
@@ -11,7 +11,7 @@
ssize_t vivid_radio_tx_write(struct file *, const char __user *, size_t, loff_t *);
__poll_t vivid_radio_tx_poll(struct file *file, struct poll_table_struct *wait);
-int vidioc_g_modulator(struct file *file, void *fh, struct v4l2_modulator *a);
-int vidioc_s_modulator(struct file *file, void *fh, const struct v4l2_modulator *a);
+int vidioc_g_modulator(struct file *file, void *priv, struct v4l2_modulator *a);
+int vidioc_s_modulator(struct file *file, void *priv, const struct v4l2_modulator *a);
#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
index c633fc2ed664..2664a593e8e1 100644
--- a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
@@ -344,7 +344,7 @@ const struct vb2_ops vivid_sdr_cap_qops = {
.buf_request_complete = sdr_cap_buf_request_complete,
};
-int vivid_sdr_enum_freq_bands(struct file *file, void *fh,
+int vivid_sdr_enum_freq_bands(struct file *file, void *priv,
struct v4l2_frequency_band *band)
{
switch (band->tuner) {
@@ -363,7 +363,7 @@ int vivid_sdr_enum_freq_bands(struct file *file, void *fh,
}
}
-int vivid_sdr_g_frequency(struct file *file, void *fh,
+int vivid_sdr_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -382,7 +382,7 @@ int vivid_sdr_g_frequency(struct file *file, void *fh,
}
}
-int vivid_sdr_s_frequency(struct file *file, void *fh,
+int vivid_sdr_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -423,7 +423,7 @@ int vivid_sdr_s_frequency(struct file *file, void *fh,
}
}
-int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+int vivid_sdr_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
{
switch (vt->index) {
case 0:
@@ -447,14 +447,14 @@ int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
}
}
-int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+int vivid_sdr_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
{
if (vt->index > 1)
return -EINVAL;
return 0;
}
-int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+int vidioc_enum_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f)
{
if (f->index >= ARRAY_SIZE(formats))
return -EINVAL;
@@ -462,7 +462,7 @@ int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
return 0;
}
-int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
+int vidioc_g_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -471,7 +471,7 @@ int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
return 0;
}
-int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
+int vidioc_s_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f)
{
struct vivid_dev *dev = video_drvdata(file);
struct vb2_queue *q = &dev->vb_sdr_cap_q;
@@ -495,7 +495,7 @@ int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
return 0;
}
-int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
+int vidioc_try_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f)
{
int i;
diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.h b/drivers/media/test-drivers/vivid/vivid-sdr-cap.h
index 813c9248e5a7..3d8eeabbfc10 100644
--- a/drivers/media/test-drivers/vivid/vivid-sdr-cap.h
+++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.h
@@ -8,15 +8,15 @@
#ifndef _VIVID_SDR_CAP_H_
#define _VIVID_SDR_CAP_H_
-int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band);
-int vivid_sdr_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int vivid_sdr_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
-int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
-int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
-int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f);
-int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
-int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
-int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f);
+int vivid_sdr_enum_freq_bands(struct file *file, void *priv, struct v4l2_frequency_band *band);
+int vivid_sdr_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf);
+int vivid_sdr_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf);
+int vivid_sdr_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt);
+int vivid_sdr_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt);
+int vidioc_enum_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f);
+int vidioc_g_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_s_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f);
+int vidioc_try_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f);
void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf);
extern const struct vb2_ops vivid_sdr_cap_qops;
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c
index a09f62c66c33..791382a54b4f 100644
--- a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c
@@ -282,7 +282,7 @@ void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_se
}
}
-int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
@@ -294,7 +294,7 @@ int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format
return 0;
}
-int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
@@ -310,11 +310,11 @@ int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_forma
return 0;
}
-int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
- int ret = vidioc_try_fmt_sliced_vbi_cap(file, fh, fmt);
+ int ret = vidioc_try_fmt_sliced_vbi_cap(file, priv, fmt);
if (ret)
return ret;
@@ -324,7 +324,7 @@ int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format
return 0;
}
-int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
+int vidioc_g_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_sliced_vbi_cap *cap)
{
struct vivid_dev *dev = video_drvdata(file);
struct video_device *vdev = video_devdata(file);
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.h b/drivers/media/test-drivers/vivid/vivid-vbi-cap.h
index 91d2de01381c..ec2d200c9e0d 100644
--- a/drivers/media/test-drivers/vivid/vivid-vbi-cap.h
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.h
@@ -16,10 +16,10 @@ int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f);
int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f);
-int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap);
+int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *fmt);
+int vidioc_try_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *fmt);
+int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *fmt);
+int vidioc_g_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_sliced_vbi_cap *cap);
void vivid_fill_service_lines(struct v4l2_sliced_vbi_format *vbi, u32 service_set);
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-out.c b/drivers/media/test-drivers/vivid/vivid-vbi-out.c
index b7a09d2f394e..7b3ea96744bb 100644
--- a/drivers/media/test-drivers/vivid/vivid-vbi-out.c
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-out.c
@@ -168,7 +168,7 @@ int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
return 0;
}
-int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
@@ -180,7 +180,7 @@ int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format
return 0;
}
-int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
@@ -196,12 +196,12 @@ int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_forma
return 0;
}
-int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *priv,
struct v4l2_format *fmt)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
- int ret = vidioc_try_fmt_sliced_vbi_out(file, fh, fmt);
+ int ret = vidioc_try_fmt_sliced_vbi_out(file, priv, fmt);
if (ret)
return ret;
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-out.h b/drivers/media/test-drivers/vivid/vivid-vbi-out.h
index 76584940cdaf..a28e55519ade 100644
--- a/drivers/media/test-drivers/vivid/vivid-vbi-out.h
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-out.h
@@ -13,9 +13,9 @@ int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
struct v4l2_format *f);
int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
struct v4l2_format *f);
-int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
-int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt);
+int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt);
+int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt);
+int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *priv, struct v4l2_format *fmt);
extern const struct vb2_ops vivid_vbi_out_qops;
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index 2e4c1ed37cd2..8b3162e82032 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -899,7 +899,7 @@ int vivid_vid_cap_g_selection(struct file *file, void *priv,
return 0;
}
-int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+int vivid_vid_cap_s_selection(struct file *file, void *priv, struct v4l2_selection *s)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_rect *crop = &dev->crop_cap;
@@ -1222,7 +1222,7 @@ int vidioc_s_input(struct file *file, void *priv, unsigned i)
return 0;
}
-int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
+int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
{
if (vin->index >= ARRAY_SIZE(vivid_audio_inputs))
return -EINVAL;
@@ -1230,7 +1230,7 @@ int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
return 0;
}
-int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
+int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1240,7 +1240,7 @@ int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
return 0;
}
-int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin)
+int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *vin)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1252,7 +1252,7 @@ int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin)
return 0;
}
-int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+int vivid_video_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1262,7 +1262,7 @@ int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
return 0;
}
-int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
+int vivid_video_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1274,7 +1274,7 @@ int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequ
return 0;
}
-int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
+int vivid_video_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1286,7 +1286,7 @@ int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt
return 0;
}
-int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+int vivid_video_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
{
struct vivid_dev *dev = video_drvdata(file);
enum tpg_quality qual;
@@ -1490,7 +1490,7 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
return false;
}
-int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,
+int vivid_vid_cap_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1513,7 +1513,7 @@ int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,
return 0;
}
-int vidioc_query_dv_timings(struct file *file, void *_fh,
+int vidioc_query_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1600,7 +1600,7 @@ void vivid_update_connected_outputs(struct vivid_dev *dev)
}
}
-int vidioc_s_edid(struct file *file, void *_fh,
+int vidioc_s_edid(struct file *file, void *priv,
struct v4l2_edid *edid)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1638,7 +1638,7 @@ int vidioc_s_edid(struct file *file, void *_fh,
return 0;
}
-int vidioc_enum_framesizes(struct file *file, void *fh,
+int vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
struct vivid_dev *dev = video_drvdata(file);
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.h b/drivers/media/test-drivers/vivid/vivid-vid-cap.h
index 7a8daf0af2ca..38a99f7e038e 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.h
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.h
@@ -29,7 +29,7 @@ int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f);
int vivid_vid_cap_g_selection(struct file *file, void *priv, struct v4l2_selection *sel);
-int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection *s);
+int vivid_vid_cap_s_selection(struct file *file, void *priv, struct v4l2_selection *s);
int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f);
int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f);
int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f);
@@ -38,19 +38,19 @@ int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *
int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp);
int vidioc_g_input(struct file *file, void *priv, unsigned *i);
int vidioc_s_input(struct file *file, void *priv, unsigned i);
-int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin);
-int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *vin);
-int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *vin);
-int vivid_video_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int vivid_video_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
-int vivid_video_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt);
-int vivid_video_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt);
+int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin);
+int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *vin);
+int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *vin);
+int vivid_video_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf);
+int vivid_video_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf);
+int vivid_video_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt);
+int vivid_video_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt);
int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *id);
int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id);
-int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vidioc_query_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vidioc_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid);
-int vidioc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize);
+int vivid_vid_cap_s_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *timings);
+int vidioc_query_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *timings);
+int vidioc_s_edid(struct file *file, void *priv, struct v4l2_edid *edid);
+int vidioc_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *fsize);
int vidioc_enum_frameintervals(struct file *file, void *priv, struct v4l2_frmivalenum *fival);
int vivid_vid_cap_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
int vivid_vid_cap_s_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.c b/drivers/media/test-drivers/vivid/vivid-vid-common.c
index df7678db67fb..786a1aa3b26b 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-common.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-common.c
@@ -1021,7 +1021,7 @@ int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
return 0;
}
-int vidioc_g_dv_timings(struct file *file, void *_fh,
+int vidioc_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1039,7 +1039,7 @@ int vidioc_g_dv_timings(struct file *file, void *_fh,
return 0;
}
-int vidioc_enum_dv_timings(struct file *file, void *_fh,
+int vidioc_enum_dv_timings(struct file *file, void *priv,
struct v4l2_enum_dv_timings *timings)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1056,7 +1056,7 @@ int vidioc_enum_dv_timings(struct file *file, void *_fh,
NULL, NULL);
}
-int vidioc_dv_timings_cap(struct file *file, void *_fh,
+int vidioc_dv_timings_cap(struct file *file, void *priv,
struct v4l2_dv_timings_cap *cap)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1073,7 +1073,7 @@ int vidioc_dv_timings_cap(struct file *file, void *_fh,
return 0;
}
-int vidioc_g_edid(struct file *file, void *_fh,
+int vidioc_g_edid(struct file *file, void *priv,
struct v4l2_edid *edid)
{
struct vivid_dev *dev = video_drvdata(file);
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.h b/drivers/media/test-drivers/vivid/vivid-vid-common.h
index c49ac85abaed..fb5878174dba 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-common.h
+++ b/drivers/media/test-drivers/vivid/vivid-vid-common.h
@@ -32,10 +32,10 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r);
int vivid_enum_fmt_vid(struct file *file, void *priv, struct v4l2_fmtdesc *f);
int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id);
-int vidioc_g_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
-int vidioc_enum_dv_timings(struct file *file, void *_fh, struct v4l2_enum_dv_timings *timings);
-int vidioc_dv_timings_cap(struct file *file, void *_fh, struct v4l2_dv_timings_cap *cap);
-int vidioc_g_edid(struct file *file, void *_fh, struct v4l2_edid *edid);
+int vidioc_g_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *timings);
+int vidioc_enum_dv_timings(struct file *file, void *priv, struct v4l2_enum_dv_timings *timings);
+int vidioc_dv_timings_cap(struct file *file, void *priv, struct v4l2_dv_timings_cap *cap);
+int vidioc_g_edid(struct file *file, void *priv, struct v4l2_edid *edid);
int vidioc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub);
#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c
index c3398bce6c15..8c037b90833e 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-out.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c
@@ -672,7 +672,7 @@ int vivid_vid_out_g_selection(struct file *file, void *priv,
return 0;
}
-int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+int vivid_vid_out_s_selection(struct file *file, void *priv, struct v4l2_selection *s)
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_rect *crop = &dev->crop_out;
@@ -880,7 +880,7 @@ int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv,
return ret;
}
-int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i)
+int vivid_vid_out_overlay(struct file *file, void *priv, unsigned i)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -893,7 +893,7 @@ int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i)
return 0;
}
-int vivid_vid_out_g_fbuf(struct file *file, void *fh,
+int vivid_vid_out_g_fbuf(struct file *file, void *priv,
struct v4l2_framebuffer *a)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -920,7 +920,7 @@ int vivid_vid_out_g_fbuf(struct file *file, void *fh,
return 0;
}
-int vivid_vid_out_s_fbuf(struct file *file, void *fh,
+int vivid_vid_out_s_fbuf(struct file *file, void *priv,
const struct v4l2_framebuffer *a)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1016,7 +1016,7 @@ int vidioc_s_output(struct file *file, void *priv, unsigned o)
return 0;
}
-int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout)
+int vidioc_enumaudout(struct file *file, void *priv, struct v4l2_audioout *vout)
{
if (vout->index >= ARRAY_SIZE(vivid_audio_outputs))
return -EINVAL;
@@ -1024,7 +1024,7 @@ int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout)
return 0;
}
-int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
+int vidioc_g_audout(struct file *file, void *priv, struct v4l2_audioout *vout)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1034,7 +1034,7 @@ int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
return 0;
}
-int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout)
+int vidioc_s_audout(struct file *file, void *priv, const struct v4l2_audioout *vout)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -1072,7 +1072,7 @@ static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
return false;
}
-int vivid_vid_out_s_dv_timings(struct file *file, void *_fh,
+int vivid_vid_out_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vivid_dev *dev = video_drvdata(file);
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.h b/drivers/media/test-drivers/vivid/vivid-vid-out.h
index 8d56314f4ea1..1d03891a5de5 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-out.h
+++ b/drivers/media/test-drivers/vivid/vivid-vid-out.h
@@ -22,23 +22,23 @@ int vidioc_g_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
int vidioc_try_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
int vidioc_s_fmt_vid_out(struct file *file, void *priv, struct v4l2_format *f);
int vivid_vid_out_g_selection(struct file *file, void *priv, struct v4l2_selection *sel);
-int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s);
+int vivid_vid_out_s_selection(struct file *file, void *priv, struct v4l2_selection *s);
int vivid_vid_out_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f);
int vidioc_enum_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f);
int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f);
-int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i);
-int vivid_vid_out_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a);
-int vivid_vid_out_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a);
+int vivid_vid_out_overlay(struct file *file, void *priv, unsigned i);
+int vivid_vid_out_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *a);
+int vivid_vid_out_s_fbuf(struct file *file, void *priv, const struct v4l2_framebuffer *a);
int vidioc_enum_output(struct file *file, void *priv, struct v4l2_output *out);
int vidioc_g_output(struct file *file, void *priv, unsigned *i);
int vidioc_s_output(struct file *file, void *priv, unsigned i);
-int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout);
-int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout);
-int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout);
+int vidioc_enumaudout(struct file *file, void *priv, struct v4l2_audioout *vout);
+int vidioc_g_audout(struct file *file, void *priv, struct v4l2_audioout *vout);
+int vidioc_s_audout(struct file *file, void *priv, const struct v4l2_audioout *vout);
int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id);
-int vivid_vid_out_s_dv_timings(struct file *file, void *_fh, struct v4l2_dv_timings *timings);
+int vivid_vid_out_s_dv_timings(struct file *file, void *priv, struct v4l2_dv_timings *timings);
int vivid_vid_out_g_parm(struct file *file, void *priv, struct v4l2_streamparm *parm);
#endif
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index 3cf54d776d36..b44c97e4e5ec 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -1087,12 +1087,12 @@ fail:
static void xc_debug_dump(struct xc4000_priv *priv)
{
- u16 adc_envelope;
+ u16 adc_envelope = 0;
u32 freq_error_hz = 0;
- u16 lock_status;
+ u16 lock_status = 0;
u32 hsync_freq_hz = 0;
- u16 frame_lines;
- u16 quality;
+ u16 frame_lines = 0;
+ u16 quality = 0;
u16 signal = 0;
u16 noise = 0;
u8 hw_majorversion = 0, hw_minorversion = 0;
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 30aa4ee958bd..a28481edd22e 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -622,14 +622,14 @@ static int xc5000_fwupload(struct dvb_frontend *fe,
static void xc_debug_dump(struct xc5000_priv *priv)
{
- u16 adc_envelope;
+ u16 adc_envelope = 0;
u32 freq_error_hz = 0;
- u16 lock_status;
+ u16 lock_status = 0;
u32 hsync_freq_hz = 0;
- u16 frame_lines;
- u16 quality;
- u16 snr;
- u16 totalgain;
+ u16 frame_lines = 0;
+ u16 quality = 0;
+ u16 snr = 0;
+ u16 totalgain = 0;
u8 hw_majorversion = 0, hw_minorversion = 0;
u8 fw_majorversion = 0, fw_minorversion = 0;
u16 fw_buildversion = 0;
@@ -1304,7 +1304,7 @@ static void xc5000_release(struct dvb_frontend *fe)
mutex_lock(&xc5000_list_mutex);
if (priv) {
- cancel_delayed_work(&priv->timer_sleep);
+ cancel_delayed_work_sync(&priv->timer_sleep);
hybrid_tuner_release_state(priv);
}
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index e5dff969ed57..fbaa542c8259 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1921,9 +1921,8 @@ int au0828_analog_register(struct au0828_dev *dev,
iface_desc = interface->cur_altsetting;
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint = &iface_desc->endpoint[i].desc;
- if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
- == USB_DIR_IN) &&
- ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ if (usb_endpoint_dir_in(endpoint) &&
+ (usb_endpoint_type(endpoint)
== USB_ENDPOINT_XFER_ISOC)) {
/* we find our isoc in endpoint */
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index e585c8f6e4c5..c695a97e202b 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1499,7 +1499,7 @@ static int vidioc_g_selection(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
{
struct cx231xx *dev = video_drvdata(file);
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
index cb61fd6cc6c6..3122d4bdfc59 100644
--- a/drivers/media/usb/em28xx/Kconfig
+++ b/drivers/media/usb/em28xx/Kconfig
@@ -68,6 +68,7 @@ config VIDEO_EM28XX_DVB
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MXL692 if MEDIA_SUBDRV_AUTOSELECT
+ select GPIOLIB_LEGACY if GPIOLIB && DVB_CXD2820R
help
This adds support for DVB cards based on the
Empiatech em28xx chips.
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 9fce59979e3b..b94f5c70ab75 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -727,7 +727,7 @@ static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv;
struct em28xx *dev = i2c_bus->dev;
-#ifdef CONFIG_GPIOLIB
+#ifdef CONFIG_GPIOLIB_LEGACY
struct em28xx_dvb *dvb = dev->dvb;
int ret;
unsigned long flags;
@@ -1705,7 +1705,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
goto out_free;
}
-#ifdef CONFIG_GPIOLIB
+#ifdef CONFIG_GPIOLIB_LEGACY
/* enable LNA for DVB-T, DVB-T2 and DVB-C */
result = gpio_request_one(dvb->lna_gpio,
GPIOF_OUT_INIT_LOW, NULL);
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index 25edd2189654..3fc15d16df8e 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1029,15 +1029,15 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_fmt_vid_cap(struct file *file, void *_priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *fmt)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
- u32 priv = fmt->fmt.pix.priv;
+ u32 fmt_priv = fmt->fmt.pix.priv;
fmt->fmt.pix = gspca_dev->pixfmt;
/* some drivers use priv internally, so keep the original value */
- fmt->fmt.pix.priv = priv;
+ fmt->fmt.pix.priv = fmt_priv;
return 0;
}
@@ -1075,24 +1075,24 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
return mode; /* used when s_fmt */
}
-static int vidioc_try_fmt_vid_cap(struct file *file, void *_priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *fmt)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
- u32 priv = fmt->fmt.pix.priv;
+ u32 fmt_priv = fmt->fmt.pix.priv;
if (try_fmt_vid_cap(gspca_dev, fmt) < 0)
return -EINVAL;
/* some drivers use priv internally, so keep the original value */
- fmt->fmt.pix.priv = priv;
+ fmt->fmt.pix.priv = fmt_priv;
return 0;
}
-static int vidioc_s_fmt_vid_cap(struct file *file, void *_priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *fmt)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
- u32 priv = fmt->fmt.pix.priv;
+ u32 fmt_priv = fmt->fmt.pix.priv;
int mode;
if (vb2_is_busy(&gspca_dev->queue))
@@ -1109,7 +1109,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *_priv,
else
gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode];
/* some drivers use priv internally, so keep the original value */
- fmt->fmt.pix.priv = priv;
+ fmt->fmt.pix.priv = fmt_priv;
return 0;
}
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index fd7d2a9d0449..8c7ae362d992 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -52,6 +52,11 @@ struct hdpvr_fh {
bool legacy_mode;
};
+static inline struct hdpvr_fh *file_to_hdpvr_fh(struct file *file)
+{
+ return container_of(file_to_v4l2_fh(file), struct hdpvr_fh, fh);
+}
+
static uint list_size(struct list_head *list)
{
struct list_head *tmp;
@@ -380,8 +385,7 @@ static int hdpvr_open(struct file *file)
return -ENOMEM;
fh->legacy_mode = true;
v4l2_fh_init(&fh->fh, video_devdata(file));
- v4l2_fh_add(&fh->fh);
- file->private_data = fh;
+ v4l2_fh_add(&fh->fh, file);
return 0;
}
@@ -390,7 +394,7 @@ static int hdpvr_release(struct file *file)
struct hdpvr_device *dev = video_drvdata(file);
mutex_lock(&dev->io_mutex);
- if (file->private_data == dev->owner) {
+ if (file_to_v4l2_fh(file) == dev->owner) {
hdpvr_stop_streaming(dev);
dev->owner = NULL;
}
@@ -426,7 +430,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
mutex_unlock(&dev->io_mutex);
goto err;
}
- dev->owner = file->private_data;
+ dev->owner = file_to_v4l2_fh(file);
print_buffer_status();
}
mutex_unlock(&dev->io_mutex);
@@ -541,7 +545,7 @@ static __poll_t hdpvr_poll(struct file *filp, poll_table *wait)
"start_streaming failed\n");
dev->status = STATUS_IDLE;
} else {
- dev->owner = filp->private_data;
+ dev->owner = file_to_v4l2_fh(filp);
}
print_buffer_status();
@@ -586,11 +590,11 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_std(struct file *file, void *_fh,
+static int vidioc_s_std(struct file *file, void *priv,
v4l2_std_id std)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
u8 std_type = 1;
if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
@@ -606,11 +610,12 @@ static int vidioc_s_std(struct file *file, void *_fh,
return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
}
-static int vidioc_g_std(struct file *file, void *_fh,
+static int vidioc_g_std(struct file *file, void *priv,
v4l2_std_id *std)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
+
if (!fh->legacy_mode && dev->options.video_input == HDPVR_COMPONENT)
return -ENODATA;
@@ -618,11 +623,11 @@ static int vidioc_g_std(struct file *file, void *_fh,
return 0;
}
-static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
+static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *a)
{
struct hdpvr_device *dev = video_drvdata(file);
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
struct hdpvr_video_info vid_info;
- struct hdpvr_fh *fh = _fh;
int ret;
*a = V4L2_STD_UNKNOWN;
@@ -637,11 +642,11 @@ static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
return ret;
}
-static int vidioc_s_dv_timings(struct file *file, void *_fh,
+static int vidioc_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
int i;
fh->legacy_mode = false;
@@ -660,11 +665,11 @@ static int vidioc_s_dv_timings(struct file *file, void *_fh,
return 0;
}
-static int vidioc_g_dv_timings(struct file *file, void *_fh,
+static int vidioc_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
fh->legacy_mode = false;
if (dev->options.video_input)
@@ -673,11 +678,11 @@ static int vidioc_g_dv_timings(struct file *file, void *_fh,
return 0;
}
-static int vidioc_query_dv_timings(struct file *file, void *_fh,
+static int vidioc_query_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
struct hdpvr_video_info vid_info;
bool interlaced;
int ret = 0;
@@ -715,11 +720,11 @@ static int vidioc_query_dv_timings(struct file *file, void *_fh,
return ret;
}
-static int vidioc_enum_dv_timings(struct file *file, void *_fh,
+static int vidioc_enum_dv_timings(struct file *file, void *priv,
struct v4l2_enum_dv_timings *timings)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
fh->legacy_mode = false;
memset(timings->reserved, 0, sizeof(timings->reserved));
@@ -731,11 +736,11 @@ static int vidioc_enum_dv_timings(struct file *file, void *_fh,
return 0;
}
-static int vidioc_dv_timings_cap(struct file *file, void *_fh,
+static int vidioc_dv_timings_cap(struct file *file, void *priv,
struct v4l2_dv_timings_cap *cap)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
fh->legacy_mode = false;
if (dev->options.video_input)
@@ -758,7 +763,7 @@ static const char *iname[] = {
[HDPVR_COMPOSITE] = "Composite",
};
-static int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i)
+static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
{
unsigned int n;
@@ -778,7 +783,7 @@ static int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i)
return 0;
}
-static int vidioc_s_input(struct file *file, void *_fh,
+static int vidioc_s_input(struct file *file, void *priv,
unsigned int index)
{
struct hdpvr_device *dev = video_drvdata(file);
@@ -812,7 +817,7 @@ static int vidioc_s_input(struct file *file, void *_fh,
return retval;
}
-static int vidioc_g_input(struct file *file, void *private_data,
+static int vidioc_g_input(struct file *file, void *priv,
unsigned int *index)
{
struct hdpvr_device *dev = video_drvdata(file);
@@ -844,7 +849,7 @@ static int vidioc_enumaudio(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_audio(struct file *file, void *private_data,
+static int vidioc_s_audio(struct file *file, void *priv,
const struct v4l2_audio *audio)
{
struct hdpvr_device *dev = video_drvdata(file);
@@ -863,7 +868,7 @@ static int vidioc_s_audio(struct file *file, void *private_data,
return retval;
}
-static int vidioc_g_audio(struct file *file, void *private_data,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
struct hdpvr_device *dev = video_drvdata(file);
@@ -980,7 +985,7 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
return ret;
}
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (f->index != 0)
@@ -991,11 +996,11 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
return 0;
}
-static int vidioc_g_fmt_vid_cap(struct file *file, void *_fh,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_fh *fh = _fh;
+ struct hdpvr_fh *fh = file_to_hdpvr_fh(file);
int ret;
/*
@@ -1048,7 +1053,7 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv,
switch (a->cmd) {
case V4L2_ENC_CMD_START:
- if (dev->owner && filp->private_data != dev->owner) {
+ if (dev->owner && file_to_v4l2_fh(filp) != dev->owner) {
res = -EBUSY;
break;
}
@@ -1056,12 +1061,12 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv,
break;
res = hdpvr_start_streaming(dev);
if (!res)
- dev->owner = filp->private_data;
+ dev->owner = file_to_v4l2_fh(filp);
else
dev->status = STATUS_IDLE;
break;
case V4L2_ENC_CMD_STOP:
- if (dev->owner && filp->private_data != dev->owner) {
+ if (dev->owner && file_to_v4l2_fh(filp) != dev->owner) {
res = -EBUSY;
break;
}
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index ad38e1240541..f9535a484738 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -21,8 +21,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-struct pvr2_v4l2_dev;
-struct pvr2_v4l2_fh;
struct pvr2_v4l2;
struct pvr2_v4l2_dev {
@@ -48,6 +46,11 @@ struct pvr2_v4l2_fh {
unsigned int input_cnt;
};
+static inline struct pvr2_v4l2_fh *to_pvr2_v4l2_fh(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct pvr2_v4l2_fh, fh);
+}
+
struct pvr2_v4l2 {
struct pvr2_channel channel;
@@ -108,7 +111,7 @@ static struct v4l2_format pvr_format [] = {
*/
static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
strscpy(cap->driver, "pvrusb2", sizeof(cap->driver));
@@ -123,7 +126,7 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *
static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int val = 0;
int ret;
@@ -136,7 +139,7 @@ static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
static int pvr2_s_std(struct file *file, void *priv, v4l2_std_id std)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int ret;
@@ -148,7 +151,7 @@ static int pvr2_s_std(struct file *file, void *priv, v4l2_std_id std)
static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int val = 0;
int ret;
@@ -161,7 +164,7 @@ static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct pvr2_ctrl *cptr;
struct v4l2_input tmp;
@@ -209,7 +212,7 @@ static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
unsigned int idx;
struct pvr2_ctrl *cptr;
@@ -231,7 +234,7 @@ static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
static int pvr2_s_input(struct file *file, void *priv, unsigned int inp)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int ret;
@@ -286,7 +289,7 @@ static int pvr2_s_audio(struct file *file, void *priv, const struct v4l2_audio *
static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
if (vt->index != 0)
@@ -298,7 +301,7 @@ static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
static int pvr2_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int ret;
@@ -314,7 +317,7 @@ static int pvr2_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *
static int pvr2_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
unsigned long fv;
struct v4l2_tuner vt;
@@ -349,7 +352,7 @@ static int pvr2_s_frequency(struct file *file, void *priv, const struct v4l2_fre
static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int val = 0;
int cur_input;
@@ -391,7 +394,7 @@ static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtd
static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int val;
@@ -411,7 +414,7 @@ static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format
static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int lmin, lmax, ldef;
struct pvr2_ctrl *hcp, *vcp;
@@ -449,7 +452,7 @@ static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_forma
static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct pvr2_ctrl *hcp, *vcp;
int ret = pvr2_try_fmt_vid_cap(file, fh, vf);
@@ -466,7 +469,7 @@ static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format
static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct pvr2_v4l2_dev *pdi = fh->pdi;
int ret;
@@ -485,7 +488,7 @@ static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
if (!fh->pdi->stream) {
@@ -500,7 +503,7 @@ static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
static int pvr2_query_ext_ctrl(struct file *file, void *priv,
struct v4l2_query_ext_ctrl *vc)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct pvr2_ctrl *cptr;
int val;
@@ -561,7 +564,7 @@ static int pvr2_query_ext_ctrl(struct file *file, void *priv,
static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
unsigned int cnt = 0;
int ret;
@@ -577,7 +580,7 @@ static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *
static int pvr2_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctls)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct v4l2_ext_control *ctrl;
struct pvr2_ctrl *cptr;
@@ -612,7 +615,7 @@ static int pvr2_g_ext_ctrls(struct file *file, void *priv,
static int pvr2_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctls)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct v4l2_ext_control *ctrl;
unsigned int idx;
@@ -637,7 +640,7 @@ commit:
static int pvr2_try_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctls)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct v4l2_ext_control *ctrl;
struct pvr2_ctrl *pctl;
@@ -659,7 +662,7 @@ static int pvr2_try_ext_ctrls(struct file *file, void *priv,
static int pvr2_g_pixelaspect(struct file *file, void *priv,
int type, struct v4l2_fract *f)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct v4l2_cropcap cap = { .type = type };
int ret;
@@ -675,7 +678,7 @@ static int pvr2_g_pixelaspect(struct file *file, void *priv,
static int pvr2_g_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
struct v4l2_cropcap cap;
int val = 0;
@@ -726,7 +729,7 @@ static int pvr2_g_selection(struct file *file, void *priv,
static int pvr2_s_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
int ret;
@@ -758,7 +761,7 @@ commit:
static int pvr2_log_status(struct file *file, void *priv)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
pvr2_hdw_trigger_module_log(hdw);
@@ -882,7 +885,7 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
static int pvr2_v4l2_release(struct file *file)
{
- struct pvr2_v4l2_fh *fhp = file->private_data;
+ struct pvr2_v4l2_fh *fhp = to_pvr2_v4l2_fh(file);
struct pvr2_v4l2 *vp = fhp->pdi->v4lp;
struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
@@ -897,9 +900,8 @@ static int pvr2_v4l2_release(struct file *file)
fhp->rhp = NULL;
}
- v4l2_fh_del(&fhp->fh);
+ v4l2_fh_del(&fhp->fh, file);
v4l2_fh_exit(&fhp->fh);
- file->private_data = NULL;
pvr2_channel_done(&fhp->channel);
pvr2_trace(PVR2_TRACE_STRUCT,
@@ -1000,10 +1002,9 @@ static int pvr2_v4l2_open(struct file *file)
}
fhp->file = file;
- file->private_data = fhp;
fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
- v4l2_fh_add(&fhp->fh);
+ v4l2_fh_add(&fhp->fh, file);
return 0;
}
@@ -1055,7 +1056,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
static ssize_t pvr2_v4l2_read(struct file *file,
char __user *buff, size_t count, loff_t *ppos)
{
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
int ret;
if (fh->fw_mode_flag) {
@@ -1117,7 +1118,7 @@ static ssize_t pvr2_v4l2_read(struct file *file,
static __poll_t pvr2_v4l2_poll(struct file *file, poll_table *wait)
{
__poll_t mask = 0;
- struct pvr2_v4l2_fh *fh = file->private_data;
+ struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
int ret;
if (fh->fw_mode_flag) {
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
index ce717502ea4c..25d725c2ab3c 100644
--- a/drivers/media/usb/stk1160/stk1160-core.c
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -195,8 +195,7 @@ static int stk1160_scan_usb(struct usb_interface *intf, struct usb_device *udev,
if (udev->speed == USB_SPEED_HIGH)
size = size * hb_mult(sizedescr);
- if (usb_endpoint_xfer_isoc(desc) &&
- usb_endpoint_dir_in(desc)) {
+ if (usb_endpoint_is_isoc_in(desc)) {
switch (desc->bEndpointAddress) {
case STK1160_EP_AUDIO:
has_audio = true;
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index 416cb74377eb..f4baf9263286 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -408,8 +408,13 @@ static int stk1160_fill_urb(struct stk1160 *dev, struct stk1160_urb *stk_urb,
stk_urb->transfer_buffer = usb_alloc_noncoherent(dev->udev, sb_size,
GFP_KERNEL, &stk_urb->dma,
DMA_FROM_DEVICE, &stk_urb->sgt);
- if (!stk_urb->transfer_buffer)
+ if (!stk_urb->transfer_buffer) {
+ /*
+ * If the buffer allocation failed, we exit but return 0 since
+ * we allow the driver working with less buffers.
+ */
goto free_urb;
+ }
stk_urb->dev = dev;
return 0;
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index efe609d70877..2905505c240c 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -376,6 +376,15 @@ static const struct uvc_control_info uvc_ctrls[] = {
| UVC_CTRL_FLAG_GET_DEF
| UVC_CTRL_FLAG_AUTO_UPDATE,
},
+ {
+ .entity = UVC_GUID_CHROMEOS_XU,
+ .selector = UVC_CROSXU_CONTROL_IQ_PROFILE,
+ .index = 3,
+ .size = 1,
+ .flags = UVC_CTRL_FLAG_SET_CUR
+ | UVC_CTRL_FLAG_GET_RANGE
+ | UVC_CTRL_FLAG_RESTORE,
+ },
};
static const u32 uvc_control_classes[] = {
@@ -384,6 +393,19 @@ static const u32 uvc_control_classes[] = {
};
static const int exposure_auto_mapping[] = { 2, 1, 4, 8 };
+static const int cros_colorfx_mapping[] = {
+ 1, /* V4L2_COLORFX_NONE */
+ -1, /* V4L2_COLORFX_BW */
+ -1, /* V4L2_COLORFX_SEPIA */
+ -1, /* V4L2_COLORFX_NEGATIVE */
+ -1, /* V4L2_COLORFX_EMBOSS */
+ -1, /* V4L2_COLORFX_SKETCH */
+ -1, /* V4L2_COLORFX_SKY_BLUE */
+ -1, /* V4L2_COLORFX_GRASS_GREEN */
+ -1, /* V4L2_COLORFX_SKIN_WHITEN */
+ 0, /* V4L2_COLORFX_VIVID */
+};
+
static bool uvc_ctrl_mapping_is_compound(struct uvc_control_mapping *mapping)
{
@@ -975,6 +997,18 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = {
.data_type = UVC_CTRL_DATA_TYPE_BITMASK,
.name = "Region of Interest Auto Ctrls",
},
+ {
+ .id = V4L2_CID_COLORFX,
+ .entity = UVC_GUID_CHROMEOS_XU,
+ .selector = UVC_CROSXU_CONTROL_IQ_PROFILE,
+ .size = 8,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_MENU,
+ .data_type = UVC_CTRL_DATA_TYPE_ENUM,
+ .menu_mapping = cros_colorfx_mapping,
+ .menu_mask = BIT(V4L2_COLORFX_VIVID) |
+ BIT(V4L2_COLORFX_NONE),
+ },
};
/* ------------------------------------------------------------------------
@@ -1619,7 +1653,7 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
}
if (ret == -EIO) {
- dev_warn_ratelimited(&chain->dev->udev->dev,
+ dev_warn_ratelimited(&chain->dev->intf->dev,
"UVC non compliance: Error %d querying master control %x (%s)\n",
ret, master_map->id,
uvc_map_get_name(master_map));
@@ -1643,7 +1677,7 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
ret = __uvc_queryctrl_boundaries(chain, ctrl, mapping, v4l2_ctrl);
if (ret && !mapping->disabled) {
- dev_warn(&chain->dev->udev->dev,
+ dev_warn(&chain->dev->intf->dev,
"UVC non compliance: permanently disabling control %x (%s), due to error %d\n",
mapping->id, uvc_map_get_name(mapping), ret);
mapping->disabled = true;
@@ -1858,7 +1892,7 @@ static int uvc_ctrl_set_handle(struct uvc_control *ctrl, struct uvc_fh *handle)
lockdep_assert_held(&handle->chain->ctrl_mutex);
if (ctrl->handle) {
- dev_warn_ratelimited(&handle->stream->dev->udev->dev,
+ dev_warn_ratelimited(&handle->stream->dev->intf->dev,
"UVC non compliance: Setting an async control with a pending operation.");
if (ctrl->handle == handle)
@@ -1956,7 +1990,7 @@ static void uvc_ctrl_status_event_work(struct work_struct *work)
w->urb->interval = dev->int_ep->desc.bInterval;
ret = usb_submit_urb(w->urb, GFP_KERNEL);
if (ret < 0)
- dev_err(&dev->udev->dev,
+ dev_err(&dev->intf->dev,
"Failed to resubmit status URB (%d).\n", ret);
}
@@ -2895,7 +2929,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
if (!ctrl->initialized || !ctrl->modified ||
(ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)
continue;
- dev_dbg(&dev->udev->dev,
+ dev_dbg(&dev->intf->dev,
"restoring control %pUl/%u/%u\n",
ctrl->info.entity, ctrl->info.index,
ctrl->info.selector);
@@ -3181,15 +3215,6 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
{
unsigned int i;
- /*
- * XU controls initialization requires querying the device for control
- * information. As some buggy UVC devices will crash when queried
- * repeatedly in a tight loop, delay XU controls initialization until
- * first use.
- */
- if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT)
- return;
-
for (i = 0; i < ARRAY_SIZE(uvc_ctrls); ++i) {
const struct uvc_control_info *info = &uvc_ctrls[i];
@@ -3307,7 +3332,6 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
{
struct uvc_entity *entity;
- int i;
guard(mutex)(&handle->chain->ctrl_mutex);
@@ -3325,7 +3349,7 @@ void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
if (!WARN_ON(handle->pending_async_ctrls))
return;
- for (i = 0; i < handle->pending_async_ctrls; i++)
+ for (unsigned int i = 0; i < handle->pending_async_ctrls; i++)
uvc_pm_put(handle->stream->dev);
}
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 775bede0d93d..fa61f1d0ea2c 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -137,6 +137,9 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
{
struct uvc_entity *entity;
+ if (id == UVC_INVALID_ENTITY_ID)
+ return NULL;
+
list_for_each_entry(entity, &dev->entities, list) {
if (entity->id == id)
return entity;
@@ -183,8 +186,6 @@ static void uvc_stream_delete(struct uvc_streaming *stream)
if (stream->async_wq)
destroy_workqueue(stream->async_wq);
- mutex_destroy(&stream->mutex);
-
usb_put_intf(stream->intf);
kfree(stream->formats);
@@ -201,8 +202,6 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
if (stream == NULL)
return NULL;
- mutex_init(&stream->mutex);
-
stream->dev = dev;
stream->intf = usb_get_intf(intf);
stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
@@ -795,14 +794,27 @@ static const u8 uvc_media_transport_input_guid[16] =
UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
-static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
- unsigned int num_pads, unsigned int extra_size)
+static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type,
+ u16 id, unsigned int num_pads,
+ unsigned int extra_size)
{
struct uvc_entity *entity;
unsigned int num_inputs;
unsigned int size;
unsigned int i;
+ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */
+ if (id == 0) {
+ dev_err(&dev->intf->dev, "Found Unit with invalid ID 0\n");
+ id = UVC_INVALID_ENTITY_ID;
+ }
+
+ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */
+ if (uvc_entity_by_id(dev, id)) {
+ dev_err(&dev->intf->dev, "Found multiple Units with ID %u\n", id);
+ id = UVC_INVALID_ENTITY_ID;
+ }
+
extra_size = roundup(extra_size, sizeof(*entity->pads));
if (num_pads)
num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1;
@@ -812,7 +824,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
+ num_inputs;
entity = kzalloc(size, GFP_KERNEL);
if (entity == NULL)
- return NULL;
+ return ERR_PTR(-ENOMEM);
entity->id = id;
entity->type = type;
@@ -882,7 +894,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
unsigned int n, p;
int handled = 0;
- switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {
+ switch (le16_to_cpu(udev->descriptor.idVendor)) {
case 0x046d: /* Logitech */
if (buffer[1] != 0x41 || buffer[2] != 0x01)
break;
@@ -924,10 +936,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
break;
}
- unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
- p + 1, 2*n);
- if (unit == NULL)
- return -ENOMEM;
+ unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT,
+ buffer[3], p + 1, 2 * n);
+ if (IS_ERR(unit))
+ return PTR_ERR(unit);
memcpy(unit->guid, &buffer[4], 16);
unit->extension.bNumControls = buffer[20];
@@ -1036,10 +1048,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}
- term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
- 1, n + p);
- if (term == NULL)
- return -ENOMEM;
+ term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT,
+ buffer[3], 1, n + p);
+ if (IS_ERR(term))
+ return PTR_ERR(term);
if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
term->camera.bControlSize = n;
@@ -1095,10 +1107,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return 0;
}
- term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
- 1, 0);
- if (term == NULL)
- return -ENOMEM;
+ term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT,
+ buffer[3], 1, 0);
+ if (IS_ERR(term))
+ return PTR_ERR(term);
memcpy(term->baSourceID, &buffer[7], 1);
@@ -1117,9 +1129,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}
- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
- if (unit == NULL)
- return -ENOMEM;
+ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],
+ p + 1, 0);
+ if (IS_ERR(unit))
+ return PTR_ERR(unit);
memcpy(unit->baSourceID, &buffer[5], p);
@@ -1139,9 +1152,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}
- unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
- if (unit == NULL)
- return -ENOMEM;
+ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n);
+ if (IS_ERR(unit))
+ return PTR_ERR(unit);
memcpy(unit->baSourceID, &buffer[4], 1);
unit->processing.wMaxMultiplier =
@@ -1168,9 +1181,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}
- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
- if (unit == NULL)
- return -ENOMEM;
+ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],
+ p + 1, n);
+ if (IS_ERR(unit))
+ return PTR_ERR(unit);
memcpy(unit->guid, &buffer[4], 16);
unit->extension.bNumControls = buffer[20];
@@ -1315,9 +1329,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
return dev_err_probe(&dev->intf->dev, irq,
"No IRQ for privacy GPIO\n");
- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
- if (!unit)
- return -ENOMEM;
+ unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT,
+ UVC_EXT_GPIO_UNIT_ID, 0, 1);
+ if (IS_ERR(unit))
+ return PTR_ERR(unit);
unit->gpio.gpio_privacy = gpio_privacy;
unit->gpio.irq = irq;
@@ -1868,7 +1883,7 @@ static int uvc_scan_device(struct uvc_device *dev)
uvc_scan_fallback(dev);
if (list_empty(&dev->chains)) {
- dev_info(&dev->udev->dev, "No valid video chain found.\n");
+ dev_info(&dev->intf->dev, "No valid video chain found.\n");
return -ENODEV;
}
@@ -1958,11 +1973,11 @@ static void uvc_unregister_video(struct uvc_device *dev)
list_for_each_entry(stream, &dev->streams, list) {
/* Nothing to do here, continue. */
- if (!video_is_registered(&stream->vdev))
+ if (!video_is_registered(&stream->queue.vdev))
continue;
- vb2_video_unregister_device(&stream->vdev);
- vb2_video_unregister_device(&stream->meta.vdev);
+ vb2_video_unregister_device(&stream->queue.vdev);
+ vb2_video_unregister_device(&stream->meta.queue.vdev);
/*
* Now both vdevs are not streaming and all the ioctls will
@@ -1984,12 +1999,12 @@ static void uvc_unregister_video(struct uvc_device *dev)
int uvc_register_video_device(struct uvc_device *dev,
struct uvc_streaming *stream,
- struct video_device *vdev,
struct uvc_video_queue *queue,
enum v4l2_buf_type type,
const struct v4l2_file_operations *fops,
const struct v4l2_ioctl_ops *ioctl_ops)
{
+ struct video_device *vdev = &queue->vdev;
int ret;
/* Initialize the video buffers queue. */
@@ -2071,9 +2086,9 @@ static int uvc_register_video(struct uvc_device *dev,
uvc_debugfs_init_stream(stream);
/* Register the device with V4L. */
- return uvc_register_video_device(dev, stream, &stream->vdev,
- &stream->queue, stream->type,
- &uvc_fops, &uvc_ioctl_ops);
+ return uvc_register_video_device(dev, stream, &stream->queue,
+ stream->type, &uvc_fops,
+ &uvc_ioctl_ops);
}
/*
@@ -2092,7 +2107,7 @@ static int uvc_register_terms(struct uvc_device *dev,
stream = uvc_stream_by_id(dev, term->id);
if (stream == NULL) {
- dev_info(&dev->udev->dev,
+ dev_info(&dev->intf->dev,
"No streaming interface found for terminal %u.",
term->id);
continue;
@@ -2109,7 +2124,7 @@ static int uvc_register_terms(struct uvc_device *dev,
*/
uvc_meta_register(stream);
- term->vdev = &stream->vdev;
+ term->vdev = &stream->queue.vdev;
}
return 0;
@@ -2128,7 +2143,7 @@ static int uvc_register_chains(struct uvc_device *dev)
#ifdef CONFIG_MEDIA_CONTROLLER
ret = uvc_mc_register_entities(chain);
if (ret < 0)
- dev_info(&dev->udev->dev,
+ dev_info(&dev->intf->dev,
"Failed to register entities (%d).\n", ret);
#endif
}
@@ -2229,23 +2244,23 @@ static int uvc_probe(struct usb_interface *intf,
if (ret < 0)
goto error;
- dev_info(&dev->udev->dev, "Found UVC %u.%02x device %s (%04x:%04x)\n",
+ dev_info(&dev->intf->dev, "Found UVC %u.%02x device %s (%04x:%04x)\n",
dev->uvc_version >> 8, dev->uvc_version & 0xff,
udev->product ? udev->product : "<unnamed>",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
if (dev->quirks != dev->info->quirks) {
- dev_info(&dev->udev->dev,
+ dev_info(&dev->intf->dev,
"Forcing device quirks to 0x%x by module parameter for testing purpose.\n",
dev->quirks);
- dev_info(&dev->udev->dev,
+ dev_info(&dev->intf->dev,
"Please report required quirks to the linux-media mailing list.\n");
}
if (dev->info->uvc_version) {
dev->uvc_version = dev->info->uvc_version;
- dev_info(&dev->udev->dev, "Forcing UVC version to %u.%02x\n",
+ dev_info(&dev->intf->dev, "Forcing UVC version to %u.%02x\n",
dev->uvc_version >> 8, dev->uvc_version & 0xff);
}
@@ -2281,21 +2296,21 @@ static int uvc_probe(struct usb_interface *intf,
/* Initialize the interrupt URB. */
ret = uvc_status_init(dev);
if (ret < 0) {
- dev_info(&dev->udev->dev,
+ dev_info(&dev->intf->dev,
"Unable to initialize the status endpoint (%d), status interrupt will not be supported.\n",
ret);
}
ret = uvc_gpio_init_irq(dev);
if (ret < 0) {
- dev_err(&dev->udev->dev,
+ dev_err(&dev->intf->dev,
"Unable to request privacy GPIO IRQ (%d)\n", ret);
goto error;
}
ret = uvc_meta_init(dev);
if (ret < 0) {
- dev_err(&dev->udev->dev,
+ dev_err(&dev->intf->dev,
"Error initializing the metadata formats (%d)\n", ret);
goto error;
}
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index cc68dd24eb42..3823ac9c8045 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -140,7 +140,7 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain)
list_for_each_entry(entity, &chain->entities, chain) {
ret = uvc_mc_init_entity(chain, entity);
if (ret < 0) {
- dev_info(&chain->dev->udev->dev,
+ dev_info(&chain->dev->intf->dev,
"Failed to initialize entity for entity %u\n",
entity->id);
return ret;
@@ -150,7 +150,7 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain)
list_for_each_entry(entity, &chain->entities, chain) {
ret = uvc_mc_create_links(chain, entity);
if (ret < 0) {
- dev_info(&chain->dev->udev->dev,
+ dev_info(&chain->dev->intf->dev,
"Failed to create links for entity %u\n",
entity->id);
return ret;
diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
index 229e08ff323e..c23b174965c3 100644
--- a/drivers/media/usb/uvc/uvc_metadata.c
+++ b/drivers/media/usb/uvc/uvc_metadata.c
@@ -23,10 +23,10 @@
* V4L2 ioctls
*/
-static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
+static int uvc_meta_v4l2_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
struct uvc_video_chain *chain = stream->chain;
@@ -39,28 +39,26 @@ static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
return 0;
}
-static int uvc_meta_v4l2_get_format(struct file *file, void *fh,
+static int uvc_meta_v4l2_get_format(struct file *file, void *priv,
struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
struct v4l2_meta_format *fmt = &format->fmt.meta;
if (format->type != vfh->vdev->queue->type)
return -EINVAL;
- memset(fmt, 0, sizeof(*fmt));
-
fmt->dataformat = stream->meta.format;
fmt->buffersize = UVC_METADATA_BUF_SIZE;
return 0;
}
-static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
+static int uvc_meta_v4l2_try_format(struct file *file, void *priv,
struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
struct uvc_device *dev = stream->dev;
struct v4l2_meta_format *fmt = &format->fmt.meta;
@@ -69,11 +67,12 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
if (format->type != vfh->vdev->queue->type)
return -EINVAL;
- for (unsigned int i = 0; i < dev->nmeta_formats; i++)
+ for (unsigned int i = 0; i < dev->nmeta_formats; i++) {
if (dev->meta_formats[i] == fmt->dataformat) {
fmeta = fmt->dataformat;
break;
}
+ }
memset(fmt, 0, sizeof(*fmt));
@@ -83,15 +82,15 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
return 0;
}
-static int uvc_meta_v4l2_set_format(struct file *file, void *fh,
+static int uvc_meta_v4l2_set_format(struct file *file, void *priv,
struct v4l2_format *format)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
struct v4l2_meta_format *fmt = &format->fmt.meta;
int ret;
- ret = uvc_meta_v4l2_try_format(file, fh, format);
+ ret = uvc_meta_v4l2_try_format(file, priv, format);
if (ret < 0)
return ret;
@@ -100,37 +99,28 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *fh,
* Metadata buffers would still be perfectly parseable, but it's more
* consistent and cleaner to disallow that.
*/
- mutex_lock(&stream->mutex);
-
if (vb2_is_busy(&stream->meta.queue.queue))
- ret = -EBUSY;
- else
- stream->meta.format = fmt->dataformat;
+ return -EBUSY;
- mutex_unlock(&stream->mutex);
+ stream->meta.format = fmt->dataformat;
- return ret;
+ return 0;
}
-static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh,
+static int uvc_meta_v4l2_enum_formats(struct file *file, void *priv,
struct v4l2_fmtdesc *fdesc)
{
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
struct uvc_device *dev = stream->dev;
- u32 i = fdesc->index;
if (fdesc->type != vfh->vdev->queue->type)
return -EINVAL;
- if (i >= dev->nmeta_formats)
+ if (fdesc->index >= dev->nmeta_formats)
return -EINVAL;
- memset(fdesc, 0, sizeof(*fdesc));
-
- fdesc->type = vfh->vdev->queue->type;
- fdesc->index = i;
- fdesc->pixelformat = dev->meta_formats[i];
+ fdesc->pixelformat = dev->meta_formats[fdesc->index];
return 0;
}
@@ -177,7 +167,6 @@ static struct uvc_entity *uvc_meta_find_msxu(struct uvc_device *dev)
return NULL;
}
-#define MSXU_CONTROL_METADATA 0x9
static int uvc_meta_detect_msxu(struct uvc_device *dev)
{
u32 *data __free(kfree) = NULL;
@@ -196,9 +185,12 @@ static int uvc_meta_detect_msxu(struct uvc_device *dev)
if (!data)
return -ENOMEM;
- /* Check if the metadata is already enabled. */
+ /*
+ * Check if the metadata is already enabled, or if the device always
+ * returns metadata.
+ */
ret = uvc_query_ctrl(dev, UVC_GET_CUR, entity->id, dev->intfnum,
- MSXU_CONTROL_METADATA, data, sizeof(*data));
+ UVC_MSXU_CONTROL_METADATA, data, sizeof(*data));
if (ret)
return 0;
@@ -208,21 +200,23 @@ static int uvc_meta_detect_msxu(struct uvc_device *dev)
}
/*
- * We have seen devices that require 1 to enable the metadata, others
- * requiring a value != 1 and others requiring a value >1. Luckily for
- * us, the value from GET_MAX seems to work all the time.
+ * Set the value of UVC_MSXU_CONTROL_METADATA to the value reported by
+ * GET_MAX to enable production of MSXU metadata. The GET_MAX request
+ * reports the maximum size of the metadata, if its value is 0 then MSXU
+ * metadata is not supported. For more information, see
+ * https://learn.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5#2229-metadata-control
*/
ret = uvc_query_ctrl(dev, UVC_GET_MAX, entity->id, dev->intfnum,
- MSXU_CONTROL_METADATA, data, sizeof(*data));
+ UVC_MSXU_CONTROL_METADATA, data, sizeof(*data));
if (ret || !*data)
return 0;
/*
- * If we can set MSXU_CONTROL_METADATA, the device will report
+ * If we can set UVC_MSXU_CONTROL_METADATA, the device will report
* metadata.
*/
ret = uvc_query_ctrl(dev, UVC_SET_CUR, entity->id, dev->intfnum,
- MSXU_CONTROL_METADATA, data, sizeof(*data));
+ UVC_MSXU_CONTROL_METADATA, data, sizeof(*data));
if (!ret)
dev->quirks |= UVC_QUIRK_MSXU_META;
@@ -232,12 +226,11 @@ static int uvc_meta_detect_msxu(struct uvc_device *dev)
int uvc_meta_register(struct uvc_streaming *stream)
{
struct uvc_device *dev = stream->dev;
- struct video_device *vdev = &stream->meta.vdev;
struct uvc_video_queue *queue = &stream->meta.queue;
stream->meta.format = V4L2_META_FMT_UVC;
- return uvc_register_video_device(dev, stream, vdev, queue,
+ return uvc_register_video_device(dev, stream, queue,
V4L2_BUF_TYPE_META_CAPTURE,
&uvc_meta_fops, &uvc_meta_ioctl_ops);
}
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index ee01dce4b783..231cfee8e7c2 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -62,7 +62,8 @@ static int uvc_input_init(struct uvc_device *dev)
__set_bit(EV_KEY, input->evbit);
__set_bit(KEY_CAMERA, input->keybit);
- if ((ret = input_register_device(input)) < 0)
+ ret = input_register_device(input);
+ if (ret < 0)
goto error;
dev->input = input;
@@ -215,7 +216,7 @@ static void uvc_status_complete(struct urb *urb)
return;
default:
- dev_warn(&dev->udev->dev,
+ dev_warn(&dev->intf->dev,
"Non-zero status (%d) in status completion handler.\n",
urb->status);
return;
@@ -247,7 +248,7 @@ static void uvc_status_complete(struct urb *urb)
urb->interval = dev->int_ep->desc.bInterval;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret < 0)
- dev_err(&dev->udev->dev,
+ dev_err(&dev->intf->dev,
"Failed to resubmit status URB (%d).\n", ret);
}
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 160f9cf6e6db..9e4a251eca88 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -329,14 +329,12 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
* developers test their webcams with the Linux driver as well as with
* the Windows driver).
*/
- mutex_lock(&stream->mutex);
if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
probe->dwMaxVideoFrameSize =
stream->ctrl.dwMaxVideoFrameSize;
/* Probe the device. */
ret = uvc_probe_video(stream, probe);
- mutex_unlock(&stream->mutex);
if (ret < 0)
return ret;
@@ -388,26 +386,22 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
return ret;
}
-static int uvc_ioctl_g_fmt(struct file *file, void *fh,
+static int uvc_ioctl_g_fmt(struct file *file, void *priv,
struct v4l2_format *fmt)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
const struct uvc_format *format;
const struct uvc_frame *frame;
- int ret = 0;
if (fmt->type != stream->type)
return -EINVAL;
- mutex_lock(&stream->mutex);
format = stream->cur_format;
frame = stream->cur_frame;
- if (format == NULL || frame == NULL) {
- ret = -EINVAL;
- goto done;
- }
+ if (!format || !frame)
+ return -EINVAL;
fmt->fmt.pix.pixelformat = format->fcc;
fmt->fmt.pix.width = frame->wWidth;
@@ -419,15 +413,13 @@ static int uvc_ioctl_g_fmt(struct file *file, void *fh,
fmt->fmt.pix.xfer_func = format->xfer_func;
fmt->fmt.pix.ycbcr_enc = format->ycbcr_enc;
-done:
- mutex_unlock(&stream->mutex);
- return ret;
+ return 0;
}
-static int uvc_ioctl_s_fmt(struct file *file, void *fh,
+static int uvc_ioctl_s_fmt(struct file *file, void *priv,
struct v4l2_format *fmt)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
struct uvc_streaming_control probe;
const struct uvc_format *format;
@@ -441,35 +433,27 @@ static int uvc_ioctl_s_fmt(struct file *file, void *fh,
if (ret < 0)
return ret;
- mutex_lock(&stream->mutex);
- if (vb2_is_busy(&stream->queue.queue)) {
- ret = -EBUSY;
- goto done;
- }
+ if (vb2_is_busy(&stream->queue.queue))
+ return -EBUSY;
stream->ctrl = probe;
stream->cur_format = format;
stream->cur_frame = frame;
-done:
- mutex_unlock(&stream->mutex);
- return ret;
+ return 0;
}
-static int uvc_ioctl_g_parm(struct file *file, void *fh,
+static int uvc_ioctl_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
u32 numerator, denominator;
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
if (parm->type != stream->type)
return -EINVAL;
- mutex_lock(&stream->mutex);
numerator = stream->ctrl.dwFrameInterval;
- mutex_unlock(&stream->mutex);
-
denominator = 10000000;
v4l2_simplify_fraction(&numerator, &denominator, 8, 333);
@@ -493,10 +477,10 @@ static int uvc_ioctl_g_parm(struct file *file, void *fh,
return 0;
}
-static int uvc_ioctl_s_parm(struct file *file, void *fh,
+static int uvc_ioctl_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *parm)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
struct uvc_streaming_control probe;
struct v4l2_fract timeperframe;
@@ -519,12 +503,8 @@ static int uvc_ioctl_s_parm(struct file *file, void *fh,
uvc_dbg(stream->dev, FORMAT, "Setting frame interval to %u/%u (%u)\n",
timeperframe.numerator, timeperframe.denominator, interval);
- mutex_lock(&stream->mutex);
-
- if (uvc_queue_streaming(&stream->queue)) {
- mutex_unlock(&stream->mutex);
+ if (uvc_queue_streaming(&stream->queue))
return -EBUSY;
- }
format = stream->cur_format;
frame = stream->cur_frame;
@@ -556,14 +536,11 @@ static int uvc_ioctl_s_parm(struct file *file, void *fh,
/* Probe the device with the new settings. */
ret = uvc_probe_video(stream, &probe);
- if (ret < 0) {
- mutex_unlock(&stream->mutex);
+ if (ret < 0)
return ret;
- }
stream->ctrl = probe;
stream->cur_frame = frame;
- mutex_unlock(&stream->mutex);
/* Return the actual frame period. */
timeperframe.numerator = probe.dwFrameInterval;
@@ -599,18 +576,17 @@ static int uvc_v4l2_open(struct file *file)
if (!handle)
return -ENOMEM;
- v4l2_fh_init(&handle->vfh, &stream->vdev);
- v4l2_fh_add(&handle->vfh);
+ v4l2_fh_init(&handle->vfh, &stream->queue.vdev);
+ v4l2_fh_add(&handle->vfh, file);
handle->chain = stream->chain;
handle->stream = stream;
- file->private_data = handle;
return 0;
}
static int uvc_v4l2_release(struct file *file)
{
- struct uvc_fh *handle = file->private_data;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
@@ -623,10 +599,10 @@ static int uvc_v4l2_release(struct file *file)
return 0;
}
-static int uvc_ioctl_querycap(struct file *file, void *fh,
+static int uvc_ioctl_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct uvc_fh *handle = file->private_data;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
struct uvc_streaming *stream = handle->stream;
@@ -639,10 +615,10 @@ static int uvc_ioctl_querycap(struct file *file, void *fh,
return 0;
}
-static int uvc_ioctl_enum_fmt(struct file *file, void *fh,
+static int uvc_ioctl_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *fmt)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
enum v4l2_buf_type type = fmt->type;
const struct uvc_format *format;
@@ -663,20 +639,20 @@ static int uvc_ioctl_enum_fmt(struct file *file, void *fh,
return 0;
}
-static int uvc_ioctl_try_fmt(struct file *file, void *fh,
+static int uvc_ioctl_try_fmt(struct file *file, void *priv,
struct v4l2_format *fmt)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
struct uvc_streaming_control probe;
return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
}
-static int uvc_ioctl_enum_input(struct file *file, void *fh,
+static int uvc_ioctl_enum_input(struct file *file, void *priv,
struct v4l2_input *input)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
const struct uvc_entity *selector = chain->selector;
struct uvc_entity *iterm = NULL;
@@ -716,9 +692,9 @@ static int uvc_ioctl_enum_input(struct file *file, void *fh,
return 0;
}
-static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
+static int uvc_ioctl_g_input(struct file *file, void *priv, unsigned int *input)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
u8 *buf;
int ret;
@@ -744,9 +720,9 @@ static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
return ret;
}
-static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
+static int uvc_ioctl_s_input(struct file *file, void *priv, unsigned int input)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
struct uvc_video_chain *chain = handle->chain;
u8 *buf;
@@ -778,10 +754,10 @@ static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
return ret;
}
-static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
+static int uvc_ioctl_query_ext_ctrl(struct file *file, void *priv,
struct v4l2_query_ext_ctrl *qec)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
return uvc_query_v4l2_ctrl(chain, qec);
@@ -806,10 +782,10 @@ static int uvc_ctrl_check_access(struct uvc_video_chain *chain,
return ret;
}
-static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
+static int uvc_ioctl_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
struct v4l2_ext_control *ctrl = ctrls->controls;
unsigned int i;
@@ -890,35 +866,35 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
return uvc_ctrl_rollback(handle);
}
-static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh,
+static int uvc_ioctl_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, VIDIOC_S_EXT_CTRLS);
}
-static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh,
+static int uvc_ioctl_try_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, VIDIOC_TRY_EXT_CTRLS);
}
-static int uvc_ioctl_querymenu(struct file *file, void *fh,
+static int uvc_ioctl_querymenu(struct file *file, void *priv,
struct v4l2_querymenu *qm)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
return uvc_query_v4l2_menu(chain, qm);
}
-static int uvc_ioctl_g_selection(struct file *file, void *fh,
+static int uvc_ioctl_g_selection(struct file *file, void *priv,
struct v4l2_selection *sel)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
if (sel->type != stream->type)
@@ -941,18 +917,16 @@ static int uvc_ioctl_g_selection(struct file *file, void *fh,
sel->r.left = 0;
sel->r.top = 0;
- mutex_lock(&stream->mutex);
sel->r.width = stream->cur_frame->wWidth;
sel->r.height = stream->cur_frame->wHeight;
- mutex_unlock(&stream->mutex);
return 0;
}
-static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
+static int uvc_ioctl_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
const struct uvc_format *format = NULL;
const struct uvc_frame *frame = NULL;
@@ -989,10 +963,10 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
return 0;
}
-static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh,
+static int uvc_ioctl_enum_frameintervals(struct file *file, void *priv,
struct v4l2_frmivalenum *fival)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_streaming *stream = handle->stream;
const struct uvc_format *format = NULL;
const struct uvc_frame *frame = NULL;
@@ -1061,10 +1035,10 @@ static int uvc_ioctl_subscribe_event(struct v4l2_fh *fh,
}
}
-static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio,
+static long uvc_ioctl_default(struct file *file, void *priv, bool valid_prio,
unsigned int cmd, void *arg)
{
- struct uvc_fh *handle = fh;
+ struct uvc_fh *handle = to_uvc_fh(file);
struct uvc_video_chain *chain = handle->chain;
switch (cmd) {
@@ -1170,7 +1144,7 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
static long uvc_v4l2_compat_ioctl32(struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct uvc_fh *handle = file->private_data;
+ struct uvc_fh *handle = to_uvc_fh(file);
union {
struct uvc_xu_control_mapping xmap;
struct uvc_xu_control_query xqry;
@@ -1221,7 +1195,7 @@ static long uvc_v4l2_compat_ioctl32(struct file *file,
static long uvc_v4l2_unlocked_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct uvc_fh *handle = file->private_data;
+ struct uvc_fh *handle = to_uvc_fh(file);
unsigned int converted_cmd = v4l2_translate_cmd(cmd);
int ret;
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index a5013a7fbca4..784be9330320 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -95,14 +95,14 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
*/
if (ret > 0 && query != UVC_GET_INFO) {
memset(data + ret, 0, size - ret);
- dev_warn_once(&dev->udev->dev,
+ dev_warn_once(&dev->intf->dev,
"UVC non compliance: %s control %u on unit %u returned %d bytes when we expected %u.\n",
uvc_query_name(query), cs, unit, ret, size);
return 0;
}
if (ret != -EPIPE) {
- dev_err(&dev->udev->dev,
+ dev_err(&dev->intf->dev,
"Failed to query (%s) UVC control %u on unit %u: %d (exp. %u).\n",
uvc_query_name(query), cs, unit, ret, size);
return ret < 0 ? ret : -EPIPE;
@@ -119,7 +119,7 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
*(u8 *)data = tmp;
if (ret != 1) {
- dev_err_ratelimited(&dev->udev->dev,
+ dev_err_ratelimited(&dev->intf->dev,
"Failed to query (%s) UVC error code control %u on unit %u: %d (exp. 1).\n",
uvc_query_name(query), cs, unit, ret);
return ret < 0 ? ret : -EPIPE;
@@ -266,7 +266,7 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
if (stream->intf->num_altsetting > 1 &&
ctrl->dwMaxPayloadTransferSize > stream->maxpsize) {
dev_warn_ratelimited(&stream->intf->dev,
- "UVC non compliance: the max payload transmission size (%u) exceeds the size of the ep max packet (%u). Using the max size.\n",
+ "UVC non compliance: Reducing max payload transfer size (%u) to fit endpoint limit (%u).\n",
ctrl->dwMaxPayloadTransferSize,
stream->maxpsize);
ctrl->dwMaxPayloadTransferSize = stream->maxpsize;
@@ -1691,7 +1691,7 @@ static void uvc_video_complete(struct urb *urb)
struct uvc_streaming *stream = uvc_urb->stream;
struct uvc_video_queue *queue = &stream->queue;
struct uvc_video_queue *qmeta = &stream->meta.queue;
- struct vb2_queue *vb2_qmeta = stream->meta.vdev.queue;
+ struct vb2_queue *vb2_qmeta = stream->meta.queue.vdev.queue;
struct uvc_buffer *buf = NULL;
struct uvc_buffer *buf_meta = NULL;
unsigned long flags;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 757254fc4fe9..24292efbe47d 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -41,6 +41,8 @@
#define UVC_EXT_GPIO_UNIT 0x7ffe
#define UVC_EXT_GPIO_UNIT_ID 0x100
+#define UVC_INVALID_ENTITY_ID 0xffff
+
/* ------------------------------------------------------------------------
* Driver specific constants.
*/
@@ -328,6 +330,7 @@ struct uvc_buffer {
#define UVC_QUEUE_DISCONNECTED (1 << 0)
struct uvc_video_queue {
+ struct video_device vdev;
struct vb2_queue queue;
struct mutex mutex; /*
* Serializes vb2_queue and
@@ -450,7 +453,6 @@ struct uvc_urb {
struct uvc_streaming {
struct list_head list;
struct uvc_device *dev;
- struct video_device vdev;
struct uvc_video_chain *chain;
atomic_t active;
@@ -469,12 +471,6 @@ struct uvc_streaming {
const struct uvc_format *cur_format;
const struct uvc_frame *cur_frame;
- /*
- * Protect access to ctrl, cur_format, cur_frame and hardware video
- * probe control.
- */
- struct mutex mutex;
-
/* Buffers queue. */
unsigned int frozen : 1;
struct uvc_video_queue queue;
@@ -483,7 +479,6 @@ struct uvc_streaming {
struct uvc_buffer *meta_buf);
struct {
- struct video_device vdev;
struct uvc_video_queue queue;
u32 format;
} meta;
@@ -637,6 +632,11 @@ struct uvc_fh {
unsigned int pending_async_ctrls;
};
+static inline struct uvc_fh *to_uvc_fh(struct file *filp)
+{
+ return container_of(file_to_v4l2_fh(filp), struct uvc_fh, vfh);
+}
+
/* ------------------------------------------------------------------------
* Debugging, printing and logging
*/
@@ -667,7 +667,7 @@ extern unsigned int uvc_hw_timestamps_param;
#define uvc_dbg(_dev, flag, fmt, ...) \
do { \
if (uvc_dbg_param & UVC_DBG_##flag) \
- dev_printk(KERN_DEBUG, &(_dev)->udev->dev, fmt, \
+ dev_printk(KERN_DEBUG, &(_dev)->intf->dev, fmt, \
##__VA_ARGS__); \
} while (0)
@@ -680,7 +680,7 @@ do { \
#define uvc_warn_once(_dev, warn, fmt, ...) \
do { \
if (!test_and_set_bit(warn, &(_dev)->warnings)) \
- dev_info(&(_dev)->udev->dev, fmt, ##__VA_ARGS__); \
+ dev_info(&(_dev)->intf->dev, fmt, ##__VA_ARGS__); \
} while (0)
/* --------------------------------------------------------------------------
@@ -733,7 +733,6 @@ int uvc_meta_register(struct uvc_streaming *stream);
int uvc_register_video_device(struct uvc_device *dev,
struct uvc_streaming *stream,
- struct video_device *vdev,
struct uvc_video_queue *queue,
enum v4l2_buf_type type,
const struct v4l2_file_operations *fops,
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 6e585bc76367..b367d479d6b3 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -34,6 +34,9 @@
* Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
*/
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -509,8 +512,9 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
}
EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);
-s64 __v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler,
- unsigned int mul, unsigned int div)
+#ifdef CONFIG_MEDIA_CONTROLLER
+static s64 v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler,
+ unsigned int mul, unsigned int div)
{
struct v4l2_ctrl *ctrl;
s64 freq;
@@ -545,11 +549,9 @@ s64 __v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler,
return freq > 0 ? freq : -EINVAL;
}
-EXPORT_SYMBOL_GPL(__v4l2_get_link_freq_ctrl);
-#ifdef CONFIG_MEDIA_CONTROLLER
-s64 __v4l2_get_link_freq_pad(struct media_pad *pad, unsigned int mul,
- unsigned int div)
+s64 v4l2_get_link_freq(const struct media_pad *pad, unsigned int mul,
+ unsigned int div)
{
struct v4l2_mbus_config mbus_config = {};
struct v4l2_subdev *sd;
@@ -568,10 +570,10 @@ s64 __v4l2_get_link_freq_pad(struct media_pad *pad, unsigned int mul,
* Fall back to using the link frequency control if the media bus config
* doesn't provide a link frequency.
*/
- return __v4l2_get_link_freq_ctrl(sd->ctrl_handler, mul, div);
+ return v4l2_get_link_freq_ctrl(sd->ctrl_handler, mul, div);
}
-EXPORT_SYMBOL_GPL(__v4l2_get_link_freq_pad);
-#endif /* CONFIG_MEDIA_CONTROLLER */
+EXPORT_SYMBOL_GPL(v4l2_get_link_freq);
+#endif
/*
* Simplify a fraction using a simple continued fraction decomposition. The
@@ -705,3 +707,73 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
+
+struct clk *__devm_v4l2_sensor_clk_get(struct device *dev, const char *id,
+ bool legacy, bool fixed_rate,
+ unsigned long clk_rate)
+{
+ bool of_node = is_of_node(dev_fwnode(dev));
+ const char *clk_id __free(kfree) = NULL;
+ struct clk_hw *clk_hw;
+ struct clk *clk;
+ u32 rate = clk_rate;
+ int ret = 0;
+
+ clk = devm_clk_get_optional(dev, id);
+ if (IS_ERR(clk))
+ return clk;
+
+ /*
+ * If the caller didn't request a fixed rate, retrieve it from the
+ * clock-frequency property. -EINVAL indicates the property is absent,
+ * and is not a failure. Other errors, or success with a clock-frequency
+ * value of 0, are hard failures.
+ */
+ if (!fixed_rate || !clk_rate) {
+ ret = device_property_read_u32(dev, "clock-frequency", &rate);
+ if ((ret && ret != -EINVAL) || (!ret && !rate))
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (clk) {
+ /*
+ * On non-OF platforms, or when legacy behaviour is requested,
+ * set the clock rate if a rate has been specified by the caller
+ * or by the clock-frequency property.
+ */
+ if (rate && (!of_node || legacy)) {
+ ret = clk_set_rate(clk, rate);
+ if (ret) {
+ dev_err(dev, "Failed to set clock rate: %u\n",
+ rate);
+ return ERR_PTR(ret);
+ }
+ }
+ return clk;
+ }
+
+ /*
+ * Register a dummy fixed clock on non-OF platforms or when legacy
+ * behaviour is requested. This required the common clock framework.
+ */
+ if (!IS_ENABLED(CONFIG_COMMON_CLK) || (of_node && !legacy))
+ return ERR_PTR(-ENOENT);
+
+ /* We need a rate to create a clock. */
+ if (ret)
+ return ERR_PTR(ret == -EINVAL ? -EPROBE_DEFER : ret);
+
+ if (!id) {
+ clk_id = kasprintf(GFP_KERNEL, "clk-%s", dev_name(dev));
+ if (!clk_id)
+ return ERR_PTR(-ENOMEM);
+ id = clk_id;
+ }
+
+ clk_hw = devm_clk_hw_register_fixed_rate(dev, id, NULL, 0, rate);
+ if (IS_ERR(clk_hw))
+ return ERR_CAST(clk_hw);
+
+ return clk_hw->clk;
+}
+EXPORT_SYMBOL_GPL(__devm_v4l2_sensor_clk_get);
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 8c07400bd280..2c88e1175a10 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -8,7 +8,7 @@
* Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
* Copyright (C) 2003 Pavel Machek (pavel@ucw.cz)
* Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be)
- * Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ * Copyright (C) 2008 Hans Verkuil <hverkuil@kernel.org>
*
* These routines maintain argument size conversion between 32bit and 64bit
* ioctls.
@@ -672,15 +672,12 @@ struct v4l2_ext_control32 {
static inline bool ctrl_is_pointer(struct file *file, u32 id)
{
struct video_device *vdev = video_devdata(file);
- struct v4l2_fh *fh = NULL;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct v4l2_ctrl_handler *hdl = NULL;
struct v4l2_query_ext_ctrl qec = { id };
const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
- fh = file->private_data;
-
- if (fh && fh->ctrl_handler)
+ if (fh->ctrl_handler)
hdl = fh->ctrl_handler;
else if (vdev->ctrl_handler)
hdl = vdev->ctrl_handler;
@@ -694,7 +691,7 @@ static inline bool ctrl_is_pointer(struct file *file, u32 id)
if (!ops || !ops->vidioc_query_ext_ctrl)
return false;
- return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
+ return !ops->vidioc_query_ext_ctrl(file, NULL, &qec) &&
(qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
}
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index d49a68b36c28..0078a04c5445 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -2,7 +2,7 @@
/*
* V4L2 controls framework uAPI implementation:
*
- * Copyright (C) 2010-2021 Hans Verkuil <hverkuil-cisco@xs4all.nl>
+ * Copyright (C) 2010-2021 Hans Verkuil <hverkuil@kernel.org>
*/
#define pr_fmt(fmt) "v4l2-ctrls: " fmt
@@ -1250,14 +1250,17 @@ EXPORT_SYMBOL(v4l2_querymenu);
* VIDIOC_LOG_STATUS helpers
*/
-int v4l2_ctrl_log_status(struct file *file, void *fh)
+int v4l2_ctrl_log_status(struct file *file, void *priv)
{
struct video_device *vfd = video_devdata(file);
- struct v4l2_fh *vfh = file->private_data;
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
+ if (vfd->v4l2_dev) {
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
+
v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
vfd->v4l2_dev->name);
+ }
+
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_log_status);
@@ -1348,7 +1351,7 @@ EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event);
*/
__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
poll_wait(file, &fh->wait, wait);
if (v4l2_event_pending(fh))
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 98b960775e87..85d07ef44f62 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -2,7 +2,7 @@
/*
* V4L2 controls framework core implementation.
*
- * Copyright (C) 2010-2021 Hans Verkuil <hverkuil-cisco@xs4all.nl>
+ * Copyright (C) 2010-2021 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/export.h>
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 1ea52011247a..ad41f65374e2 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -2,7 +2,7 @@
/*
* V4L2 controls framework control definitions.
*
- * Copyright (C) 2010-2021 Hans Verkuil <hverkuil-cisco@xs4all.nl>
+ * Copyright (C) 2010-2021 Hans Verkuil <hverkuil@kernel.org>
*/
#include <linux/export.h>
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-priv.h b/drivers/media/v4l2-core/v4l2-ctrls-priv.h
index aba6176fab6c..f4cf273ecf30 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-priv.h
+++ b/drivers/media/v4l2-core/v4l2-ctrls-priv.h
@@ -2,7 +2,7 @@
/*
* V4L2 controls framework private header.
*
- * Copyright (C) 2010-2021 Hans Verkuil <hverkuil-cisco@xs4all.nl>
+ * Copyright (C) 2010-2021 Hans Verkuil <hverkuil@kernel.org>
*/
#ifndef _V4L2_CTRLS_PRIV_H_
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-request.c b/drivers/media/v4l2-core/v4l2-ctrls-request.c
index c637049d7a2b..e77f722b36a4 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-request.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-request.c
@@ -2,7 +2,7 @@
/*
* V4L2 controls framework Request API implementation.
*
- * Copyright (C) 2018-2021 Hans Verkuil <hverkuil-cisco@xs4all.nl>
+ * Copyright (C) 2018-2021 Hans Verkuil <hverkuil@kernel.org>
*/
#define pr_fmt(fmt) "v4l2-ctrls: " fmt
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index c369235113d9..10a126e50c1c 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -411,7 +411,7 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
static int v4l2_open(struct inode *inode, struct file *filp)
{
struct video_device *vdev;
- int ret = 0;
+ int ret;
/* Check if the video device is available */
mutex_lock(&videodev_lock);
@@ -424,16 +424,27 @@ static int v4l2_open(struct inode *inode, struct file *filp)
/* and increase the device refcount */
video_get(vdev);
mutex_unlock(&videodev_lock);
- if (vdev->fops->open) {
- if (video_is_registered(vdev))
- ret = vdev->fops->open(filp);
- else
- ret = -ENODEV;
+
+ if (!video_is_registered(vdev)) {
+ ret = -ENODEV;
+ goto done;
+ }
+
+ ret = vdev->fops->open(filp);
+ if (ret)
+ goto done;
+
+ /* All drivers must use v4l2_fh. */
+ if (WARN_ON(!test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))) {
+ vdev->fops->release(filp);
+ ret = -ENODEV;
}
+done:
if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP)
dprintk("%s: open (%d)\n",
video_device_node_name(vdev), ret);
+
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
@@ -444,7 +455,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
static int v4l2_release(struct inode *inode, struct file *filp)
{
struct video_device *vdev = video_devdata(filp);
- int ret = 0;
+ int ret;
/*
* We need to serialize the release() with queueing new requests.
@@ -452,14 +463,12 @@ static int v4l2_release(struct inode *inode, struct file *filp)
* operation, and that should not be mixed with queueing a new
* request at the same time.
*/
- if (vdev->fops->release) {
- if (v4l2_device_supports_requests(vdev->v4l2_dev)) {
- mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex);
- ret = vdev->fops->release(filp);
- mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex);
- } else {
- ret = vdev->fops->release(filp);
- }
+ if (v4l2_device_supports_requests(vdev->v4l2_dev)) {
+ mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex);
+ ret = vdev->fops->release(filp);
+ mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex);
+ } else {
+ ret = vdev->fops->release(filp);
}
if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP)
@@ -922,6 +931,9 @@ int __video_register_device(struct video_device *vdev,
/* the device_caps field MUST be set for all but subdevs */
if (WARN_ON(type != VFL_TYPE_SUBDEV && !vdev->device_caps))
return -EINVAL;
+ /* the open and release file operations are mandatory */
+ if (WARN_ON(!vdev->fops || !vdev->fops->open || !vdev->fops->release))
+ return -EINVAL;
/* v4l2_fh support */
spin_lock_init(&vdev->fh_lock);
@@ -1114,8 +1126,7 @@ void video_unregister_device(struct video_device *vdev)
*/
clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
mutex_unlock(&videodev_lock);
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
- v4l2_event_wake_all(vdev);
+ v4l2_event_wake_all(vdev);
device_unregister(&vdev->dev);
}
EXPORT_SYMBOL(video_unregister_device);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 5e537454f5cd..63b12ef9d4d9 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -2,7 +2,7 @@
/*
V4L2 device support.
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ Copyright (C) 2008 Hans Verkuil <hverkuil@kernel.org>
*/
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 7710cb26bea0..346d1b0e10ce 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -1226,6 +1226,7 @@ DEBUGFS_FOPS(avi, V4L2_DEBUGFS_IF_AVI);
DEBUGFS_FOPS(audio, V4L2_DEBUGFS_IF_AUDIO);
DEBUGFS_FOPS(spd, V4L2_DEBUGFS_IF_SPD);
DEBUGFS_FOPS(hdmi, V4L2_DEBUGFS_IF_HDMI);
+DEBUGFS_FOPS(drm, V4L2_DEBUGFS_IF_DRM);
struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 if_types,
void *priv,
@@ -1255,6 +1256,9 @@ struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 if_types,
if (if_types & V4L2_DEBUGFS_IF_HDMI)
debugfs_create_file("hdmi", 0400, infoframes->if_dir,
infoframes, &infoframe_hdmi_fops);
+ if (if_types & V4L2_DEBUGFS_IF_DRM)
+ debugfs_create_file("hdr_drm", 0400, infoframes->if_dir,
+ infoframes, &infoframe_drm_fops);
return infoframes;
}
EXPORT_SYMBOL_GPL(v4l2_debugfs_if_alloc);
diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index 90eec79ee995..df3ba9d4674b 100644
--- a/drivers/media/v4l2-core/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
@@ -41,10 +41,12 @@ void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
}
EXPORT_SYMBOL_GPL(v4l2_fh_init);
-void v4l2_fh_add(struct v4l2_fh *fh)
+void v4l2_fh_add(struct v4l2_fh *fh, struct file *filp)
{
unsigned long flags;
+ filp->private_data = fh;
+
v4l2_prio_open(fh->vdev->prio, &fh->prio);
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_add(&fh->list, &fh->vdev->fh_list);
@@ -57,16 +59,15 @@ int v4l2_fh_open(struct file *filp)
struct video_device *vdev = video_devdata(filp);
struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- filp->private_data = fh;
if (fh == NULL)
return -ENOMEM;
v4l2_fh_init(fh, vdev);
- v4l2_fh_add(fh);
+ v4l2_fh_add(fh, filp);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_fh_open);
-void v4l2_fh_del(struct v4l2_fh *fh)
+void v4l2_fh_del(struct v4l2_fh *fh, struct file *filp)
{
unsigned long flags;
@@ -74,6 +75,8 @@ void v4l2_fh_del(struct v4l2_fh *fh)
list_del_init(&fh->list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
v4l2_prio_close(fh->vdev->prio, fh->prio);
+
+ filp->private_data = NULL;
}
EXPORT_SYMBOL_GPL(v4l2_fh_del);
@@ -90,13 +93,12 @@ EXPORT_SYMBOL_GPL(v4l2_fh_exit);
int v4l2_fh_release(struct file *filp)
{
- struct v4l2_fh *fh = filp->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(filp);
if (fh) {
- v4l2_fh_del(fh);
+ v4l2_fh_del(fh, filp);
v4l2_fh_exit(fh);
kfree(fh);
- filp->private_data = NULL;
}
return 0;
}
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 46da373066f4..01cf52c3ea33 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1089,8 +1089,8 @@ static void v4l_sanitize_format(struct v4l2_format *fmt)
}
}
-static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_querycap(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_capability *cap = (struct v4l2_capability *)arg;
struct video_device *vfd = video_devdata(file);
@@ -1103,7 +1103,7 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
media_set_bus_info(cap->bus_info, sizeof(cap->bus_info),
vfd->dev_parent);
- ret = ops->vidioc_querycap(file, fh, cap);
+ ret = ops->vidioc_querycap(file, NULL, cap);
/*
* Drivers must not change device_caps, so check for this and
@@ -1123,8 +1123,8 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
return ret;
}
-static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_input(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
@@ -1133,11 +1133,11 @@ static int v4l_g_input(const struct v4l2_ioctl_ops *ops,
return 0;
}
- return ops->vidioc_g_input(file, fh, arg);
+ return ops->vidioc_g_input(file, NULL, arg);
}
-static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_output(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
@@ -1146,11 +1146,11 @@ static int v4l_g_output(const struct v4l2_ioctl_ops *ops,
return 0;
}
- return ops->vidioc_g_output(file, fh, arg);
+ return ops->vidioc_g_output(file, NULL, arg);
}
-static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_input(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
int ret;
@@ -1162,22 +1162,22 @@ static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
if (vfd->device_caps & V4L2_CAP_IO_MC)
return *(int *)arg ? -EINVAL : 0;
- return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
+ return ops->vidioc_s_input(file, NULL, *(unsigned int *)arg);
}
-static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_output(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
if (vfd->device_caps & V4L2_CAP_IO_MC)
return *(int *)arg ? -EINVAL : 0;
- return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
+ return ops->vidioc_s_output(file, NULL, *(unsigned int *)arg);
}
-static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd;
u32 *p = arg;
@@ -1187,22 +1187,20 @@ static int v4l_g_priority(const struct v4l2_ioctl_ops *ops,
return 0;
}
-static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd;
struct v4l2_fh *vfh;
u32 *p = arg;
vfd = video_devdata(file);
- if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
- return -ENOTTY;
- vfh = file->private_data;
+ vfh = file_to_v4l2_fh(file);
return v4l2_prio_change(vfd->prio, &vfh->prio, *p);
}
-static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_enuminput(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_input *p = arg;
@@ -1224,11 +1222,11 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
return 0;
}
- return ops->vidioc_enum_input(file, fh, p);
+ return ops->vidioc_enum_input(file, NULL, p);
}
-static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_output *p = arg;
@@ -1250,7 +1248,7 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
return 0;
}
- return ops->vidioc_enum_output(file, fh, p);
+ return ops->vidioc_enum_output(file, NULL, p);
}
static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
@@ -1589,8 +1587,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
fmt->flags |= flags;
}
-static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vdev = video_devdata(file);
struct v4l2_fmtdesc *p = arg;
@@ -1620,12 +1618,12 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
break;
- ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_cap(file, NULL, arg);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
break;
- ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_overlay(file, NULL, arg);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
@@ -1637,27 +1635,27 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!ops->vidioc_enum_fmt_vid_out))
break;
- ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_vid_out(file, NULL, arg);
break;
case V4L2_BUF_TYPE_SDR_CAPTURE:
if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
break;
- ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_sdr_cap(file, NULL, arg);
break;
case V4L2_BUF_TYPE_SDR_OUTPUT:
if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
break;
- ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_sdr_out(file, NULL, arg);
break;
case V4L2_BUF_TYPE_META_CAPTURE:
if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
break;
- ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_meta_cap(file, NULL, arg);
break;
case V4L2_BUF_TYPE_META_OUTPUT:
if (unlikely(!ops->vidioc_enum_fmt_meta_out))
break;
- ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
+ ret = ops->vidioc_enum_fmt_meta_out(file, NULL, arg);
break;
}
if (ret == 0)
@@ -1680,8 +1678,8 @@ static void v4l_pix_format_touch(struct v4l2_pix_format *p)
p->xfer_func = 0;
}
-static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
@@ -1697,50 +1695,50 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!ops->vidioc_g_fmt_vid_cap))
break;
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
- ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_g_fmt_vid_cap(file, NULL, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
if (vfd->vfl_type == VFL_TYPE_TOUCH)
v4l_pix_format_touch(&p->fmt.pix);
return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
+ return ops->vidioc_g_fmt_vid_cap_mplane(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
+ return ops->vidioc_g_fmt_vid_overlay(file, NULL, arg);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
+ return ops->vidioc_g_fmt_vbi_cap(file, NULL, arg);
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
+ return ops->vidioc_g_fmt_sliced_vbi_cap(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (unlikely(!ops->vidioc_g_fmt_vid_out))
break;
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
- ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_g_fmt_vid_out(file, NULL, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
+ return ops->vidioc_g_fmt_vid_out_mplane(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
+ return ops->vidioc_g_fmt_vid_out_overlay(file, NULL, arg);
case V4L2_BUF_TYPE_VBI_OUTPUT:
- return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
+ return ops->vidioc_g_fmt_vbi_out(file, NULL, arg);
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
+ return ops->vidioc_g_fmt_sliced_vbi_out(file, NULL, arg);
case V4L2_BUF_TYPE_SDR_CAPTURE:
- return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
+ return ops->vidioc_g_fmt_sdr_cap(file, NULL, arg);
case V4L2_BUF_TYPE_SDR_OUTPUT:
- return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
+ return ops->vidioc_g_fmt_sdr_out(file, NULL, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
- return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
+ return ops->vidioc_g_fmt_meta_cap(file, NULL, arg);
case V4L2_BUF_TYPE_META_OUTPUT:
- return ops->vidioc_g_fmt_meta_out(file, fh, arg);
+ return ops->vidioc_g_fmt_meta_out(file, NULL, arg);
}
return -EINVAL;
}
-static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
@@ -1760,7 +1758,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!ops->vidioc_s_fmt_vid_cap))
break;
memset_after(p, 0, fmt.pix);
- ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_s_fmt_vid_cap(file, NULL, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
if (vfd->vfl_type == VFL_TYPE_TOUCH)
@@ -1773,7 +1771,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
memset_after(&p->fmt.pix_mp.plane_fmt[i],
0, bytesperline);
- return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
+ return ops->vidioc_s_fmt_vid_cap_mplane(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
break;
@@ -1781,22 +1779,22 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.win.clips = NULL;
p->fmt.win.clipcount = 0;
p->fmt.win.bitmap = NULL;
- return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
+ return ops->vidioc_s_fmt_vid_overlay(file, NULL, arg);
case V4L2_BUF_TYPE_VBI_CAPTURE:
if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
break;
memset_after(p, 0, fmt.vbi.flags);
- return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
+ return ops->vidioc_s_fmt_vbi_cap(file, NULL, arg);
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
break;
memset_after(p, 0, fmt.sliced.io_size);
- return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
+ return ops->vidioc_s_fmt_sliced_vbi_cap(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (unlikely(!ops->vidioc_s_fmt_vid_out))
break;
memset_after(p, 0, fmt.pix);
- ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_s_fmt_vid_out(file, NULL, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
@@ -1807,7 +1805,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
memset_after(&p->fmt.pix_mp.plane_fmt[i],
0, bytesperline);
- return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
+ return ops->vidioc_s_fmt_vid_out_mplane(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
break;
@@ -1815,43 +1813,43 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.win.clips = NULL;
p->fmt.win.clipcount = 0;
p->fmt.win.bitmap = NULL;
- return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
+ return ops->vidioc_s_fmt_vid_out_overlay(file, NULL, arg);
case V4L2_BUF_TYPE_VBI_OUTPUT:
if (unlikely(!ops->vidioc_s_fmt_vbi_out))
break;
memset_after(p, 0, fmt.vbi.flags);
- return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
+ return ops->vidioc_s_fmt_vbi_out(file, NULL, arg);
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
break;
memset_after(p, 0, fmt.sliced.io_size);
- return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
+ return ops->vidioc_s_fmt_sliced_vbi_out(file, NULL, arg);
case V4L2_BUF_TYPE_SDR_CAPTURE:
if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
break;
memset_after(p, 0, fmt.sdr.buffersize);
- return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
+ return ops->vidioc_s_fmt_sdr_cap(file, NULL, arg);
case V4L2_BUF_TYPE_SDR_OUTPUT:
if (unlikely(!ops->vidioc_s_fmt_sdr_out))
break;
memset_after(p, 0, fmt.sdr.buffersize);
- return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
+ return ops->vidioc_s_fmt_sdr_out(file, NULL, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
if (unlikely(!ops->vidioc_s_fmt_meta_cap))
break;
memset_after(p, 0, fmt.meta);
- return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
+ return ops->vidioc_s_fmt_meta_cap(file, NULL, arg);
case V4L2_BUF_TYPE_META_OUTPUT:
if (unlikely(!ops->vidioc_s_fmt_meta_out))
break;
memset_after(p, 0, fmt.meta);
- return ops->vidioc_s_fmt_meta_out(file, fh, arg);
+ return ops->vidioc_s_fmt_meta_out(file, NULL, arg);
}
return -EINVAL;
}
-static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
@@ -1868,7 +1866,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!ops->vidioc_try_fmt_vid_cap))
break;
memset_after(p, 0, fmt.pix);
- ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_try_fmt_vid_cap(file, NULL, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
if (vfd->vfl_type == VFL_TYPE_TOUCH)
@@ -1881,7 +1879,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
memset_after(&p->fmt.pix_mp.plane_fmt[i],
0, bytesperline);
- return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
+ return ops->vidioc_try_fmt_vid_cap_mplane(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
break;
@@ -1889,22 +1887,22 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.win.clips = NULL;
p->fmt.win.clipcount = 0;
p->fmt.win.bitmap = NULL;
- return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
+ return ops->vidioc_try_fmt_vid_overlay(file, NULL, arg);
case V4L2_BUF_TYPE_VBI_CAPTURE:
if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
break;
memset_after(p, 0, fmt.vbi.flags);
- return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
+ return ops->vidioc_try_fmt_vbi_cap(file, NULL, arg);
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
break;
memset_after(p, 0, fmt.sliced.io_size);
- return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
+ return ops->vidioc_try_fmt_sliced_vbi_cap(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (unlikely(!ops->vidioc_try_fmt_vid_out))
break;
memset_after(p, 0, fmt.pix);
- ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_try_fmt_vid_out(file, NULL, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
@@ -1915,7 +1913,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
for (i = 0; i < p->fmt.pix_mp.num_planes; i++)
memset_after(&p->fmt.pix_mp.plane_fmt[i],
0, bytesperline);
- return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
+ return ops->vidioc_try_fmt_vid_out_mplane(file, NULL, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
break;
@@ -1923,55 +1921,55 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.win.clips = NULL;
p->fmt.win.clipcount = 0;
p->fmt.win.bitmap = NULL;
- return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
+ return ops->vidioc_try_fmt_vid_out_overlay(file, NULL, arg);
case V4L2_BUF_TYPE_VBI_OUTPUT:
if (unlikely(!ops->vidioc_try_fmt_vbi_out))
break;
memset_after(p, 0, fmt.vbi.flags);
- return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
+ return ops->vidioc_try_fmt_vbi_out(file, NULL, arg);
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
break;
memset_after(p, 0, fmt.sliced.io_size);
- return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
+ return ops->vidioc_try_fmt_sliced_vbi_out(file, NULL, arg);
case V4L2_BUF_TYPE_SDR_CAPTURE:
if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
break;
memset_after(p, 0, fmt.sdr.buffersize);
- return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
+ return ops->vidioc_try_fmt_sdr_cap(file, NULL, arg);
case V4L2_BUF_TYPE_SDR_OUTPUT:
if (unlikely(!ops->vidioc_try_fmt_sdr_out))
break;
memset_after(p, 0, fmt.sdr.buffersize);
- return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
+ return ops->vidioc_try_fmt_sdr_out(file, NULL, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
if (unlikely(!ops->vidioc_try_fmt_meta_cap))
break;
memset_after(p, 0, fmt.meta);
- return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
+ return ops->vidioc_try_fmt_meta_cap(file, NULL, arg);
case V4L2_BUF_TYPE_META_OUTPUT:
if (unlikely(!ops->vidioc_try_fmt_meta_out))
break;
memset_after(p, 0, fmt.meta);
- return ops->vidioc_try_fmt_meta_out(file, fh, arg);
+ return ops->vidioc_try_fmt_meta_out(file, NULL, arg);
}
return -EINVAL;
}
-static int v4l_streamon(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_streamon(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
- return ops->vidioc_streamon(file, fh, *(unsigned int *)arg);
+ return ops->vidioc_streamon(file, NULL, *(unsigned int *)arg);
}
-static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_streamoff(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
- return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
+ return ops->vidioc_streamoff(file, NULL, *(unsigned int *)arg);
}
-static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_tuner *p = arg;
@@ -1979,14 +1977,14 @@ static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- err = ops->vidioc_g_tuner(file, fh, p);
+ err = ops->vidioc_g_tuner(file, NULL, p);
if (!err)
p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
return err;
}
-static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_tuner *p = arg;
@@ -1997,11 +1995,11 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
return ret;
p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- return ops->vidioc_s_tuner(file, fh, p);
+ return ops->vidioc_s_tuner(file, NULL, p);
}
static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_modulator *p = arg;
@@ -2010,14 +2008,14 @@ static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
if (vfd->vfl_type == VFL_TYPE_RADIO)
p->type = V4L2_TUNER_RADIO;
- err = ops->vidioc_g_modulator(file, fh, p);
+ err = ops->vidioc_g_modulator(file, NULL, p);
if (!err)
p->capability |= V4L2_TUNER_CAP_FREQ_BANDS;
return err;
}
static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_modulator *p = arg;
@@ -2025,11 +2023,11 @@ static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
if (vfd->vfl_type == VFL_TYPE_RADIO)
p->type = V4L2_TUNER_RADIO;
- return ops->vidioc_s_modulator(file, fh, p);
+ return ops->vidioc_s_modulator(file, NULL, p);
}
static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_frequency *p = arg;
@@ -2039,11 +2037,11 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
else
p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- return ops->vidioc_g_frequency(file, fh, p);
+ return ops->vidioc_g_frequency(file, NULL, p);
}
static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
const struct v4l2_frequency *p = arg;
@@ -2062,11 +2060,11 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
if (type != p->type)
return -EINVAL;
}
- return ops->vidioc_s_frequency(file, fh, p);
+ return ops->vidioc_s_frequency(file, NULL, p);
}
-static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_enumstd(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_standard *p = arg;
@@ -2074,8 +2072,8 @@ static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
return v4l_video_std_enumstd(p, vfd->tvnorms);
}
-static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_std(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
v4l2_std_id id = *(v4l2_std_id *)arg, norm;
@@ -2089,11 +2087,11 @@ static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
return -EINVAL;
/* Calls the specific handler */
- return ops->vidioc_s_std(file, fh, norm);
+ return ops->vidioc_s_std(file, NULL, norm);
}
-static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_querystd(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
v4l2_std_id *p = arg;
@@ -2111,11 +2109,11 @@ static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
* their efforts to improve the standards detection.
*/
*p = vfd->tvnorms;
- return ops->vidioc_querystd(file, fh, arg);
+ return ops->vidioc_querystd(file, NULL, arg);
}
static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_hw_freq_seek *p = arg;
@@ -2133,26 +2131,26 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
if (p->type != type)
return -EINVAL;
- return ops->vidioc_s_hw_freq_seek(file, fh, p);
+ return ops->vidioc_s_hw_freq_seek(file, NULL, p);
}
-static int v4l_s_fbuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_fbuf(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_framebuffer *p = arg;
p->base = NULL;
- return ops->vidioc_s_fbuf(file, fh, p);
+ return ops->vidioc_s_fbuf(file, NULL, p);
}
-static int v4l_overlay(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_overlay(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
- return ops->vidioc_overlay(file, fh, *(unsigned int *)arg);
+ return ops->vidioc_overlay(file, NULL, *(unsigned int *)arg);
}
-static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_requestbuffers *p = arg;
@@ -2167,38 +2165,38 @@ static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops,
if (is_valid_ioctl(vfd, VIDIOC_REMOVE_BUFS))
p->capabilities = V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS;
- return ops->vidioc_reqbufs(file, fh, p);
+ return ops->vidioc_reqbufs(file, NULL, p);
}
-static int v4l_querybuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_querybuf(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_buffer *p = arg;
int ret = check_fmt(file, p->type);
- return ret ? ret : ops->vidioc_querybuf(file, fh, p);
+ return ret ? ret : ops->vidioc_querybuf(file, NULL, p);
}
-static int v4l_qbuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_qbuf(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_buffer *p = arg;
int ret = check_fmt(file, p->type);
- return ret ? ret : ops->vidioc_qbuf(file, fh, p);
+ return ret ? ret : ops->vidioc_qbuf(file, NULL, p);
}
-static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_buffer *p = arg;
int ret = check_fmt(file, p->type);
- return ret ? ret : ops->vidioc_dqbuf(file, fh, p);
+ return ret ? ret : ops->vidioc_dqbuf(file, NULL, p);
}
static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_create_buffers *create = arg;
@@ -2215,7 +2213,7 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
if (is_valid_ioctl(vfd, VIDIOC_REMOVE_BUFS))
create->capabilities = V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS;
- ret = ops->vidioc_create_bufs(file, fh, create);
+ ret = ops->vidioc_create_bufs(file, NULL, create);
if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -2225,27 +2223,27 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
}
static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct v4l2_buffer *b = arg;
int ret = check_fmt(file, b->type);
- return ret ? ret : ops->vidioc_prepare_buf(file, fh, b);
+ return ret ? ret : ops->vidioc_prepare_buf(file, NULL, b);
}
static int v4l_remove_bufs(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct v4l2_remove_buffers *remove = arg;
if (ops->vidioc_remove_bufs)
- return ops->vidioc_remove_bufs(file, fh, remove);
+ return ops->vidioc_remove_bufs(file, NULL, remove);
return -ENOTTY;
}
-static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_streamparm *p = arg;
@@ -2255,20 +2253,20 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
if (ret)
return ret;
if (ops->vidioc_g_parm)
- return ops->vidioc_g_parm(file, fh, p);
+ return ops->vidioc_g_parm(file, NULL, p);
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
return -EINVAL;
if (vfd->device_caps & V4L2_CAP_READWRITE)
p->parm.capture.readbuffers = 2;
- ret = ops->vidioc_g_std(file, fh, &std);
+ ret = ops->vidioc_g_std(file, NULL, &std);
if (ret == 0)
v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
return ret;
}
-static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_parm(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct v4l2_streamparm *p = arg;
int ret = check_fmt(file, p->type);
@@ -2288,17 +2286,16 @@ static int v4l_s_parm(const struct v4l2_ioctl_ops *ops,
p->parm.capture.extendedmode = 0;
p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY;
}
- return ops->vidioc_s_parm(file, fh, p);
+ return ops->vidioc_s_parm(file, NULL, p);
}
-static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_query_ext_ctrl qec = {};
struct v4l2_queryctrl *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
int ret;
if (vfh && vfh->ctrl_handler)
@@ -2310,7 +2307,7 @@ static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
/* Simulate query_ext_ctr using query_ctrl. */
qec.id = p->id;
- ret = ops->vidioc_query_ext_ctrl(file, fh, &qec);
+ ret = ops->vidioc_query_ext_ctrl(file, NULL, &qec);
if (ret)
return ret;
v4l2_query_ext_ctrl_to_v4l2_queryctrl(p, &qec);
@@ -2318,46 +2315,43 @@ static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
}
static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_query_ext_ctrl *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
if (vfh && vfh->ctrl_handler)
return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
if (vfd->ctrl_handler)
return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
if (ops->vidioc_query_ext_ctrl)
- return ops->vidioc_query_ext_ctrl(file, fh, p);
+ return ops->vidioc_query_ext_ctrl(file, NULL, p);
return -ENOTTY;
}
-static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_querymenu(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_querymenu *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
if (vfh && vfh->ctrl_handler)
return v4l2_querymenu(vfh->ctrl_handler, p);
if (vfd->ctrl_handler)
return v4l2_querymenu(vfd->ctrl_handler, p);
if (ops->vidioc_querymenu)
- return ops->vidioc_querymenu(file, fh, p);
+ return ops->vidioc_querymenu(file, NULL, p);
return -ENOTTY;
}
-static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_control *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct v4l2_ext_controls ctrls;
struct v4l2_ext_control ctrl;
@@ -2374,7 +2368,7 @@ static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
ctrl.id = p->id;
ctrl.value = p->value;
if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
- int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
+ int ret = ops->vidioc_g_ext_ctrls(file, NULL, &ctrls);
if (ret == 0)
p->value = ctrl.value;
@@ -2383,13 +2377,12 @@ static int v4l_g_ctrl(const struct v4l2_ioctl_ops *ops,
return -EINVAL;
}
-static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_control *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct v4l2_ext_controls ctrls;
struct v4l2_ext_control ctrl;
int ret;
@@ -2408,18 +2401,17 @@ static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops,
ctrl.value = p->value;
if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL))
return -EINVAL;
- ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls);
+ ret = ops->vidioc_s_ext_ctrls(file, NULL, &ctrls);
p->value = ctrl.value;
return ret;
}
static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_ext_controls *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
p->error_idx = p->count;
if (vfh && vfh->ctrl_handler)
@@ -2431,16 +2423,15 @@ static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
if (ops->vidioc_g_ext_ctrls == NULL)
return -ENOTTY;
return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ?
- ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL;
+ ops->vidioc_g_ext_ctrls(file, NULL, p) : -EINVAL;
}
static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_ext_controls *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
p->error_idx = p->count;
if (vfh && vfh->ctrl_handler)
@@ -2452,16 +2443,15 @@ static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
if (ops->vidioc_s_ext_ctrls == NULL)
return -ENOTTY;
return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ?
- ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL;
+ ops->vidioc_s_ext_ctrls(file, NULL, p) : -EINVAL;
}
static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_ext_controls *p = arg;
- struct v4l2_fh *vfh =
- test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
p->error_idx = p->count;
if (vfh && vfh->ctrl_handler)
@@ -2473,7 +2463,7 @@ static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
if (ops->vidioc_try_ext_ctrls == NULL)
return -ENOTTY;
return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ?
- ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL;
+ ops->vidioc_try_ext_ctrls(file, NULL, p) : -EINVAL;
}
/*
@@ -2486,7 +2476,7 @@ static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
* type and drivers don't need to check for both.
*/
static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct v4l2_selection *p = arg;
u32 old_type = p->type;
@@ -2496,13 +2486,13 @@ static int v4l_g_selection(const struct v4l2_ioctl_ops *ops,
p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- ret = ops->vidioc_g_selection(file, fh, p);
+ ret = ops->vidioc_g_selection(file, NULL, p);
p->type = old_type;
return ret;
}
static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct v4l2_selection *p = arg;
u32 old_type = p->type;
@@ -2512,13 +2502,13 @@ static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
p->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
else if (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
p->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- ret = ops->vidioc_s_selection(file, fh, p);
+ ret = ops->vidioc_s_selection(file, NULL, p);
p->type = old_type;
return ret;
}
-static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_g_crop(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_crop *p = arg;
@@ -2539,7 +2529,7 @@ static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
- ret = v4l_g_selection(ops, file, fh, &s);
+ ret = v4l_g_selection(ops, file, &s);
/* copying results to old structure on success */
if (!ret)
@@ -2547,8 +2537,8 @@ static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
return ret;
}
-static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_s_crop(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_crop *p = arg;
@@ -2569,11 +2559,11 @@ static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
- return v4l_s_selection(ops, file, fh, &s);
+ return v4l_s_selection(ops, file, &s);
}
-static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_cropcap *p = arg;
@@ -2597,7 +2587,7 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
return -ENOTTY;
if (ops->vidioc_g_pixelaspect)
- ret = ops->vidioc_g_pixelaspect(file, fh, s.type,
+ ret = ops->vidioc_g_pixelaspect(file, NULL, s.type,
&p->pixelaspect);
/*
@@ -2619,7 +2609,7 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
- ret = v4l_g_selection(ops, file, fh, &s);
+ ret = v4l_g_selection(ops, file, &s);
if (ret)
return ret;
p->bounds = s.r;
@@ -2630,7 +2620,7 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
else
s.target = V4L2_SEL_TGT_CROP_DEFAULT;
- ret = v4l_g_selection(ops, file, fh, &s);
+ ret = v4l_g_selection(ops, file, &s);
if (ret)
return ret;
p->defrect = s.r;
@@ -2638,8 +2628,8 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
return 0;
}
-static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_log_status(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
struct video_device *vfd = video_devdata(file);
int ret;
@@ -2647,7 +2637,7 @@ static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
if (vfd->v4l2_dev)
pr_info("%s: ================= START STATUS =================\n",
vfd->v4l2_dev->name);
- ret = ops->vidioc_log_status(file, fh);
+ ret = ops->vidioc_log_status(file, NULL);
if (vfd->v4l2_dev)
pr_info("%s: ================== END STATUS ==================\n",
vfd->v4l2_dev->name);
@@ -2655,7 +2645,7 @@ static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
}
static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
struct v4l2_dbg_register *p = arg;
@@ -2675,7 +2665,7 @@ static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
}
if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
(ops->vidioc_g_chip_info || p->match.addr == 0))
- return ops->vidioc_g_register(file, fh, p);
+ return ops->vidioc_g_register(file, NULL, p);
return -EINVAL;
#else
return -ENOTTY;
@@ -2683,7 +2673,7 @@ static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
}
static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
const struct v4l2_dbg_register *p = arg;
@@ -2703,7 +2693,7 @@ static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
}
if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
(ops->vidioc_g_chip_info || p->match.addr == 0))
- return ops->vidioc_s_register(file, fh, p);
+ return ops->vidioc_s_register(file, NULL, p);
return -EINVAL;
#else
return -ENOTTY;
@@ -2711,7 +2701,7 @@ static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
}
static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
struct video_device *vfd = video_devdata(file);
@@ -2727,7 +2717,7 @@ static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
p->flags |= V4L2_CHIP_FL_READABLE;
strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
if (ops->vidioc_g_chip_info)
- return ops->vidioc_g_chip_info(file, fh, arg);
+ return ops->vidioc_g_chip_info(file, NULL, arg);
if (p->match.addr)
return -EINVAL;
return 0;
@@ -2753,26 +2743,32 @@ static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
#endif
}
-static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+static int v4l_dqevent(const struct v4l2_ioctl_ops *ops, struct file *file,
+ void *arg)
{
- return v4l2_event_dequeue(fh, arg, file->f_flags & O_NONBLOCK);
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
+
+ return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
}
static int v4l_subscribe_event(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
- return ops->vidioc_subscribe_event(fh, arg);
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
+
+ return ops->vidioc_subscribe_event(vfh, arg);
}
static int v4l_unsubscribe_event(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
- return ops->vidioc_unsubscribe_event(fh, arg);
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
+
+ return ops->vidioc_unsubscribe_event(vfh, arg);
}
static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct v4l2_sliced_vbi_cap *p = arg;
int ret = check_fmt(file, p->type);
@@ -2783,11 +2779,11 @@ static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops,
/* Clear up to type, everything after type is zeroed already */
memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
- return ops->vidioc_g_sliced_vbi_cap(file, fh, p);
+ return ops->vidioc_g_sliced_vbi_cap(file, NULL, p);
}
static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
+ struct file *file, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_frequency_band *p = arg;
@@ -2805,7 +2801,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
return -EINVAL;
}
if (ops->vidioc_enum_freq_bands) {
- err = ops->vidioc_enum_freq_bands(file, fh, p);
+ err = ops->vidioc_enum_freq_bands(file, NULL, p);
if (err != -ENOTTY)
return err;
}
@@ -2817,7 +2813,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
if (p->index)
return -EINVAL;
- err = ops->vidioc_g_tuner(file, fh, &t);
+ err = ops->vidioc_g_tuner(file, NULL, &t);
if (err)
return err;
p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS;
@@ -2836,7 +2832,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
return -EINVAL;
if (p->index)
return -EINVAL;
- err = ops->vidioc_g_modulator(file, fh, &m);
+ err = ops->vidioc_g_modulator(file, NULL, &m);
if (err)
return err;
p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS;
@@ -2853,7 +2849,7 @@ struct v4l2_ioctl_info {
u32 flags;
const char * const name;
int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
- void *fh, void *p);
+ void *p);
void (*debug)(const void *arg, bool write_only);
};
@@ -2874,9 +2870,9 @@ struct v4l2_ioctl_info {
#define DEFINE_V4L_STUB_FUNC(_vidioc) \
static int v4l_stub_ ## _vidioc( \
const struct v4l2_ioctl_ops *ops, \
- struct file *file, void *fh, void *p) \
+ struct file *file, void *p) \
{ \
- return ops->vidioc_ ## _vidioc(file, fh, p); \
+ return ops->vidioc_ ## _vidioc(file, NULL, p); \
}
#define IOCTL_INFO(_ioctl, _func, _debug, _flags) \
@@ -3072,8 +3068,7 @@ static long __video_do_ioctl(struct file *file,
bool write_only = false;
struct v4l2_ioctl_info default_info;
const struct v4l2_ioctl_info *info;
- void *fh = file->private_data;
- struct v4l2_fh *vfh = NULL;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
int dev_debug = vfd->dev_debug;
long ret = -ENOTTY;
@@ -3083,9 +3078,6 @@ static long __video_do_ioctl(struct file *file,
return ret;
}
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
- vfh = file->private_data;
-
/*
* We need to serialize streamon/off with queueing new requests.
* These ioctls may trigger the cancellation of a streaming
@@ -3117,10 +3109,10 @@ static long __video_do_ioctl(struct file *file,
info = &v4l2_ioctls[_IOC_NR(cmd)];
if (!is_valid_ioctl(vfd, cmd) &&
- !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
+ !((info->flags & INFO_FL_CTRL) && vfh->ctrl_handler))
goto done;
- if (vfh && (info->flags & INFO_FL_PRIO)) {
+ if (info->flags & INFO_FL_PRIO) {
ret = v4l2_prio_check(vfd->prio, vfh->prio);
if (ret)
goto done;
@@ -3134,12 +3126,12 @@ static long __video_do_ioctl(struct file *file,
write_only = _IOC_DIR(cmd) == _IOC_WRITE;
if (info != &default_info) {
- ret = info->func(ops, file, fh, arg);
+ ret = info->func(ops, file, arg);
} else if (!ops->vidioc_default) {
ret = -ENOTTY;
} else {
- ret = ops->vidioc_default(file, fh,
- vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
+ ret = ops->vidioc_default(file, NULL,
+ v4l2_prio_check(vfd->prio, vfh->prio) >= 0,
cmd, arg);
}
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index eb22d6172462..21acd9bc8607 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -951,7 +951,7 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file,
__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
struct poll_table_struct *wait)
{
- struct video_device *vfd = video_devdata(file);
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct vb2_queue *src_q = v4l2_m2m_get_src_vq(m2m_ctx);
struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
__poll_t req_events = poll_requested_events(wait);
@@ -970,13 +970,9 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
if (req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM))
rc = v4l2_m2m_poll_for_data(file, m2m_ctx, wait);
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
- struct v4l2_fh *fh = file->private_data;
-
- poll_wait(file, &fh->wait, wait);
- if (v4l2_event_pending(fh))
- rc |= EPOLLPRI;
- }
+ poll_wait(file, &fh->wait, wait);
+ if (v4l2_event_pending(fh))
+ rc |= EPOLLPRI;
return rc;
}
@@ -1004,7 +1000,7 @@ unsigned long v4l2_m2m_get_unmapped_area(struct file *file, unsigned long addr,
unsigned long len, unsigned long pgoff,
unsigned long flags)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
unsigned long offset = pgoff << PAGE_SHIFT;
struct vb2_queue *vq;
@@ -1371,7 +1367,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_request_queue);
int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *rb)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_reqbufs(file, fh->m2m_ctx, rb);
}
@@ -1380,7 +1376,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_reqbufs);
int v4l2_m2m_ioctl_create_bufs(struct file *file, void *priv,
struct v4l2_create_buffers *create)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_create_bufs(file, fh->m2m_ctx, create);
}
@@ -1389,7 +1385,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_create_bufs);
int v4l2_m2m_ioctl_remove_bufs(struct file *file, void *priv,
struct v4l2_remove_buffers *remove)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct vb2_queue *q = v4l2_m2m_get_vq(fh->m2m_ctx, remove->type);
if (!q)
@@ -1404,7 +1400,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_remove_bufs);
int v4l2_m2m_ioctl_querybuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_querybuf(file, fh->m2m_ctx, buf);
}
@@ -1413,7 +1409,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_querybuf);
int v4l2_m2m_ioctl_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
}
@@ -1422,7 +1418,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_qbuf);
int v4l2_m2m_ioctl_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
}
@@ -1431,7 +1427,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_dqbuf);
int v4l2_m2m_ioctl_prepare_buf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_prepare_buf(file, fh->m2m_ctx, buf);
}
@@ -1440,7 +1436,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_prepare_buf);
int v4l2_m2m_ioctl_expbuf(struct file *file, void *priv,
struct v4l2_exportbuffer *eb)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_expbuf(file, fh->m2m_ctx, eb);
}
@@ -1449,7 +1445,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_expbuf);
int v4l2_m2m_ioctl_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_streamon(file, fh->m2m_ctx, type);
}
@@ -1458,13 +1454,13 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamon);
int v4l2_m2m_ioctl_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_streamoff(file, fh->m2m_ctx, type);
}
EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_streamoff);
-int v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *fh,
+int v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *ec)
{
if (ec->cmd != V4L2_ENC_CMD_STOP && ec->cmd != V4L2_ENC_CMD_START)
@@ -1475,7 +1471,7 @@ int v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *fh,
}
EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_try_encoder_cmd);
-int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh,
+int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *dc)
{
if (dc->cmd != V4L2_DEC_CMD_STOP && dc->cmd != V4L2_DEC_CMD_START)
@@ -1542,7 +1538,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_decoder_cmd);
int v4l2_m2m_ioctl_encoder_cmd(struct file *file, void *priv,
struct v4l2_encoder_cmd *ec)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_encoder_cmd(file, fh->m2m_ctx, ec);
}
@@ -1551,13 +1547,13 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_encoder_cmd);
int v4l2_m2m_ioctl_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *dc)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_decoder_cmd(file, fh->m2m_ctx, dc);
}
EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_decoder_cmd);
-int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh,
+int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *dc)
{
if (dc->cmd != V4L2_DEC_CMD_FLUSH)
@@ -1572,7 +1568,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_stateless_try_decoder_cmd);
int v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv,
struct v4l2_decoder_cmd *dc)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct vb2_v4l2_buffer *out_vb, *cap_vb;
struct v4l2_m2m_dev *m2m_dev = fh->m2m_ctx->m2m_dev;
unsigned long flags;
@@ -1617,7 +1613,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_stateless_decoder_cmd);
int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
return v4l2_m2m_mmap(file, fh->m2m_ctx, vma);
}
@@ -1625,7 +1621,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_fop_mmap);
__poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait)
{
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct v4l2_m2m_ctx *m2m_ctx = fh->m2m_ctx;
__poll_t ret;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 4fd25fea3b58..1da953629010 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -26,6 +26,30 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
+/**
+ * struct v4l2_subdev_stream_config - Used for storing stream configuration.
+ *
+ * @pad: pad number
+ * @stream: stream number
+ * @enabled: has the stream been enabled with v4l2_subdev_enable_streams()
+ * @fmt: &struct v4l2_mbus_framefmt
+ * @crop: &struct v4l2_rect to be used for crop
+ * @compose: &struct v4l2_rect to be used for compose
+ * @interval: frame interval
+ *
+ * This structure stores configuration for a stream.
+ */
+struct v4l2_subdev_stream_config {
+ u32 pad;
+ u32 stream;
+ bool enabled;
+
+ struct v4l2_mbus_framefmt fmt;
+ struct v4l2_rect crop;
+ struct v4l2_rect compose;
+ struct v4l2_fract interval;
+};
+
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
/*
* The Streams API is an experimental feature. To use the Streams API, set
@@ -86,8 +110,7 @@ static int subdev_open(struct file *file)
}
v4l2_fh_init(&subdev_fh->vfh, vdev);
- v4l2_fh_add(&subdev_fh->vfh);
- file->private_data = &subdev_fh->vfh;
+ v4l2_fh_add(&subdev_fh->vfh, file);
if (sd->v4l2_dev->mdev && sd->entity.graph_obj.mdev->dev) {
struct module *owner;
@@ -110,7 +133,7 @@ static int subdev_open(struct file *file)
err:
module_put(subdev_fh->owner);
- v4l2_fh_del(&subdev_fh->vfh);
+ v4l2_fh_del(&subdev_fh->vfh, file);
v4l2_fh_exit(&subdev_fh->vfh);
subdev_fh_free(subdev_fh);
kfree(subdev_fh);
@@ -122,17 +145,16 @@ static int subdev_close(struct file *file)
{
struct video_device *vdev = video_devdata(file);
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
if (sd->internal_ops && sd->internal_ops->close)
sd->internal_ops->close(sd, subdev_fh);
module_put(subdev_fh->owner);
- v4l2_fh_del(vfh);
+ v4l2_fh_del(vfh, file);
v4l2_fh_exit(vfh);
subdev_fh_free(subdev_fh);
kfree(subdev_fh);
- file->private_data = NULL;
return 0;
}
@@ -612,7 +634,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
{
struct video_device *vdev = video_devdata(file);
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
bool ro_subdev = test_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags);
bool streams_subdev = sd->flags & V4L2_SUBDEV_FL_STREAMS;
@@ -1135,7 +1157,7 @@ static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg)
if (video_is_registered(vdev)) {
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *vfh = file->private_data;
+ struct v4l2_fh *vfh = file_to_v4l2_fh(file);
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
struct v4l2_subdev_state *state;
@@ -1192,7 +1214,7 @@ static __poll_t subdev_poll(struct file *file, poll_table *wait)
{
struct video_device *vdev = video_devdata(file);
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
- struct v4l2_fh *fh = file->private_data;
+ struct v4l2_fh *fh = file_to_v4l2_fh(file);
if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
return EPOLLERR;