aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Makefile1
-rw-r--r--drivers/media/cec/Makefile1
-rw-r--r--drivers/media/cec/cec-adap.c18
-rw-r--r--drivers/media/cec/cec-api.c19
-rw-r--r--drivers/media/cec/cec-core.c9
-rw-r--r--drivers/media/cec/cec-pin-priv.h133
-rw-r--r--drivers/media/cec/cec-pin.c40
-rw-r--r--drivers/media/common/b2c2/Makefile1
-rw-r--r--drivers/media/common/b2c2/flexcop-common.h1
-rw-r--r--drivers/media/common/b2c2/flexcop-eeprom.c1
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c1
-rw-r--r--drivers/media/common/b2c2/flexcop-hw-filter.c1
-rw-r--r--drivers/media/common/b2c2/flexcop-i2c.c1
-rw-r--r--drivers/media/common/b2c2/flexcop-misc.c1
-rw-r--r--drivers/media/common/b2c2/flexcop-reg.h1
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c1
-rw-r--r--drivers/media/common/b2c2/flexcop.h1
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_be.h1
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_le.h1
-rw-r--r--drivers/media/common/btcx-risc.h1
-rw-r--r--drivers/media/common/cypress_firmware.c6
-rw-r--r--drivers/media/common/cypress_firmware.h1
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c6
-rw-r--r--drivers/media/common/saa7146/saa7146_i2c.c1
-rw-r--r--drivers/media/common/saa7146/saa7146_vbi.c13
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c5
-rw-r--r--drivers/media/common/siano/Makefile1
-rw-r--r--drivers/media/common/siano/smscoreapi.c105
-rw-r--r--drivers/media/common/v4l2-tpg/v4l2-tpg-core.c12
-rw-r--r--drivers/media/dvb-core/Makefile1
-rw-r--r--drivers/media/dvb-core/dmxdev.c8
-rw-r--r--drivers/media/dvb-core/dmxdev.h90
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c68
-rw-r--r--drivers/media/dvb-core/dvb_demux.c17
-rw-r--r--drivers/media/dvb-core/dvb_demux.h248
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c531
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h117
-rw-r--r--drivers/media/dvb-core/dvb_net.c15
-rw-r--r--drivers/media/dvb-core/dvb_net.h34
-rw-r--r--drivers/media/dvb-core/dvb_ringbuffer.c8
-rw-r--r--drivers/media/dvb-core/dvbdev.c32
-rw-r--r--drivers/media/dvb-core/dvbdev.h137
-rw-r--r--drivers/media/dvb-frontends/Kconfig6
-rw-r--r--drivers/media/dvb-frontends/Makefile1
-rw-r--r--drivers/media/dvb-frontends/af9013.h24
-rw-r--r--drivers/media/dvb-frontends/as102_fe.c7
-rw-r--r--drivers/media/dvb-frontends/ascot2e.h9
-rw-r--r--drivers/media/dvb-frontends/cx24113.c10
-rw-r--r--drivers/media/dvb-frontends/cx24116.c22
-rw-r--r--drivers/media/dvb-frontends/cxd2820r.h24
-rw-r--r--drivers/media/dvb-frontends/dib7000m.h1
-rw-r--r--drivers/media/dvb-frontends/dib7000p.h1
-rw-r--r--drivers/media/dvb-frontends/dib8000.h1
-rw-r--r--drivers/media/dvb-frontends/dib9000.h1
-rw-r--r--drivers/media/dvb-frontends/dibx000_common.h1
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h12
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drx_driver.h878
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c248
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.h220
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c9
-rw-r--r--drivers/media/dvb-frontends/drxk.h14
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c32
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.h1
-rw-r--r--drivers/media/dvb-frontends/drxk_map.h1
-rw-r--r--drivers/media/dvb-frontends/ds3000.c22
-rw-r--r--drivers/media/dvb-frontends/dvb-pll.h14
-rw-r--r--drivers/media/dvb-frontends/helene.h30
-rw-r--r--drivers/media/dvb-frontends/horus3a.h9
-rw-r--r--drivers/media/dvb-frontends/ix2505v.c6
-rw-r--r--drivers/media/dvb-frontends/ix2505v.h28
-rw-r--r--drivers/media/dvb-frontends/l64781.c2
-rw-r--r--drivers/media/dvb-frontends/lg2160.c14
-rw-r--r--drivers/media/dvb-frontends/lgdt3306a.c3
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.h155
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c23
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.h17
-rw-r--r--drivers/media/dvb-frontends/mn88472.h16
-rw-r--r--drivers/media/dvb-frontends/mxl5xx.c2
-rw-r--r--drivers/media/dvb-frontends/nxt6000_priv.h1
-rw-r--r--drivers/media/dvb-frontends/rtl2830.h1
-rw-r--r--drivers/media/dvb-frontends/rtl2832.h1
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.h6
-rw-r--r--drivers/media/dvb-frontends/si2168.c1
-rw-r--r--drivers/media/dvb-frontends/si21xx.h1
-rw-r--r--drivers/media/dvb-frontends/sp2.c9
-rw-r--r--drivers/media/dvb-frontends/sp887x.c6
-rw-r--r--drivers/media/dvb-frontends/sp887x.h1
-rw-r--r--drivers/media/dvb-frontends/stb6000.h11
-rw-r--r--drivers/media/dvb-frontends/stv0288.c7
-rw-r--r--drivers/media/dvb-frontends/stv0299.c2
-rw-r--r--drivers/media/dvb-frontends/stv6110.c9
-rw-r--r--drivers/media/dvb-frontends/tda10071.h1
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.h1
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd_maps.h1
-rw-r--r--drivers/media/dvb-frontends/tda826x.h11
-rw-r--r--drivers/media/dvb-frontends/tua6100.c2
-rw-r--r--drivers/media/dvb-frontends/tua6100.h2
-rw-r--r--drivers/media/dvb-frontends/zd1301_demod.h13
-rw-r--r--drivers/media/dvb-frontends/zl10036.c8
-rw-r--r--drivers/media/dvb-frontends/zl10036.h16
-rw-r--r--drivers/media/i2c/Kconfig17
-rw-r--r--drivers/media/i2c/Makefile2
-rw-r--r--drivers/media/i2c/adv7180.c2
-rw-r--r--drivers/media/i2c/adv748x/adv748x-afe.c7
-rw-r--r--drivers/media/i2c/adv7604.c10
-rw-r--r--drivers/media/i2c/adv7842.c6
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.c2
-rw-r--r--drivers/media/i2c/dw9714.c7
-rw-r--r--drivers/media/i2c/et8ek8/Kconfig1
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_driver.c2
-rw-r--r--drivers/media/i2c/imx274.c1810
-rw-r--r--drivers/media/i2c/ir-kbd-i2c.c1
-rw-r--r--drivers/media/i2c/lm3560.c1
-rw-r--r--drivers/media/i2c/m5mols/m5mols_capture.c5
-rw-r--r--drivers/media/i2c/m5mols/m5mols_controls.c1
-rw-r--r--drivers/media/i2c/m5mols/m5mols_core.c20
-rw-r--r--drivers/media/i2c/max2175.c2
-rw-r--r--drivers/media/i2c/msp3400-driver.h1
-rw-r--r--drivers/media/i2c/mt9m111.c2
-rw-r--r--drivers/media/i2c/ov13858.c61
-rw-r--r--drivers/media/i2c/ov2640.c17
-rw-r--r--drivers/media/i2c/ov5640.c2
-rw-r--r--drivers/media/i2c/ov5647.c55
-rw-r--r--drivers/media/i2c/ov5670.c37
-rw-r--r--drivers/media/i2c/ov6650.c5
-rw-r--r--drivers/media/i2c/ov7670.c129
-rw-r--r--drivers/media/i2c/ov9650.c1
-rw-r--r--drivers/media/i2c/s5k6a3.c3
-rw-r--r--drivers/media/i2c/s5k6aa.c5
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c149
-rw-r--r--drivers/media/i2c/smiapp/smiapp-regs.c3
-rw-r--r--drivers/media/i2c/smiapp/smiapp.h1
-rw-r--r--drivers/media/i2c/soc_camera/Makefile1
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.c11
-rw-r--r--drivers/media/i2c/soc_camera/ov9740.c6
-rw-r--r--drivers/media/i2c/tc358743.c220
-rw-r--r--drivers/media/i2c/tc358743_regs.h94
-rw-r--r--drivers/media/i2c/tea6415c.h1
-rw-r--r--drivers/media/i2c/tea6420.h1
-rw-r--r--drivers/media/i2c/tvaudio.c8
-rw-r--r--drivers/media/i2c/tvp514x.c12
-rw-r--r--drivers/media/media-entity.c13
-rw-r--r--drivers/media/mmc/Makefile1
-rw-r--r--drivers/media/pci/Makefile1
-rw-r--r--drivers/media/pci/b2c2/Kconfig4
-rw-r--r--drivers/media/pci/b2c2/Makefile1
-rw-r--r--drivers/media/pci/b2c2/flexcop-dma.c1
-rw-r--r--drivers/media/pci/bt8xx/Makefile1
-rw-r--r--drivers/media/pci/bt8xx/btcx-risc.h1
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c6
-rw-r--r--drivers/media/pci/bt8xx/bttv-input.c19
-rw-r--r--drivers/media/pci/bt8xx/bttv-vbi.c2
-rw-r--r--drivers/media/pci/bt8xx/bttv.h1
-rw-r--r--drivers/media/pci/bt8xx/bttvp.h3
-rw-r--r--drivers/media/pci/bt8xx/dst_priv.h1
-rw-r--r--drivers/media/pci/cobalt/cobalt-driver.c5
-rw-r--r--drivers/media/pci/cx18/Makefile1
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c28
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.c4
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.h2
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c2
-rw-r--r--drivers/media/pci/cx23885/Makefile1
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-f300.h1
-rw-r--r--drivers/media/pci/cx23885/cx23885-i2c.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-vbi.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885.h2
-rw-r--r--drivers/media/pci/cx25821/Makefile1
-rw-r--r--drivers/media/pci/cx25821/cx25821-i2c.c2
-rw-r--r--drivers/media/pci/cx88/Makefile1
-rw-r--r--drivers/media/pci/cx88/cx88-input.c4
-rw-r--r--drivers/media/pci/cx88/cx88-vbi.c1
-rw-r--r--drivers/media/pci/ddbridge/Makefile1
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-io.h4
-rw-r--r--drivers/media/pci/ivtv/Makefile1
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c3
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.c4
-rw-r--r--drivers/media/pci/ivtv/ivtv-irq.h2
-rw-r--r--drivers/media/pci/mantis/Makefile1
-rw-r--r--drivers/media/pci/mantis/hopper_cards.c9
-rw-r--r--drivers/media/pci/mantis/mantis_cards.c8
-rw-r--r--drivers/media/pci/meye/meye.c20
-rw-r--r--drivers/media/pci/netup_unidvb/Kconfig12
-rw-r--r--drivers/media/pci/netup_unidvb/Makefile1
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c15
-rw-r--r--drivers/media/pci/ngene/Makefile1
-rw-r--r--drivers/media/pci/pt3/Makefile1
-rw-r--r--drivers/media/pci/saa7134/Makefile1
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c6
-rw-r--r--drivers/media/pci/saa7134/saa7134-i2c.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-input.c9
-rw-r--r--drivers/media/pci/saa7134/saa7134-reg.h1
-rw-r--r--drivers/media/pci/saa7134/saa7134-ts.c3
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c5
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c3
-rw-r--r--drivers/media/pci/saa7134/saa7134.h4
-rw-r--r--drivers/media/pci/saa7146/hexium_gemini.c7
-rw-r--r--drivers/media/pci/saa7146/hexium_orion.c10
-rw-r--r--drivers/media/pci/saa7164/Makefile1
-rw-r--r--drivers/media/pci/saa7164/saa7164-buffer.c8
-rw-r--r--drivers/media/pci/saa7164/saa7164-i2c.c2
-rw-r--r--drivers/media/pci/smipcie/Makefile1
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-enc.c2
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c11
-rw-r--r--drivers/media/pci/ttpci/Makefile1
-rw-r--r--drivers/media/pci/ttpci/av7110.c8
-rw-r--r--drivers/media/pci/ttpci/av7110.h3
-rw-r--r--drivers/media/pci/ttpci/av7110_av.h1
-rw-r--r--drivers/media/pci/ttpci/av7110_ca.h1
-rw-r--r--drivers/media/pci/ttpci/av7110_hw.h1
-rw-r--r--drivers/media/pci/ttpci/av7110_ipack.c1
-rw-r--r--drivers/media/pci/ttpci/av7110_ipack.h1
-rw-r--r--drivers/media/pci/ttpci/av7110_ir.c56
-rw-r--r--drivers/media/pci/ttpci/budget-core.c2
-rw-r--r--drivers/media/pci/ttpci/budget.h1
-rw-r--r--drivers/media/pci/ttpci/dvb_filter.c1
-rw-r--r--drivers/media/pci/tw5864/tw5864-util.c1
-rw-r--r--drivers/media/pci/tw68/tw68-risc.c33
-rw-r--r--drivers/media/pci/tw686x/tw686x-core.c11
-rw-r--r--drivers/media/pci/tw686x/tw686x-regs.h1
-rw-r--r--drivers/media/pci/zoran/Makefile1
-rw-r--r--drivers/media/pci/zoran/zoran_card.h2
-rw-r--r--drivers/media/pci/zoran/zoran_driver.c2
-rw-r--r--drivers/media/platform/Kconfig36
-rw-r--r--drivers/media/platform/Makefile7
-rw-r--r--drivers/media/platform/am437x/am437x-vpfe.c8
-rw-r--r--drivers/media/platform/atmel/atmel-isc-regs.h2
-rw-r--r--drivers/media/platform/atmel/atmel-isc.c652
-rw-r--r--drivers/media/platform/atmel/atmel-isi.c24
-rw-r--r--drivers/media/platform/blackfin/ppi.c1
-rw-r--r--drivers/media/platform/cec-gpio/Makefile1
-rw-r--r--drivers/media/platform/cec-gpio/cec-gpio.c239
-rw-r--r--drivers/media/platform/coda/coda-bit.c4
-rw-r--r--drivers/media/platform/coda/trace.h1
-rw-r--r--drivers/media/platform/davinci/Makefile1
-rw-r--r--drivers/media/platform/davinci/ccdc_hw_device.h4
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc.c2
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc.c2
-rw-r--r--drivers/media/platform/davinci/isif.c2
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c37
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c6
-rw-r--r--drivers/media/platform/davinci/vpif.c3
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c35
-rw-r--r--drivers/media/platform/davinci/vpif_display.c24
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.c127
-rw-r--r--drivers/media/platform/exynos4-is/Kconfig2
-rw-r--r--drivers/media/platform/exynos4-is/Makefile1
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c3
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c19
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c2
-rw-r--r--drivers/media/platform/fsl-viu.c7
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.c1
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.h1
-rw-r--r--drivers/media/platform/mtk-mdp/Makefile1
-rw-r--r--drivers/media/platform/mtk-vcodec/Makefile1
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c1
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c1
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c4
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c2
-rw-r--r--drivers/media/platform/mtk-vpu/mtk_vpu.c3
-rw-r--r--drivers/media/platform/omap/omap_vout.c3
-rw-r--r--drivers/media/platform/omap3isp/Makefile1
-rw-r--r--drivers/media/platform/omap3isp/isp.c133
-rw-r--r--drivers/media/platform/omap3isp/isp.h5
-rw-r--r--drivers/media/platform/pxa_camera.c17
-rw-r--r--drivers/media/platform/qcom/camss-8x16/camss-vfe.c3
-rw-r--r--drivers/media/platform/qcom/camss-8x16/camss-video.c1
-rw-r--r--drivers/media/platform/qcom/camss-8x16/camss.c8
-rw-r--r--drivers/media/platform/qcom/venus/Makefile1
-rw-r--r--drivers/media/platform/qcom/venus/core.h2
-rw-r--r--drivers/media/platform/qcom/venus/helpers.c7
-rw-r--r--drivers/media/platform/qcom/venus/hfi.c9
-rw-r--r--drivers/media/platform/qcom/venus/hfi_venus.c12
-rw-r--r--drivers/media/platform/qcom/venus/vdec.c34
-rw-r--r--drivers/media/platform/qcom/venus/venc.c7
-rw-r--r--drivers/media/platform/rcar-vin/rcar-core.c117
-rw-r--r--drivers/media/platform/rcar-vin/rcar-dma.c10
-rw-r--r--drivers/media/platform/rcar-vin/rcar-v4l2.c14
-rw-r--r--drivers/media/platform/rcar-vin/rcar-vin.h4
-rw-r--r--drivers/media/platform/rcar_drif.c12
-rw-r--r--drivers/media/platform/rcar_fdp1.c2
-rw-r--r--drivers/media/platform/rcar_jpu.c4
-rw-r--r--drivers/media/platform/rockchip/rga/Makefile3
-rw-r--r--drivers/media/platform/rockchip/rga/rga-buf.c154
-rw-r--r--drivers/media/platform/rockchip/rga/rga-hw.c421
-rw-r--r--drivers/media/platform/rockchip/rga/rga-hw.h437
-rw-r--r--drivers/media/platform/rockchip/rga/rga.c1010
-rw-r--r--drivers/media/platform/rockchip/rga/rga.h125
-rw-r--r--drivers/media/platform/s3c-camif/camif-core.c1
-rw-r--r--drivers/media/platform/s5p-mfc/Makefile1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c26
-rw-r--r--drivers/media/platform/sh_veu.c2
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c14
-rw-r--r--drivers/media/platform/soc_camera/soc_scale_crop.c21
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-v4l2.c2
-rw-r--r--drivers/media/platform/sti/c8sectpfe/Makefile1
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c7
-rw-r--r--drivers/media/platform/sti/hva/hva-h264.c23
-rw-r--r--drivers/media/platform/stm32/stm32-dcmi.c10
-rw-r--r--drivers/media/platform/tegra-cec/Makefile1
-rw-r--r--drivers/media/platform/tegra-cec/tegra_cec.c495
-rw-r--r--drivers/media/platform/tegra-cec/tegra_cec.h127
-rw-r--r--drivers/media/platform/ti-vpe/Makefile1
-rw-r--r--drivers/media/platform/ti-vpe/cal.c8
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c2
-rw-r--r--drivers/media/platform/via-camera.h1
-rw-r--r--drivers/media/platform/vim2m.c8
-rw-r--r--drivers/media/platform/vimc/Makefile1
-rw-r--r--drivers/media/platform/vimc/vimc-core.c5
-rw-r--r--drivers/media/platform/vivid/Makefile1
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c16
-rw-r--r--drivers/media/platform/vsp1/Makefile1
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.c1
-rw-r--r--drivers/media/platform/xilinx/xilinx-vipp.c8
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/lm7000.h1
-rw-r--r--drivers/media/radio/radio-cadet.c7
-rw-r--r--drivers/media/radio/radio-raremono.c2
-rw-r--r--drivers/media/radio/radio-si476x.c18
-rw-r--r--drivers/media/radio/radio-wl1273.c2
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c2
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h2
-rw-r--r--drivers/media/radio/wl128x/Kconfig10
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c7
-rw-r--r--drivers/media/rc/Kconfig16
-rw-r--r--drivers/media/rc/Makefile2
-rw-r--r--drivers/media/rc/ati_remote.c2
-rw-r--r--drivers/media/rc/ene_ir.c7
-rw-r--r--drivers/media/rc/gpio-ir-recv.c192
-rw-r--r--drivers/media/rc/igorplugusb.c8
-rw-r--r--drivers/media/rc/img-ir/Makefile1
-rw-r--r--drivers/media/rc/img-ir/img-ir-core.c5
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.c15
-rw-r--r--drivers/media/rc/img-ir/img-ir-raw.c6
-rw-r--r--drivers/media/rc/imon.c70
-rw-r--r--drivers/media/rc/ir-jvc-decoder.c2
-rw-r--r--drivers/media/rc/ir-lirc-codec.c69
-rw-r--r--drivers/media/rc/ir-mce_kbd-decoder.c7
-rw-r--r--drivers/media/rc/ir-nec-decoder.c32
-rw-r--r--drivers/media/rc/ir-sanyo-decoder.c2
-rw-r--r--drivers/media/rc/ir-sharp-decoder.c2
-rw-r--r--drivers/media/rc/ir-xmp-decoder.c2
-rw-r--r--drivers/media/rc/keymaps/Makefile5
-rw-r--r--drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c70
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m135a.c3
-rw-r--r--drivers/media/rc/keymaps/rc-hisi-poplar.c69
-rw-r--r--drivers/media/rc/keymaps/rc-hisi-tv-demo.c81
-rw-r--r--drivers/media/rc/keymaps/rc-tango.c92
-rw-r--r--drivers/media/rc/keymaps/rc-twinhan1027.c2
-rw-r--r--drivers/media/rc/lirc_dev.c515
-rw-r--r--drivers/media/rc/mceusb.c20
-rw-r--r--drivers/media/rc/rc-core-priv.h2
-rw-r--r--drivers/media/rc/rc-ir-raw.c10
-rw-r--r--drivers/media/rc/rc-main.c157
-rw-r--r--drivers/media/rc/redrat3.c2
-rw-r--r--drivers/media/rc/serial_ir.c5
-rw-r--r--drivers/media/rc/sir_ir.c44
-rw-r--r--drivers/media/rc/st_rc.c6
-rw-r--r--drivers/media/rc/streamzap.c8
-rw-r--r--drivers/media/rc/tango-ir.c281
-rw-r--r--drivers/media/tuners/Makefile1
-rw-r--r--drivers/media/tuners/fc0011.h1
-rw-r--r--drivers/media/tuners/mt2063.c6
-rw-r--r--drivers/media/tuners/mt2063.h1
-rw-r--r--drivers/media/usb/Makefile1
-rw-r--r--drivers/media/usb/as102/Makefile1
-rw-r--r--drivers/media/usb/as102/as102_fw.c28
-rw-r--r--drivers/media/usb/au0828/Makefile1
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c8
-rw-r--r--drivers/media/usb/au0828/au0828-i2c.c2
-rw-r--r--drivers/media/usb/au0828/au0828-input.c2
-rw-r--r--drivers/media/usb/au0828/au0828-vbi.c2
-rw-r--r--drivers/media/usb/au0828/au0828-video.c18
-rw-r--r--drivers/media/usb/au0828/au0828.h2
-rw-r--r--drivers/media/usb/b2c2/Kconfig6
-rw-r--r--drivers/media/usb/b2c2/flexcop-usb.h1
-rw-r--r--drivers/media/usb/cx231xx/Makefile1
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c5
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c4
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-vbi.c6
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-vbi.h2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/Makefile1
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c3
-rw-r--r--drivers/media/usb/dvb-usb-v2/gl861.h1
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c1
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/usb_urb.c1
-rw-r--r--drivers/media/usb/dvb-usb/Makefile1
-rw-r--r--drivers/media/usb/dvb-usb/a800.c65
-rw-r--r--drivers/media/usb/dvb-usb/af9005-script.h1
-rw-r--r--drivers/media/usb/dvb-usb/az6027.h1
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-fe.c2
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h1
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c32
-rw-r--r--drivers/media/usb/dvb-usb/dib07x0.h1
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-common.c16
-rw-r--r--drivers/media/usb/dvb-usb/digitv.h1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-common.h1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-dvb.c1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-firmware.c1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-i2c.c1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-remote.c4
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-urb.c1
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.h1
-rw-r--r--drivers/media/usb/dvb-usb/friio-fe.c26
-rw-r--r--drivers/media/usb/dvb-usb/friio.c2
-rw-r--r--drivers/media/usb/dvb-usb/m920x.h1
-rw-r--r--drivers/media/usb/dvb-usb/usb-urb.c1
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.h1
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.c88
-rw-r--r--drivers/media/usb/em28xx/Makefile1
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c4
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/usb/em28xx/em28xx-v4l.h2
-rw-r--r--drivers/media/usb/em28xx/em28xx-vbi.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/usb/go7007/Makefile1
-rw-r--r--drivers/media/usb/gspca/Kconfig16
-rw-r--r--drivers/media/usb/gspca/Makefile1
-rw-r--r--drivers/media/usb/gspca/gl860/Makefile1
-rw-r--r--drivers/media/usb/gspca/gspca.c1
-rw-r--r--drivers/media/usb/gspca/gspca.h1
-rw-r--r--drivers/media/usb/gspca/m5602/Makefile1
-rw-r--r--drivers/media/usb/gspca/ov519.c24
-rw-r--r--drivers/media/usb/gspca/stv06xx/Makefile1
-rw-r--r--drivers/media/usb/msi2500/msi2500.c2
-rw-r--r--drivers/media/usb/pvrusb2/Kconfig1
-rw-r--r--drivers/media/usb/pvrusb2/Makefile1
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.h1
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c64
-rw-r--r--drivers/media/usb/pwc/pwc-dec23.c7
-rw-r--r--drivers/media/usb/pwc/pwc-if.c3
-rw-r--r--drivers/media/usb/pwc/pwc-nala.h1
-rw-r--r--drivers/media/usb/s2255/s2255drv.c7
-rw-r--r--drivers/media/usb/siano/smsusb.c4
-rw-r--r--drivers/media/usb/stk1160/Makefile1
-rw-r--r--drivers/media/usb/stk1160/stk1160-i2c.c2
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c4
-rw-r--r--drivers/media/usb/tm6000/Makefile1
-rw-r--r--drivers/media/usb/tm6000/tm6000-cards.c27
-rw-r--r--drivers/media/usb/tm6000/tm6000-dvb.c15
-rw-r--r--drivers/media/usb/tm6000/tm6000-input.c2
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c21
-rw-r--r--drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c6
-rw-r--r--drivers/media/usb/usbtv/usbtv-core.c3
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c4
-rw-r--r--drivers/media/usb/usbvision/usbvision-cards.h1
-rw-r--r--drivers/media/usb/uvc/Makefile1
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c4
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h1
-rw-r--r--drivers/media/usb/zr364xx/zr364xx.c32
-rw-r--r--drivers/media/v4l2-core/Makefile1
-rw-r--r--drivers/media/v4l2-core/tuner-core.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c515
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c22
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c10
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c702
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c9
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-trace.c1
-rw-r--r--drivers/media/v4l2-core/vb2-trace.c1
-rw-r--r--drivers/media/v4l2-core/videobuf-core.c2
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-sg.c5
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c56
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c4
-rw-r--r--drivers/media/v4l2-core/videobuf2-memops.c2
-rw-r--r--drivers/media/v4l2-core/videobuf2-v4l2.c10
472 files changed, 11511 insertions, 3741 deletions
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 044503aa8801..594b462ddf0e 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel multimedia device drivers.
#
diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile
index 3353c1741961..41ee3325e1ea 100644
--- a/drivers/media/cec/Makefile
+++ b/drivers/media/cec/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o
ifeq ($(CONFIG_CEC_NOTIFIER),y)
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index f8a808d45034..98f88c43f62c 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -86,7 +86,7 @@ void cec_queue_event_fh(struct cec_fh *fh,
const struct cec_event *new_ev, u64 ts)
{
static const u8 max_events[CEC_NUM_EVENTS] = {
- 1, 1, 64, 64,
+ 1, 1, 64, 64, 8, 8,
};
struct cec_event_entry *entry;
unsigned int ev_idx = new_ev->event - 1;
@@ -170,6 +170,22 @@ void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
}
EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);
+/* Notify userspace that the HPD pin changed state at the given time. */
+void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
+{
+ struct cec_event ev = {
+ .event = is_high ? CEC_EVENT_PIN_HPD_HIGH :
+ CEC_EVENT_PIN_HPD_LOW,
+ };
+ struct cec_fh *fh;
+
+ mutex_lock(&adap->devnode.lock);
+ list_for_each_entry(fh, &adap->devnode.fhs, list)
+ cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
+ mutex_unlock(&adap->devnode.lock);
+}
+EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event);
+
/*
* Queue a new message for this filehandle.
*
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index a079f7fe018c..3dba3aa34a43 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -32,6 +32,7 @@
#include <media/cec-pin.h>
#include "cec-priv.h"
+#include "cec-pin-priv.h"
static inline struct cec_devnode *cec_devnode_data(struct file *filp)
{
@@ -529,7 +530,7 @@ static int cec_open(struct inode *inode, struct file *filp)
* Initial events that are automatically sent when the cec device is
* opened.
*/
- struct cec_event ev_state = {
+ struct cec_event ev = {
.event = CEC_EVENT_STATE_CHANGE,
.flags = CEC_EVENT_FL_INITIAL_STATE,
};
@@ -569,9 +570,19 @@ static int cec_open(struct inode *inode, struct file *filp)
filp->private_data = fh;
/* Queue up initial state events */
- ev_state.state_change.phys_addr = adap->phys_addr;
- ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
- cec_queue_event_fh(fh, &ev_state, 0);
+ ev.state_change.phys_addr = adap->phys_addr;
+ ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
+ cec_queue_event_fh(fh, &ev, 0);
+#ifdef CONFIG_CEC_PIN
+ if (adap->pin && adap->pin->ops->read_hpd) {
+ err = adap->pin->ops->read_hpd(adap);
+ if (err >= 0) {
+ ev.event = err ? CEC_EVENT_PIN_HPD_HIGH :
+ CEC_EVENT_PIN_HPD_LOW;
+ cec_queue_event_fh(fh, &ev, 0);
+ }
+ }
+#endif
list_add(&fh->list, &devnode->fhs);
mutex_unlock(&devnode->lock);
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index 648136e552d5..5870da6a567f 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -112,10 +112,6 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
int minor;
int ret;
- /* Initialization */
- INIT_LIST_HEAD(&devnode->fhs);
- mutex_init(&devnode->lock);
-
/* Part 1: Find a free minor number */
mutex_lock(&cec_devnode_lock);
minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0);
@@ -242,6 +238,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
INIT_LIST_HEAD(&adap->wait_queue);
init_waitqueue_head(&adap->kthread_waitq);
+ /* adap->devnode initialization */
+ INIT_LIST_HEAD(&adap->devnode.fhs);
+ mutex_init(&adap->devnode.lock);
+
adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
if (IS_ERR(adap->kthread)) {
pr_err("cec-%s: kernel_thread() failed\n", name);
@@ -277,7 +277,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
adap->rc->input_id.version = 1;
adap->rc->driver_name = CEC_NAME;
adap->rc->allowed_protocols = RC_PROTO_BIT_CEC;
- adap->rc->enabled_protocols = RC_PROTO_BIT_CEC;
adap->rc->priv = adap;
adap->rc->map_name = RC_MAP_CEC;
adap->rc->timeout = MS_TO_NS(100);
diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h
new file mode 100644
index 000000000000..7d0def199762
--- /dev/null
+++ b/drivers/media/cec/cec-pin-priv.h
@@ -0,0 +1,133 @@
+/*
+ * cec-pin-priv.h - internal cec-pin header
+ *
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef LINUX_CEC_PIN_PRIV_H
+#define LINUX_CEC_PIN_PRIV_H
+
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <media/cec-pin.h>
+
+enum cec_pin_state {
+ /* CEC is off */
+ CEC_ST_OFF,
+ /* CEC is idle, waiting for Rx or Tx */
+ CEC_ST_IDLE,
+
+ /* Tx states */
+
+ /* Pending Tx, waiting for Signal Free Time to expire */
+ CEC_ST_TX_WAIT,
+ /* Low-drive was detected, wait for bus to go high */
+ CEC_ST_TX_WAIT_FOR_HIGH,
+ /* Drive CEC low for the start bit */
+ CEC_ST_TX_START_BIT_LOW,
+ /* Drive CEC high for the start bit */
+ CEC_ST_TX_START_BIT_HIGH,
+ /* Drive CEC low for the 0 bit */
+ CEC_ST_TX_DATA_BIT_0_LOW,
+ /* Drive CEC high for the 0 bit */
+ CEC_ST_TX_DATA_BIT_0_HIGH,
+ /* Drive CEC low for the 1 bit */
+ CEC_ST_TX_DATA_BIT_1_LOW,
+ /* Drive CEC high for the 1 bit */
+ CEC_ST_TX_DATA_BIT_1_HIGH,
+ /*
+ * Wait for start of sample time to check for Ack bit or first
+ * four initiator bits to check for Arbitration Lost.
+ */
+ CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
+ /* Wait for end of bit period after sampling */
+ CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
+
+ /* Rx states */
+
+ /* Start bit low detected */
+ CEC_ST_RX_START_BIT_LOW,
+ /* Start bit high detected */
+ CEC_ST_RX_START_BIT_HIGH,
+ /* Wait for bit sample time */
+ CEC_ST_RX_DATA_SAMPLE,
+ /* Wait for earliest end of bit period after sampling */
+ CEC_ST_RX_DATA_POST_SAMPLE,
+ /* Wait for CEC to go high (i.e. end of bit period */
+ CEC_ST_RX_DATA_HIGH,
+ /* Drive CEC low to send 0 Ack bit */
+ CEC_ST_RX_ACK_LOW,
+ /* End of 0 Ack time, wait for earliest end of bit period */
+ CEC_ST_RX_ACK_LOW_POST,
+ /* Wait for CEC to go high (i.e. end of bit period */
+ CEC_ST_RX_ACK_HIGH_POST,
+ /* Wait for earliest end of bit period and end of message */
+ CEC_ST_RX_ACK_FINISH,
+
+ /* Start low drive */
+ CEC_ST_LOW_DRIVE,
+ /* Monitor pin using interrupts */
+ CEC_ST_RX_IRQ,
+
+ /* Total number of pin states */
+ CEC_PIN_STATES
+};
+
+#define CEC_NUM_PIN_EVENTS 128
+
+#define CEC_PIN_IRQ_UNCHANGED 0
+#define CEC_PIN_IRQ_DISABLE 1
+#define CEC_PIN_IRQ_ENABLE 2
+
+struct cec_pin {
+ struct cec_adapter *adap;
+ const struct cec_pin_ops *ops;
+ struct task_struct *kthread;
+ wait_queue_head_t kthread_waitq;
+ struct hrtimer timer;
+ ktime_t ts;
+ unsigned int wait_usecs;
+ u16 la_mask;
+ bool enabled;
+ bool monitor_all;
+ bool rx_eom;
+ bool enable_irq_failed;
+ enum cec_pin_state state;
+ struct cec_msg tx_msg;
+ u32 tx_bit;
+ bool tx_nacked;
+ u32 tx_signal_free_time;
+ struct cec_msg rx_msg;
+ u32 rx_bit;
+
+ struct cec_msg work_rx_msg;
+ u8 work_tx_status;
+ ktime_t work_tx_ts;
+ atomic_t work_irq_change;
+ atomic_t work_pin_events;
+ unsigned int work_pin_events_wr;
+ unsigned int work_pin_events_rd;
+ ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS];
+ bool work_pin_is_high[CEC_NUM_PIN_EVENTS];
+ ktime_t timer_ts;
+ u32 timer_cnt;
+ u32 timer_100ms_overruns;
+ u32 timer_300ms_overruns;
+ u32 timer_max_overrun;
+ u32 timer_sum_overrun;
+};
+
+#endif
diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c
index c003b8eac617..b48dfe844118 100644
--- a/drivers/media/cec/cec-pin.c
+++ b/drivers/media/cec/cec-pin.c
@@ -20,6 +20,7 @@
#include <linux/sched/types.h>
#include <media/cec-pin.h>
+#include "cec-pin-priv.h"
/* All timings are in microseconds */
@@ -132,7 +133,7 @@ static void cec_pin_to_idle(struct cec_pin *pin)
pin->rx_msg.len = 0;
memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
pin->state = CEC_ST_IDLE;
- pin->ts = 0;
+ pin->ts = ns_to_ktime(0);
}
/*
@@ -426,7 +427,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
v = cec_pin_read(pin);
if (v && pin->rx_eom) {
pin->work_rx_msg = pin->rx_msg;
- pin->work_rx_msg.rx_ts = ts;
+ pin->work_rx_msg.rx_ts = ktime_to_ns(ts);
wake_up_interruptible(&pin->kthread_waitq);
pin->ts = ts;
pin->state = CEC_ST_RX_ACK_FINISH;
@@ -457,7 +458,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
s32 delta;
ts = ktime_get();
- if (pin->timer_ts) {
+ if (ktime_to_ns(pin->timer_ts)) {
delta = ktime_us_delta(ts, pin->timer_ts);
pin->timer_cnt++;
if (delta > 100 && pin->state != CEC_ST_IDLE) {
@@ -481,17 +482,19 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
if (pin->wait_usecs > 150) {
pin->wait_usecs -= 100;
pin->timer_ts = ktime_add_us(ts, 100);
- hrtimer_forward_now(timer, 100000);
+ hrtimer_forward_now(timer, ns_to_ktime(100000));
return HRTIMER_RESTART;
}
if (pin->wait_usecs > 100) {
pin->wait_usecs /= 2;
pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
- hrtimer_forward_now(timer, pin->wait_usecs * 1000);
+ hrtimer_forward_now(timer,
+ ns_to_ktime(pin->wait_usecs * 1000));
return HRTIMER_RESTART;
}
pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
- hrtimer_forward_now(timer, pin->wait_usecs * 1000);
+ hrtimer_forward_now(timer,
+ ns_to_ktime(pin->wait_usecs * 1000));
pin->wait_usecs = 0;
return HRTIMER_RESTART;
}
@@ -531,7 +534,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
pin->state = CEC_ST_RX_START_BIT_LOW;
break;
}
- if (pin->ts == 0)
+ if (ktime_to_ns(pin->ts) == 0)
pin->ts = ts;
if (pin->tx_msg.len) {
/*
@@ -572,12 +575,13 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
if (!adap->monitor_pin_cnt || states[pin->state].usecs <= 150) {
pin->wait_usecs = 0;
pin->timer_ts = ktime_add_us(ts, states[pin->state].usecs);
- hrtimer_forward_now(timer, states[pin->state].usecs * 1000);
+ hrtimer_forward_now(timer,
+ ns_to_ktime(states[pin->state].usecs * 1000));
return HRTIMER_RESTART;
}
pin->wait_usecs = states[pin->state].usecs - 100;
pin->timer_ts = ktime_add_us(ts, 100);
- hrtimer_forward_now(timer, 100000);
+ hrtimer_forward_now(timer, ns_to_ktime(100000));
return HRTIMER_RESTART;
}
@@ -596,7 +600,7 @@ static int cec_pin_thread_func(void *_adap)
if (pin->work_rx_msg.len) {
cec_received_msg_ts(adap, &pin->work_rx_msg,
- pin->work_rx_msg.rx_ts);
+ ns_to_ktime(pin->work_rx_msg.rx_ts));
pin->work_rx_msg.len = 0;
}
if (pin->work_tx_status) {
@@ -623,13 +627,15 @@ static int cec_pin_thread_func(void *_adap)
pin->ops->disable_irq(adap);
cec_pin_high(pin);
cec_pin_to_idle(pin);
- hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+ hrtimer_start(&pin->timer, ns_to_ktime(0),
+ HRTIMER_MODE_REL);
break;
case CEC_PIN_IRQ_ENABLE:
pin->enable_irq_failed = !pin->ops->enable_irq(adap);
if (pin->enable_irq_failed) {
cec_pin_to_idle(pin);
- hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+ hrtimer_start(&pin->timer, ns_to_ktime(0),
+ HRTIMER_MODE_REL);
}
break;
default:
@@ -653,7 +659,7 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
cec_pin_read(pin);
cec_pin_to_idle(pin);
pin->tx_msg.len = 0;
- pin->timer_ts = 0;
+ pin->timer_ts = ns_to_ktime(0);
atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
pin->kthread = kthread_run(cec_pin_thread_func, adap,
"cec-pin");
@@ -661,7 +667,8 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
pr_err("cec-pin: kernel_thread() failed\n");
return PTR_ERR(pin->kthread);
}
- hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+ hrtimer_start(&pin->timer, ns_to_ktime(0),
+ HRTIMER_MODE_REL);
} else {
if (pin->ops->disable_irq)
pin->ops->disable_irq(adap);
@@ -699,7 +706,8 @@ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
pin->ops->disable_irq(adap);
cec_pin_high(pin);
cec_pin_to_idle(pin);
- hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+ hrtimer_start(&pin->timer, ns_to_ktime(0),
+ HRTIMER_MODE_REL);
}
return 0;
}
@@ -789,7 +797,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,
CEC_MAX_LOG_ADDRS);
- if (PTR_ERR_OR_ZERO(adap)) {
+ if (IS_ERR(adap)) {
kfree(pin);
return adap;
}
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
index 24993a5b38ba..73df4a334eda 100644
--- a/drivers/media/common/b2c2/Makefile
+++ b/drivers/media/common/b2c2/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
b2c2-flexcop-objs += flexcop.o flexcop-fe-tuner.o flexcop-i2c.o
b2c2-flexcop-objs += flexcop-sram.o flexcop-eeprom.o flexcop-misc.o
b2c2-flexcop-objs += flexcop-hw-filter.o
diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
index 2533574c0cf4..b7e5e4c17acb 100644
--- a/drivers/media/common/b2c2/flexcop-common.h
+++ b/drivers/media/common/b2c2/flexcop-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-common.h - common header file for device-specific source files
diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c
index 844c7836c2a6..0f2151cd36f2 100644
--- a/drivers/media/common/b2c2/flexcop-eeprom.c
+++ b/drivers/media/common/b2c2/flexcop-eeprom.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
index 7636606f0be5..a1ce3e8eb1d3 100644
--- a/drivers/media/common/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
diff --git a/drivers/media/common/b2c2/flexcop-hw-filter.c b/drivers/media/common/b2c2/flexcop-hw-filter.c
index 8220257903ef..335f30a54ba8 100644
--- a/drivers/media/common/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/common/b2c2/flexcop-hw-filter.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-hw-filter.c - pid and mac address filtering and control functions
diff --git a/drivers/media/common/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c
index 58d39a59fc09..564da6fa900d 100644
--- a/drivers/media/common/b2c2/flexcop-i2c.c
+++ b/drivers/media/common/b2c2/flexcop-i2c.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
diff --git a/drivers/media/common/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c
index bb0d95fe64f9..83d01d3a81cc 100644
--- a/drivers/media/common/b2c2/flexcop-misc.c
+++ b/drivers/media/common/b2c2/flexcop-misc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-misc.c - miscellaneous functions
diff --git a/drivers/media/common/b2c2/flexcop-reg.h b/drivers/media/common/b2c2/flexcop-reg.h
index 835c54d60e74..dd7c962db565 100644
--- a/drivers/media/common/b2c2/flexcop-reg.h
+++ b/drivers/media/common/b2c2/flexcop-reg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
index 185c285f70fc..d97962eb0112 100644
--- a/drivers/media/common/b2c2/flexcop-sram.c
+++ b/drivers/media/common/b2c2/flexcop-sram.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-sram.c - functions for controlling the SRAM
diff --git a/drivers/media/common/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h
index 8942bdacbf61..911ece59ea02 100644
--- a/drivers/media/common/b2c2/flexcop.h
+++ b/drivers/media/common/b2c2/flexcop.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop.h - private header file for all flexcop-chip-source files
diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_be.h b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
index 8f64bdbd72bb..c97a0d6d7b3a 100644
--- a/drivers/media/common/b2c2/flexcop_ibi_value_be.h
+++ b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
* see flexcop.c for copyright information
diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_le.h b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
index c75830d7d942..5db3b46f21ee 100644
--- a/drivers/media/common/b2c2/flexcop_ibi_value_le.h
+++ b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
* see flexcop.c for copyright information
diff --git a/drivers/media/common/btcx-risc.h b/drivers/media/common/btcx-risc.h
index 03583ef90506..76dc16f402b9 100644
--- a/drivers/media/common/btcx-risc.h
+++ b/drivers/media/common/btcx-risc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
*/
struct btcx_riscmem {
diff --git a/drivers/media/common/cypress_firmware.c b/drivers/media/common/cypress_firmware.c
index 50e3f76d4847..8895158c1962 100644
--- a/drivers/media/common/cypress_firmware.c
+++ b/drivers/media/common/cypress_firmware.c
@@ -74,11 +74,9 @@ int cypress_load_firmware(struct usb_device *udev,
struct hexline *hx;
int ret, pos = 0;
- hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
- if (!hx) {
- dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
+ hx = kmalloc(sizeof(*hx), GFP_KERNEL);
+ if (!hx)
return -ENOMEM;
- }
/* stop the CPU */
hx->data[0] = 1;
diff --git a/drivers/media/common/cypress_firmware.h b/drivers/media/common/cypress_firmware.h
index 1e4f27356205..0aa46e602b07 100644
--- a/drivers/media/common/cypress_firmware.h
+++ b/drivers/media/common/cypress_firmware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
* see dvb-usb-init.c for copyright information.
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index 930d2c94d5d3..8c87d6837c49 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -163,9 +163,9 @@ void saa7146_buffer_next(struct saa7146_dev *dev,
}
}
-void saa7146_buffer_timeout(unsigned long data)
+void saa7146_buffer_timeout(struct timer_list *t)
{
- struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
+ struct saa7146_dmaqueue *q = from_timer(q, t, timeout);
struct saa7146_dev *dev = q->dev;
unsigned long flags;
@@ -559,7 +559,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
vbi->start[1] = 312;
vbi->count[1] = 16;
- init_timer(&vv->vbi_read_timeout);
+ timer_setup(&vv->vbi_read_timeout, NULL, 0);
vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING;
vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY;
diff --git a/drivers/media/common/saa7146/saa7146_i2c.c b/drivers/media/common/saa7146/saa7146_i2c.c
index 75897f95e4b4..f9e099d812c8 100644
--- a/drivers/media/common/saa7146/saa7146_i2c.c
+++ b/drivers/media/common/saa7146/saa7146_i2c.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/drv-intf/saa7146_vv.h>
diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c
index d79e4d7ecd9f..e1d369b976ed 100644
--- a/drivers/media/common/saa7146/saa7146_vbi.c
+++ b/drivers/media/common/saa7146/saa7146_vbi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <media/drv-intf/saa7146_vv.h>
static int vbi_pixel_to_capture = 720 * 2;
@@ -348,9 +349,10 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file)
spin_unlock_irqrestore(&dev->slock, flags);
}
-static void vbi_read_timeout(unsigned long data)
+static void vbi_read_timeout(struct timer_list *t)
{
- struct file *file = (struct file*)data;
+ struct saa7146_vv *vv = from_timer(vv, t, vbi_read_timeout);
+ struct file *file = vv->vbi_read_timeout_file;
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
@@ -365,8 +367,7 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
- setup_timer(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout,
- (unsigned long)(&vv->vbi_dmaq));
+ timer_setup(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout, 0);
vv->vbi_dmaq.dev = dev;
init_waitqueue_head(&vv->vbi_wq);
@@ -402,7 +403,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
file, &dev->v4l2_lock);
vv->vbi_read_timeout.function = vbi_read_timeout;
- vv->vbi_read_timeout.data = (unsigned long)file;
+ vv->vbi_read_timeout_file = file;
/* initialize the brs */
if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
@@ -488,7 +489,7 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff
return ret;
}
-struct saa7146_use_ops saa7146_vbi_uops = {
+const struct saa7146_use_ops saa7146_vbi_uops = {
.init = vbi_init,
.open = vbi_open,
.release = vbi_close,
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 37b4654dc21c..2b631eaa65b3 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -1201,8 +1201,7 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
{
INIT_LIST_HEAD(&vv->video_dmaq.queue);
- setup_timer(&vv->video_dmaq.timeout, saa7146_buffer_timeout,
- (unsigned long)(&vv->video_dmaq));
+ timer_setup(&vv->video_dmaq.timeout, saa7146_buffer_timeout, 0);
vv->video_dmaq.dev = dev;
/* set some default values */
@@ -1303,7 +1302,7 @@ out:
return ret;
}
-struct saa7146_use_ops saa7146_video_uops = {
+const struct saa7146_use_ops saa7146_video_uops = {
.init = video_init,
.open = video_open,
.release = video_close,
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
index 4c0567f106b2..88e2b7ffc537 100644
--- a/drivers/media/common/siano/Makefile
+++ b/drivers/media/common/siano/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
smsdvb-objs := smsdvb-main.o
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index e7a0d7798d5b..c5c827e11b64 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -447,7 +447,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
return entry;
}
}
- entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (entry) {
entry->mode = default_mode;
strcpy(entry->devpath, devpath);
@@ -521,13 +521,13 @@ static void list_add_locked(struct list_head *new, struct list_head *head,
spin_unlock_irqrestore(lock, flags);
}
-/**
+/*
* register a client callback that called when device plugged in/unplugged
* NOTE: if devices exist callback is called immediately for each device
*
* @param hotplug callback
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
int smscore_register_hotplug(hotplug_t hotplug)
{
@@ -536,9 +536,7 @@ int smscore_register_hotplug(hotplug_t hotplug)
int rc = 0;
kmutex_lock(&g_smscore_deviceslock);
-
- notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
- GFP_KERNEL);
+ notifyee = kmalloc(sizeof(*notifyee), GFP_KERNEL);
if (notifyee) {
/* now notify callback about existing devices */
first = &g_smscore_devices;
@@ -564,7 +562,7 @@ int smscore_register_hotplug(hotplug_t hotplug)
}
EXPORT_SYMBOL_GPL(smscore_register_hotplug);
-/**
+/*
* unregister a client callback that called when device plugged in/unplugged
*
* @param hotplug callback
@@ -627,7 +625,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
{
struct smscore_buffer_t *cb;
- cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
+ cb = kzalloc(sizeof(*cb), GFP_KERNEL);
if (!cb)
return NULL;
@@ -638,7 +636,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
return cb;
}
-/**
+/*
* creates coredev object for a device, prepares buffers,
* creates buffer mappings, notifies registered hotplugs about new device.
*
@@ -646,7 +644,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
* and handlers
* @param coredev pointer to a value that receives created coredev object
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
int smscore_register_device(struct smsdevice_params_t *params,
struct smscore_device_t **coredev,
@@ -655,7 +653,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
struct smscore_device_t *dev;
u8 *buffer;
- dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
@@ -751,7 +749,7 @@ static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
void *buffer, size_t size, struct completion *completion) {
int rc;
- if (completion == NULL)
+ if (!completion)
return -EINVAL;
init_completion(completion);
@@ -766,10 +764,10 @@ static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
0 : -ETIME;
}
-/**
+/*
* Starts & enables IR operations
*
- * @return 0 on success, < 0 on error.
+ * return: 0 on success, < 0 on error.
*/
static int smscore_init_ir(struct smscore_device_t *coredev)
{
@@ -814,13 +812,13 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
return 0;
}
-/**
+/*
* configures device features according to board configuration structure.
*
* @param coredev pointer to a coredev object returned by
* smscore_register_device
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
static int smscore_configure_board(struct smscore_device_t *coredev)
{
@@ -863,13 +861,13 @@ static int smscore_configure_board(struct smscore_device_t *coredev)
return 0;
}
-/**
+/*
* sets initial device mode and notifies client hotplugs that device is ready
*
* @param coredev pointer to a coredev object returned by
* smscore_register_device
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
int smscore_start_device(struct smscore_device_t *coredev)
{
@@ -1089,7 +1087,7 @@ static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = {
},
};
-/**
+/*
* get firmware file name from one of the two mechanisms : sms_boards or
* smscore_fw_lkup.
* @param coredev pointer to a coredev object returned by
@@ -1098,7 +1096,7 @@ static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = {
* @param lookup if 1, always get the fw filename from smscore_fw_lkup
* table. if 0, try first to get from sms_boards
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
int mode)
@@ -1127,7 +1125,7 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
return fw[mode];
}
-/**
+/*
* loads specified firmware into a buffer and calls device loadfirmware_handler
*
* @param coredev pointer to a coredev object returned by
@@ -1135,7 +1133,7 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
* @param filename null-terminated string specifies firmware file name
* @param loadfirmware_handler device handler that loads firmware
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
int mode,
@@ -1153,8 +1151,8 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
}
pr_debug("Firmware name: %s\n", fw_filename);
- if (loadfirmware_handler == NULL && !(coredev->device_flags
- & SMS_DEVICE_FAMILY2))
+ if (!loadfirmware_handler &&
+ !(coredev->device_flags & SMS_DEVICE_FAMILY2))
return -EINVAL;
rc = request_firmware(&fw, fw_filename, coredev->device);
@@ -1184,14 +1182,14 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
return rc;
}
-/**
+/*
* notifies all clients registered with the device, notifies hotplugs,
* frees all buffers and coredev object
*
* @param coredev pointer to a coredev object returned by
* smscore_register_device
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
void smscore_unregister_device(struct smscore_device_t *coredev)
{
@@ -1284,14 +1282,14 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
return rc;
}
-/**
+/*
* send init device request and wait for response
*
* @param coredev pointer to a coredev object returned by
* smscore_register_device
* @param mode requested mode of operation
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
static int smscore_init_device(struct smscore_device_t *coredev, int mode)
{
@@ -1301,10 +1299,8 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode)
buffer = kmalloc(sizeof(struct sms_msg_data) +
SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
- if (!buffer) {
- pr_err("Could not allocate buffer for init device message.\n");
+ if (!buffer)
return -ENOMEM;
- }
msg = (struct sms_msg_data *)SMS_ALIGN_ADDRESS(buffer);
SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
@@ -1319,7 +1315,7 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode)
return rc;
}
-/**
+/*
* calls device handler to change mode of operation
* NOTE: stellar/usb may disconnect when changing mode
*
@@ -1327,7 +1323,7 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode)
* smscore_register_device
* @param mode requested mode of operation
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
{
@@ -1415,13 +1411,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
return rc;
}
-/**
+/*
* calls device handler to get current mode of operation
*
* @param coredev pointer to a coredev object returned by
* smscore_register_device
*
- * @return current mode
+ * return: current mode
*/
int smscore_get_device_mode(struct smscore_device_t *coredev)
{
@@ -1429,7 +1425,7 @@ int smscore_get_device_mode(struct smscore_device_t *coredev)
}
EXPORT_SYMBOL_GPL(smscore_get_device_mode);
-/**
+/*
* find client by response id & type within the clients list.
* return client handle or NULL.
*
@@ -1466,7 +1462,7 @@ found:
return client;
}
-/**
+/*
* find client by response id/type, call clients onresponse handler
* return buffer to pool on error
*
@@ -1619,13 +1615,13 @@ void smscore_onresponse(struct smscore_device_t *coredev,
}
EXPORT_SYMBOL_GPL(smscore_onresponse);
-/**
+/*
* return pointer to next free buffer descriptor from core pool
*
* @param coredev pointer to a coredev object returned by
* smscore_register_device
*
- * @return pointer to descriptor on success, NULL on error.
+ * return: pointer to descriptor on success, NULL on error.
*/
static struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
@@ -1652,7 +1648,7 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
}
EXPORT_SYMBOL_GPL(smscore_getbuffer);
-/**
+/*
* return buffer descriptor to a pool
*
* @param coredev pointer to a coredev object returned by
@@ -1686,11 +1682,10 @@ static int smscore_validate_client(struct smscore_device_t *coredev,
pr_err("The msg ID already registered to another client.\n");
return -EEXIST;
}
- listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
- if (!listentry) {
- pr_err("Can't allocate memory for client id.\n");
+ listentry = kzalloc(sizeof(*listentry), GFP_KERNEL);
+ if (!listentry)
return -ENOMEM;
- }
+
listentry->id = id;
listentry->data_type = data_type;
list_add_locked(&listentry->entry, &client->idlist,
@@ -1698,7 +1693,7 @@ static int smscore_validate_client(struct smscore_device_t *coredev,
return 0;
}
-/**
+/*
* creates smsclient object, check that id is taken by another client
*
* @param coredev pointer to a coredev object from clients hotplug
@@ -1710,7 +1705,7 @@ static int smscore_validate_client(struct smscore_device_t *coredev,
* @param context client-specific context
* @param client pointer to a value that receives created smsclient object
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
int smscore_register_client(struct smscore_device_t *coredev,
struct smsclient_params_t *params,
@@ -1724,11 +1719,9 @@ int smscore_register_client(struct smscore_device_t *coredev,
return -EEXIST;
}
- newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
- if (!newclient) {
- pr_err("Failed to allocate memory for client.\n");
+ newclient = kzalloc(sizeof(*newclient), GFP_KERNEL);
+ if (!newclient)
return -ENOMEM;
- }
INIT_LIST_HEAD(&newclient->idlist);
newclient->coredev = coredev;
@@ -1747,7 +1740,7 @@ int smscore_register_client(struct smscore_device_t *coredev,
}
EXPORT_SYMBOL_GPL(smscore_register_client);
-/**
+/*
* frees smsclient object and all subclients associated with it
*
* @param client pointer to smsclient object returned by
@@ -1778,7 +1771,7 @@ void smscore_unregister_client(struct smscore_client_t *client)
}
EXPORT_SYMBOL_GPL(smscore_unregister_client);
-/**
+/*
* verifies that source id is not taken by another client,
* calls device handler to send requests to the device
*
@@ -1787,7 +1780,7 @@ EXPORT_SYMBOL_GPL(smscore_unregister_client);
* @param buffer pointer to a request buffer
* @param size size (in bytes) of request buffer
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
int smsclient_sendrequest(struct smscore_client_t *client,
void *buffer, size_t size)
@@ -1796,7 +1789,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer;
int rc;
- if (client == NULL) {
+ if (!client) {
pr_err("Got NULL client\n");
return -EINVAL;
}
@@ -1804,7 +1797,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
coredev = client->coredev;
/* check that no other channel with same id exists */
- if (coredev == NULL) {
+ if (!coredev) {
pr_err("Got NULL coredev\n");
return -EINVAL;
}
@@ -1961,7 +1954,7 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num,
if (pin_num > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
- if (p_gpio_config == NULL)
+ if (!p_gpio_config)
return -EINVAL;
total_len = sizeof(struct sms_msg_hdr) + (sizeof(u32) * 6);
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index a772976cfe26..f96968c11312 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -238,6 +238,8 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
tpg->color_enc = TGP_COLOR_ENC_RGB;
break;
case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_Y10:
+ case V4L2_PIX_FMT_Y12:
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y16_BE:
tpg->color_enc = TGP_COLOR_ENC_LUMA;
@@ -352,6 +354,8 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
case V4L2_PIX_FMT_YUV444:
case V4L2_PIX_FMT_YUV555:
case V4L2_PIX_FMT_YUV565:
+ case V4L2_PIX_FMT_Y10:
+ case V4L2_PIX_FMT_Y12:
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y16_BE:
tpg->twopixelsize[0] = 2 * 2;
@@ -1056,6 +1060,14 @@ static void gen_twopix(struct tpg_data *tpg,
case V4L2_PIX_FMT_GREY:
buf[0][offset] = r_y_h;
break;
+ case V4L2_PIX_FMT_Y10:
+ buf[0][offset] = (r_y_h << 2) & 0xff;
+ buf[0][offset+1] = r_y_h >> 6;
+ break;
+ case V4L2_PIX_FMT_Y12:
+ buf[0][offset] = (r_y_h << 4) & 0xff;
+ buf[0][offset+1] = r_y_h >> 4;
+ break;
case V4L2_PIX_FMT_Y16:
/*
* Ideally both bytes should be set to r_y_h, but then you won't
diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile
index 281bc89576e6..47e2e391bfb8 100644
--- a/drivers/media/dvb-core/Makefile
+++ b/drivers/media/dvb-core/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel DVB device drivers.
#
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 18e4230865be..3ddd44e1ee77 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -329,9 +329,9 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
return 0;
}
-static void dvb_dmxdev_filter_timeout(unsigned long data)
+static void dvb_dmxdev_filter_timeout(struct timer_list *t)
{
- struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data;
+ struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer);
dmxdevfilter->buffer.error = -ETIMEDOUT;
spin_lock_irq(&dmxdevfilter->dev->lock);
@@ -346,8 +346,6 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
del_timer(&dmxdevfilter->timer);
if (para->timeout) {
- dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout;
- dmxdevfilter->timer.data = (unsigned long)dmxdevfilter;
dmxdevfilter->timer.expires =
jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
add_timer(&dmxdevfilter->timer);
@@ -754,7 +752,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
dmxdevfilter->type = DMXDEV_TYPE_NONE;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
- init_timer(&dmxdevfilter->timer);
+ timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0);
dvbdev->users++;
diff --git a/drivers/media/dvb-core/dmxdev.h b/drivers/media/dvb-core/dmxdev.h
index 054fd4eb6192..5e795f5f0f41 100644
--- a/drivers/media/dvb-core/dmxdev.h
+++ b/drivers/media/dvb-core/dmxdev.h
@@ -36,12 +36,33 @@
#include "demux.h"
#include "dvb_ringbuffer.h"
+/**
+ * enum dmxdev_type - type of demux filter type.
+ *
+ * @DMXDEV_TYPE_NONE: no filter set.
+ * @DMXDEV_TYPE_SEC: section filter.
+ * @DMXDEV_TYPE_PES: Program Elementary Stream (PES) filter.
+ */
enum dmxdev_type {
DMXDEV_TYPE_NONE,
DMXDEV_TYPE_SEC,
DMXDEV_TYPE_PES,
};
+/**
+ * enum dmxdev_state - state machine for the dmxdev.
+ *
+ * @DMXDEV_STATE_FREE: indicates that the filter is freed.
+ * @DMXDEV_STATE_ALLOCATED: indicates that the filter was allocated
+ * to be used.
+ * @DMXDEV_STATE_SET: indicates that the filter parameters are set.
+ * @DMXDEV_STATE_GO: indicates that the filter is running.
+ * @DMXDEV_STATE_DONE: indicates that a packet was already filtered
+ * and the filter is now disabled.
+ * Set only if %DMX_ONESHOT. See
+ * &dmx_sct_filter_params.
+ * @DMXDEV_STATE_TIMEDOUT: Indicates a timeout condition.
+ */
enum dmxdev_state {
DMXDEV_STATE_FREE,
DMXDEV_STATE_ALLOCATED,
@@ -51,12 +72,49 @@ enum dmxdev_state {
DMXDEV_STATE_TIMEDOUT
};
+/**
+ * struct dmxdev_feed - digital TV dmxdev feed
+ *
+ * @pid: Program ID to be filtered
+ * @ts: pointer to &struct dmx_ts_feed
+ * @next: &struct list_head pointing to the next feed.
+ */
+
struct dmxdev_feed {
u16 pid;
struct dmx_ts_feed *ts;
struct list_head next;
};
+/**
+ * struct dmxdev_filter - digital TV dmxdev filter
+ *
+ * @filter: a dmxdev filter. Currently used only for section filter:
+ * if the filter is Section, it contains a
+ * &struct dmx_section_filter @sec pointer.
+ * @feed: a dmxdev feed. Depending on the feed type, it can be:
+ * for TS feed: a &struct list_head @ts list of TS and PES
+ * feeds;
+ * for section feed: a &struct dmx_section_feed @sec pointer.
+ * @params: dmxdev filter parameters. Depending on the feed type, it
+ * can be:
+ * for section filter: a &struct dmx_sct_filter_params @sec
+ * embedded struct;
+ * for a TS filter: a &struct dmx_pes_filter_params @pes
+ * embedded struct.
+ * @type: type of the dmxdev filter, as defined by &enum dmxdev_type.
+ * @state: state of the dmxdev filter, as defined by &enum dmxdev_state.
+ * @dev: pointer to &struct dmxdev.
+ * @buffer: an embedded &struct dvb_ringbuffer buffer.
+ * @mutex: protects the access to &struct dmxdev_filter.
+ * @timer: &struct timer_list embedded timer, used to check for
+ * feed timeouts.
+ * Only for section filter.
+ * @todo: index for the @secheader.
+ * Only for section filter.
+ * @secheader: buffer cache to parse the section header.
+ * Only for section filter.
+ */
struct dmxdev_filter {
union {
struct dmx_section_filter *sec;
@@ -86,7 +144,23 @@ struct dmxdev_filter {
u8 secheader[3];
};
-
+/**
+ * struct dmxdev - Describes a digital TV demux device.
+ *
+ * @dvbdev: pointer to &struct dvb_device associated with
+ * the demux device node.
+ * @dvr_dvbdev: pointer to &struct dvb_device associated with
+ * the dvr device node.
+ * @filter: pointer to &struct dmxdev_filter.
+ * @demux: pointer to &struct dmx_demux.
+ * @filternum: number of filters.
+ * @capabilities: demux capabilities as defined by &enum dmx_demux_caps.
+ * @exit: flag to indicate that the demux is being released.
+ * @dvr_orig_fe: pointer to &struct dmx_frontend.
+ * @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output.
+ * @mutex: protects the usage of this structure.
+ * @lock: protects access to &dmxdev->filter->data.
+ */
struct dmxdev {
struct dvb_device *dvbdev;
struct dvb_device *dvr_dvbdev;
@@ -108,8 +182,20 @@ struct dmxdev {
spinlock_t lock;
};
+/**
+ * dvb_dmxdev_init - initializes a digital TV demux and registers both demux
+ * and DVR devices.
+ *
+ * @dmxdev: pointer to &struct dmxdev.
+ * @adap: pointer to &struct dvb_adapter.
+ */
+int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *adap);
-int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
+/**
+ * dvb_dmxdev_release - releases a digital TV demux and unregisters it.
+ *
+ * @dmxdev: pointer to &struct dmxdev.
+ */
void dvb_dmxdev_release(struct dmxdev *dmxdev);
#endif /* _DMXDEV_H_ */
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 5b6041d462bc..54d7d8a48b18 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* dvb-usb-ids.h is part of the DVB USB library.
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de) see
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 95b3723282f4..d48b61eb01f4 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -206,7 +206,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
* @hlen: Number of bytes in haystack.
* @needle: Buffer to find.
* @nlen: Number of bytes in needle.
- * @return Pointer into haystack needle was found at, or NULL if not found.
+ * return: Pointer into haystack needle was found at, or NULL if not found.
*/
static char *findstr(char *haystack, int hlen, char *needle, int nlen)
{
@@ -226,7 +226,7 @@ static char *findstr(char *haystack, int hlen, char *needle, int nlen)
/* ************************************************************************** */
/* EN50221 physical interface functions */
-/**
+/*
* dvb_ca_en50221_check_camstatus - Check CAM status.
*/
static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
@@ -275,9 +275,9 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
* @ca: CA instance.
* @slot: Slot on interface.
* @waitfor: Flags to wait for.
- * @timeout_ms: Timeout in milliseconds.
+ * @timeout_hz: Timeout in milliseconds.
*
- * @return 0 on success, nonzero on error.
+ * return: 0 on success, nonzero on error.
*/
static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
u8 waitfor, int timeout_hz)
@@ -325,7 +325,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
* @ca: CA instance.
* @slot: Slot id.
*
- * @return 0 on success, nonzero on failure.
+ * return: 0 on success, nonzero on failure.
*/
static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
{
@@ -397,11 +397,11 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
* @ca: CA instance.
* @slot: Slot id.
* @address: Address to read from. Updated.
- * @tupleType: Tuple id byte. Updated.
- * @tupleLength: Tuple length. Updated.
+ * @tuple_type: Tuple id byte. Updated.
+ * @tuple_length: Tuple length. Updated.
* @tuple: Dest buffer for tuple (must be 256 bytes). Updated.
*
- * @return 0 on success, nonzero on error.
+ * return: 0 on success, nonzero on error.
*/
static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
int *address, int *tuple_type,
@@ -455,7 +455,7 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
* @ca: CA instance.
* @slot: Slot id.
*
- * @return 0 on success, <0 on failure.
+ * return: 0 on success, <0 on failure.
*/
static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
{
@@ -632,10 +632,11 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
* @ca: CA instance.
* @slot: Slot to read from.
* @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
- * the data will be added into the buffering system as a normal fragment.
+ * the data will be added into the buffering system as a normal
+ * fragment.
* @ecount: Size of ebuf. Ignored if ebuf is NULL.
*
- * @return Number of bytes read, or < 0 on error
+ * return: Number of bytes read, or < 0 on error
*/
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
u8 *ebuf, int ecount)
@@ -784,11 +785,11 @@ exit:
*
* @ca: CA instance.
* @slot: Slot to write to.
- * @ebuf: The data in this buffer is treated as a complete link-level packet to
- * be written.
- * @count: Size of ebuf.
+ * @buf: The data in this buffer is treated as a complete link-level packet to
+ * be written.
+ * @bytes_write: Size of ebuf.
*
- * @return Number of bytes written, or < 0 on error.
+ * return: Number of bytes written, or < 0 on error.
*/
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
u8 *buf, int bytes_write)
@@ -933,7 +934,7 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
/**
* dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
*
- * @ca: CA instance.
+ * @pubca: CA instance.
* @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values.
*/
@@ -963,7 +964,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
/**
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
*
- * @ca: CA instance.
+ * @pubca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
@@ -983,7 +984,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
/**
* dvb_ca_en50221_frda_irq - An FR or DA IRQ has occurred.
*
- * @ca: CA instance.
+ * @pubca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
@@ -1091,7 +1092,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
*
* @ca: CA instance.
* @slot: Slot to process.
- * @return: 0 .. no change
+ * return:: 0 .. no change
* 1 .. CAM state changed
*/
@@ -1296,7 +1297,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca,
mutex_unlock(&sl->slot_lock);
}
-/**
+/*
* Kernel thread which monitors CA slots for CAM changes, and performs data
* transfers.
*/
@@ -1336,12 +1337,11 @@ static int dvb_ca_en50221_thread(void *data)
* Real ioctl implementation.
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
*
- * @inode: Inode concerned.
* @file: File concerned.
* @cmd: IOCTL command.
- * @arg: Associated argument.
+ * @parg: Associated argument.
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
static int dvb_ca_en50221_io_do_ioctl(struct file *file,
unsigned int cmd, void *parg)
@@ -1420,12 +1420,11 @@ out_unlock:
/**
* Wrapper for ioctl implementation.
*
- * @inode: Inode concerned.
* @file: File concerned.
* @cmd: IOCTL command.
* @arg: Associated argument.
*
- * @return 0 on success, <0 on error.
+ * return: 0 on success, <0 on error.
*/
static long dvb_ca_en50221_io_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
@@ -1441,7 +1440,7 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
* @count: Size of source buffer.
* @ppos: Position in file (ignored).
*
- * @return Number of bytes read, or <0 on error.
+ * return: Number of bytes read, or <0 on error.
*/
static ssize_t dvb_ca_en50221_io_write(struct file *file,
const char __user *buf, size_t count,
@@ -1536,7 +1535,7 @@ exit:
return status;
}
-/**
+/*
* Condition for waking up in dvb_ca_en50221_io_read_condition
*/
static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
@@ -1593,7 +1592,7 @@ nextslot:
* @count: Size of destination buffer.
* @ppos: Position in file (ignored).
*
- * @return Number of bytes read, or <0 on error.
+ * return: Number of bytes read, or <0 on error.
*/
static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
@@ -1702,7 +1701,7 @@ exit:
* @inode: Inode concerned.
* @file: File concerned.
*
- * @return 0 on success, <0 on failure.
+ * return: 0 on success, <0 on failure.
*/
static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
{
@@ -1752,7 +1751,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
* @inode: Inode concerned.
* @file: File concerned.
*
- * @return 0 on success, <0 on failure.
+ * return: 0 on success, <0 on failure.
*/
static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
{
@@ -1781,7 +1780,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
* @file: File concerned.
* @wait: poll wait table.
*
- * @return Standard poll mask.
+ * return: Standard poll mask.
*/
static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait)
{
@@ -1838,11 +1837,11 @@ static const struct dvb_device dvbdev_ca = {
* Initialise a new DVB CA EN50221 interface device.
*
* @dvb_adapter: DVB adapter to attach the new CA device to.
- * @ca: The dvb_ca instance.
+ * @pubca: The dvb_ca instance.
* @flags: Flags describing the CA device (DVB_CA_FLAG_*).
* @slot_count: Number of slots supported.
*
- * @return 0 on success, nonzero on failure
+ * return: 0 on success, nonzero on failure
*/
int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
struct dvb_ca_en50221 *pubca, int flags, int slot_count)
@@ -1929,8 +1928,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_init);
/**
* Release a DVB CA EN50221 interface device.
*
- * @ca_dev: The dvb_device_t instance for the CA device.
- * @ca: The associated dvb_ca instance.
+ * @pubca: The associated dvb_ca instance.
*/
void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
{
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index 6628f80d184f..acade7543b82 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -223,10 +223,10 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
* when the second packet arrives.
*
* Fix:
- * when demux is started, let feed->pusi_seen = 0 to
+ * when demux is started, let feed->pusi_seen = false to
* prevent initial feeding of garbage from the end of
* previous section. When you for the first time see PUSI=1
- * then set feed->pusi_seen = 1
+ * then set feed->pusi_seen = true
*/
static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
const u8 *buf, u8 len)
@@ -318,10 +318,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
*/
#endif
/*
- * Discontinuity detected. Reset pusi_seen = 0 to
+ * Discontinuity detected. Reset pusi_seen to
* stop feeding of suspicious data until next PUSI=1 arrives
*/
- feed->pusi_seen = 0;
+ feed->pusi_seen = false;
dvb_dmx_swfilter_section_new(feed);
}
@@ -335,8 +335,8 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
dvb_dmx_swfilter_section_copy_dump(feed, before,
before_len);
- /* before start of new section, set pusi_seen = 1 */
- feed->pusi_seen = 1;
+ /* before start of new section, set pusi_seen */
+ feed->pusi_seen = true;
dvb_dmx_swfilter_section_new(feed);
dvb_dmx_swfilter_section_copy_dump(feed, after,
after_len);
@@ -367,6 +367,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
else
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
}
+ /* Used only on full-featured devices */
if (feed->ts_type & TS_DECODER)
if (feed->demux->write_to_decoder)
feed->demux->write_to_decoder(feed, buf, 188);
@@ -898,14 +899,14 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
return;
do {
sf = &f->filter;
- doneq = 0;
+ doneq = false;
for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
mode = sf->filter_mode[i];
mask = sf->filter_mask[i];
f->maskandmode[i] = mask & mode;
doneq |= f->maskandnotmode[i] = mask & ~mode;
}
- f->doneq = doneq ? 1 : 0;
+ f->doneq = doneq ? true : false;
} while ((f = f->next));
}
diff --git a/drivers/media/dvb-core/dvb_demux.h b/drivers/media/dvb-core/dvb_demux.h
index 6f572ca8d339..cc048f09aa85 100644
--- a/drivers/media/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb-core/dvb_demux.h
@@ -26,15 +26,33 @@
#include "demux.h"
-#define DMX_TYPE_TS 0
-#define DMX_TYPE_SEC 1
-#define DMX_TYPE_PES 2
+/**
+ * enum dvb_dmx_filter_type - type of demux feed.
+ *
+ * @DMX_TYPE_TS: feed is in TS mode.
+ * @DMX_TYPE_SEC: feed is in Section mode.
+ */
+enum dvb_dmx_filter_type {
+ DMX_TYPE_TS,
+ DMX_TYPE_SEC,
+};
-#define DMX_STATE_FREE 0
-#define DMX_STATE_ALLOCATED 1
-#define DMX_STATE_SET 2
-#define DMX_STATE_READY 3
-#define DMX_STATE_GO 4
+/**
+ * enum dvb_dmx_state - state machine for a demux filter.
+ *
+ * @DMX_STATE_FREE: indicates that the filter is freed.
+ * @DMX_STATE_ALLOCATED: indicates that the filter was allocated
+ * to be used.
+ * @DMX_STATE_READY: indicates that the filter is ready
+ * to be used.
+ * @DMX_STATE_GO: indicates that the filter is running.
+ */
+enum dvb_dmx_state {
+ DMX_STATE_FREE,
+ DMX_STATE_ALLOCATED,
+ DMX_STATE_READY,
+ DMX_STATE_GO,
+};
#define DVB_DEMUX_MASK_MAX 18
@@ -42,24 +60,66 @@
#define SPEED_PKTS_INTERVAL 50000
+/**
+ * struct dvb_demux_filter - Describes a DVB demux section filter.
+ *
+ * @filter: Section filter as defined by &struct dmx_section_filter.
+ * @maskandmode: logical ``and`` bit mask.
+ * @maskandnotmode: logical ``and not`` bit mask.
+ * @doneq: flag that indicates when a filter is ready.
+ * @next: pointer to the next section filter.
+ * @feed: &struct dvb_demux_feed pointer.
+ * @index: index of the used demux filter.
+ * @state: state of the filter as described by &enum dvb_dmx_state.
+ * @type: type of the filter as described
+ * by &enum dvb_dmx_filter_type.
+ */
+
struct dvb_demux_filter {
struct dmx_section_filter filter;
u8 maskandmode[DMX_MAX_FILTER_SIZE];
u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
- int doneq;
+ bool doneq;
struct dvb_demux_filter *next;
struct dvb_demux_feed *feed;
int index;
- int state;
- int type;
+ enum dvb_dmx_state state;
+ enum dvb_dmx_filter_type type;
+ /* private: used only by av7110 */
u16 hw_handle;
- struct timer_list timer;
};
-#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
-
+/**
+ * struct dvb_demux_feed - describes a DVB field
+ *
+ * @feed: a digital TV feed. It can either be a TS or a section feed:
+ * if the feed is TS, it contains &struct dvb_ts_feed @ts;
+ * if the feed is section, it contains
+ * &struct dmx_section_feed @sec.
+ * @cb: digital TV callbacks. depending on the feed type, it can be:
+ * if the feed is TS, it contains a dmx_ts_cb() @ts callback;
+ * if the feed is section, it contains a dmx_section_cb() @sec
+ * callback.
+ *
+ * @demux: pointer to &struct dvb_demux.
+ * @priv: private data that can optionally be used by a DVB driver.
+ * @type: type of the filter, as defined by &enum dvb_dmx_filter_type.
+ * @state: state of the filter as defined by &enum dvb_dmx_state.
+ * @pid: PID to be filtered.
+ * @timeout: feed timeout.
+ * @filter: pointer to &struct dvb_demux_filter.
+ * @ts_type: type of TS, as defined by &enum ts_filter_type.
+ * @pes_type: type of PES, as defined by &enum dmx_ts_pes.
+ * @cc: MPEG-TS packet continuity counter
+ * @pusi_seen: if true, indicates that a discontinuity was detected.
+ * it is used to prevent feeding of garbage from previous section.
+ * @peslen: length of the PES (Packet Elementary Stream).
+ * @list_head: head for the list of digital TV demux feeds.
+ * @index: a unique index for each feed. Can be used as hardware
+ * pid filter index.
+ */
struct dvb_demux_feed {
union {
struct dmx_ts_feed ts;
@@ -73,25 +133,63 @@ struct dvb_demux_feed {
struct dvb_demux *demux;
void *priv;
- int type;
- int state;
+ enum dvb_dmx_filter_type type;
+ enum dvb_dmx_state state;
u16 pid;
ktime_t timeout;
struct dvb_demux_filter *filter;
- int ts_type;
+ enum ts_filter_type ts_type;
enum dmx_ts_pes pes_type;
int cc;
- int pusi_seen; /* prevents feeding of garbage from previous section */
+ bool pusi_seen;
u16 peslen;
struct list_head list_head;
- unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
+ unsigned int index;
};
+/**
+ * struct dvb_demux - represents a digital TV demux
+ * @dmx: embedded &struct dmx_demux with demux capabilities
+ * and callbacks.
+ * @priv: private data that can optionally be used by
+ * a DVB driver.
+ * @filternum: maximum amount of DVB filters.
+ * @feednum: maximum amount of DVB feeds.
+ * @start_feed: callback routine to be called in order to start
+ * a DVB feed.
+ * @stop_feed: callback routine to be called in order to stop
+ * a DVB feed.
+ * @write_to_decoder: callback routine to be called if the feed is TS and
+ * it is routed to an A/V decoder, when a new TS packet
+ * is received.
+ * Used only on av7110-av.c.
+ * @check_crc32: callback routine to check CRC. If not initialized,
+ * dvb_demux will use an internal one.
+ * @memcopy: callback routine to memcopy received data.
+ * If not initialized, dvb_demux will default to memcpy().
+ * @users: counter for the number of demux opened file descriptors.
+ * Currently, it is limited to 10 users.
+ * @filter: pointer to &struct dvb_demux_filter.
+ * @feed: pointer to &struct dvb_demux_feed.
+ * @frontend_list: &struct list_head with frontends used by the demux.
+ * @pesfilter: array of &struct dvb_demux_feed with the PES types
+ * that will be filtered.
+ * @pids: list of filtered program IDs.
+ * @feed_list: &struct list_head with feeds.
+ * @tsbuf: temporary buffer used internally to store TS packets.
+ * @tsbufp: temporary buffer index used internally.
+ * @mutex: pointer to &struct mutex used to protect feed set
+ * logic.
+ * @lock: pointer to &spinlock_t, used to protect buffer handling.
+ * @cnt_storage: buffer used for TS/TEI continuity check.
+ * @speed_last_time: &ktime_t used for TS speed check.
+ * @speed_pkts_cnt: packets count used for TS speed check.
+ */
struct dvb_demux {
struct dmx_demux dmx;
void *priv;
@@ -115,8 +213,6 @@ struct dvb_demux {
struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
u16 pids[DMX_PES_OTHER];
- int playing;
- int recording;
#define DMX_MAX_PID 0x2000
struct list_head feed_list;
@@ -130,15 +226,119 @@ struct dvb_demux {
ktime_t speed_last_time; /* for TS speed check */
uint32_t speed_pkts_cnt; /* for TS speed check */
+
+ /* private: used only on av7110 */
+ int playing;
+ int recording;
};
-int dvb_dmx_init(struct dvb_demux *dvbdemux);
-void dvb_dmx_release(struct dvb_demux *dvbdemux);
-void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
+/**
+ * dvb_dmx_init - initialize a digital TV demux struct.
+ *
+ * @demux: &struct dvb_demux to be initialized.
+ *
+ * Before being able to register a digital TV demux struct, drivers
+ * should call this routine. On its typical usage, some fields should
+ * be initialized at the driver before calling it.
+ *
+ * A typical usecase is::
+ *
+ * dvb->demux.dmx.capabilities =
+ * DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+ * DMX_MEMORY_BASED_FILTERING;
+ * dvb->demux.priv = dvb;
+ * dvb->demux.filternum = 256;
+ * dvb->demux.feednum = 256;
+ * dvb->demux.start_feed = driver_start_feed;
+ * dvb->demux.stop_feed = driver_stop_feed;
+ * ret = dvb_dmx_init(&dvb->demux);
+ * if (ret < 0)
+ * return ret;
+ */
+int dvb_dmx_init(struct dvb_demux *demux);
+
+/**
+ * dvb_dmx_release - releases a digital TV demux internal buffers.
+ *
+ * @demux: &struct dvb_demux to be released.
+ *
+ * The DVB core internally allocates data at @demux. This routine
+ * releases those data. Please notice that the struct itelf is not
+ * released, as it can be embedded on other structs.
+ */
+void dvb_dmx_release(struct dvb_demux *demux);
+
+/**
+ * dvb_dmx_swfilter_packets - use dvb software filter for a buffer with
+ * multiple MPEG-TS packets with 188 bytes each.
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data to be filtered
+ * @count: number of MPEG-TS packets with size of 188.
+ *
+ * The routine will discard a DVB packet that don't start with 0x47.
+ *
+ * Use this routine if the DVB demux fills MPEG-TS buffers that are
+ * already aligned.
+ *
+ * NOTE: The @buf size should have size equal to ``count * 188``.
+ */
+void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count);
+
+/**
+ * dvb_dmx_swfilter - use dvb software filter for a buffer with
+ * multiple MPEG-TS packets with 188 bytes each.
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data to be filtered
+ * @count: number of MPEG-TS packets with size of 188.
+ *
+ * If a DVB packet doesn't start with 0x47, it will seek for the first
+ * byte that starts with 0x47.
+ *
+ * Use this routine if the DVB demux fill buffers that may not start with
+ * a packet start mark (0x47).
+ *
+ * NOTE: The @buf size should have size equal to ``count * 188``.
+ */
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
+
+/**
+ * dvb_dmx_swfilter_204 - use dvb software filter for a buffer with
+ * multiple MPEG-TS packets with 204 bytes each.
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data to be filtered
+ * @count: number of MPEG-TS packets with size of 204.
+ *
+ * If a DVB packet doesn't start with 0x47, it will seek for the first
+ * byte that starts with 0x47.
+ *
+ * Use this routine if the DVB demux fill buffers that may not start with
+ * a packet start mark (0x47).
+ *
+ * NOTE: The @buf size should have size equal to ``count * 204``.
+ */
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
size_t count);
+
+/**
+ * dvb_dmx_swfilter_raw - make the raw data available to userspace without
+ * filtering
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data
+ * @count: number of packets to be passed. The actual size of each packet
+ * depends on the &dvb_demux->feed->cb.ts logic.
+ *
+ * Use it if the driver needs to deliver the raw payload to userspace without
+ * passing through the kernel demux. That is meant to support some
+ * delivery systems that aren't based on MPEG-TS.
+ *
+ * This function relies on &dvb_demux->feed->cb.ts to actually handle the
+ * buffer.
+ */
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
size_t count);
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 9139d01ba7ed..2afaa8226342 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -145,15 +145,13 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- if (!fepriv)
- return;
-
- dvb_free_device(fepriv->dvbdev);
+ if (fepriv)
+ dvb_free_device(fepriv->dvbdev);
dvb_frontend_invoke_release(fe, fe->ops.release);
- kfree(fepriv);
- fe->frontend_priv = NULL;
+ if (fepriv)
+ kfree(fepriv);
}
static void dvb_frontend_free(struct kref *ref)
@@ -371,11 +369,14 @@ static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepr
}
/**
- * Performs automatic twiddling of frontend parameters.
+ * dvb_frontend_swzigzag_autotune - Performs automatic twiddling of frontend
+ * parameters.
*
- * @param fe The frontend concerned.
- * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
- * @returns Number of complete iterations that have been performed.
+ * @fe: The frontend concerned.
+ * @check_wrapped: Checks if an iteration has completed.
+ * DO NOT SET ON THE FIRST ATTEMPT.
+ *
+ * return: Number of complete iterations that have been performed.
*/
static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped)
{
@@ -951,8 +952,6 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
memset(c, 0, offsetof(struct dtv_frontend_properties, strength));
c->delivery_system = delsys;
- c->state = DTV_CLEAR;
-
dev_dbg(fe->dvb->device, "%s: Clearing cache for delivery system %d\n",
__func__, c->delivery_system);
@@ -1109,39 +1108,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
};
-static void dtv_property_dump(struct dvb_frontend *fe,
- bool is_set,
- struct dtv_property *tvp)
-{
- int i;
-
- if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
- dev_warn(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x undefined\n",
- __func__,
- is_set ? "SET" : "GET",
- tvp->cmd);
- return;
- }
-
- dev_dbg(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x (%s)\n", __func__,
- is_set ? "SET" : "GET",
- tvp->cmd,
- dtv_cmds[tvp->cmd].name);
-
- if (dtv_cmds[tvp->cmd].buffer) {
- dev_dbg(fe->dvb->device, "%s: tvp.u.buffer.len = 0x%02x\n",
- __func__, tvp->u.buffer.len);
-
- for(i = 0; i < tvp->u.buffer.len; i++)
- dev_dbg(fe->dvb->device,
- "%s: tvp.u.buffer.data[0x%02x] = 0x%02x\n",
- __func__, i, tvp->u.buffer.data[i]);
- } else {
- dev_dbg(fe->dvb->device, "%s: tvp.u.data = 0x%08x\n", __func__,
- tvp->u.data);
- }
-}
-
/* Synchronise the legacy tuning parameters into the cache, so that demodulator
* drivers can use a single set_frontend tuning function, regardless of whether
* it's being used for the legacy or new API, reducing code and complexity.
@@ -1290,7 +1256,7 @@ dtv_property_legacy_params_sync(struct dvb_frontend *fe,
* dtv_get_frontend - calls a callback for retrieving DTV parameters
* @fe: struct dvb_frontend pointer
* @c: struct dtv_frontend_properties pointer (DVBv5 cache)
- * @p_out struct dvb_frontend_parameters pointer (DVBv3 FE struct)
+ * @p_out: struct dvb_frontend_parameters pointer (DVBv3 FE struct)
*
* This routine calls either the DVBv3 or DVBv5 get_frontend call.
* If c is not null, it will update the DVBv5 cache struct pointed by it.
@@ -1315,17 +1281,15 @@ static int dtv_get_frontend(struct dvb_frontend *fe,
return 0;
}
-static int dvb_frontend_ioctl_legacy(struct file *file,
- unsigned int cmd, void *parg);
-static int dvb_frontend_ioctl_properties(struct file *file,
- unsigned int cmd, void *parg);
+static int dvb_frontend_handle_ioctl(struct file *file,
+ unsigned int cmd, void *parg);
static int dtv_property_process_get(struct dvb_frontend *fe,
const struct dtv_frontend_properties *c,
struct dtv_property *tvp,
struct file *file)
{
- int r, ncaps;
+ int ncaps;
switch(tvp->cmd) {
case DTV_ENUM_DELSYS:
@@ -1536,14 +1500,18 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
return -EINVAL;
}
- /* Allow the frontend to override outgoing properties */
- if (fe->ops.get_property) {
- r = fe->ops.get_property(fe, tvp);
- if (r < 0)
- return r;
- }
-
- dtv_property_dump(fe, false, tvp);
+ if (!dtv_cmds[tvp->cmd].buffer)
+ dev_dbg(fe->dvb->device,
+ "%s: GET cmd 0x%08x (%s) = 0x%08x\n",
+ __func__, tvp->cmd, dtv_cmds[tvp->cmd].name,
+ tvp->u.data);
+ else
+ dev_dbg(fe->dvb->device,
+ "%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
+ __func__,
+ tvp->cmd, dtv_cmds[tvp->cmd].name,
+ tvp->u.buffer.len,
+ tvp->u.buffer.len, tvp->u.buffer.data);
return 0;
}
@@ -1766,23 +1734,36 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
return emulate_delivery_system(fe, delsys);
}
+/**
+ * dtv_property_process_set - Sets a single DTV property
+ * @fe: Pointer to &struct dvb_frontend
+ * @file: Pointer to &struct file
+ * @cmd: Digital TV command
+ * @data: An unsigned 32-bits number
+ *
+ * This routine assigns the property
+ * value to the corresponding member of
+ * &struct dtv_frontend_properties
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
static int dtv_property_process_set(struct dvb_frontend *fe,
- struct dtv_property *tvp,
- struct file *file)
+ struct file *file,
+ u32 cmd, u32 data)
{
int r = 0;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- /* Allow the frontend to validate incoming properties */
- if (fe->ops.set_property) {
- r = fe->ops.set_property(fe, tvp);
- if (r < 0)
- return r;
- }
-
- dtv_property_dump(fe, true, tvp);
-
- switch(tvp->cmd) {
+ /** Dump DTV command name and value*/
+ if (!cmd || cmd > DTV_MAX_COMMAND)
+ dev_warn(fe->dvb->device, "%s: SET cmd 0x%08x undefined\n",
+ __func__, cmd);
+ else
+ dev_dbg(fe->dvb->device,
+ "%s: SET cmd 0x%08x (%s) to 0x%08x\n",
+ __func__, cmd, dtv_cmds[cmd].name, data);
+ switch (cmd) {
case DTV_CLEAR:
/*
* Reset a cache of data specific to the frontend here. This does
@@ -1791,144 +1772,144 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
dvb_frontend_clear_cache(fe);
break;
case DTV_TUNE:
- /* interpret the cache of data, build either a traditional frontend
- * tunerequest so we can pass validation in the FE_SET_FRONTEND
- * ioctl.
+ /*
+ * Use the cached Digital TV properties to tune the
+ * frontend
*/
- c->state = tvp->cmd;
- dev_dbg(fe->dvb->device, "%s: Finalised property cache\n",
- __func__);
+ dev_dbg(fe->dvb->device,
+ "%s: Setting the frontend from property cache\n",
+ __func__);
r = dtv_set_frontend(fe);
break;
case DTV_FREQUENCY:
- c->frequency = tvp->u.data;
+ c->frequency = data;
break;
case DTV_MODULATION:
- c->modulation = tvp->u.data;
+ c->modulation = data;
break;
case DTV_BANDWIDTH_HZ:
- c->bandwidth_hz = tvp->u.data;
+ c->bandwidth_hz = data;
break;
case DTV_INVERSION:
- c->inversion = tvp->u.data;
+ c->inversion = data;
break;
case DTV_SYMBOL_RATE:
- c->symbol_rate = tvp->u.data;
+ c->symbol_rate = data;
break;
case DTV_INNER_FEC:
- c->fec_inner = tvp->u.data;
+ c->fec_inner = data;
break;
case DTV_PILOT:
- c->pilot = tvp->u.data;
+ c->pilot = data;
break;
case DTV_ROLLOFF:
- c->rolloff = tvp->u.data;
+ c->rolloff = data;
break;
case DTV_DELIVERY_SYSTEM:
- r = dvbv5_set_delivery_system(fe, tvp->u.data);
+ r = dvbv5_set_delivery_system(fe, data);
break;
case DTV_VOLTAGE:
- c->voltage = tvp->u.data;
- r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE,
+ c->voltage = data;
+ r = dvb_frontend_handle_ioctl(file, FE_SET_VOLTAGE,
(void *)c->voltage);
break;
case DTV_TONE:
- c->sectone = tvp->u.data;
- r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE,
+ c->sectone = data;
+ r = dvb_frontend_handle_ioctl(file, FE_SET_TONE,
(void *)c->sectone);
break;
case DTV_CODE_RATE_HP:
- c->code_rate_HP = tvp->u.data;
+ c->code_rate_HP = data;
break;
case DTV_CODE_RATE_LP:
- c->code_rate_LP = tvp->u.data;
+ c->code_rate_LP = data;
break;
case DTV_GUARD_INTERVAL:
- c->guard_interval = tvp->u.data;
+ c->guard_interval = data;
break;
case DTV_TRANSMISSION_MODE:
- c->transmission_mode = tvp->u.data;
+ c->transmission_mode = data;
break;
case DTV_HIERARCHY:
- c->hierarchy = tvp->u.data;
+ c->hierarchy = data;
break;
case DTV_INTERLEAVING:
- c->interleaving = tvp->u.data;
+ c->interleaving = data;
break;
/* ISDB-T Support here */
case DTV_ISDBT_PARTIAL_RECEPTION:
- c->isdbt_partial_reception = tvp->u.data;
+ c->isdbt_partial_reception = data;
break;
case DTV_ISDBT_SOUND_BROADCASTING:
- c->isdbt_sb_mode = tvp->u.data;
+ c->isdbt_sb_mode = data;
break;
case DTV_ISDBT_SB_SUBCHANNEL_ID:
- c->isdbt_sb_subchannel = tvp->u.data;
+ c->isdbt_sb_subchannel = data;
break;
case DTV_ISDBT_SB_SEGMENT_IDX:
- c->isdbt_sb_segment_idx = tvp->u.data;
+ c->isdbt_sb_segment_idx = data;
break;
case DTV_ISDBT_SB_SEGMENT_COUNT:
- c->isdbt_sb_segment_count = tvp->u.data;
+ c->isdbt_sb_segment_count = data;
break;
case DTV_ISDBT_LAYER_ENABLED:
- c->isdbt_layer_enabled = tvp->u.data;
+ c->isdbt_layer_enabled = data;
break;
case DTV_ISDBT_LAYERA_FEC:
- c->layer[0].fec = tvp->u.data;
+ c->layer[0].fec = data;
break;
case DTV_ISDBT_LAYERA_MODULATION:
- c->layer[0].modulation = tvp->u.data;
+ c->layer[0].modulation = data;
break;
case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
- c->layer[0].segment_count = tvp->u.data;
+ c->layer[0].segment_count = data;
break;
case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
- c->layer[0].interleaving = tvp->u.data;
+ c->layer[0].interleaving = data;
break;
case DTV_ISDBT_LAYERB_FEC:
- c->layer[1].fec = tvp->u.data;
+ c->layer[1].fec = data;
break;
case DTV_ISDBT_LAYERB_MODULATION:
- c->layer[1].modulation = tvp->u.data;
+ c->layer[1].modulation = data;
break;
case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
- c->layer[1].segment_count = tvp->u.data;
+ c->layer[1].segment_count = data;
break;
case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
- c->layer[1].interleaving = tvp->u.data;
+ c->layer[1].interleaving = data;
break;
case DTV_ISDBT_LAYERC_FEC:
- c->layer[2].fec = tvp->u.data;
+ c->layer[2].fec = data;
break;
case DTV_ISDBT_LAYERC_MODULATION:
- c->layer[2].modulation = tvp->u.data;
+ c->layer[2].modulation = data;
break;
case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
- c->layer[2].segment_count = tvp->u.data;
+ c->layer[2].segment_count = data;
break;
case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
- c->layer[2].interleaving = tvp->u.data;
+ c->layer[2].interleaving = data;
break;
/* Multistream support */
case DTV_STREAM_ID:
case DTV_DVBT2_PLP_ID_LEGACY:
- c->stream_id = tvp->u.data;
+ c->stream_id = data;
break;
/* ATSC-MH */
case DTV_ATSCMH_PARADE_ID:
- fe->dtv_property_cache.atscmh_parade_id = tvp->u.data;
+ fe->dtv_property_cache.atscmh_parade_id = data;
break;
case DTV_ATSCMH_RS_FRAME_ENSEMBLE:
- fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data;
+ fe->dtv_property_cache.atscmh_rs_frame_ensemble = data;
break;
case DTV_LNA:
- c->lna = tvp->u.data;
+ c->lna = data;
if (fe->ops.set_lna)
r = fe->ops.set_lna(fe);
if (r < 0)
@@ -1942,14 +1923,12 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
return r;
}
-static int dvb_frontend_ioctl(struct file *file,
- unsigned int cmd, void *parg)
+static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- int err = -EOPNOTSUPP;
+ int err;
dev_dbg(fe->dvb->device, "%s: (%d)\n", __func__, _IOC_NR(cmd));
if (down_interruptible(&fepriv->sem))
@@ -1960,109 +1939,33 @@ static int dvb_frontend_ioctl(struct file *file,
return -ENODEV;
}
- if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
- (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT ||
- cmd == FE_DISEQC_RECV_SLAVE_REPLY)) {
+ /*
+ * If the frontend is opened in read-only mode, only the ioctls
+ * that don't interfere with the tune logic should be accepted.
+ * That allows an external application to monitor the DVB QoS and
+ * statistics parameters.
+ *
+ * That matches all _IOR() ioctls, except for two special cases:
+ * - FE_GET_EVENT is part of the tuning logic on a DVB application;
+ * - FE_DISEQC_RECV_SLAVE_REPLY is part of DiSEqC 2.0
+ * setup
+ * So, those two ioctls should also return -EPERM, as otherwise
+ * reading from them would interfere with a DVB tune application
+ */
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY
+ && (_IOC_DIR(cmd) != _IOC_READ
+ || cmd == FE_GET_EVENT
+ || cmd == FE_DISEQC_RECV_SLAVE_REPLY)) {
up(&fepriv->sem);
return -EPERM;
}
- if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
- err = dvb_frontend_ioctl_properties(file, cmd, parg);
- else {
- c->state = DTV_UNDEFINED;
- err = dvb_frontend_ioctl_legacy(file, cmd, parg);
- }
+ err = dvb_frontend_handle_ioctl(file, cmd, parg);
up(&fepriv->sem);
return err;
}
-static int dvb_frontend_ioctl_properties(struct file *file,
- unsigned int cmd, void *parg)
-{
- struct dvb_device *dvbdev = file->private_data;
- struct dvb_frontend *fe = dvbdev->priv;
- struct dvb_frontend_private *fepriv = fe->frontend_priv;
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int err = 0;
-
- struct dtv_properties *tvps = parg;
- struct dtv_property *tvp = NULL;
- int i;
-
- dev_dbg(fe->dvb->device, "%s:\n", __func__);
-
- if (cmd == FE_SET_PROPERTY) {
- dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
- dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
-
- /* Put an arbitrary limit on the number of messages that can
- * be sent at once */
- if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
- return -EINVAL;
-
- tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
- if (IS_ERR(tvp))
- return PTR_ERR(tvp);
-
- for (i = 0; i < tvps->num; i++) {
- err = dtv_property_process_set(fe, tvp + i, file);
- if (err < 0)
- goto out;
- (tvp + i)->result = err;
- }
-
- if (c->state == DTV_TUNE)
- dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
-
- } else if (cmd == FE_GET_PROPERTY) {
- struct dtv_frontend_properties getp = fe->dtv_property_cache;
-
- dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
- dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
-
- /* Put an arbitrary limit on the number of messages that can
- * be sent at once */
- if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
- return -EINVAL;
-
- tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
- if (IS_ERR(tvp))
- return PTR_ERR(tvp);
-
- /*
- * Let's use our own copy of property cache, in order to
- * avoid mangling with DTV zigzag logic, as drivers might
- * return crap, if they don't check if the data is available
- * before updating the properties cache.
- */
- if (fepriv->state != FESTATE_IDLE) {
- err = dtv_get_frontend(fe, &getp, NULL);
- if (err < 0)
- goto out;
- }
- for (i = 0; i < tvps->num; i++) {
- err = dtv_property_process_get(fe, &getp, tvp + i, file);
- if (err < 0)
- goto out;
- (tvp + i)->result = err;
- }
-
- if (copy_to_user((void __user *)tvps->props, tvp,
- tvps->num * sizeof(struct dtv_property))) {
- err = -EFAULT;
- goto out;
- }
-
- } else
- err = -EOPNOTSUPP;
-
-out:
- kfree(tvp);
- return err;
-}
-
static int dtv_set_frontend(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
@@ -2200,16 +2103,102 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
}
-static int dvb_frontend_ioctl_legacy(struct file *file,
- unsigned int cmd, void *parg)
+static int dvb_frontend_handle_ioctl(struct file *file,
+ unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int err = -EOPNOTSUPP;
+ int i, err;
+
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
switch (cmd) {
+ case FE_SET_PROPERTY: {
+ struct dtv_properties *tvps = parg;
+ struct dtv_property *tvp = NULL;
+
+ dev_dbg(fe->dvb->device, "%s: properties.num = %d\n",
+ __func__, tvps->num);
+ dev_dbg(fe->dvb->device, "%s: properties.props = %p\n",
+ __func__, tvps->props);
+
+ /*
+ * Put an arbitrary limit on the number of messages that can
+ * be sent at once
+ */
+ if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
+ return -EINVAL;
+
+ tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
+ if (IS_ERR(tvp))
+ return PTR_ERR(tvp);
+
+ for (i = 0; i < tvps->num; i++) {
+ err = dtv_property_process_set(fe, file,
+ (tvp + i)->cmd,
+ (tvp + i)->u.data);
+ if (err < 0) {
+ kfree(tvp);
+ return err;
+ }
+ }
+ kfree(tvp);
+ break;
+ }
+ case FE_GET_PROPERTY: {
+ struct dtv_properties *tvps = parg;
+ struct dtv_property *tvp = NULL;
+ struct dtv_frontend_properties getp = fe->dtv_property_cache;
+
+ dev_dbg(fe->dvb->device, "%s: properties.num = %d\n",
+ __func__, tvps->num);
+ dev_dbg(fe->dvb->device, "%s: properties.props = %p\n",
+ __func__, tvps->props);
+
+ /*
+ * Put an arbitrary limit on the number of messages that can
+ * be sent at once
+ */
+ if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
+ return -EINVAL;
+
+ tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
+ if (IS_ERR(tvp))
+ return PTR_ERR(tvp);
+
+ /*
+ * Let's use our own copy of property cache, in order to
+ * avoid mangling with DTV zigzag logic, as drivers might
+ * return crap, if they don't check if the data is available
+ * before updating the properties cache.
+ */
+ if (fepriv->state != FESTATE_IDLE) {
+ err = dtv_get_frontend(fe, &getp, NULL);
+ if (err < 0) {
+ kfree(tvp);
+ return err;
+ }
+ }
+ for (i = 0; i < tvps->num; i++) {
+ err = dtv_property_process_get(fe, &getp,
+ tvp + i, file);
+ if (err < 0) {
+ kfree(tvp);
+ return err;
+ }
+ }
+
+ if (copy_to_user((void __user *)tvps->props, tvp,
+ tvps->num * sizeof(struct dtv_property))) {
+ kfree(tvp);
+ return -EFAULT;
+ }
+ kfree(tvp);
+ break;
+ }
+
case FE_GET_INFO: {
struct dvb_frontend_info* info = parg;
@@ -2273,42 +2262,6 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
break;
}
- case FE_READ_BER:
- if (fe->ops.read_ber) {
- if (fepriv->thread)
- err = fe->ops.read_ber(fe, (__u32 *) parg);
- else
- err = -EAGAIN;
- }
- break;
-
- case FE_READ_SIGNAL_STRENGTH:
- if (fe->ops.read_signal_strength) {
- if (fepriv->thread)
- err = fe->ops.read_signal_strength(fe, (__u16 *) parg);
- else
- err = -EAGAIN;
- }
- break;
-
- case FE_READ_SNR:
- if (fe->ops.read_snr) {
- if (fepriv->thread)
- err = fe->ops.read_snr(fe, (__u16 *) parg);
- else
- err = -EAGAIN;
- }
- break;
-
- case FE_READ_UNCORRECTED_BLOCKS:
- if (fe->ops.read_ucblocks) {
- if (fepriv->thread)
- err = fe->ops.read_ucblocks(fe, (__u32 *) parg);
- else
- err = -EAGAIN;
- }
- break;
-
case FE_DISEQC_RESET_OVERLOAD:
if (fe->ops.diseqc_reset_overload) {
err = fe->ops.diseqc_reset_overload(fe);
@@ -2360,6 +2313,23 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
}
break;
+ case FE_DISEQC_RECV_SLAVE_REPLY:
+ if (fe->ops.diseqc_recv_slave_reply)
+ err = fe->ops.diseqc_recv_slave_reply(fe, parg);
+ break;
+
+ case FE_ENABLE_HIGH_LNB_VOLTAGE:
+ if (fe->ops.enable_high_lnb_voltage)
+ err = fe->ops.enable_high_lnb_voltage(fe, (long) parg);
+ break;
+
+ case FE_SET_FRONTEND_TUNE_MODE:
+ fepriv->tune_mode_flags = (unsigned long) parg;
+ err = 0;
+ break;
+
+ /* DEPRECATED dish control ioctls */
+
case FE_DISHNETWORK_SEND_LEGACY_CMD:
if (fe->ops.dishnetwork_send_legacy_command) {
err = fe->ops.dishnetwork_send_legacy_command(fe,
@@ -2425,16 +2395,46 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
}
break;
- case FE_DISEQC_RECV_SLAVE_REPLY:
- if (fe->ops.diseqc_recv_slave_reply)
- err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg);
+ /* DEPRECATED statistics ioctls */
+
+ case FE_READ_BER:
+ if (fe->ops.read_ber) {
+ if (fepriv->thread)
+ err = fe->ops.read_ber(fe, parg);
+ else
+ err = -EAGAIN;
+ }
break;
- case FE_ENABLE_HIGH_LNB_VOLTAGE:
- if (fe->ops.enable_high_lnb_voltage)
- err = fe->ops.enable_high_lnb_voltage(fe, (long) parg);
+ case FE_READ_SIGNAL_STRENGTH:
+ if (fe->ops.read_signal_strength) {
+ if (fepriv->thread)
+ err = fe->ops.read_signal_strength(fe, parg);
+ else
+ err = -EAGAIN;
+ }
break;
+ case FE_READ_SNR:
+ if (fe->ops.read_snr) {
+ if (fepriv->thread)
+ err = fe->ops.read_snr(fe, parg);
+ else
+ err = -EAGAIN;
+ }
+ break;
+
+ case FE_READ_UNCORRECTED_BLOCKS:
+ if (fe->ops.read_ucblocks) {
+ if (fepriv->thread)
+ err = fe->ops.read_ucblocks(fe, parg);
+ else
+ err = -EAGAIN;
+ }
+ break;
+
+ /* DEPRECATED DVBv3 ioctls */
+
case FE_SET_FRONTEND:
err = dvbv3_set_delivery_system(fe);
if (err)
@@ -2461,11 +2461,10 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
err = dtv_get_frontend(fe, &getp, parg);
break;
}
- case FE_SET_FRONTEND_TUNE_MODE:
- fepriv->tune_mode_flags = (unsigned long) parg;
- err = 0;
- break;
- }
+
+ default:
+ return -ENOTSUPP;
+ } /* switch */
return err;
}
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 907a05bde162..ace0c2fb26c2 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -180,8 +180,8 @@ enum dvbfe_search {
/**
* struct dvb_tuner_ops - Tuner information and callbacks
*
- * @info: embedded struct dvb_tuner_info with tuner properties
- * @release: callback function called when frontend is dettached.
+ * @info: embedded &struct dvb_tuner_info with tuner properties
+ * @release: callback function called when frontend is detached.
* drivers should free any allocated memory.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
@@ -191,14 +191,14 @@ enum dvbfe_search {
* resuming from suspend.
* @set_params: callback function used to inform the tuner to tune
* into a digital TV channel. The properties to be used
- * are stored at @dvb_frontend.dtv_property_cache;. The
- * tuner demod can change the parameters to reflect the
- * changes needed for the channel to be tuned, and
+ * are stored at &struct dvb_frontend.dtv_property_cache.
+ * The tuner demod can change the parameters to reflect
+ * the changes needed for the channel to be tuned, and
* update statistics. This is the recommended way to set
* the tuner parameters and should be used on newer
* drivers.
* @set_analog_params: callback function used to tune into an analog TV
- * channel on hybrid tuners. It passes @analog_parameters;
+ * channel on hybrid tuners. It passes @analog_parameters
* to the driver.
* @set_config: callback function used to send some tuner-specific
* parameters.
@@ -207,9 +207,9 @@ enum dvbfe_search {
* @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband,
* should return 0.
* @get_status: returns the frontend lock status
- * @get_rf_strength: returns the RF signal strengh. Used mostly to support
+ * @get_rf_strength: returns the RF signal strength. Used mostly to support
* analog TV and radio. Digital TV should report, instead,
- * via DVBv5 API (@dvb_frontend.dtv_property_cache;).
+ * via DVBv5 API (&struct dvb_frontend.dtv_property_cache).
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @calc_regs: callback function used to pass register data settings
@@ -217,7 +217,7 @@ enum dvbfe_search {
* @set_frequency: Set a new frequency. Shouldn't be used on newer drivers.
* @set_bandwidth: Set a new frequency. Shouldn't be used on newer drivers.
*
- * NOTE: frequencies used on get_frequency and set_frequency are in Hz for
+ * NOTE: frequencies used on @get_frequency and @set_frequency are in Hz for
* terrestrial/cable or kHz for satellite.
*
*/
@@ -283,14 +283,14 @@ struct analog_demod_info {
* @set_params: callback function used to inform the demod to set the
* demodulator parameters needed to decode an analog or
* radio channel. The properties are passed via
- * struct @analog_params;.
+ * &struct analog_params.
* @has_signal: returns 0xffff if has signal, or 0 if it doesn't.
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @tuner_status: callback function that returns tuner status bits, e. g.
- * TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO.
+ * %TUNER_STATUS_LOCKED and %TUNER_STATUS_STEREO.
* @standby: set the tuner to standby mode.
- * @release: callback function called when frontend is dettached.
+ * @release: callback function called when frontend is detached.
* drivers should free any allocated memory.
* @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C
* mux support instead.
@@ -321,10 +321,10 @@ struct dtv_frontend_properties;
* struct dvb_frontend_ops - Demodulation information and callbacks for
* ditialt TV
*
- * @info: embedded struct dvb_tuner_info with tuner properties
+ * @info: embedded &struct dvb_tuner_info with tuner properties
* @delsys: Delivery systems supported by the frontend
* @detach: callback function called when frontend is detached.
- * drivers should clean up, but not yet free the struct
+ * drivers should clean up, but not yet free the &struct
* dvb_frontend allocation.
* @release: callback function called when frontend is ready to be
* freed.
@@ -338,57 +338,57 @@ struct dtv_frontend_properties;
* allow other drivers to write data into their registers.
* Should not be used on new drivers.
* @tune: callback function used by demod drivers that use
- * @DVBFE_ALGO_HW; to tune into a frequency.
+ * @DVBFE_ALGO_HW to tune into a frequency.
* @get_frontend_algo: returns the desired hardware algorithm.
* @set_frontend: callback function used to inform the demod to set the
* parameters for demodulating a digital TV channel.
- * The properties to be used are stored at
- * @dvb_frontend.dtv_property_cache;. The demod can change
+ * The properties to be used are stored at &struct
+ * dvb_frontend.dtv_property_cache. The demod can change
* the parameters to reflect the changes needed for the
* channel to be decoded, and update statistics.
* @get_tune_settings: callback function
* @get_frontend: callback function used to inform the parameters
* actuall in use. The properties to be used are stored at
- * @dvb_frontend.dtv_property_cache; and update
+ * &struct dvb_frontend.dtv_property_cache and update
* statistics. Please notice that it should not return
* an error code if the statistics are not available
* because the demog is not locked.
* @read_status: returns the locking status of the frontend.
* @read_ber: legacy callback function to return the bit error rate.
* Newer drivers should provide such info via DVBv5 API,
- * e. g. @set_frontend;/@get_frontend;, implementing this
+ * e. g. @set_frontend;/@get_frontend, implementing this
* callback only if DVBv3 API compatibility is wanted.
* @read_signal_strength: legacy callback function to return the signal
* strength. Newer drivers should provide such info via
- * DVBv5 API, e. g. @set_frontend;/@get_frontend;,
+ * DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_snr: legacy callback function to return the Signal/Noise
* rate. Newer drivers should provide such info via
- * DVBv5 API, e. g. @set_frontend;/@get_frontend;,
+ * DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_ucblocks: legacy callback function to return the Uncorrected Error
* Blocks. Newer drivers should provide such info via
- * DVBv5 API, e. g. @set_frontend;/@get_frontend;,
+ * DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @diseqc_reset_overload: callback function to implement the
- * FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite)
+ * FE_DISEQC_RESET_OVERLOAD() ioctl (only Satellite)
* @diseqc_send_master_cmd: callback function to implement the
- * FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite).
+ * FE_DISEQC_SEND_MASTER_CMD() ioctl (only Satellite).
* @diseqc_recv_slave_reply: callback function to implement the
- * FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite)
+ * FE_DISEQC_RECV_SLAVE_REPLY() ioctl (only Satellite)
* @diseqc_send_burst: callback function to implement the
- * FE_DISEQC_SEND_BURST ioctl (only Satellite).
+ * FE_DISEQC_SEND_BURST() ioctl (only Satellite).
* @set_tone: callback function to implement the
- * FE_SET_TONE ioctl (only Satellite).
+ * FE_SET_TONE() ioctl (only Satellite).
* @set_voltage: callback function to implement the
- * FE_SET_VOLTAGE ioctl (only Satellite).
+ * FE_SET_VOLTAGE() ioctl (only Satellite).
* @enable_high_lnb_voltage: callback function to implement the
- * FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite).
+ * FE_ENABLE_HIGH_LNB_VOLTAGE() ioctl (only Satellite).
* @dishnetwork_send_legacy_command: callback function to implement the
- * FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite).
+ * FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl (only Satellite).
* Drivers should not use this, except when the DVB
* core emulation fails to provide proper support (e.g.
* if @set_voltage takes more than 8ms to work), and
@@ -399,15 +399,10 @@ struct dtv_frontend_properties;
* @ts_bus_ctrl: callback function used to take control of the TS bus.
* @set_lna: callback function to power on/off/auto the LNA.
* @search: callback function used on some custom algo search algos.
- * @tuner_ops: pointer to struct dvb_tuner_ops
- * @analog_ops: pointer to struct analog_demod_ops
- * @set_property: callback function to allow the frontend to validade
- * incoming properties. Should not be used on new drivers.
- * @get_property: callback function to allow the frontend to override
- * outcoming properties. Should not be used on new drivers.
+ * @tuner_ops: pointer to &struct dvb_tuner_ops
+ * @analog_ops: pointer to &struct analog_demod_ops
*/
struct dvb_frontend_ops {
-
struct dvb_frontend_info info;
u8 delsys[MAX_DELSYS];
@@ -466,9 +461,6 @@ struct dvb_frontend_ops {
struct dvb_tuner_ops tuner_ops;
struct analog_demod_ops analog_ops;
-
- int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
- int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
};
#ifdef __DVB_CORE__
@@ -565,15 +557,15 @@ struct dtv_frontend_properties {
enum fe_sec_voltage voltage;
enum fe_sec_tone_mode sectone;
- enum fe_spectral_inversion inversion;
- enum fe_code_rate fec_inner;
+ enum fe_spectral_inversion inversion;
+ enum fe_code_rate fec_inner;
enum fe_transmit_mode transmission_mode;
u32 bandwidth_hz; /* 0 = AUTO */
enum fe_guard_interval guard_interval;
- enum fe_hierarchy hierarchy;
+ enum fe_hierarchy hierarchy;
u32 symbol_rate;
- enum fe_code_rate code_rate_HP;
- enum fe_code_rate code_rate_LP;
+ enum fe_code_rate code_rate_HP;
+ enum fe_code_rate code_rate_LP;
enum fe_pilot pilot;
enum fe_rolloff rolloff;
@@ -628,11 +620,6 @@ struct dtv_frontend_properties {
struct dtv_fe_stats post_bit_count;
struct dtv_fe_stats block_error;
struct dtv_fe_stats block_count;
-
- /* private: */
- /* Cache State */
- u32 state;
-
};
#define DVB_FE_NO_EXIT 0
@@ -643,16 +630,16 @@ struct dtv_frontend_properties {
/**
* struct dvb_frontend - Frontend structure to be used on drivers.
*
- * @refcount: refcount to keep track of struct dvb_frontend
+ * @refcount: refcount to keep track of &struct dvb_frontend
* references
- * @ops: embedded struct dvb_frontend_ops
- * @dvb: pointer to struct dvb_adapter
+ * @ops: embedded &struct dvb_frontend_ops
+ * @dvb: pointer to &struct dvb_adapter
* @demodulator_priv: demod private data
* @tuner_priv: tuner private data
* @frontend_priv: frontend private data
* @sec_priv: SEC private data
* @analog_demod_priv: Analog demod private data
- * @dtv_property_cache: embedded struct dtv_frontend_properties
+ * @dtv_property_cache: embedded &struct dtv_frontend_properties
* @callback: callback function used on some drivers to call
* either the tuner or the demodulator.
* @id: Frontend ID
@@ -681,8 +668,8 @@ struct dvb_frontend {
/**
* dvb_register_frontend() - Registers a DVB frontend at the adapter
*
- * @dvb: pointer to the dvb adapter
- * @fe: pointer to the frontend struct
+ * @dvb: pointer to &struct dvb_adapter
+ * @fe: pointer to &struct dvb_frontend
*
* Allocate and initialize the private data needed by the frontend core to
* manage the frontend and calls dvb_register_device() to register a new
@@ -695,7 +682,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
/**
* dvb_unregister_frontend() - Unregisters a DVB frontend
*
- * @fe: pointer to the frontend struct
+ * @fe: pointer to &struct dvb_frontend
*
* Stops the frontend kthread, calls dvb_unregister_device() and frees the
* private frontend data allocated by dvb_register_frontend().
@@ -709,14 +696,14 @@ int dvb_unregister_frontend(struct dvb_frontend *fe);
/**
* dvb_frontend_detach() - Detaches and frees frontend specific data
*
- * @fe: pointer to the frontend struct
+ * @fe: pointer to &struct dvb_frontend
*
* This function should be called after dvb_unregister_frontend(). It
* calls the SEC, tuner and demod release functions:
* &dvb_frontend_ops.release_sec, &dvb_frontend_ops.tuner_ops.release,
* &dvb_frontend_ops.analog_ops.release and &dvb_frontend_ops.release.
*
- * If the driver is compiled with CONFIG_MEDIA_ATTACH, it also decreases
+ * If the driver is compiled with %CONFIG_MEDIA_ATTACH, it also decreases
* the module reference count, needed to allow userspace to remove the
* previously used DVB frontend modules.
*/
@@ -725,7 +712,7 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
/**
* dvb_frontend_suspend() - Suspends a Digital TV frontend
*
- * @fe: pointer to the frontend struct
+ * @fe: pointer to &struct dvb_frontend
*
* This function prepares a Digital TV frontend to suspend.
*
@@ -743,7 +730,7 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);
/**
* dvb_frontend_resume() - Resumes a Digital TV frontend
*
- * @fe: pointer to the frontend struct
+ * @fe: pointer to &struct dvb_frontend
*
* This function resumes the usual operation of the tuner after resume.
*
@@ -764,7 +751,7 @@ int dvb_frontend_resume(struct dvb_frontend *fe);
/**
* dvb_frontend_reinitialise() - forces a reinitialisation at the frontend
*
- * @fe: pointer to the frontend struct
+ * @fe: pointer to &struct dvb_frontend
*
* Calls &dvb_frontend_ops.init\(\) and &dvb_frontend_ops.tuner_ops.init\(\),
* and resets SEC tone and voltage (for Satellite systems).
@@ -779,16 +766,16 @@ void dvb_frontend_reinitialise(struct dvb_frontend *fe);
* dvb_frontend_sleep_until() - Sleep for the amount of time given by
* add_usec parameter
*
- * @waketime: pointer to a struct ktime_t
+ * @waketime: pointer to &struct ktime_t
* @add_usec: time to sleep, in microseconds
*
* This function is used to measure the time required for the
- * %FE_DISHNETWORK_SEND_LEGACY_CMD ioctl to work. It needs to be as precise
+ * FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl to work. It needs to be as precise
* as possible, as it affects the detection of the dish tone command at the
* satellite subsystem.
*
* Its used internally by the DVB frontend core, in order to emulate
- * %FE_DISHNETWORK_SEND_LEGACY_CMD using the &dvb_frontend_ops.set_voltage\(\)
+ * FE_DISHNETWORK_SEND_LEGACY_CMD() using the &dvb_frontend_ops.set_voltage\(\)
* callback.
*
* NOTE: it should not be used at the drivers, as the emulation for the
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index 06b0dcc13695..c018e3c06d5d 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -125,7 +125,7 @@ struct dvb_net_priv {
};
-/**
+/*
* Determine the packet's protocol ID. The rule here is that we
* assume 802.3 if the type field is short enough to be a length.
* This is normal practice and works for any 'now in use' protocol.
@@ -155,7 +155,7 @@ static __be16 dvb_net_eth_type_trans(struct sk_buff *skb,
rawp = skb->data;
- /**
+ /*
* This is a magic hack to spot IPX packets. Older Novell breaks
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
@@ -164,7 +164,7 @@ static __be16 dvb_net_eth_type_trans(struct sk_buff *skb,
if (*(unsigned short *)rawp == 0xFFFF)
return htons(ETH_P_802_3);
- /**
+ /*
* Real 802.2 LLC
*/
return htons(ETH_P_802_2);
@@ -215,7 +215,8 @@ static int ule_exthdr_padding(struct dvb_net_priv *p)
return 0;
}
-/** Handle ULE extension headers.
+/*
+ * Handle ULE extension headers.
* Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
* Returns: >= 0: nr. of bytes consumed by next extension header
* -1: Mandatory extension header that is not recognized or TEST SNDU; discard.
@@ -291,7 +292,7 @@ static int handle_ule_extensions( struct dvb_net_priv *p )
}
-/** Prepare for a new ULE SNDU: reset the decoder state. */
+/* Prepare for a new ULE SNDU: reset the decoder state. */
static inline void reset_ule( struct dvb_net_priv *p )
{
p->ule_skb = NULL;
@@ -304,7 +305,7 @@ static inline void reset_ule( struct dvb_net_priv *p )
p->ule_bridged = 0;
}
-/**
+/*
* Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of
* TS cells of a single PID.
*/
@@ -1005,7 +1006,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
{
struct net_device *dev = filter->priv;
- /**
+ /*
* we rely on the DVB API definition where exactly one complete
* section is delivered in buffer1
*/
diff --git a/drivers/media/dvb-core/dvb_net.h b/drivers/media/dvb-core/dvb_net.h
index e9b18aa03e02..1eae8bad7cc1 100644
--- a/drivers/media/dvb-core/dvb_net.h
+++ b/drivers/media/dvb-core/dvb_net.h
@@ -30,6 +30,22 @@
#ifdef CONFIG_DVB_NET
+/**
+ * struct dvb_net - describes a DVB network interface
+ *
+ * @dvbdev: pointer to &struct dvb_device.
+ * @device: array of pointers to &struct net_device.
+ * @state: array of integers to each net device. A value
+ * different than zero means that the interface is
+ * in usage.
+ * @exit: flag to indicate when the device is being removed.
+ * @demux: pointer to &struct dmx_demux.
+ * @ioctl_mutex: protect access to this struct.
+ *
+ * Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
+ * devices.
+ */
+
struct dvb_net {
struct dvb_device *dvbdev;
struct net_device *device[DVB_NET_DEVICES_MAX];
@@ -39,8 +55,22 @@ struct dvb_net {
struct mutex ioctl_mutex;
};
-void dvb_net_release(struct dvb_net *);
-int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
+/**
+ * dvb_net_init - nitializes a digital TV network device and registers it.
+ *
+ * @adap: pointer to &struct dvb_adapter.
+ * @dvbnet: pointer to &struct dvb_net.
+ * @dmxdemux: pointer to &struct dmx_demux.
+ */
+int dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet,
+ struct dmx_demux *dmxdemux);
+
+/**
+ * dvb_net_release - releases a digital TV network device and unregisters it.
+ *
+ * @dvbnet: pointer to &struct dvb_net.
+ */
+void dvb_net_release(struct dvb_net *dvbnet);
#else
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c
index 2322af1b8742..53011629c9ad 100644
--- a/drivers/media/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
@@ -66,12 +66,12 @@ ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
{
ssize_t free;
- /* ACCESS_ONCE() to load read pointer on writer side
+ /* READ_ONCE() to load read pointer on writer side
* this pairs with smp_store_release() in dvb_ringbuffer_read(),
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
* or dvb_ringbuffer_reset()
*/
- free = ACCESS_ONCE(rbuf->pread) - rbuf->pwrite;
+ free = READ_ONCE(rbuf->pread) - rbuf->pwrite;
if (free <= 0)
free += rbuf->size;
return free-1;
@@ -143,7 +143,7 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si
todo -= split;
/* smp_store_release() for read pointer update to ensure
* that buf is not overwritten until read is complete,
- * this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
+ * this pairs with READ_ONCE() in dvb_ringbuffer_free()
*/
smp_store_release(&rbuf->pread, 0);
}
@@ -168,7 +168,7 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
todo -= split;
/* smp_store_release() for read pointer update to ensure
* that buf is not overwritten until read is complete,
- * this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
+ * this pairs with READ_ONCE() in dvb_ringbuffer_free()
*/
smp_store_release(&rbuf->pread, 0);
}
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 41aad0f99d73..060c60ddfcc3 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -51,8 +51,15 @@ static LIST_HEAD(dvb_adapter_list);
static DEFINE_MUTEX(dvbdev_register_lock);
static const char * const dnames[] = {
- "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
- "net", "osd"
+ [DVB_DEVICE_VIDEO] = "video",
+ [DVB_DEVICE_AUDIO] = "audio",
+ [DVB_DEVICE_SEC] = "sec",
+ [DVB_DEVICE_FRONTEND] = "frontend",
+ [DVB_DEVICE_DEMUX] = "demux",
+ [DVB_DEVICE_DVR] = "dvr",
+ [DVB_DEVICE_CA] = "ca",
+ [DVB_DEVICE_NET] = "net",
+ [DVB_DEVICE_OSD] = "osd"
};
#ifdef CONFIG_DVB_DYNAMIC_MINORS
@@ -60,7 +67,22 @@ static const char * const dnames[] = {
#define DVB_MAX_IDS MAX_DVB_MINORS
#else
#define DVB_MAX_IDS 4
-#define nums2minor(num, type, id) ((num << 6) | (id << 4) | type)
+
+static const u8 minor_type[] = {
+ [DVB_DEVICE_VIDEO] = 0,
+ [DVB_DEVICE_AUDIO] = 1,
+ [DVB_DEVICE_SEC] = 2,
+ [DVB_DEVICE_FRONTEND] = 3,
+ [DVB_DEVICE_DEMUX] = 4,
+ [DVB_DEVICE_DVR] = 5,
+ [DVB_DEVICE_CA] = 6,
+ [DVB_DEVICE_NET] = 7,
+ [DVB_DEVICE_OSD] = 8,
+};
+
+#define nums2minor(num, type, id) \
+ (((num) << 6) | ((id) << 4) | minor_type[type])
+
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
#endif
@@ -426,8 +448,8 @@ static int dvb_register_media_device(struct dvb_device *dvbdev,
}
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
- const struct dvb_device *template, void *priv, int type,
- int demux_sink_pads)
+ const struct dvb_device *template, void *priv,
+ enum dvb_device_type type, int demux_sink_pads)
{
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index 49189392cf3b..bbc1c20c0529 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -35,15 +35,37 @@
#define DVB_UNSET (-1)
-#define DVB_DEVICE_VIDEO 0
-#define DVB_DEVICE_AUDIO 1
-#define DVB_DEVICE_SEC 2
-#define DVB_DEVICE_FRONTEND 3
-#define DVB_DEVICE_DEMUX 4
-#define DVB_DEVICE_DVR 5
-#define DVB_DEVICE_CA 6
-#define DVB_DEVICE_NET 7
-#define DVB_DEVICE_OSD 8
+/* List of DVB device types */
+
+/**
+ * enum dvb_device_type - type of the Digital TV device
+ *
+ * @DVB_DEVICE_SEC: Digital TV standalone Common Interface (CI)
+ * @DVB_DEVICE_FRONTEND: Digital TV frontend.
+ * @DVB_DEVICE_DEMUX: Digital TV demux.
+ * @DVB_DEVICE_DVR: Digital TV digital video record (DVR).
+ * @DVB_DEVICE_CA: Digital TV Conditional Access (CA).
+ * @DVB_DEVICE_NET: Digital TV network.
+ *
+ * @DVB_DEVICE_VIDEO: Digital TV video decoder.
+ * Deprecated. Used only on av7110-av.
+ * @DVB_DEVICE_AUDIO: Digital TV audio decoder.
+ * Deprecated. Used only on av7110-av.
+ * @DVB_DEVICE_OSD: Digital TV On Screen Display (OSD).
+ * Deprecated. Used only on av7110.
+ */
+enum dvb_device_type {
+ DVB_DEVICE_SEC,
+ DVB_DEVICE_FRONTEND,
+ DVB_DEVICE_DEMUX,
+ DVB_DEVICE_DVR,
+ DVB_DEVICE_CA,
+ DVB_DEVICE_NET,
+
+ DVB_DEVICE_VIDEO,
+ DVB_DEVICE_AUDIO,
+ DVB_DEVICE_OSD,
+};
#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
static short adapter_nr[] = \
@@ -104,8 +126,7 @@ struct dvb_adapter {
* @list_head: List head with all DVB devices
* @fops: pointer to struct file_operations
* @adapter: pointer to the adapter that holds this device node
- * @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
- * DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
+ * @type: type of the device, as defined by &enum dvb_device_type.
* @minor: devnode minor number. Major number is always DVB_MAJOR.
* @id: device ID number, inside the adapter
* @readers: Initialized by the caller. Each call to open() in Read Only mode
@@ -135,7 +156,7 @@ struct dvb_device {
struct list_head list_head;
const struct file_operations *fops;
struct dvb_adapter *adapter;
- int type;
+ enum dvb_device_type type;
int minor;
u32 id;
@@ -194,9 +215,7 @@ int dvb_unregister_adapter(struct dvb_adapter *adap);
* stored
* @template: Template used to create &pdvbdev;
* @priv: private data
- * @type: type of the device: %DVB_DEVICE_SEC, %DVB_DEVICE_FRONTEND,
- * %DVB_DEVICE_DEMUX, %DVB_DEVICE_DVR, %DVB_DEVICE_CA,
- * %DVB_DEVICE_NET
+ * @type: type of the device, as defined by &enum dvb_device_type.
* @demux_sink_pads: Number of demux outputs, to be used to create the TS
* outputs via the Media Controller.
*/
@@ -204,7 +223,7 @@ int dvb_register_device(struct dvb_adapter *adap,
struct dvb_device **pdvbdev,
const struct dvb_device *template,
void *priv,
- int type,
+ enum dvb_device_type type,
int demux_sink_pads);
/**
@@ -242,7 +261,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
* dvb_create_media_graph - Creates media graph for the Digital TV part of the
* device.
*
- * @adap: pointer to struct dvb_adapter
+ * @adap: pointer to &struct dvb_adapter
* @create_rf_connector: if true, it creates the RF connector too
*
* This function checks all DVB-related functions at the media controller
@@ -255,12 +274,23 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
bool create_rf_connector);
+/**
+ * dvb_register_media_controller - registers a media controller at DVB adapter
+ *
+ * @adap: pointer to &struct dvb_adapter
+ * @mdev: pointer to &struct media_device
+ */
static inline void dvb_register_media_controller(struct dvb_adapter *adap,
struct media_device *mdev)
{
adap->mdev = mdev;
}
+/**
+ * dvb_get_media_controller - gets the associated media controller
+ *
+ * @adap: pointer to &struct dvb_adapter
+ */
static inline struct media_device
*dvb_get_media_controller(struct dvb_adapter *adap)
{
@@ -277,20 +307,71 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
#define dvb_get_media_controller(a) NULL
#endif
-int dvb_generic_open (struct inode *inode, struct file *file);
-int dvb_generic_release (struct inode *inode, struct file *file);
-long dvb_generic_ioctl (struct file *file,
- unsigned int cmd, unsigned long arg);
+/**
+ * dvb_generic_open - Digital TV open function, used by DVB devices
+ *
+ * @inode: pointer to &struct inode.
+ * @file: pointer to &struct file.
+ *
+ * Checks if a DVB devnode is still valid, and if the permissions are
+ * OK and increment negative use count.
+ */
+int dvb_generic_open(struct inode *inode, struct file *file);
-/* we don't mess with video_usercopy() any more,
-we simply define out own dvb_usercopy(), which will hopefully become
-generic_usercopy() someday... */
+/**
+ * dvb_generic_close - Digital TV close function, used by DVB devices
+ *
+ * @inode: pointer to &struct inode.
+ * @file: pointer to &struct file.
+ *
+ * Checks if a DVB devnode is still valid, and if the permissions are
+ * OK and decrement negative use count.
+ */
+int dvb_generic_release(struct inode *inode, struct file *file);
+/**
+ * dvb_generic_ioctl - Digital TV close function, used by DVB devices
+ *
+ * @file: pointer to &struct file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ *
+ * Checks if a DVB devnode and struct dvbdev.kernel_ioctl is still valid.
+ * If so, calls dvb_usercopy().
+ */
+long dvb_generic_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+
+/**
+ * dvb_usercopy - copies data from/to userspace memory when an ioctl is
+ * issued.
+ *
+ * @file: Pointer to struct &file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ * @func: function that will actually handle the ioctl
+ *
+ * Ancillary function that uses ioctl direction and size to copy from
+ * userspace. Then, it calls @func, and, if needed, data is copied back
+ * to userspace.
+ */
int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
int (*func)(struct file *file, unsigned int cmd, void *arg));
/** generic DVB attach function. */
#ifdef CONFIG_MEDIA_ATTACH
+
+/**
+ * dvb_attach - attaches a DVB frontend into the DVB core.
+ *
+ * @FUNCTION: function on a frontend module to be called.
+ * @ARGS...: @FUNCTION arguments.
+ *
+ * This ancillary function loads a frontend module in runtime and runs
+ * the @FUNCTION function there, with @ARGS.
+ * As it increments symbol usage cont, at unregister, dvb_detach()
+ * should be called.
+ */
#define dvb_attach(FUNCTION, ARGS...) ({ \
void *__r = NULL; \
typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
@@ -304,6 +385,14 @@ int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
__r; \
})
+/**
+ * dvb_detach - detaches a DVB frontend loaded via dvb_attach()
+ *
+ * @FUNC: attach function
+ *
+ * Decrements usage count for a function previously called via dvb_attach().
+ */
+
#define dvb_detach(FUNC) symbol_put_addr(FUNC)
#else
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 2631d0e0a024..d17722eb4456 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -173,7 +173,7 @@ config DVB_STB6000
tristate "ST STB6000 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
- help
+ help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0299
@@ -187,7 +187,7 @@ config DVB_STV6110
tristate "ST STV6110 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
- help
+ help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0900
@@ -902,7 +902,7 @@ config DVB_HELENE
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
- Say Y when you want to support this frontend.
+ Say Y when you want to support this frontend.
comment "Tools to develop new frontends"
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index f45f6a4a4371..d025eb373842 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel DVB frontend device drivers.
#
diff --git a/drivers/media/dvb-frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h
index 353274524f1b..a290722c04fd 100644
--- a/drivers/media/dvb-frontends/af9013.h
+++ b/drivers/media/dvb-frontends/af9013.h
@@ -38,6 +38,13 @@
* @api_version: Firmware API version.
* @gpio: GPIOs.
* @get_dvb_frontend: Get DVB frontend callback.
+ *
+ * AF9013/5 GPIOs (mostly guessed):
+ * * demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
+ * * demod#1-gpio#1 - xtal setting (?)
+ * * demod#1-gpio#3 - tuner#1
+ * * demod#2-gpio#0 - tuner#2
+ * * demod#2-gpio#1 - xtal setting (?)
*/
struct af9013_platform_data {
/*
@@ -89,16 +96,15 @@ struct af9013_platform_data {
#define AF9013_TS_PARALLEL AF9013_TS_MODE_PARALLEL
#define AF9013_TS_SERIAL AF9013_TS_MODE_SERIAL
-/*
- * AF9013/5 GPIOs (mostly guessed)
- * demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
- * demod#1-gpio#1 - xtal setting (?)
- * demod#1-gpio#3 - tuner#1
- * demod#2-gpio#0 - tuner#2
- * demod#2-gpio#1 - xtal setting (?)
- */
-
#if IS_REACHABLE(CONFIG_DVB_AF9013)
+/**
+ * Attach an af9013 demod
+ *
+ * @config: pointer to &struct af9013_config with demod configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
struct i2c_adapter *i2c);
#else
diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c
index 98d575f2744c..b1c84ee914f0 100644
--- a/drivers/media/dvb-frontends/as102_fe.c
+++ b/drivers/media/dvb-frontends/as102_fe.c
@@ -455,11 +455,10 @@ struct dvb_frontend *as102_attach(const char *name,
struct as102_state *state;
struct dvb_frontend *fe;
- state = kzalloc(sizeof(struct as102_state), GFP_KERNEL);
- if (state == NULL) {
- pr_err("%s: unable to allocate memory for state\n", __func__);
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
return NULL;
- }
+
fe = &state->frontend;
fe->demodulator_priv = state;
state->ops = ops;
diff --git a/drivers/media/dvb-frontends/ascot2e.h b/drivers/media/dvb-frontends/ascot2e.h
index dc61bf7d1b09..418c565baf83 100644
--- a/drivers/media/dvb-frontends/ascot2e.h
+++ b/drivers/media/dvb-frontends/ascot2e.h
@@ -41,6 +41,15 @@ struct ascot2e_config {
};
#if IS_REACHABLE(CONFIG_DVB_ASCOT2E)
+/**
+ * Attach an ascot2e tuner
+ *
+ * @fe: frontend to be attached
+ * @config: pointer to &struct ascot2e_config with tuner configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c);
diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
index 0118c2658cf7..ee1f704f81f2 100644
--- a/drivers/media/dvb-frontends/cx24113.c
+++ b/drivers/media/dvb-frontends/cx24113.c
@@ -552,13 +552,11 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
const struct cx24113_config *config, struct i2c_adapter *i2c)
{
/* allocate memory for the internal state */
- struct cx24113_state *state =
- kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
+ struct cx24113_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
int rc;
- if (state == NULL) {
- cx_err("Unable to kzalloc\n");
- goto error;
- }
+
+ if (!state)
+ return NULL;
/* setup the state */
state->config = config;
diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
index e105532bfba8..8fb3f095e21c 100644
--- a/drivers/media/dvb-frontends/cx24116.c
+++ b/drivers/media/dvb-frontends/cx24116.c
@@ -221,16 +221,13 @@ static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
static int cx24116_writeregN(struct cx24116_state *state, int reg,
const u8 *data, u16 len)
{
- int ret = -EREMOTEIO;
+ int ret;
struct i2c_msg msg;
u8 *buf;
buf = kmalloc(len + 1, GFP_KERNEL);
- if (buf == NULL) {
- printk("Unable to kmalloc\n");
- ret = -ENOMEM;
- goto error;
- }
+ if (!buf)
+ return -ENOMEM;
*(buf) = reg;
memcpy(buf + 1, data, len);
@@ -251,7 +248,6 @@ static int cx24116_writeregN(struct cx24116_state *state, int reg,
ret = -EREMOTEIO;
}
-error:
kfree(buf);
return ret;
@@ -1121,15 +1117,15 @@ static const struct dvb_frontend_ops cx24116_ops;
struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
struct i2c_adapter *i2c)
{
- struct cx24116_state *state = NULL;
+ struct cx24116_state *state;
int ret;
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
- state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
- goto error1;
+ return NULL;
state->config = config;
state->i2c = i2c;
@@ -1138,8 +1134,9 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
ret = (cx24116_readreg(state, 0xFF) << 8) |
cx24116_readreg(state, 0xFE);
if (ret != 0x0501) {
+ kfree(state);
printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
- goto error2;
+ return NULL;
}
/* create dvb_frontend */
@@ -1147,9 +1144,6 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
-
-error2: kfree(state);
-error1: return NULL;
}
EXPORT_SYMBOL(cx24116_attach);
diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h
index f3ff8f6eb3bb..a49400c0e28e 100644
--- a/drivers/media/dvb-frontends/cxd2820r.h
+++ b/drivers/media/dvb-frontends/cxd2820r.h
@@ -49,7 +49,6 @@
* @gpio_chip_base: GPIO.
* @get_dvb_frontend: Get DVB frontend.
*/
-
struct cxd2820r_platform_data {
u8 ts_mode;
bool ts_clk_inv;
@@ -62,6 +61,17 @@ struct cxd2820r_platform_data {
bool attach_in_use;
};
+/**
+ * struct cxd2820r_config - configuration for cxd2020r demod
+ *
+ * @i2c_address: Demodulator I2C address. Driver determines DVB-C slave I2C
+ * address automatically from master address.
+ * Default: none, must set. Values: 0x6c, 0x6d.
+ * @ts_mode: TS output mode. Default: none, must set. Values: FIXME?
+ * @ts_clock_inv: TS clock inverted. Default: 0. Values: 0, 1.
+ * @if_agc_polarity: Default: 0. Values: 0, 1
+ * @spec_inv: Spectrum inversion. Default: 0. Values: 0, 1.
+ */
struct cxd2820r_config {
/* Demodulator I2C address.
* Driver determines DVB-C slave I2C address automatically from master
@@ -98,6 +108,18 @@ struct cxd2820r_config {
#if IS_REACHABLE(CONFIG_DVB_CXD2820R)
+/**
+ * Attach a cxd2820r demod
+ *
+ * @config: pointer to &struct cxd2820r_config with demod configuration.
+ * @i2c: i2c adapter to use.
+ * @gpio_chip_base: if zero, disables GPIO setting. Otherwise, if
+ * CONFIG_GPIOLIB is set dynamically allocate
+ * gpio base; if is not set, use its value to
+ * setup the GPIO pins.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *cxd2820r_attach(
const struct cxd2820r_config *config,
struct i2c_adapter *i2c,
diff --git a/drivers/media/dvb-frontends/dib7000m.h b/drivers/media/dvb-frontends/dib7000m.h
index 8f84dfa9bb58..df7ecb4314cd 100644
--- a/drivers/media/dvb-frontends/dib7000m.h
+++ b/drivers/media/dvb-frontends/dib7000m.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DIB7000M_H
#define DIB7000M_H
diff --git a/drivers/media/dvb-frontends/dib7000p.h b/drivers/media/dvb-frontends/dib7000p.h
index 205fbbff632b..2e10b5ccce67 100644
--- a/drivers/media/dvb-frontends/dib7000p.h
+++ b/drivers/media/dvb-frontends/dib7000p.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DIB7000P_H
#define DIB7000P_H
diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h
index 75cc8e47ec8f..b920fe769021 100644
--- a/drivers/media/dvb-frontends/dib8000.h
+++ b/drivers/media/dvb-frontends/dib8000.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DIB8000_H
#define DIB8000_H
diff --git a/drivers/media/dvb-frontends/dib9000.h b/drivers/media/dvb-frontends/dib9000.h
index 40883b41e66b..bb03362ac7a3 100644
--- a/drivers/media/dvb-frontends/dib9000.h
+++ b/drivers/media/dvb-frontends/dib9000.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DIB9000_H
#define DIB9000_H
diff --git a/drivers/media/dvb-frontends/dibx000_common.h b/drivers/media/dvb-frontends/dibx000_common.h
index 61f4152f24ee..8784af962eba 100644
--- a/drivers/media/dvb-frontends/dibx000_common.h
+++ b/drivers/media/dvb-frontends/dibx000_common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DIBX000_COMMON_H
#define DIBX000_COMMON_H
diff --git a/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h b/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h
index 5b5421f70388..2b3af247a1f1 100644
--- a/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h
+++ b/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h
@@ -52,7 +52,7 @@ struct i2c_device_addr {
};
-/**
+/*
* \def IS_I2C_10BIT( addr )
* \brief Determine if I2C address 'addr' is a 10 bits address or not.
* \param addr The I2C address.
@@ -67,7 +67,7 @@ struct i2c_device_addr {
Exported FUNCTIONS
------------------------------------------------------------------------------*/
-/**
+/*
* \fn drxbsp_i2c_init()
* \brief Initialize I2C communication module.
* \return drx_status_t Return status.
@@ -76,7 +76,7 @@ Exported FUNCTIONS
*/
drx_status_t drxbsp_i2c_init(void);
-/**
+/*
* \fn drxbsp_i2c_term()
* \brief Terminate I2C communication module.
* \return drx_status_t Return status.
@@ -85,7 +85,7 @@ Exported FUNCTIONS
*/
drx_status_t drxbsp_i2c_term(void);
-/**
+/*
* \fn drx_status_t drxbsp_i2c_write_read( struct i2c_device_addr *w_dev_addr,
* u16 w_count,
* u8 *wData,
@@ -121,7 +121,7 @@ Exported FUNCTIONS
struct i2c_device_addr *r_dev_addr,
u16 r_count, u8 *r_data);
-/**
+/*
* \fn drxbsp_i2c_error_text()
* \brief Returns a human readable error.
* Counter part of numerical drx_i2c_error_g.
@@ -130,7 +130,7 @@ Exported FUNCTIONS
*/
char *drxbsp_i2c_error_text(void);
-/**
+/*
* \var drx_i2c_error_g;
* \brief I2C specific error codes, platform dependent.
*/
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
index cd69e187ba7a..855685b6b386 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
@@ -46,7 +46,7 @@ struct i2c_device_addr {
void *user_data; /* User data pointer */
};
-/**
+/*
* \def IS_I2C_10BIT( addr )
* \brief Determine if I2C address 'addr' is a 10 bits address or not.
* \param addr The I2C address.
@@ -61,7 +61,7 @@ struct i2c_device_addr {
Exported FUNCTIONS
------------------------------------------------------------------------------*/
-/**
+/*
* \fn drxbsp_i2c_init()
* \brief Initialize I2C communication module.
* \return int Return status.
@@ -70,7 +70,7 @@ Exported FUNCTIONS
*/
int drxbsp_i2c_init(void);
-/**
+/*
* \fn drxbsp_i2c_term()
* \brief Terminate I2C communication module.
* \return int Return status.
@@ -79,7 +79,7 @@ int drxbsp_i2c_init(void);
*/
int drxbsp_i2c_term(void);
-/**
+/*
* \fn int drxbsp_i2c_write_read( struct i2c_device_addr *w_dev_addr,
* u16 w_count,
* u8 * wData,
@@ -115,7 +115,7 @@ int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
struct i2c_device_addr *r_dev_addr,
u16 r_count, u8 *r_data);
-/**
+/*
* \fn drxbsp_i2c_error_text()
* \brief Returns a human readable error.
* Counter part of numerical drx_i2c_error_g.
@@ -124,7 +124,7 @@ int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
*/
char *drxbsp_i2c_error_text(void);
-/**
+/*
* \var drx_i2c_error_g;
* \brief I2C specific error codes, platform dependent.
*/
@@ -241,13 +241,13 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
struct i2c_device_addr *r_dev_addr,
u16 r_count, u8 *r_data);
-/**************
+/*************
*
* This section configures the DRX Data Access Protocols (DAPs).
*
**************/
-/**
+/*
* \def DRXDAP_SINGLE_MASTER
* \brief Enable I2C single or I2C multimaster mode on host.
*
@@ -262,7 +262,7 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
#define DRXDAP_SINGLE_MASTER 1
#endif
-/**
+/*
* \def DRXDAP_MAX_WCHUNKSIZE
* \brief Defines maximum chunksize of an i2c write action by host.
*
@@ -282,7 +282,7 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
#define DRXDAP_MAX_WCHUNKSIZE 60
#endif
-/**
+/*
* \def DRXDAP_MAX_RCHUNKSIZE
* \brief Defines maximum chunksize of an i2c read action by host.
*
@@ -297,13 +297,13 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
#define DRXDAP_MAX_RCHUNKSIZE 60
#endif
-/**************
+/*************
*
* This section describes drxdriver defines.
*
**************/
-/**
+/*
* \def DRX_UNKNOWN
* \brief Generic UNKNOWN value for DRX enumerated types.
*
@@ -313,7 +313,7 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
#define DRX_UNKNOWN (254)
#endif
-/**
+/*
* \def DRX_AUTO
* \brief Generic AUTO value for DRX enumerated types.
*
@@ -324,104 +324,104 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
#define DRX_AUTO (255)
#endif
-/**************
+/*************
*
* This section describes flag definitions for the device capbilities.
*
**************/
-/**
+/*
* \brief LNA capability flag
*
* Device has a Low Noise Amplifier
*
*/
#define DRX_CAPABILITY_HAS_LNA (1UL << 0)
-/**
+/*
* \brief OOB-RX capability flag
*
* Device has OOB-RX
*
*/
#define DRX_CAPABILITY_HAS_OOBRX (1UL << 1)
-/**
+/*
* \brief ATV capability flag
*
* Device has ATV
*
*/
#define DRX_CAPABILITY_HAS_ATV (1UL << 2)
-/**
+/*
* \brief DVB-T capability flag
*
* Device has DVB-T
*
*/
#define DRX_CAPABILITY_HAS_DVBT (1UL << 3)
-/**
+/*
* \brief ITU-B capability flag
*
* Device has ITU-B
*
*/
#define DRX_CAPABILITY_HAS_ITUB (1UL << 4)
-/**
+/*
* \brief Audio capability flag
*
* Device has Audio
*
*/
#define DRX_CAPABILITY_HAS_AUD (1UL << 5)
-/**
+/*
* \brief SAW switch capability flag
*
* Device has SAW switch
*
*/
#define DRX_CAPABILITY_HAS_SAWSW (1UL << 6)
-/**
+/*
* \brief GPIO1 capability flag
*
* Device has GPIO1
*
*/
#define DRX_CAPABILITY_HAS_GPIO1 (1UL << 7)
-/**
+/*
* \brief GPIO2 capability flag
*
* Device has GPIO2
*
*/
#define DRX_CAPABILITY_HAS_GPIO2 (1UL << 8)
-/**
+/*
* \brief IRQN capability flag
*
* Device has IRQN
*
*/
#define DRX_CAPABILITY_HAS_IRQN (1UL << 9)
-/**
+/*
* \brief 8VSB capability flag
*
* Device has 8VSB
*
*/
#define DRX_CAPABILITY_HAS_8VSB (1UL << 10)
-/**
+/*
* \brief SMA-TX capability flag
*
* Device has SMATX
*
*/
#define DRX_CAPABILITY_HAS_SMATX (1UL << 11)
-/**
+/*
* \brief SMA-RX capability flag
*
* Device has SMARX
*
*/
#define DRX_CAPABILITY_HAS_SMARX (1UL << 12)
-/**
+/*
* \brief ITU-A/C capability flag
*
* Device has ITU-A/C
@@ -439,7 +439,7 @@ MACROS
DRX_VERSIONSTRING_HELP(PATCH)
#define DRX_VERSIONSTRING_HELP(NUM) #NUM
-/**
+/*
* \brief Macro to create byte array elements from 16 bit integers.
* This macro is used to create byte arrays for block writes.
* Block writes speed up I2C traffic between host and demod.
@@ -449,7 +449,7 @@ MACROS
#define DRX_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
((u8)((((u16)x)>>8)&0xFF))
-/**
+/*
* \brief Macro to convert 16 bit register value to a s32
*/
#define DRX_U16TODRXFREQ(x) ((x & 0x8000) ? \
@@ -461,191 +461,191 @@ MACROS
ENUM
-------------------------------------------------------------------------*/
-/**
+/*
* \enum enum drx_standard
* \brief Modulation standards.
*/
enum drx_standard {
- DRX_STANDARD_DVBT = 0, /**< Terrestrial DVB-T. */
- DRX_STANDARD_8VSB, /**< Terrestrial 8VSB. */
- DRX_STANDARD_NTSC, /**< Terrestrial\Cable analog NTSC. */
+ DRX_STANDARD_DVBT = 0, /*< Terrestrial DVB-T. */
+ DRX_STANDARD_8VSB, /*< Terrestrial 8VSB. */
+ DRX_STANDARD_NTSC, /*< Terrestrial\Cable analog NTSC. */
DRX_STANDARD_PAL_SECAM_BG,
- /**< Terrestrial analog PAL/SECAM B/G */
+ /*< Terrestrial analog PAL/SECAM B/G */
DRX_STANDARD_PAL_SECAM_DK,
- /**< Terrestrial analog PAL/SECAM D/K */
+ /*< Terrestrial analog PAL/SECAM D/K */
DRX_STANDARD_PAL_SECAM_I,
- /**< Terrestrial analog PAL/SECAM I */
+ /*< Terrestrial analog PAL/SECAM I */
DRX_STANDARD_PAL_SECAM_L,
- /**< Terrestrial analog PAL/SECAM L
+ /*< Terrestrial analog PAL/SECAM L
with negative modulation */
DRX_STANDARD_PAL_SECAM_LP,
- /**< Terrestrial analog PAL/SECAM L
+ /*< Terrestrial analog PAL/SECAM L
with positive modulation */
- DRX_STANDARD_ITU_A, /**< Cable ITU ANNEX A. */
- DRX_STANDARD_ITU_B, /**< Cable ITU ANNEX B. */
- DRX_STANDARD_ITU_C, /**< Cable ITU ANNEX C. */
- DRX_STANDARD_ITU_D, /**< Cable ITU ANNEX D. */
- DRX_STANDARD_FM, /**< Terrestrial\Cable FM radio */
- DRX_STANDARD_DTMB, /**< Terrestrial DTMB standard (China)*/
+ DRX_STANDARD_ITU_A, /*< Cable ITU ANNEX A. */
+ DRX_STANDARD_ITU_B, /*< Cable ITU ANNEX B. */
+ DRX_STANDARD_ITU_C, /*< Cable ITU ANNEX C. */
+ DRX_STANDARD_ITU_D, /*< Cable ITU ANNEX D. */
+ DRX_STANDARD_FM, /*< Terrestrial\Cable FM radio */
+ DRX_STANDARD_DTMB, /*< Terrestrial DTMB standard (China)*/
DRX_STANDARD_UNKNOWN = DRX_UNKNOWN,
- /**< Standard unknown. */
+ /*< Standard unknown. */
DRX_STANDARD_AUTO = DRX_AUTO
- /**< Autodetect standard. */
+ /*< Autodetect standard. */
};
-/**
+/*
* \enum enum drx_standard
* \brief Modulation sub-standards.
*/
enum drx_substandard {
- DRX_SUBSTANDARD_MAIN = 0, /**< Main subvariant of standard */
+ DRX_SUBSTANDARD_MAIN = 0, /*< Main subvariant of standard */
DRX_SUBSTANDARD_ATV_BG_SCANDINAVIA,
DRX_SUBSTANDARD_ATV_DK_POLAND,
DRX_SUBSTANDARD_ATV_DK_CHINA,
DRX_SUBSTANDARD_UNKNOWN = DRX_UNKNOWN,
- /**< Sub-standard unknown. */
+ /*< Sub-standard unknown. */
DRX_SUBSTANDARD_AUTO = DRX_AUTO
- /**< Auto (default) sub-standard */
+ /*< Auto (default) sub-standard */
};
-/**
+/*
* \enum enum drx_bandwidth
* \brief Channel bandwidth or channel spacing.
*/
enum drx_bandwidth {
- DRX_BANDWIDTH_8MHZ = 0, /**< Bandwidth 8 MHz. */
- DRX_BANDWIDTH_7MHZ, /**< Bandwidth 7 MHz. */
- DRX_BANDWIDTH_6MHZ, /**< Bandwidth 6 MHz. */
+ DRX_BANDWIDTH_8MHZ = 0, /*< Bandwidth 8 MHz. */
+ DRX_BANDWIDTH_7MHZ, /*< Bandwidth 7 MHz. */
+ DRX_BANDWIDTH_6MHZ, /*< Bandwidth 6 MHz. */
DRX_BANDWIDTH_UNKNOWN = DRX_UNKNOWN,
- /**< Bandwidth unknown. */
+ /*< Bandwidth unknown. */
DRX_BANDWIDTH_AUTO = DRX_AUTO
- /**< Auto Set Bandwidth */
+ /*< Auto Set Bandwidth */
};
-/**
+/*
* \enum enum drx_mirror
* \brief Indicate if channel spectrum is mirrored or not.
*/
enum drx_mirror {
- DRX_MIRROR_NO = 0, /**< Spectrum is not mirrored. */
- DRX_MIRROR_YES, /**< Spectrum is mirrored. */
+ DRX_MIRROR_NO = 0, /*< Spectrum is not mirrored. */
+ DRX_MIRROR_YES, /*< Spectrum is mirrored. */
DRX_MIRROR_UNKNOWN = DRX_UNKNOWN,
- /**< Unknown if spectrum is mirrored. */
+ /*< Unknown if spectrum is mirrored. */
DRX_MIRROR_AUTO = DRX_AUTO
- /**< Autodetect if spectrum is mirrored. */
+ /*< Autodetect if spectrum is mirrored. */
};
-/**
+/*
* \enum enum drx_modulation
* \brief Constellation type of the channel.
*/
enum drx_modulation {
- DRX_CONSTELLATION_BPSK = 0, /**< Modulation is BPSK. */
- DRX_CONSTELLATION_QPSK, /**< Constellation is QPSK. */
- DRX_CONSTELLATION_PSK8, /**< Constellation is PSK8. */
- DRX_CONSTELLATION_QAM16, /**< Constellation is QAM16. */
- DRX_CONSTELLATION_QAM32, /**< Constellation is QAM32. */
- DRX_CONSTELLATION_QAM64, /**< Constellation is QAM64. */
- DRX_CONSTELLATION_QAM128, /**< Constellation is QAM128. */
- DRX_CONSTELLATION_QAM256, /**< Constellation is QAM256. */
- DRX_CONSTELLATION_QAM512, /**< Constellation is QAM512. */
- DRX_CONSTELLATION_QAM1024, /**< Constellation is QAM1024. */
- DRX_CONSTELLATION_QPSK_NR, /**< Constellation is QPSK_NR */
+ DRX_CONSTELLATION_BPSK = 0, /*< Modulation is BPSK. */
+ DRX_CONSTELLATION_QPSK, /*< Constellation is QPSK. */
+ DRX_CONSTELLATION_PSK8, /*< Constellation is PSK8. */
+ DRX_CONSTELLATION_QAM16, /*< Constellation is QAM16. */
+ DRX_CONSTELLATION_QAM32, /*< Constellation is QAM32. */
+ DRX_CONSTELLATION_QAM64, /*< Constellation is QAM64. */
+ DRX_CONSTELLATION_QAM128, /*< Constellation is QAM128. */
+ DRX_CONSTELLATION_QAM256, /*< Constellation is QAM256. */
+ DRX_CONSTELLATION_QAM512, /*< Constellation is QAM512. */
+ DRX_CONSTELLATION_QAM1024, /*< Constellation is QAM1024. */
+ DRX_CONSTELLATION_QPSK_NR, /*< Constellation is QPSK_NR */
DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
- /**< Constellation unknown. */
+ /*< Constellation unknown. */
DRX_CONSTELLATION_AUTO = DRX_AUTO
- /**< Autodetect constellation. */
+ /*< Autodetect constellation. */
};
-/**
+/*
* \enum enum drx_hierarchy
* \brief Hierarchy of the channel.
*/
enum drx_hierarchy {
- DRX_HIERARCHY_NONE = 0, /**< None hierarchical channel. */
- DRX_HIERARCHY_ALPHA1, /**< Hierarchical channel, alpha=1. */
- DRX_HIERARCHY_ALPHA2, /**< Hierarchical channel, alpha=2. */
- DRX_HIERARCHY_ALPHA4, /**< Hierarchical channel, alpha=4. */
+ DRX_HIERARCHY_NONE = 0, /*< None hierarchical channel. */
+ DRX_HIERARCHY_ALPHA1, /*< Hierarchical channel, alpha=1. */
+ DRX_HIERARCHY_ALPHA2, /*< Hierarchical channel, alpha=2. */
+ DRX_HIERARCHY_ALPHA4, /*< Hierarchical channel, alpha=4. */
DRX_HIERARCHY_UNKNOWN = DRX_UNKNOWN,
- /**< Hierarchy unknown. */
+ /*< Hierarchy unknown. */
DRX_HIERARCHY_AUTO = DRX_AUTO
- /**< Autodetect hierarchy. */
+ /*< Autodetect hierarchy. */
};
-/**
+/*
* \enum enum drx_priority
* \brief Channel priority in case of hierarchical transmission.
*/
enum drx_priority {
- DRX_PRIORITY_LOW = 0, /**< Low priority channel. */
- DRX_PRIORITY_HIGH, /**< High priority channel. */
+ DRX_PRIORITY_LOW = 0, /*< Low priority channel. */
+ DRX_PRIORITY_HIGH, /*< High priority channel. */
DRX_PRIORITY_UNKNOWN = DRX_UNKNOWN
- /**< Priority unknown. */
+ /*< Priority unknown. */
};
-/**
+/*
* \enum enum drx_coderate
* \brief Channel priority in case of hierarchical transmission.
*/
enum drx_coderate {
- DRX_CODERATE_1DIV2 = 0, /**< Code rate 1/2nd. */
- DRX_CODERATE_2DIV3, /**< Code rate 2/3nd. */
- DRX_CODERATE_3DIV4, /**< Code rate 3/4nd. */
- DRX_CODERATE_5DIV6, /**< Code rate 5/6nd. */
- DRX_CODERATE_7DIV8, /**< Code rate 7/8nd. */
+ DRX_CODERATE_1DIV2 = 0, /*< Code rate 1/2nd. */
+ DRX_CODERATE_2DIV3, /*< Code rate 2/3nd. */
+ DRX_CODERATE_3DIV4, /*< Code rate 3/4nd. */
+ DRX_CODERATE_5DIV6, /*< Code rate 5/6nd. */
+ DRX_CODERATE_7DIV8, /*< Code rate 7/8nd. */
DRX_CODERATE_UNKNOWN = DRX_UNKNOWN,
- /**< Code rate unknown. */
+ /*< Code rate unknown. */
DRX_CODERATE_AUTO = DRX_AUTO
- /**< Autodetect code rate. */
+ /*< Autodetect code rate. */
};
-/**
+/*
* \enum enum drx_guard
* \brief Guard interval of a channel.
*/
enum drx_guard {
- DRX_GUARD_1DIV32 = 0, /**< Guard interval 1/32nd. */
- DRX_GUARD_1DIV16, /**< Guard interval 1/16th. */
- DRX_GUARD_1DIV8, /**< Guard interval 1/8th. */
- DRX_GUARD_1DIV4, /**< Guard interval 1/4th. */
+ DRX_GUARD_1DIV32 = 0, /*< Guard interval 1/32nd. */
+ DRX_GUARD_1DIV16, /*< Guard interval 1/16th. */
+ DRX_GUARD_1DIV8, /*< Guard interval 1/8th. */
+ DRX_GUARD_1DIV4, /*< Guard interval 1/4th. */
DRX_GUARD_UNKNOWN = DRX_UNKNOWN,
- /**< Guard interval unknown. */
+ /*< Guard interval unknown. */
DRX_GUARD_AUTO = DRX_AUTO
- /**< Autodetect guard interval. */
+ /*< Autodetect guard interval. */
};
-/**
+/*
* \enum enum drx_fft_mode
* \brief FFT mode.
*/
enum drx_fft_mode {
- DRX_FFTMODE_2K = 0, /**< 2K FFT mode. */
- DRX_FFTMODE_4K, /**< 4K FFT mode. */
- DRX_FFTMODE_8K, /**< 8K FFT mode. */
+ DRX_FFTMODE_2K = 0, /*< 2K FFT mode. */
+ DRX_FFTMODE_4K, /*< 4K FFT mode. */
+ DRX_FFTMODE_8K, /*< 8K FFT mode. */
DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
- /**< FFT mode unknown. */
+ /*< FFT mode unknown. */
DRX_FFTMODE_AUTO = DRX_AUTO
- /**< Autodetect FFT mode. */
+ /*< Autodetect FFT mode. */
};
-/**
+/*
* \enum enum drx_classification
* \brief Channel classification.
*/
enum drx_classification {
- DRX_CLASSIFICATION_GAUSS = 0, /**< Gaussion noise. */
- DRX_CLASSIFICATION_HVY_GAUSS, /**< Heavy Gaussion noise. */
- DRX_CLASSIFICATION_COCHANNEL, /**< Co-channel. */
- DRX_CLASSIFICATION_STATIC, /**< Static echo. */
- DRX_CLASSIFICATION_MOVING, /**< Moving echo. */
- DRX_CLASSIFICATION_ZERODB, /**< Zero dB echo. */
+ DRX_CLASSIFICATION_GAUSS = 0, /*< Gaussion noise. */
+ DRX_CLASSIFICATION_HVY_GAUSS, /*< Heavy Gaussion noise. */
+ DRX_CLASSIFICATION_COCHANNEL, /*< Co-channel. */
+ DRX_CLASSIFICATION_STATIC, /*< Static echo. */
+ DRX_CLASSIFICATION_MOVING, /*< Moving echo. */
+ DRX_CLASSIFICATION_ZERODB, /*< Zero dB echo. */
DRX_CLASSIFICATION_UNKNOWN = DRX_UNKNOWN,
- /**< Unknown classification */
+ /*< Unknown classification */
DRX_CLASSIFICATION_AUTO = DRX_AUTO
- /**< Autodetect classification. */
+ /*< Autodetect classification. */
};
-/**
+/*
* /enum enum drx_interleave_mode
* /brief Interleave modes
*/
@@ -673,80 +673,80 @@ enum drx_interleave_mode {
DRX_INTERLEAVEMODE_B52_M48,
DRX_INTERLEAVEMODE_B52_M0,
DRX_INTERLEAVEMODE_UNKNOWN = DRX_UNKNOWN,
- /**< Unknown interleave mode */
+ /*< Unknown interleave mode */
DRX_INTERLEAVEMODE_AUTO = DRX_AUTO
- /**< Autodetect interleave mode */
+ /*< Autodetect interleave mode */
};
-/**
+/*
* \enum enum drx_carrier_mode
* \brief Channel Carrier Mode.
*/
enum drx_carrier_mode {
- DRX_CARRIER_MULTI = 0, /**< Multi carrier mode */
- DRX_CARRIER_SINGLE, /**< Single carrier mode */
+ DRX_CARRIER_MULTI = 0, /*< Multi carrier mode */
+ DRX_CARRIER_SINGLE, /*< Single carrier mode */
DRX_CARRIER_UNKNOWN = DRX_UNKNOWN,
- /**< Carrier mode unknown. */
- DRX_CARRIER_AUTO = DRX_AUTO /**< Autodetect carrier mode */
+ /*< Carrier mode unknown. */
+ DRX_CARRIER_AUTO = DRX_AUTO /*< Autodetect carrier mode */
};
-/**
+/*
* \enum enum drx_frame_mode
* \brief Channel Frame Mode.
*/
enum drx_frame_mode {
- DRX_FRAMEMODE_420 = 0, /**< 420 with variable PN */
- DRX_FRAMEMODE_595, /**< 595 */
- DRX_FRAMEMODE_945, /**< 945 with variable PN */
+ DRX_FRAMEMODE_420 = 0, /*< 420 with variable PN */
+ DRX_FRAMEMODE_595, /*< 595 */
+ DRX_FRAMEMODE_945, /*< 945 with variable PN */
DRX_FRAMEMODE_420_FIXED_PN,
- /**< 420 with fixed PN */
+ /*< 420 with fixed PN */
DRX_FRAMEMODE_945_FIXED_PN,
- /**< 945 with fixed PN */
+ /*< 945 with fixed PN */
DRX_FRAMEMODE_UNKNOWN = DRX_UNKNOWN,
- /**< Frame mode unknown. */
+ /*< Frame mode unknown. */
DRX_FRAMEMODE_AUTO = DRX_AUTO
- /**< Autodetect frame mode */
+ /*< Autodetect frame mode */
};
-/**
+/*
* \enum enum drx_tps_frame
* \brief Frame number in current super-frame.
*/
enum drx_tps_frame {
- DRX_TPS_FRAME1 = 0, /**< TPS frame 1. */
- DRX_TPS_FRAME2, /**< TPS frame 2. */
- DRX_TPS_FRAME3, /**< TPS frame 3. */
- DRX_TPS_FRAME4, /**< TPS frame 4. */
+ DRX_TPS_FRAME1 = 0, /*< TPS frame 1. */
+ DRX_TPS_FRAME2, /*< TPS frame 2. */
+ DRX_TPS_FRAME3, /*< TPS frame 3. */
+ DRX_TPS_FRAME4, /*< TPS frame 4. */
DRX_TPS_FRAME_UNKNOWN = DRX_UNKNOWN
- /**< TPS frame unknown. */
+ /*< TPS frame unknown. */
};
-/**
+/*
* \enum enum drx_ldpc
* \brief TPS LDPC .
*/
enum drx_ldpc {
- DRX_LDPC_0_4 = 0, /**< LDPC 0.4 */
- DRX_LDPC_0_6, /**< LDPC 0.6 */
- DRX_LDPC_0_8, /**< LDPC 0.8 */
+ DRX_LDPC_0_4 = 0, /*< LDPC 0.4 */
+ DRX_LDPC_0_6, /*< LDPC 0.6 */
+ DRX_LDPC_0_8, /*< LDPC 0.8 */
DRX_LDPC_UNKNOWN = DRX_UNKNOWN,
- /**< LDPC unknown. */
- DRX_LDPC_AUTO = DRX_AUTO /**< Autodetect LDPC */
+ /*< LDPC unknown. */
+ DRX_LDPC_AUTO = DRX_AUTO /*< Autodetect LDPC */
};
-/**
+/*
* \enum enum drx_pilot_mode
* \brief Pilot modes in DTMB.
*/
enum drx_pilot_mode {
- DRX_PILOT_ON = 0, /**< Pilot On */
- DRX_PILOT_OFF, /**< Pilot Off */
+ DRX_PILOT_ON = 0, /*< Pilot On */
+ DRX_PILOT_OFF, /*< Pilot Off */
DRX_PILOT_UNKNOWN = DRX_UNKNOWN,
- /**< Pilot unknown. */
- DRX_PILOT_AUTO = DRX_AUTO /**< Autodetect Pilot */
+ /*< Pilot unknown. */
+ DRX_PILOT_AUTO = DRX_AUTO /*< Autodetect Pilot */
};
-/**
+/*
* enum drxu_code_action - indicate if firmware has to be uploaded or verified.
* @UCODE_UPLOAD: Upload the microcode image to device
* @UCODE_VERIFY: Compare microcode image with code on device
@@ -756,7 +756,7 @@ enum drxu_code_action {
UCODE_VERIFY
};
-/**
+/*
* \enum enum drx_lock_status * \brief Used to reflect current lock status of demodulator.
*
* The generic lock states have device dependent semantics.
@@ -801,7 +801,7 @@ enum drx_lock_status {
DRX_LOCKED
};
-/**
+/*
* \enum enum drx_uio* \brief Used to address a User IO (UIO).
*/
enum drx_uio {
@@ -840,7 +840,7 @@ enum drx_uio {
DRX_UIO_MAX = DRX_UIO32
};
-/**
+/*
* \enum enum drxuio_mode * \brief Used to configure the modus oprandi of a UIO.
*
* DRX_UIO_MODE_FIRMWARE is an old uio mode.
@@ -850,37 +850,37 @@ enum drx_uio {
*/
enum drxuio_mode {
DRX_UIO_MODE_DISABLE = 0x01,
- /**< not used, pin is configured as input */
+ /*< not used, pin is configured as input */
DRX_UIO_MODE_READWRITE = 0x02,
- /**< used for read/write by application */
+ /*< used for read/write by application */
DRX_UIO_MODE_FIRMWARE = 0x04,
- /**< controlled by firmware, function 0 */
+ /*< controlled by firmware, function 0 */
DRX_UIO_MODE_FIRMWARE0 = DRX_UIO_MODE_FIRMWARE,
- /**< same as above */
+ /*< same as above */
DRX_UIO_MODE_FIRMWARE1 = 0x08,
- /**< controlled by firmware, function 1 */
+ /*< controlled by firmware, function 1 */
DRX_UIO_MODE_FIRMWARE2 = 0x10,
- /**< controlled by firmware, function 2 */
+ /*< controlled by firmware, function 2 */
DRX_UIO_MODE_FIRMWARE3 = 0x20,
- /**< controlled by firmware, function 3 */
+ /*< controlled by firmware, function 3 */
DRX_UIO_MODE_FIRMWARE4 = 0x40,
- /**< controlled by firmware, function 4 */
+ /*< controlled by firmware, function 4 */
DRX_UIO_MODE_FIRMWARE5 = 0x80
- /**< controlled by firmware, function 5 */
+ /*< controlled by firmware, function 5 */
};
-/**
+/*
* \enum enum drxoob_downstream_standard * \brief Used to select OOB standard.
*
* Based on ANSI 55-1 and 55-2
*/
enum drxoob_downstream_standard {
DRX_OOB_MODE_A = 0,
- /**< ANSI 55-1 */
+ /*< ANSI 55-1 */
DRX_OOB_MODE_B_GRADE_A,
- /**< ANSI 55-2 A */
+ /*< ANSI 55-2 A */
DRX_OOB_MODE_B_GRADE_B
- /**< ANSI 55-2 B */
+ /*< ANSI 55-2 B */
};
/*-------------------------------------------------------------------------
@@ -924,7 +924,7 @@ STRUCTS
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* struct drxu_code_info Parameters for microcode upload and verfiy.
*
* @mc_file: microcode file name
@@ -935,7 +935,7 @@ struct drxu_code_info {
char *mc_file;
};
-/**
+/*
* \struct drx_mc_version_rec_t
* \brief Microcode version record
* Version numbers are stored in BCD format, as usual:
@@ -963,7 +963,7 @@ struct drx_mc_version_rec {
/*========================================*/
-/**
+/*
* \struct drx_filter_info_t
* \brief Parameters for loading filter coefficients
*
@@ -971,18 +971,18 @@ struct drx_mc_version_rec {
*/
struct drx_filter_info {
u8 *data_re;
- /**< pointer to coefficients for RE */
+ /*< pointer to coefficients for RE */
u8 *data_im;
- /**< pointer to coefficients for IM */
+ /*< pointer to coefficients for IM */
u16 size_re;
- /**< size of coefficients for RE */
+ /*< size of coefficients for RE */
u16 size_im;
- /**< size of coefficients for IM */
+ /*< size of coefficients for IM */
};
/*========================================*/
-/**
+/*
* \struct struct drx_channel * \brief The set of parameters describing a single channel.
*
* Used by DRX_CTRL_SET_CHANNEL and DRX_CTRL_GET_CHANNEL.
@@ -991,29 +991,29 @@ struct drx_filter_info {
*/
struct drx_channel {
s32 frequency;
- /**< frequency in kHz */
+ /*< frequency in kHz */
enum drx_bandwidth bandwidth;
- /**< bandwidth */
- enum drx_mirror mirror; /**< mirrored or not on RF */
+ /*< bandwidth */
+ enum drx_mirror mirror; /*< mirrored or not on RF */
enum drx_modulation constellation;
- /**< constellation */
+ /*< constellation */
enum drx_hierarchy hierarchy;
- /**< hierarchy */
- enum drx_priority priority; /**< priority */
- enum drx_coderate coderate; /**< coderate */
- enum drx_guard guard; /**< guard interval */
- enum drx_fft_mode fftmode; /**< fftmode */
+ /*< hierarchy */
+ enum drx_priority priority; /*< priority */
+ enum drx_coderate coderate; /*< coderate */
+ enum drx_guard guard; /*< guard interval */
+ enum drx_fft_mode fftmode; /*< fftmode */
enum drx_classification classification;
- /**< classification */
+ /*< classification */
u32 symbolrate;
- /**< symbolrate in symbols/sec */
+ /*< symbolrate in symbols/sec */
enum drx_interleave_mode interleavemode;
- /**< interleaveMode QAM */
- enum drx_ldpc ldpc; /**< ldpc */
- enum drx_carrier_mode carrier; /**< carrier */
+ /*< interleaveMode QAM */
+ enum drx_ldpc ldpc; /*< ldpc */
+ enum drx_carrier_mode carrier; /*< carrier */
enum drx_frame_mode framemode;
- /**< frame mode */
- enum drx_pilot_mode pilot; /**< pilot mode */
+ /*< frame mode */
+ enum drx_pilot_mode pilot; /*< pilot mode */
};
/*========================================*/
@@ -1027,74 +1027,74 @@ enum drx_cfg_sqi_speed {
/*========================================*/
-/**
+/*
* \struct struct drx_complex * A complex number.
*
* Used by DRX_CTRL_CONSTEL.
*/
struct drx_complex {
s16 im;
- /**< Imaginary part. */
+ /*< Imaginary part. */
s16 re;
- /**< Real part. */
+ /*< Real part. */
};
/*========================================*/
-/**
+/*
* \struct struct drx_frequency_plan * Array element of a frequency plan.
*
* Used by DRX_CTRL_SCAN_INIT.
*/
struct drx_frequency_plan {
s32 first;
- /**< First centre frequency in this band */
+ /*< First centre frequency in this band */
s32 last;
- /**< Last centre frequency in this band */
+ /*< Last centre frequency in this band */
s32 step;
- /**< Stepping frequency in this band */
+ /*< Stepping frequency in this band */
enum drx_bandwidth bandwidth;
- /**< Bandwidth within this frequency band */
+ /*< Bandwidth within this frequency band */
u16 ch_number;
- /**< First channel number in this band, or first
+ /*< First channel number in this band, or first
index in ch_names */
char **ch_names;
- /**< Optional list of channel names in this
+ /*< Optional list of channel names in this
band */
};
/*========================================*/
-/**
+/*
* \struct struct drx_scan_param * Parameters for channel scan.
*
* Used by DRX_CTRL_SCAN_INIT.
*/
struct drx_scan_param {
struct drx_frequency_plan *frequency_plan;
- /**< Frequency plan (array)*/
- u16 frequency_plan_size; /**< Number of bands */
- u32 num_tries; /**< Max channels tried */
- s32 skip; /**< Minimum frequency step to take
+ /*< Frequency plan (array)*/
+ u16 frequency_plan_size; /*< Number of bands */
+ u32 num_tries; /*< Max channels tried */
+ s32 skip; /*< Minimum frequency step to take
after a channel is found */
- void *ext_params; /**< Standard specific params */
+ void *ext_params; /*< Standard specific params */
};
/*========================================*/
-/**
+/*
* \brief Scan commands.
* Used by scanning algorithms.
*/
enum drx_scan_command {
- DRX_SCAN_COMMAND_INIT = 0,/**< Initialize scanning */
- DRX_SCAN_COMMAND_NEXT, /**< Next scan */
- DRX_SCAN_COMMAND_STOP /**< Stop scanning */
+ DRX_SCAN_COMMAND_INIT = 0,/*< Initialize scanning */
+ DRX_SCAN_COMMAND_NEXT, /*< Next scan */
+ DRX_SCAN_COMMAND_STOP /*< Stop scanning */
};
/*========================================*/
-/**
+/*
* \brief Inner scan function prototype.
*/
typedef int(*drx_scan_func_t) (void *scan_context,
@@ -1104,77 +1104,77 @@ typedef int(*drx_scan_func_t) (void *scan_context,
/*========================================*/
-/**
+/*
* \struct struct drxtps_info * TPS information, DVB-T specific.
*
* Used by DRX_CTRL_TPS_INFO.
*/
struct drxtps_info {
- enum drx_fft_mode fftmode; /**< Fft mode */
- enum drx_guard guard; /**< Guard interval */
+ enum drx_fft_mode fftmode; /*< Fft mode */
+ enum drx_guard guard; /*< Guard interval */
enum drx_modulation constellation;
- /**< Constellation */
+ /*< Constellation */
enum drx_hierarchy hierarchy;
- /**< Hierarchy */
+ /*< Hierarchy */
enum drx_coderate high_coderate;
- /**< High code rate */
+ /*< High code rate */
enum drx_coderate low_coderate;
- /**< Low cod rate */
- enum drx_tps_frame frame; /**< Tps frame */
- u8 length; /**< Length */
- u16 cell_id; /**< Cell id */
+ /*< Low cod rate */
+ enum drx_tps_frame frame; /*< Tps frame */
+ u8 length; /*< Length */
+ u16 cell_id; /*< Cell id */
};
/*========================================*/
-/**
+/*
* \brief Power mode of device.
*
* Used by DRX_CTRL_SET_POWER_MODE.
*/
enum drx_power_mode {
DRX_POWER_UP = 0,
- /**< Generic , Power Up Mode */
+ /*< Generic , Power Up Mode */
DRX_POWER_MODE_1,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_2,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_3,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_4,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_5,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_6,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_7,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_8,
- /**< Device specific , Power Up Mode */
+ /*< Device specific , Power Up Mode */
DRX_POWER_MODE_9,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_10,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_11,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_12,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_13,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_14,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_15,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_MODE_16,
- /**< Device specific , Power Down Mode */
+ /*< Device specific , Power Down Mode */
DRX_POWER_DOWN = 255
- /**< Generic , Power Down Mode */
+ /*< Generic , Power Down Mode */
};
/*========================================*/
-/**
+/*
* \enum enum drx_module * \brief Software module identification.
*
* Used by DRX_CTRL_VERSION.
@@ -1191,93 +1191,93 @@ typedef int(*drx_scan_func_t) (void *scan_context,
DRX_MODULE_UNKNOWN
};
-/**
+/*
* \enum struct drx_version * \brief Version information of one software module.
*
* Used by DRX_CTRL_VERSION.
*/
struct drx_version {
enum drx_module module_type;
- /**< Type identifier of the module */
+ /*< Type identifier of the module */
char *module_name;
- /**< Name or description of module */
- u16 v_major; /**< Major version number */
- u16 v_minor; /**< Minor version number */
- u16 v_patch; /**< Patch version number */
- char *v_string; /**< Version as text string */
+ /*< Name or description of module */
+ u16 v_major; /*< Major version number */
+ u16 v_minor; /*< Minor version number */
+ u16 v_patch; /*< Patch version number */
+ char *v_string; /*< Version as text string */
};
-/**
+/*
* \enum struct drx_version_list * \brief List element of NULL terminated, linked list for version information.
*
* Used by DRX_CTRL_VERSION.
*/
struct drx_version_list {
- struct drx_version *version;/**< Version information */
+ struct drx_version *version;/*< Version information */
struct drx_version_list *next;
- /**< Next list element */
+ /*< Next list element */
};
/*========================================*/
-/**
+/*
* \brief Parameters needed to confiugure a UIO.
*
* Used by DRX_CTRL_UIO_CFG.
*/
struct drxuio_cfg {
enum drx_uio uio;
- /**< UIO identifier */
+ /*< UIO identifier */
enum drxuio_mode mode;
- /**< UIO operational mode */
+ /*< UIO operational mode */
};
/*========================================*/
-/**
+/*
* \brief Parameters needed to read from or write to a UIO.
*
* Used by DRX_CTRL_UIO_READ and DRX_CTRL_UIO_WRITE.
*/
struct drxuio_data {
enum drx_uio uio;
- /**< UIO identifier */
+ /*< UIO identifier */
bool value;
- /**< UIO value (true=1, false=0) */
+ /*< UIO value (true=1, false=0) */
};
/*========================================*/
-/**
+/*
* \brief Parameters needed to configure OOB.
*
* Used by DRX_CTRL_SET_OOB.
*/
struct drxoob {
- s32 frequency; /**< Frequency in kHz */
+ s32 frequency; /*< Frequency in kHz */
enum drxoob_downstream_standard standard;
- /**< OOB standard */
- bool spectrum_inverted; /**< If true, then spectrum
+ /*< OOB standard */
+ bool spectrum_inverted; /*< If true, then spectrum
is inverted */
};
/*========================================*/
-/**
+/*
* \brief Metrics from OOB.
*
* Used by DRX_CTRL_GET_OOB.
*/
struct drxoob_status {
- s32 frequency; /**< Frequency in Khz */
- enum drx_lock_status lock; /**< Lock status */
- u32 mer; /**< MER */
- s32 symbol_rate_offset; /**< Symbolrate offset in ppm */
+ s32 frequency; /*< Frequency in Khz */
+ enum drx_lock_status lock; /*< Lock status */
+ u32 mer; /*< MER */
+ s32 symbol_rate_offset; /*< Symbolrate offset in ppm */
};
/*========================================*/
-/**
+/*
* \brief Device dependent configuration data.
*
* Used by DRX_CTRL_SET_CFG and DRX_CTRL_GET_CFG.
@@ -1285,14 +1285,14 @@ struct drx_version_list {
*/
struct drx_cfg {
u32 cfg_type;
- /**< Function identifier */
+ /*< Function identifier */
void *cfg_data;
- /**< Function data */
+ /*< Function data */
};
/*========================================*/
-/**
+/*
* /struct DRXMpegStartWidth_t
* MStart width [nr MCLK cycles] for serial MPEG output.
*/
@@ -1303,7 +1303,7 @@ struct drx_version_list {
};
/* CTRL CFG MPEG output */
-/**
+/*
* \struct struct drx_cfg_mpeg_output * \brief Configuration parameters for MPEG output control.
*
* Used by DRX_CFG_MPEG_OUTPUT, in combination with DRX_CTRL_SET_CFG and
@@ -1311,29 +1311,29 @@ struct drx_version_list {
*/
struct drx_cfg_mpeg_output {
- bool enable_mpeg_output;/**< If true, enable MPEG output */
- bool insert_rs_byte; /**< If true, insert RS byte */
- bool enable_parallel; /**< If true, parallel out otherwise
+ bool enable_mpeg_output;/*< If true, enable MPEG output */
+ bool insert_rs_byte; /*< If true, insert RS byte */
+ bool enable_parallel; /*< If true, parallel out otherwise
serial */
- bool invert_data; /**< If true, invert DATA signals */
- bool invert_err; /**< If true, invert ERR signal */
- bool invert_str; /**< If true, invert STR signals */
- bool invert_val; /**< If true, invert VAL signals */
- bool invert_clk; /**< If true, invert CLK signals */
- bool static_clk; /**< If true, static MPEG clockrate
+ bool invert_data; /*< If true, invert DATA signals */
+ bool invert_err; /*< If true, invert ERR signal */
+ bool invert_str; /*< If true, invert STR signals */
+ bool invert_val; /*< If true, invert VAL signals */
+ bool invert_clk; /*< If true, invert CLK signals */
+ bool static_clk; /*< If true, static MPEG clockrate
will be used, otherwise clockrate
will adapt to the bitrate of the
TS */
- u32 bitrate; /**< Maximum bitrate in b/s in case
+ u32 bitrate; /*< Maximum bitrate in b/s in case
static clockrate is selected */
enum drxmpeg_str_width width_str;
- /**< MPEG start width */
+ /*< MPEG start width */
};
/*========================================*/
-/**
+/*
* \struct struct drxi2c_data * \brief Data for I2C via 2nd or 3rd or etc I2C port.
*
* Used by DRX_CTRL_I2C_READWRITE.
@@ -1341,187 +1341,187 @@ struct drx_version_list {
*
*/
struct drxi2c_data {
- u16 port_nr; /**< I2C port number */
+ u16 port_nr; /*< I2C port number */
struct i2c_device_addr *w_dev_addr;
- /**< Write device address */
- u16 w_count; /**< Size of write data in bytes */
- u8 *wData; /**< Pointer to write data */
+ /*< Write device address */
+ u16 w_count; /*< Size of write data in bytes */
+ u8 *wData; /*< Pointer to write data */
struct i2c_device_addr *r_dev_addr;
- /**< Read device address */
- u16 r_count; /**< Size of data to read in bytes */
- u8 *r_data; /**< Pointer to read buffer */
+ /*< Read device address */
+ u16 r_count; /*< Size of data to read in bytes */
+ u8 *r_data; /*< Pointer to read buffer */
};
/*========================================*/
-/**
+/*
* \enum enum drx_aud_standard * \brief Audio standard identifier.
*
* Used by DRX_CTRL_SET_AUD.
*/
enum drx_aud_standard {
- DRX_AUD_STANDARD_BTSC, /**< set BTSC standard (USA) */
- DRX_AUD_STANDARD_A2, /**< set A2-Korea FM Stereo */
- DRX_AUD_STANDARD_EIAJ, /**< set to Japanese FM Stereo */
- DRX_AUD_STANDARD_FM_STEREO,/**< set to FM-Stereo Radio */
- DRX_AUD_STANDARD_M_MONO, /**< for 4.5 MHz mono detected */
- DRX_AUD_STANDARD_D_K_MONO, /**< for 6.5 MHz mono detected */
- DRX_AUD_STANDARD_BG_FM, /**< set BG_FM standard */
- DRX_AUD_STANDARD_D_K1, /**< set D_K1 standard */
- DRX_AUD_STANDARD_D_K2, /**< set D_K2 standard */
- DRX_AUD_STANDARD_D_K3, /**< set D_K3 standard */
+ DRX_AUD_STANDARD_BTSC, /*< set BTSC standard (USA) */
+ DRX_AUD_STANDARD_A2, /*< set A2-Korea FM Stereo */
+ DRX_AUD_STANDARD_EIAJ, /*< set to Japanese FM Stereo */
+ DRX_AUD_STANDARD_FM_STEREO,/*< set to FM-Stereo Radio */
+ DRX_AUD_STANDARD_M_MONO, /*< for 4.5 MHz mono detected */
+ DRX_AUD_STANDARD_D_K_MONO, /*< for 6.5 MHz mono detected */
+ DRX_AUD_STANDARD_BG_FM, /*< set BG_FM standard */
+ DRX_AUD_STANDARD_D_K1, /*< set D_K1 standard */
+ DRX_AUD_STANDARD_D_K2, /*< set D_K2 standard */
+ DRX_AUD_STANDARD_D_K3, /*< set D_K3 standard */
DRX_AUD_STANDARD_BG_NICAM_FM,
- /**< set BG_NICAM_FM standard */
+ /*< set BG_NICAM_FM standard */
DRX_AUD_STANDARD_L_NICAM_AM,
- /**< set L_NICAM_AM standard */
+ /*< set L_NICAM_AM standard */
DRX_AUD_STANDARD_I_NICAM_FM,
- /**< set I_NICAM_FM standard */
+ /*< set I_NICAM_FM standard */
DRX_AUD_STANDARD_D_K_NICAM_FM,
- /**< set D_K_NICAM_FM standard */
- DRX_AUD_STANDARD_NOT_READY,/**< used to detect audio standard */
+ /*< set D_K_NICAM_FM standard */
+ DRX_AUD_STANDARD_NOT_READY,/*< used to detect audio standard */
DRX_AUD_STANDARD_AUTO = DRX_AUTO,
- /**< Automatic Standard Detection */
+ /*< Automatic Standard Detection */
DRX_AUD_STANDARD_UNKNOWN = DRX_UNKNOWN
- /**< used as auto and for readback */
+ /*< used as auto and for readback */
};
/* CTRL_AUD_GET_STATUS - struct drx_aud_status */
-/**
+/*
* \enum enum drx_aud_nicam_status * \brief Status of NICAM carrier.
*/
enum drx_aud_nicam_status {
DRX_AUD_NICAM_DETECTED = 0,
- /**< NICAM carrier detected */
+ /*< NICAM carrier detected */
DRX_AUD_NICAM_NOT_DETECTED,
- /**< NICAM carrier not detected */
- DRX_AUD_NICAM_BAD /**< NICAM carrier bad quality */
+ /*< NICAM carrier not detected */
+ DRX_AUD_NICAM_BAD /*< NICAM carrier bad quality */
};
-/**
+/*
* \struct struct drx_aud_status * \brief Audio status characteristics.
*/
struct drx_aud_status {
- bool stereo; /**< stereo detection */
- bool carrier_a; /**< carrier A detected */
- bool carrier_b; /**< carrier B detected */
- bool sap; /**< sap / bilingual detection */
- bool rds; /**< RDS data array present */
+ bool stereo; /*< stereo detection */
+ bool carrier_a; /*< carrier A detected */
+ bool carrier_b; /*< carrier B detected */
+ bool sap; /*< sap / bilingual detection */
+ bool rds; /*< RDS data array present */
enum drx_aud_nicam_status nicam_status;
- /**< status of NICAM carrier */
- s8 fm_ident; /**< FM Identification value */
+ /*< status of NICAM carrier */
+ s8 fm_ident; /*< FM Identification value */
};
/* CTRL_AUD_READ_RDS - DRXRDSdata_t */
-/**
+/*
* \struct DRXRDSdata_t
* \brief Raw RDS data array.
*/
struct drx_cfg_aud_rds {
- bool valid; /**< RDS data validation */
- u16 data[18]; /**< data from one RDS data array */
+ bool valid; /*< RDS data validation */
+ u16 data[18]; /*< data from one RDS data array */
};
/* DRX_CFG_AUD_VOLUME - struct drx_cfg_aud_volume - set/get */
-/**
+/*
* \enum DRXAudAVCDecayTime_t
* \brief Automatic volume control configuration.
*/
enum drx_aud_avc_mode {
- DRX_AUD_AVC_OFF, /**< Automatic volume control off */
- DRX_AUD_AVC_DECAYTIME_8S, /**< level volume in 8 seconds */
- DRX_AUD_AVC_DECAYTIME_4S, /**< level volume in 4 seconds */
- DRX_AUD_AVC_DECAYTIME_2S, /**< level volume in 2 seconds */
- DRX_AUD_AVC_DECAYTIME_20MS/**< level volume in 20 millisec */
+ DRX_AUD_AVC_OFF, /*< Automatic volume control off */
+ DRX_AUD_AVC_DECAYTIME_8S, /*< level volume in 8 seconds */
+ DRX_AUD_AVC_DECAYTIME_4S, /*< level volume in 4 seconds */
+ DRX_AUD_AVC_DECAYTIME_2S, /*< level volume in 2 seconds */
+ DRX_AUD_AVC_DECAYTIME_20MS/*< level volume in 20 millisec */
};
-/**
+/*
* /enum DRXAudMaxAVCGain_t
* /brief Automatic volume control max gain in audio baseband.
*/
enum drx_aud_avc_max_gain {
- DRX_AUD_AVC_MAX_GAIN_0DB, /**< maximum AVC gain 0 dB */
- DRX_AUD_AVC_MAX_GAIN_6DB, /**< maximum AVC gain 6 dB */
- DRX_AUD_AVC_MAX_GAIN_12DB /**< maximum AVC gain 12 dB */
+ DRX_AUD_AVC_MAX_GAIN_0DB, /*< maximum AVC gain 0 dB */
+ DRX_AUD_AVC_MAX_GAIN_6DB, /*< maximum AVC gain 6 dB */
+ DRX_AUD_AVC_MAX_GAIN_12DB /*< maximum AVC gain 12 dB */
};
-/**
+/*
* /enum DRXAudMaxAVCAtten_t
* /brief Automatic volume control max attenuation in audio baseband.
*/
enum drx_aud_avc_max_atten {
DRX_AUD_AVC_MAX_ATTEN_12DB,
- /**< maximum AVC attenuation 12 dB */
+ /*< maximum AVC attenuation 12 dB */
DRX_AUD_AVC_MAX_ATTEN_18DB,
- /**< maximum AVC attenuation 18 dB */
- DRX_AUD_AVC_MAX_ATTEN_24DB/**< maximum AVC attenuation 24 dB */
+ /*< maximum AVC attenuation 18 dB */
+ DRX_AUD_AVC_MAX_ATTEN_24DB/*< maximum AVC attenuation 24 dB */
};
-/**
+/*
* \struct struct drx_cfg_aud_volume * \brief Audio volume configuration.
*/
struct drx_cfg_aud_volume {
- bool mute; /**< mute overrides volume setting */
- s16 volume; /**< volume, range -114 to 12 dB */
- enum drx_aud_avc_mode avc_mode; /**< AVC auto volume control mode */
- u16 avc_ref_level; /**< AVC reference level */
+ bool mute; /*< mute overrides volume setting */
+ s16 volume; /*< volume, range -114 to 12 dB */
+ enum drx_aud_avc_mode avc_mode; /*< AVC auto volume control mode */
+ u16 avc_ref_level; /*< AVC reference level */
enum drx_aud_avc_max_gain avc_max_gain;
- /**< AVC max gain selection */
+ /*< AVC max gain selection */
enum drx_aud_avc_max_atten avc_max_atten;
- /**< AVC max attenuation selection */
- s16 strength_left; /**< quasi-peak, left speaker */
- s16 strength_right; /**< quasi-peak, right speaker */
+ /*< AVC max attenuation selection */
+ s16 strength_left; /*< quasi-peak, left speaker */
+ s16 strength_right; /*< quasi-peak, right speaker */
};
/* DRX_CFG_I2S_OUTPUT - struct drx_cfg_i2s_output - set/get */
-/**
+/*
* \enum enum drxi2s_mode * \brief I2S output mode.
*/
enum drxi2s_mode {
- DRX_I2S_MODE_MASTER, /**< I2S is in master mode */
- DRX_I2S_MODE_SLAVE /**< I2S is in slave mode */
+ DRX_I2S_MODE_MASTER, /*< I2S is in master mode */
+ DRX_I2S_MODE_SLAVE /*< I2S is in slave mode */
};
-/**
+/*
* \enum enum drxi2s_word_length * \brief Width of I2S data.
*/
enum drxi2s_word_length {
- DRX_I2S_WORDLENGTH_32 = 0,/**< I2S data is 32 bit wide */
- DRX_I2S_WORDLENGTH_16 = 1 /**< I2S data is 16 bit wide */
+ DRX_I2S_WORDLENGTH_32 = 0,/*< I2S data is 32 bit wide */
+ DRX_I2S_WORDLENGTH_16 = 1 /*< I2S data is 16 bit wide */
};
-/**
+/*
* \enum enum drxi2s_format * \brief Data wordstrobe alignment for I2S.
*/
enum drxi2s_format {
DRX_I2S_FORMAT_WS_WITH_DATA,
- /**< I2S data and wordstrobe are aligned */
+ /*< I2S data and wordstrobe are aligned */
DRX_I2S_FORMAT_WS_ADVANCED
- /**< I2S data one cycle after wordstrobe */
+ /*< I2S data one cycle after wordstrobe */
};
-/**
+/*
* \enum enum drxi2s_polarity * \brief Polarity of I2S data.
*/
enum drxi2s_polarity {
- DRX_I2S_POLARITY_RIGHT,/**< wordstrobe - right high, left low */
- DRX_I2S_POLARITY_LEFT /**< wordstrobe - right low, left high */
+ DRX_I2S_POLARITY_RIGHT,/*< wordstrobe - right high, left low */
+ DRX_I2S_POLARITY_LEFT /*< wordstrobe - right low, left high */
};
-/**
+/*
* \struct struct drx_cfg_i2s_output * \brief I2S output configuration.
*/
struct drx_cfg_i2s_output {
- bool output_enable; /**< I2S output enable */
- u32 frequency; /**< range from 8000-48000 Hz */
- enum drxi2s_mode mode; /**< I2S mode, master or slave */
+ bool output_enable; /*< I2S output enable */
+ u32 frequency; /*< range from 8000-48000 Hz */
+ enum drxi2s_mode mode; /*< I2S mode, master or slave */
enum drxi2s_word_length word_length;
- /**< I2S wordlength, 16 or 32 bits */
- enum drxi2s_polarity polarity;/**< I2S wordstrobe polarity */
- enum drxi2s_format format; /**< I2S wordstrobe delay to data */
+ /*< I2S wordlength, 16 or 32 bits */
+ enum drxi2s_polarity polarity;/*< I2S wordstrobe polarity */
+ enum drxi2s_format format; /*< I2S wordstrobe delay to data */
};
/* ------------------------------expert interface-----------------------------*/
-/**
+/*
* /enum enum drx_aud_fm_deemphasis * setting for FM-Deemphasis in audio demodulator.
*
*/
@@ -1531,7 +1531,7 @@ struct drx_version_list {
DRX_AUD_FM_DEEMPH_OFF
};
-/**
+/*
* /enum DRXAudDeviation_t
* setting for deviation mode in audio demodulator.
*
@@ -1541,7 +1541,7 @@ struct drx_version_list {
DRX_AUD_DEVIATION_HIGH
};
-/**
+/*
* /enum enum drx_no_carrier_option * setting for carrier, mute/noise.
*
*/
@@ -1550,7 +1550,7 @@ struct drx_version_list {
DRX_NO_CARRIER_NOISE
};
-/**
+/*
* \enum DRXAudAutoSound_t
* \brief Automatic Sound
*/
@@ -1560,7 +1560,7 @@ struct drx_version_list {
DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF
};
-/**
+/*
* \enum DRXAudASSThres_t
* \brief Automatic Sound Select Thresholds
*/
@@ -1570,7 +1570,7 @@ struct drx_version_list {
u16 nicam; /* Nicam Threshold for ASS configuration */
};
-/**
+/*
* \struct struct drx_aud_carrier * \brief Carrier detection related parameters
*/
struct drx_aud_carrier {
@@ -1580,7 +1580,7 @@ struct drx_version_list {
s32 dco; /* frequency adjustment (A) */
};
-/**
+/*
* \struct struct drx_cfg_aud_carriers * \brief combining carrier A & B to one struct
*/
struct drx_cfg_aud_carriers {
@@ -1588,7 +1588,7 @@ struct drx_version_list {
struct drx_aud_carrier b;
};
-/**
+/*
* /enum enum drx_aud_i2s_src * Selection of audio source
*/
enum drx_aud_i2s_src {
@@ -1597,19 +1597,19 @@ struct drx_version_list {
DRX_AUD_SRC_STEREO_OR_A,
DRX_AUD_SRC_STEREO_OR_B};
-/**
+/*
* \enum enum drx_aud_i2s_matrix * \brief Used for selecting I2S output.
*/
enum drx_aud_i2s_matrix {
DRX_AUD_I2S_MATRIX_A_MONO,
- /**< A sound only, stereo or mono */
+ /*< A sound only, stereo or mono */
DRX_AUD_I2S_MATRIX_B_MONO,
- /**< B sound only, stereo or mono */
+ /*< B sound only, stereo or mono */
DRX_AUD_I2S_MATRIX_STEREO,
- /**< A+B sound, transparant */
- DRX_AUD_I2S_MATRIX_MONO /**< A+B mixed to mono sum, (L+R)/2 */};
+ /*< A+B sound, transparant */
+ DRX_AUD_I2S_MATRIX_MONO /*< A+B mixed to mono sum, (L+R)/2 */};
-/**
+/*
* /enum enum drx_aud_fm_matrix * setting for FM-Matrix in audio demodulator.
*
*/
@@ -1620,7 +1620,7 @@ struct drx_version_list {
DRX_AUD_FM_MATRIX_SOUND_A,
DRX_AUD_FM_MATRIX_SOUND_B};
-/**
+/*
* \struct DRXAudMatrices_t
* \brief Mixer settings
*/
@@ -1630,22 +1630,22 @@ struct drx_cfg_aud_mixer {
enum drx_aud_fm_matrix matrix_fm;
};
-/**
+/*
* \enum DRXI2SVidSync_t
* \brief Audio/video synchronization, interacts with I2S mode.
* AUTO_1 and AUTO_2 are for automatic video standard detection with preference
* for NTSC or Monochrome, because the frequencies are too close (59.94 & 60 Hz)
*/
enum drx_cfg_aud_av_sync {
- DRX_AUD_AVSYNC_OFF,/**< audio/video synchronization is off */
+ DRX_AUD_AVSYNC_OFF,/*< audio/video synchronization is off */
DRX_AUD_AVSYNC_NTSC,
- /**< it is an NTSC system */
+ /*< it is an NTSC system */
DRX_AUD_AVSYNC_MONOCHROME,
- /**< it is a MONOCHROME system */
+ /*< it is a MONOCHROME system */
DRX_AUD_AVSYNC_PAL_SECAM
- /**< it is a PAL/SECAM system */};
+ /*< it is a PAL/SECAM system */};
-/**
+/*
* \struct struct drx_cfg_aud_prescale * \brief Prescalers
*/
struct drx_cfg_aud_prescale {
@@ -1653,7 +1653,7 @@ struct drx_cfg_aud_prescale {
s16 nicam_gain;
};
-/**
+/*
* \struct struct drx_aud_beep * \brief Beep
*/
struct drx_aud_beep {
@@ -1662,14 +1662,14 @@ struct drx_aud_beep {
bool mute;
};
-/**
+/*
* \enum enum drx_aud_btsc_detect * \brief BTSC detetcion mode
*/
enum drx_aud_btsc_detect {
DRX_BTSC_STEREO,
DRX_BTSC_MONO_AND_SAP};
-/**
+/*
* \struct struct drx_aud_data * \brief Audio data structure
*/
struct drx_aud_data {
@@ -1692,7 +1692,7 @@ struct drx_aud_data {
bool rds_data_present;
};
-/**
+/*
* \enum enum drx_qam_lock_range * \brief QAM lock range mode
*/
enum drx_qam_lock_range {
@@ -1782,7 +1782,7 @@ struct drx_aud_data {
u32 wdata, /* data to write */
u32 *rdata); /* data to read */
-/**
+/*
* \struct struct drx_access_func * \brief Interface to an access protocol.
*/
struct drx_access_func {
@@ -1811,85 +1811,85 @@ struct drx_reg_dump {
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* \struct struct drx_common_attr * \brief Set of common attributes, shared by all DRX devices.
*/
struct drx_common_attr {
/* Microcode (firmware) attributes */
- char *microcode_file; /**< microcode filename */
+ char *microcode_file; /*< microcode filename */
bool verify_microcode;
- /**< Use microcode verify or not. */
+ /*< Use microcode verify or not. */
struct drx_mc_version_rec mcversion;
- /**< Version record of microcode from file */
+ /*< Version record of microcode from file */
/* Clocks and tuner attributes */
s32 intermediate_freq;
- /**< IF,if tuner instance not used. (kHz)*/
+ /*< IF,if tuner instance not used. (kHz)*/
s32 sys_clock_freq;
- /**< Systemclock frequency. (kHz) */
+ /*< Systemclock frequency. (kHz) */
s32 osc_clock_freq;
- /**< Oscillator clock frequency. (kHz) */
+ /*< Oscillator clock frequency. (kHz) */
s16 osc_clock_deviation;
- /**< Oscillator clock deviation. (ppm) */
+ /*< Oscillator clock deviation. (ppm) */
bool mirror_freq_spect;
- /**< Mirror IF frequency spectrum or not.*/
+ /*< Mirror IF frequency spectrum or not.*/
/* Initial MPEG output attributes */
struct drx_cfg_mpeg_output mpeg_cfg;
- /**< MPEG configuration */
+ /*< MPEG configuration */
- bool is_opened; /**< if true instance is already opened. */
+ bool is_opened; /*< if true instance is already opened. */
/* Channel scan */
struct drx_scan_param *scan_param;
- /**< scan parameters */
+ /*< scan parameters */
u16 scan_freq_plan_index;
- /**< next index in freq plan */
+ /*< next index in freq plan */
s32 scan_next_frequency;
- /**< next freq to scan */
- bool scan_ready; /**< scan ready flag */
- u32 scan_max_channels;/**< number of channels in freqplan */
+ /*< next freq to scan */
+ bool scan_ready; /*< scan ready flag */
+ u32 scan_max_channels;/*< number of channels in freqplan */
u32 scan_channels_scanned;
- /**< number of channels scanned */
+ /*< number of channels scanned */
/* Channel scan - inner loop: demod related */
drx_scan_func_t scan_function;
- /**< function to check channel */
+ /*< function to check channel */
/* Channel scan - inner loop: SYSObj related */
- void *scan_context; /**< Context Pointer of SYSObj */
+ void *scan_context; /*< Context Pointer of SYSObj */
/* Channel scan - parameters for default DTV scan function in core driver */
u16 scan_demod_lock_timeout;
- /**< millisecs to wait for lock */
+ /*< millisecs to wait for lock */
enum drx_lock_status scan_desired_lock;
- /**< lock requirement for channel found */
+ /*< lock requirement for channel found */
/* scan_active can be used by SetChannel to decide how to program the tuner,
fast or slow (but stable). Usually fast during scan. */
- bool scan_active; /**< true when scan routines are active */
+ bool scan_active; /*< true when scan routines are active */
/* Power management */
enum drx_power_mode current_power_mode;
- /**< current power management mode */
+ /*< current power management mode */
/* Tuner */
- u8 tuner_port_nr; /**< nr of I2C port to wich tuner is */
+ u8 tuner_port_nr; /*< nr of I2C port to wich tuner is */
s32 tuner_min_freq_rf;
- /**< minimum RF input frequency, in kHz */
+ /*< minimum RF input frequency, in kHz */
s32 tuner_max_freq_rf;
- /**< maximum RF input frequency, in kHz */
- bool tuner_rf_agc_pol; /**< if true invert RF AGC polarity */
- bool tuner_if_agc_pol; /**< if true invert IF AGC polarity */
- bool tuner_slow_mode; /**< if true invert IF AGC polarity */
+ /*< maximum RF input frequency, in kHz */
+ bool tuner_rf_agc_pol; /*< if true invert RF AGC polarity */
+ bool tuner_if_agc_pol; /*< if true invert IF AGC polarity */
+ bool tuner_slow_mode; /*< if true invert IF AGC polarity */
struct drx_channel current_channel;
- /**< current channel parameters */
+ /*< current channel parameters */
enum drx_standard current_standard;
- /**< current standard selection */
+ /*< current standard selection */
enum drx_standard prev_standard;
- /**< previous standard selection */
+ /*< previous standard selection */
enum drx_standard di_cache_standard;
- /**< standard in DI cache if available */
- bool use_bootloader; /**< use bootloader in open */
- u32 capabilities; /**< capabilities flags */
- u32 product_id; /**< product ID inc. metal fix number */};
+ /*< standard in DI cache if available */
+ bool use_bootloader; /*< use bootloader in open */
+ u32 capabilities; /*< capabilities flags */
+ u32 product_id; /*< product ID inc. metal fix number */};
/*
* Generic functions for DRX devices.
@@ -1897,16 +1897,16 @@ struct drx_reg_dump {
struct drx_demod_instance;
-/**
+/*
* \struct struct drx_demod_instance * \brief Top structure of demodulator instance.
*/
struct drx_demod_instance {
- /**< data access protocol functions */
+ /*< data access protocol functions */
struct i2c_device_addr *my_i2c_dev_addr;
- /**< i2c address and device identifier */
+ /*< i2c address and device identifier */
struct drx_common_attr *my_common_attr;
- /**< common DRX attributes */
- void *my_ext_attr; /**< device specific attributes */
+ /*< common DRX attributes */
+ void *my_ext_attr; /*< device specific attributes */
/* generic demodulator data */
struct i2c_adapter *i2c;
@@ -2195,7 +2195,7 @@ Conversion from enum values to human readable form.
Access macros
-------------------------------------------------------------------------*/
-/**
+/*
* \brief Create a compilable reference to the microcode attribute
* \param d pointer to demod instance
*
@@ -2229,7 +2229,7 @@ Access macros
#define DRX_ATTR_I2CDEVID(d) ((d)->my_i2c_dev_addr->i2c_dev_id)
#define DRX_ISMCVERTYPE(x) ((x) == AUX_VER_RECORD)
-/**************************/
+/*************************/
/* Macros with device-specific handling are converted to CFG functions */
@@ -2285,7 +2285,7 @@ Access macros
#define DRX_GET_QAM_LOCKRANGE(d, x) DRX_ACCESSMACRO_GET((d), (x), \
DRX_XS_CFG_QAM_LOCKRANGE, enum drx_qam_lock_range, DRX_UNKNOWN)
-/**
+/*
* \brief Macro to check if std is an ATV standard
* \retval true std is an ATV standard
* \retval false std is an ATV standard
@@ -2298,7 +2298,7 @@ Access macros
((std) == DRX_STANDARD_NTSC) || \
((std) == DRX_STANDARD_FM))
-/**
+/*
* \brief Macro to check if std is an QAM standard
* \retval true std is an QAM standards
* \retval false std is an QAM standards
@@ -2308,14 +2308,14 @@ Access macros
((std) == DRX_STANDARD_ITU_C) || \
((std) == DRX_STANDARD_ITU_D))
-/**
+/*
* \brief Macro to check if std is VSB standard
* \retval true std is VSB standard
* \retval false std is not VSB standard
*/
#define DRX_ISVSBSTD(std) ((std) == DRX_STANDARD_8VSB)
-/**
+/*
* \brief Macro to check if std is DVBT standard
* \retval true std is DVBT standard
* \retval false std is not DVBT standard
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 499ccff557bf..8cbd8cc21059 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -73,7 +73,7 @@ INCLUDE FILES
#define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
-/**
+/*
* \brief Maximum u32 value.
*/
#ifndef MAX_U32
@@ -100,8 +100,8 @@ INCLUDE FILES
#ifndef OOB_DRX_DRIVE_STRENGTH
#define OOB_DRX_DRIVE_STRENGTH 0x02
#endif
-/**** START DJCOMBO patches to DRXJ registermap constants *********************/
-/**** registermap 200706071303 from drxj **************************************/
+/*** START DJCOMBO patches to DRXJ registermap constants *********************/
+/*** registermap 200706071303 from drxj **************************************/
#define ATV_TOP_CR_AMP_TH_FM 0x0
#define ATV_TOP_CR_AMP_TH_L 0xA
#define ATV_TOP_CR_AMP_TH_LP 0xA
@@ -188,7 +188,7 @@ INCLUDE FILES
#define IQM_RC_ADJ_SEL_B_OFF 0x0
#define IQM_RC_ADJ_SEL_B_QAM 0x1
#define IQM_RC_ADJ_SEL_B_VSB 0x2
-/**** END DJCOMBO patches to DRXJ registermap *********************************/
+/*** END DJCOMBO patches to DRXJ registermap *********************************/
#include "drx_driver_version.h"
@@ -208,25 +208,25 @@ DEFINES
#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
#endif
-/**
+/*
* \def DRXJ_DEF_I2C_ADDR
* \brief Default I2C address of a demodulator instance.
*/
#define DRXJ_DEF_I2C_ADDR (0x52)
-/**
+/*
* \def DRXJ_DEF_DEMOD_DEV_ID
* \brief Default device identifier of a demodultor instance.
*/
#define DRXJ_DEF_DEMOD_DEV_ID (1)
-/**
+/*
* \def DRXJ_SCAN_TIMEOUT
* \brief Timeout value for waiting on demod lock during channel scan (millisec).
*/
#define DRXJ_SCAN_TIMEOUT 1000
-/**
+/*
* \def HI_I2C_DELAY
* \brief HI timing delay for I2C timing (in nano seconds)
*
@@ -234,7 +234,7 @@ DEFINES
*/
#define HI_I2C_DELAY 42
-/**
+/*
* \def HI_I2C_BRIDGE_DELAY
* \brief HI timing delay for I2C timing (in nano seconds)
*
@@ -242,13 +242,13 @@ DEFINES
*/
#define HI_I2C_BRIDGE_DELAY 750
-/**
+/*
* \brief Time Window for MER and SER Measurement in Units of Segment duration.
*/
#define VSB_TOP_MEASUREMENT_PERIOD 64
#define SYMBOLS_PER_SEGMENT 832
-/**
+/*
* \brief bit rate and segment rate constants used for SER and BER.
*/
/* values taken from the QAM microcode */
@@ -260,21 +260,21 @@ DEFINES
#define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
#define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
#define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
-/**
+/*
* \brief Min supported symbolrates.
*/
#ifndef DRXJ_QAM_SYMBOLRATE_MIN
#define DRXJ_QAM_SYMBOLRATE_MIN (520000)
#endif
-/**
+/*
* \brief Max supported symbolrates.
*/
#ifndef DRXJ_QAM_SYMBOLRATE_MAX
#define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
#endif
-/**
+/*
* \def DRXJ_QAM_MAX_WAITTIME
* \brief Maximal wait time for QAM auto constellation in ms
*/
@@ -290,7 +290,7 @@ DEFINES
#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
#endif
-/**
+/*
* \def SCU status and results
* \brief SCU
*/
@@ -299,7 +299,7 @@ DEFINES
#define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
#define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
-/**
+/*
* \def DRX_AUD_MAX_DEVIATION
* \brief Needed for calculation of prescale feature in AUD
*/
@@ -307,14 +307,14 @@ DEFINES
#define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
#endif
-/**
+/*
* \brief Needed for calculation of NICAM prescale feature in AUD
*/
#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
#define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
#endif
-/**
+/*
* \brief Needed for calculation of NICAM prescale feature in AUD
*/
#ifndef DRXJ_AUD_MAX_WAITTIME
@@ -371,21 +371,21 @@ DEFINES
/*============================================================================*/
/*=== GLOBAL VARIABLEs =======================================================*/
/*============================================================================*/
-/**
+/*
*/
-/**
+/*
* \brief Temporary register definitions.
* (register definitions that are not yet available in register master)
*/
-/******************************************************************************/
+/*****************************************************************************/
/* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
/* RAM adresses directly. This must be READ ONLY to avoid problems. */
/* Writing to the interface adresses is more than only writing the RAM */
/* locations */
-/******************************************************************************/
-/**
+/*****************************************************************************/
+/*
* \brief RAM location of MODUS registers
*/
#define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
@@ -394,13 +394,13 @@ DEFINES
#define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
#define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
-/**
+/*
* \brief RAM location of I2S config registers
*/
#define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
#define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
-/**
+/*
* \brief RAM location of DCO config registers
*/
#define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
@@ -408,20 +408,20 @@ DEFINES
#define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
#define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
-/**
+/*
* \brief RAM location of Threshold registers
*/
#define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
#define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
#define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
-/**
+/*
* \brief RAM location of Carrier Threshold registers
*/
#define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
#define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
-/**
+/*
* \brief FM Matrix register fix
*/
#ifdef AUD_DEM_WR_FM_MATRIX__A
@@ -430,7 +430,7 @@ DEFINES
#define AUD_DEM_WR_FM_MATRIX__A 0x105006F
/*============================================================================*/
-/**
+/*
* \brief Defines required for audio
*/
#define AUD_VOLUME_ZERO_DB 115
@@ -443,14 +443,14 @@ DEFINES
#define AUD_I2S_FREQUENCY_MIN 12000UL
#define AUD_RDS_ARRAY_SIZE 18
-/**
+/*
* \brief Needed for calculation of prescale feature in AUD
*/
#ifndef DRX_AUD_MAX_FM_DEVIATION
#define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
#endif
-/**
+/*
* \brief Needed for calculation of NICAM prescale feature in AUD
*/
#ifndef DRX_AUD_MAX_NICAM_PRESCALE
@@ -478,7 +478,7 @@ DEFINES
/*=== REGISTER ACCESS MACROS =================================================*/
/*============================================================================*/
-/**
+/*
* This macro is used to create byte arrays for block writes.
* Block writes speed up I2C traffic between host and demod.
* The macro takes care of the required byte order in a 16 bits word.
@@ -486,7 +486,7 @@ DEFINES
*/
#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
((u8)((((u16)x)>>8)&0xFF))
-/**
+/*
* This macro is used to convert byte array to 16 bit register value for block read.
* Block read speed up I2C traffic between host and demod.
* The macro takes care of the required byte order in a 16 bits word.
@@ -501,7 +501,7 @@ DEFINES
/*=== HI COMMAND RELATED DEFINES =============================================*/
/*============================================================================*/
-/**
+/*
* \brief General maximum number of retries for ucode command interfaces
*/
#define DRXJ_MAX_RETRIES (100)
@@ -807,7 +807,7 @@ static struct drxj_data drxj_data_g = {
},
};
-/**
+/*
* \var drxj_default_addr_g
* \brief Default I2C address and device identifier.
*/
@@ -816,7 +816,7 @@ static struct i2c_device_addr drxj_default_addr_g = {
DRXJ_DEF_DEMOD_DEV_ID /* device id */
};
-/**
+/*
* \var drxj_default_comm_attr_g
* \brief Default common attributes of a drxj demodulator instance.
*/
@@ -887,7 +887,7 @@ static struct drx_common_attr drxj_default_comm_attr_g = {
0 /* mfx */
};
-/**
+/*
* \var drxj_default_demod_g
* \brief Default drxj demodulator instance.
*/
@@ -897,7 +897,7 @@ static struct drx_demod_instance drxj_default_demod_g = {
&drxj_data_g /* demod device specific attributes */
};
-/**
+/*
* \brief Default audio data structure for DRK demodulator instance.
*
* This structure is DRXK specific.
@@ -997,7 +997,7 @@ struct drxj_hi_cmd {
/*=== MICROCODE RELATED STRUCTURES ===========================================*/
/*============================================================================*/
-/**
+/*
* struct drxu_code_block_hdr - Structure of the microcode block headers
*
* @addr: Destination address of the data in this block
@@ -1086,7 +1086,7 @@ static u32 frac28(u32 N, u32 D)
return Q1;
}
-/**
+/*
* \fn u32 log1_times100( u32 x)
* \brief Compute: 100*log10(x)
* \param x 32 bits
@@ -1198,7 +1198,7 @@ static u32 log1_times100(u32 x)
}
-/**
+/*
* \fn u32 frac_times1e6( u16 N, u32 D)
* \brief Compute: (N/D) * 1000000.
* \param N nominator 16-bits.
@@ -1235,7 +1235,7 @@ static u32 frac_times1e6(u32 N, u32 D)
/*============================================================================*/
-/**
+/*
* \brief Values for NICAM prescaler gain. Computed from dB to integer
* and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
*
@@ -1280,7 +1280,7 @@ static const u16 nicam_presc_table_val[43] = {
#define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
/*============================================================================*/
-/**
+/*
* \fn bool is_handled_by_aud_tr_if( u32 addr )
* \brief Check if this address is handled by the audio token ring interface.
* \param addr
@@ -1386,7 +1386,7 @@ int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
/*============================================================================*/
-/******************************
+/*****************************
*
* int drxdap_fasi_read_block (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1498,7 +1498,7 @@ static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
}
-/******************************
+/*****************************
*
* int drxdap_fasi_read_reg16 (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1531,7 +1531,7 @@ static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
return rc;
}
-/******************************
+/*****************************
*
* int drxdap_fasi_read_reg32 (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1566,7 +1566,7 @@ static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
return rc;
}
-/******************************
+/*****************************
*
* int drxdap_fasi_write_block (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1705,7 +1705,7 @@ static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
return first_err;
}
-/******************************
+/*****************************
*
* int drxdap_fasi_write_reg16 (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1734,7 +1734,7 @@ static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
}
-/******************************
+/*****************************
*
* int drxdap_fasi_read_modify_write_reg16 (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1778,7 +1778,7 @@ static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
return rc;
}
-/******************************
+/*****************************
*
* int drxdap_fasi_write_reg32 (
* struct i2c_device_addr *dev_addr, -- address of I2C device
@@ -1811,7 +1811,7 @@ static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
/*============================================================================*/
-/**
+/*
* \fn int drxj_dap_rm_write_reg16short
* \brief Read modify write 16 bits audio register using short format only.
* \param dev_addr
@@ -1890,7 +1890,7 @@ static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
/*============================================================================*/
-/**
+/*
* \fn int drxj_dap_read_aud_reg16
* \brief Read 16 bits audio register
* \param dev_addr
@@ -1997,7 +1997,7 @@ static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
}
/*============================================================================*/
-/**
+/*
* \fn int drxj_dap_write_aud_reg16
* \brief Write 16 bits audio register
* \param dev_addr
@@ -2086,7 +2086,7 @@ static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
#define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
#define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
-/**
+/*
* \fn int drxj_dap_atomic_read_write_block()
* \brief Basic access routine for atomic read or write access
* \param dev_addr pointer to i2c dev address
@@ -2168,7 +2168,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int drxj_dap_atomic_read_reg32()
* \brief Atomic read of 32 bits words
*/
@@ -2215,7 +2215,7 @@ int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* \fn int hi_cfg_command()
* \brief Configure HI with settings stored in the demod structure.
* \param demod Demodulator.
@@ -2258,7 +2258,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int hi_command()
* \brief Configure HI with settings stored in the demod structure.
* \param dev_addr I2C address.
@@ -2369,7 +2369,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int init_hi( const struct drx_demod_instance *demod )
* \brief Initialise and configurate HI.
* \param demod pointer to demod data.
@@ -2450,7 +2450,7 @@ rw_error:
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* \fn int get_device_capabilities()
* \brief Get and store device capabilities.
* \param demod Pointer to demodulator instance.
@@ -2656,7 +2656,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int power_up_device()
* \brief Power up device.
* \param demod Pointer to demodulator instance.
@@ -2710,7 +2710,7 @@ static int power_up_device(struct drx_demod_instance *demod)
/*----------------------------------------------------------------------------*/
/* MPEG Output Configuration Functions - begin */
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int ctrl_set_cfg_mpeg_output()
* \brief Set MPEG output configuration of the device.
* \param devmod Pointer to demodulator instance.
@@ -3356,7 +3356,7 @@ rw_error:
/* miscellaneous configurations - begin */
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int set_mpegtei_handling()
* \brief Activate MPEG TEI handling settings.
* \param devmod Pointer to demodulator instance.
@@ -3429,7 +3429,7 @@ rw_error:
}
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int bit_reverse_mpeg_output()
* \brief Set MPEG output bit-endian settings.
* \param devmod Pointer to demodulator instance.
@@ -3472,7 +3472,7 @@ rw_error:
}
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int set_mpeg_start_width()
* \brief Set MPEG start width.
* \param devmod Pointer to demodulator instance.
@@ -3522,7 +3522,7 @@ rw_error:
/*----------------------------------------------------------------------------*/
/* UIO Configuration Functions - begin */
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int ctrl_set_uio_cfg()
* \brief Configure modus oprandi UIO.
* \param demod Pointer to demodulator instance.
@@ -3659,7 +3659,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int ctrl_uio_write()
* \brief Write to a UIO.
* \param demod Pointer to demodulator instance.
@@ -3868,7 +3868,7 @@ rw_error:
/*----------------------------------------------------------------------------*/
/* I2C Bridge Functions - begin */
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int ctrl_i2c_bridge()
* \brief Open or close the I2C switch to tuner.
* \param demod Pointer to demodulator instance.
@@ -3903,7 +3903,7 @@ ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
/*----------------------------------------------------------------------------*/
/* Smart antenna Functions - begin */
/*----------------------------------------------------------------------------*/
-/**
+/*
* \fn int smart_ant_init()
* \brief Initialize Smart Antenna.
* \param pointer to struct drx_demod_instance.
@@ -4116,7 +4116,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
* \brief Basic access routine for SCU atomic read or write access
* \param dev_addr pointer to i2c dev address
@@ -4188,7 +4188,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int DRXJ_DAP_AtomicReadReg16()
* \brief Atomic read of 16 bits words
*/
@@ -4216,7 +4216,7 @@ int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
}
/*============================================================================*/
-/**
+/*
* \fn int drxj_dap_scu_atomic_write_reg16()
* \brief Atomic read of 16 bits words
*/
@@ -4237,7 +4237,7 @@ int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
}
/* -------------------------------------------------------------------------- */
-/**
+/*
* \brief Measure result of ADC synchronisation
* \param demod demod instance
* \param count (returned) count
@@ -4297,7 +4297,7 @@ rw_error:
return rc;
}
-/**
+/*
* \brief Synchronize analog and digital clock domains
* \param demod demod instance
* \return int.
@@ -4365,7 +4365,7 @@ rw_error:
/*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* \fn int init_agc ()
* \brief Initialize AGC for all standards.
* \param demod instance of demodulator.
@@ -4741,7 +4741,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_frequency ()
* \brief Set frequency shift.
* \param demod instance of demodulator.
@@ -4839,7 +4839,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int get_acc_pkt_err()
* \brief Retrieve signal strength for VSB and QAM.
* \param demod Pointer to demod instance
@@ -4891,7 +4891,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_agc_rf ()
* \brief Configure RF AGC
* \param demod instance of demodulator.
@@ -5105,7 +5105,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_agc_if ()
* \brief Configure If AGC
* \param demod instance of demodulator.
@@ -5334,7 +5334,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_iqm_af ()
* \brief Configure IQM AF registers
* \param demod instance of demodulator.
@@ -5380,7 +5380,7 @@ rw_error:
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* \fn int power_down_vsb ()
* \brief Powr down QAM related blocks.
* \param demod instance of demodulator.
@@ -5478,7 +5478,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_vsb_leak_n_gain ()
* \brief Set ATSC demod.
* \param demod instance of demodulator.
@@ -5694,7 +5694,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_vsb()
* \brief Set 8VSB demod.
* \param demod instance of demodulator.
@@ -6200,7 +6200,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
* \brief Get the values of packet error in 8VSB mode
* \return Error code
@@ -6239,7 +6239,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
* \brief Get the values of ber in VSB mode
* \return Error code
@@ -6284,7 +6284,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
* \brief Get the values of ber in VSB mode
* \return Error code
@@ -6306,7 +6306,7 @@ static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
return 0;
}
-/**
+/*
* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
* \brief Get the values of MER
* \return Error code
@@ -6340,7 +6340,7 @@ rw_error:
/*============================================================================*/
/*============================================================================*/
-/**
+/*
* \fn int power_down_qam ()
* \brief Powr down QAM related blocks.
* \param demod instance of demodulator.
@@ -6444,7 +6444,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_qam_measurement ()
* \brief Setup of the QAM Measuremnt intervals for signal quality
* \param demod instance of demod.
@@ -6656,7 +6656,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_qam16 ()
* \brief QAM16 specific setup
* \param demod instance of demod.
@@ -6891,7 +6891,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_qam32 ()
* \brief QAM32 specific setup
* \param demod instance of demod.
@@ -7126,7 +7126,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_qam64 ()
* \brief QAM64 specific setup
* \param demod instance of demod.
@@ -7362,7 +7362,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_qam128 ()
* \brief QAM128 specific setup
* \param demod: instance of demod.
@@ -7597,7 +7597,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int set_qam256 ()
* \brief QAM256 specific setup
* \param demod: instance of demod.
@@ -7835,7 +7835,7 @@ rw_error:
#define QAM_SET_OP_CONSTELLATION 0x2
#define QAM_SET_OP_SPECTRUM 0X4
-/**
+/*
* \fn int set_qam ()
* \brief Set QAM demod.
* \param demod: instance of demod.
@@ -8845,7 +8845,7 @@ rw_error:
#define DEMOD_LOCKED 0x1
#define SYNC_FLIPPED 0x2
#define SPEC_MIRRORED 0x4
-/**
+/*
* \fn int qam64auto ()
* \brief auto do sync pattern switching and mirroring.
* \param demod: instance of demod.
@@ -8993,7 +8993,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int qam256auto ()
* \brief auto do sync pattern switching and mirroring.
* \param demod: instance of demod.
@@ -9077,7 +9077,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_qam_channel ()
* \brief Set QAM channel according to the requested constellation.
* \param demod: instance of demod.
@@ -9284,7 +9284,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
* \brief Get RS error count in QAM mode (used for post RS BER calculation)
* \return Error code
@@ -9355,7 +9355,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int get_sig_strength()
* \brief Retrieve signal strength for VSB and QAM.
* \param demod Pointer to demod instance
@@ -9435,7 +9435,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int ctrl_get_qam_sig_quality()
* \brief Retrieve QAM signal quality from device.
* \param devmod Pointer to demodulator instance.
@@ -9721,7 +9721,7 @@ rw_error:
*/
/* -------------------------------------------------------------------------- */
-/**
+/*
* \fn int power_down_atv ()
* \brief Power down ATV.
* \param demod instance of demodulator
@@ -9822,7 +9822,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \brief Power up AUD.
* \param demod instance of demodulator
* \return int.
@@ -9850,7 +9850,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int set_orx_nsu_aox()
* \brief Configure OrxNsuAox for OOB
* \param demod instance of demodulator.
@@ -9884,7 +9884,7 @@ rw_error:
return rc;
}
-/**
+/*
* \fn int ctrl_set_oob()
* \brief Set OOB channel to be used.
* \param demod instance of demodulator
@@ -9986,9 +9986,9 @@ static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_par
20;
}
- /*********/
+ /********/
/* Stop */
- /*********/
+ /********/
rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
if (rc != 0) {
pr_err("error %d\n", rc);
@@ -10004,9 +10004,9 @@ static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_par
pr_err("error %d\n", rc);
goto rw_error;
}
- /*********/
+ /********/
/* Reset */
- /*********/
+ /********/
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_RESET;
scu_cmd.parameter_len = 0;
@@ -10017,9 +10017,9 @@ static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_par
pr_err("error %d\n", rc);
goto rw_error;
}
- /***********/
+ /**********/
/* SET_ENV */
- /***********/
+ /**********/
/* set frequency, spectrum inversion and data rate */
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
@@ -10376,9 +10376,9 @@ static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_par
pr_err("error %d\n", rc);
goto rw_error;
}
- /*********/
+ /********/
/* Start */
- /*********/
+ /********/
scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
| SCU_RAM_COMMAND_CMD_DEMOD_START;
scu_cmd.parameter_len = 0;
@@ -10419,7 +10419,7 @@ rw_error:
/*=============================================================================
===== ctrl_set_channel() ==========================================================
===========================================================================*/
-/**
+/*
* \fn int ctrl_set_channel()
* \brief Select a new transmission channel.
* \param demod instance of demod.
@@ -10652,7 +10652,7 @@ rw_error:
===== SigQuality() ==========================================================
===========================================================================*/
-/**
+/*
* \fn int ctrl_sig_quality()
* \brief Retrieve signal quality form device.
* \param devmod Pointer to demodulator instance.
@@ -10768,7 +10768,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int ctrl_lock_status()
* \brief Retrieve lock status .
* \param dev_addr Pointer to demodulator device address.
@@ -10856,7 +10856,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int ctrl_set_standard()
* \brief Set modulation standard to be used.
* \param standard Modulation standard.
@@ -11012,7 +11012,7 @@ static void drxj_reset_mode(struct drxj_data *ext_attr)
ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
}
-/**
+/*
* \fn int ctrl_power_mode()
* \brief Set the power mode of the device to the specified power mode
* \param demod Pointer to demodulator instance.
@@ -11171,7 +11171,7 @@ rw_error:
/*== CTRL Set/Get Config related functions ===================================*/
/*============================================================================*/
-/**
+/*
* \fn int ctrl_set_cfg_pre_saw()
* \brief Set Pre-saw reference.
* \param demod demod instance
@@ -11234,7 +11234,7 @@ rw_error:
/*============================================================================*/
-/**
+/*
* \fn int ctrl_set_cfg_afe_gain()
* \brief Set AFE Gain.
* \param demod demod instance
@@ -11324,7 +11324,7 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
enum drxu_code_action action);
static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
-/**
+/*
* \fn drxj_open()
* \brief Open the demod instance, configure device, configure drxdriver
* \return Status_t Return status.
@@ -11543,7 +11543,7 @@ rw_error:
}
/*============================================================================*/
-/**
+/*
* \fn drxj_close()
* \brief Close the demod instance, power down the device
* \return Status_t Return status.
@@ -11594,7 +11594,7 @@ rw_error:
* Microcode related functions
*/
-/**
+/*
* drx_u_code_compute_crc - Compute CRC of block of microcode data.
* @block_data: Pointer to microcode data.
* @nr_words: Size of microcode block (number of 16 bits words).
@@ -11622,7 +11622,7 @@ static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
return (u16)(crc_word >> 16);
}
-/**
+/*
* drx_check_firmware - checks if the loaded firmware is valid
*
* @demod: demod structure
@@ -11708,7 +11708,7 @@ eof:
return -EINVAL;
}
-/**
+/*
* drx_ctrl_u_code - Handle microcode upload or verify.
* @dev_addr: Address of device.
* @mc_info: Pointer to information about microcode data.
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.h b/drivers/media/dvb-frontends/drx39xyj/drxj.h
index 6c5b8f78f9f6..d3ee1c23bb2f 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.h
@@ -69,15 +69,15 @@ TYPEDEFS
struct drxjscu_cmd {
u16 command;
- /**< Command number */
+ /*< Command number */
u16 parameter_len;
- /**< Data length in byte */
+ /*< Data length in byte */
u16 result_len;
- /**< result length in byte */
+ /*< result length in byte */
u16 *parameter;
- /**< General purpous param */
+ /*< General purpous param */
u16 *result;
- /**< General purpous param */};
+ /*< General purpous param */};
/*============================================================================*/
/*============================================================================*/
@@ -130,7 +130,7 @@ TYPEDEFS
DRXJ_CFG_MAX /* dummy, never to be used */};
-/**
+/*
* /struct enum drxj_cfg_smart_ant_io * smart antenna i/o.
*/
enum drxj_cfg_smart_ant_io {
@@ -138,7 +138,7 @@ enum drxj_cfg_smart_ant_io {
DRXJ_SMT_ANT_INPUT
};
-/**
+/*
* /struct struct drxj_cfg_smart_ant * Set smart antenna.
*/
struct drxj_cfg_smart_ant {
@@ -146,7 +146,7 @@ enum drxj_cfg_smart_ant_io {
u16 ctrl_data;
};
-/**
+/*
* /struct DRXJAGCSTATUS_t
* AGC status information from the DRXJ-IQM-AF.
*/
@@ -158,7 +158,7 @@ struct drxj_agc_status {
/* DRXJ_CFG_AGC_RF, DRXJ_CFG_AGC_IF */
-/**
+/*
* /struct enum drxj_agc_ctrl_mode * Available AGCs modes in the DRXJ.
*/
enum drxj_agc_ctrl_mode {
@@ -166,7 +166,7 @@ struct drxj_agc_status {
DRX_AGC_CTRL_USER,
DRX_AGC_CTRL_OFF};
-/**
+/*
* /struct struct drxj_cfg_agc * Generic interface for all AGCs present on the DRXJ.
*/
struct drxj_cfg_agc {
@@ -182,7 +182,7 @@ struct drxj_agc_status {
/* DRXJ_CFG_PRE_SAW */
-/**
+/*
* /struct struct drxj_cfg_pre_saw * Interface to configure pre SAW sense.
*/
struct drxj_cfg_pre_saw {
@@ -192,14 +192,14 @@ struct drxj_agc_status {
/* DRXJ_CFG_AFE_GAIN */
-/**
+/*
* /struct struct drxj_cfg_afe_gain * Interface to configure gain of AFE (LNA + PGA).
*/
struct drxj_cfg_afe_gain {
enum drx_standard standard; /* standard to which these settings apply */
u16 gain; /* gain in 0.1 dB steps, DRXJ range 140 .. 335 */};
-/**
+/*
* /struct drxjrs_errors
* Available failure information in DRXJ_FEC_RS.
*
@@ -208,25 +208,25 @@ struct drxj_agc_status {
*/
struct drxjrs_errors {
u16 nr_bit_errors;
- /**< no of pre RS bit errors */
+ /*< no of pre RS bit errors */
u16 nr_symbol_errors;
- /**< no of pre RS symbol errors */
+ /*< no of pre RS symbol errors */
u16 nr_packet_errors;
- /**< no of pre RS packet errors */
+ /*< no of pre RS packet errors */
u16 nr_failures;
- /**< no of post RS failures to decode */
+ /*< no of post RS failures to decode */
u16 nr_snc_par_fail_count;
- /**< no of post RS bit erros */
+ /*< no of post RS bit erros */
};
-/**
+/*
* /struct struct drxj_cfg_vsb_misc * symbol error rate
*/
struct drxj_cfg_vsb_misc {
u32 symb_error;
- /**< symbol error rate sps */};
+ /*< symbol error rate sps */};
-/**
+/*
* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate.
*
*/
@@ -234,7 +234,7 @@ struct drxj_agc_status {
DRXJ_MPEG_START_WIDTH_1CLKCYC,
DRXJ_MPEG_START_WIDTH_8CLKCYC};
-/**
+/*
* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate.
*
*/
@@ -247,20 +247,20 @@ struct drxj_agc_status {
DRXJ_MPEGOUTPUT_CLOCK_RATE_25313K,
DRXJ_MPEGOUTPUT_CLOCK_RATE_21696K};
-/**
+/*
* /struct DRXJCfgMisc_t
* Change TEI bit of MPEG output
* reverse MPEG output bit order
* set MPEG output clock rate
*/
struct drxj_cfg_mpeg_output_misc {
- bool disable_tei_handling; /**< if true pass (not change) TEI bit */
- bool bit_reverse_mpeg_outout; /**< if true, parallel: msb on MD0; serial: lsb out first */
+ bool disable_tei_handling; /*< if true pass (not change) TEI bit */
+ bool bit_reverse_mpeg_outout; /*< if true, parallel: msb on MD0; serial: lsb out first */
enum drxj_mpeg_output_clock_rate mpeg_output_clock_rate;
- /**< set MPEG output clock rate that overwirtes the derived one from symbol rate */
- enum drxj_mpeg_start_width mpeg_start_width; /**< set MPEG output start width */};
+ /*< set MPEG output clock rate that overwirtes the derived one from symbol rate */
+ enum drxj_mpeg_start_width mpeg_start_width; /*< set MPEG output start width */};
-/**
+/*
* /enum enum drxj_xtal_freq * Supported external crystal reference frequency.
*/
enum drxj_xtal_freq {
@@ -269,21 +269,21 @@ struct drxj_agc_status {
DRXJ_XTAL_FREQ_20P25MHZ,
DRXJ_XTAL_FREQ_4MHZ};
-/**
+/*
* /enum enum drxj_xtal_freq * Supported external crystal reference frequency.
*/
enum drxji2c_speed {
DRXJ_I2C_SPEED_400KBPS,
DRXJ_I2C_SPEED_100KBPS};
-/**
+/*
* /struct struct drxj_cfg_hw_cfg * Get hw configuration, such as crystal reference frequency, I2C speed, etc...
*/
struct drxj_cfg_hw_cfg {
enum drxj_xtal_freq xtal_freq;
- /**< crystal reference frequency */
+ /*< crystal reference frequency */
enum drxji2c_speed i2c_speed;
- /**< 100 or 400 kbps */};
+ /*< 100 or 400 kbps */};
/*
* DRXJ_CFG_ATV_MISC
@@ -352,7 +352,7 @@ struct drxj_cfg_oob_misc {
* DRXJ_CFG_ATV_OUTPUT
*/
-/**
+/*
* /enum DRXJAttenuation_t
* Attenuation setting for SIF AGC.
*
@@ -363,7 +363,7 @@ struct drxj_cfg_oob_misc {
DRXJ_SIF_ATTENUATION_6DB,
DRXJ_SIF_ATTENUATION_9DB};
-/**
+/*
* /struct struct drxj_cfg_atv_output * SIF attenuation setting.
*
*/
@@ -398,7 +398,7 @@ struct drxj_cfg_atv_output {
/*============================================================================*/
/*========================================*/
-/**
+/*
* /struct struct drxj_data * DRXJ specific attributes.
*
* Global data container for DRXJ specific data.
@@ -406,93 +406,93 @@ struct drxj_cfg_atv_output {
*/
struct drxj_data {
/* device capabilties (determined during drx_open()) */
- bool has_lna; /**< true if LNA (aka PGA) present */
- bool has_oob; /**< true if OOB supported */
- bool has_ntsc; /**< true if NTSC supported */
- bool has_btsc; /**< true if BTSC supported */
- bool has_smatx; /**< true if mat_tx is available */
- bool has_smarx; /**< true if mat_rx is available */
- bool has_gpio; /**< true if GPIO is available */
- bool has_irqn; /**< true if IRQN is available */
+ bool has_lna; /*< true if LNA (aka PGA) present */
+ bool has_oob; /*< true if OOB supported */
+ bool has_ntsc; /*< true if NTSC supported */
+ bool has_btsc; /*< true if BTSC supported */
+ bool has_smatx; /*< true if mat_tx is available */
+ bool has_smarx; /*< true if mat_rx is available */
+ bool has_gpio; /*< true if GPIO is available */
+ bool has_irqn; /*< true if IRQN is available */
/* A1/A2/A... */
- u8 mfx; /**< metal fix */
+ u8 mfx; /*< metal fix */
/* tuner settings */
- bool mirror_freq_spect_oob;/**< tuner inversion (true = tuner mirrors the signal */
+ bool mirror_freq_spect_oob;/*< tuner inversion (true = tuner mirrors the signal */
/* standard/channel settings */
- enum drx_standard standard; /**< current standard information */
+ enum drx_standard standard; /*< current standard information */
enum drx_modulation constellation;
- /**< current constellation */
- s32 frequency; /**< center signal frequency in KHz */
+ /*< current constellation */
+ s32 frequency; /*< center signal frequency in KHz */
enum drx_bandwidth curr_bandwidth;
- /**< current channel bandwidth */
- enum drx_mirror mirror; /**< current channel mirror */
+ /*< current channel bandwidth */
+ enum drx_mirror mirror; /*< current channel mirror */
/* signal quality information */
- u32 fec_bits_desired; /**< BER accounting period */
- u16 fec_vd_plen; /**< no of trellis symbols: VD SER measurement period */
- u16 qam_vd_prescale; /**< Viterbi Measurement Prescale */
- u16 qam_vd_period; /**< Viterbi Measurement period */
- u16 fec_rs_plen; /**< defines RS BER measurement period */
- u16 fec_rs_prescale; /**< ReedSolomon Measurement Prescale */
- u16 fec_rs_period; /**< ReedSolomon Measurement period */
- bool reset_pkt_err_acc; /**< Set a flag to reset accumulated packet error */
- u16 pkt_err_acc_start; /**< Set a flag to reset accumulated packet error */
+ u32 fec_bits_desired; /*< BER accounting period */
+ u16 fec_vd_plen; /*< no of trellis symbols: VD SER measurement period */
+ u16 qam_vd_prescale; /*< Viterbi Measurement Prescale */
+ u16 qam_vd_period; /*< Viterbi Measurement period */
+ u16 fec_rs_plen; /*< defines RS BER measurement period */
+ u16 fec_rs_prescale; /*< ReedSolomon Measurement Prescale */
+ u16 fec_rs_period; /*< ReedSolomon Measurement period */
+ bool reset_pkt_err_acc; /*< Set a flag to reset accumulated packet error */
+ u16 pkt_err_acc_start; /*< Set a flag to reset accumulated packet error */
/* HI configuration */
- u16 hi_cfg_timing_div; /**< HI Configure() parameter 2 */
- u16 hi_cfg_bridge_delay; /**< HI Configure() parameter 3 */
- u16 hi_cfg_wake_up_key; /**< HI Configure() parameter 4 */
- u16 hi_cfg_ctrl; /**< HI Configure() parameter 5 */
- u16 hi_cfg_transmit; /**< HI Configure() parameter 6 */
+ u16 hi_cfg_timing_div; /*< HI Configure() parameter 2 */
+ u16 hi_cfg_bridge_delay; /*< HI Configure() parameter 3 */
+ u16 hi_cfg_wake_up_key; /*< HI Configure() parameter 4 */
+ u16 hi_cfg_ctrl; /*< HI Configure() parameter 5 */
+ u16 hi_cfg_transmit; /*< HI Configure() parameter 6 */
/* UIO configuration */
- enum drxuio_mode uio_sma_rx_mode;/**< current mode of SmaRx pin */
- enum drxuio_mode uio_sma_tx_mode;/**< current mode of SmaTx pin */
- enum drxuio_mode uio_gpio_mode; /**< current mode of ASEL pin */
- enum drxuio_mode uio_irqn_mode; /**< current mode of IRQN pin */
+ enum drxuio_mode uio_sma_rx_mode;/*< current mode of SmaRx pin */
+ enum drxuio_mode uio_sma_tx_mode;/*< current mode of SmaTx pin */
+ enum drxuio_mode uio_gpio_mode; /*< current mode of ASEL pin */
+ enum drxuio_mode uio_irqn_mode; /*< current mode of IRQN pin */
/* IQM fs frequecy shift and inversion */
- u32 iqm_fs_rate_ofs; /**< frequency shifter setting after setchannel */
- bool pos_image; /**< Ture: positive image */
+ u32 iqm_fs_rate_ofs; /*< frequency shifter setting after setchannel */
+ bool pos_image; /*< Ture: positive image */
/* IQM RC frequecy shift */
- u32 iqm_rc_rate_ofs; /**< frequency shifter setting after setchannel */
+ u32 iqm_rc_rate_ofs; /*< frequency shifter setting after setchannel */
/* ATV configuration */
- u32 atv_cfg_changed_flags; /**< flag: flags cfg changes */
- s16 atv_top_equ0[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU0__A */
- s16 atv_top_equ1[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU1__A */
- s16 atv_top_equ2[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU2__A */
- s16 atv_top_equ3[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU3__A */
- bool phase_correction_bypass;/**< flag: true=bypass */
- s16 atv_top_vid_peak; /**< shadow of ATV_TOP_VID_PEAK__A */
- u16 atv_top_noise_th; /**< shadow of ATV_TOP_NOISE_TH__A */
- bool enable_cvbs_output; /**< flag CVBS ouput enable */
- bool enable_sif_output; /**< flag SIF ouput enable */
+ u32 atv_cfg_changed_flags; /*< flag: flags cfg changes */
+ s16 atv_top_equ0[DRXJ_COEF_IDX_MAX]; /*< shadow of ATV_TOP_EQU0__A */
+ s16 atv_top_equ1[DRXJ_COEF_IDX_MAX]; /*< shadow of ATV_TOP_EQU1__A */
+ s16 atv_top_equ2[DRXJ_COEF_IDX_MAX]; /*< shadow of ATV_TOP_EQU2__A */
+ s16 atv_top_equ3[DRXJ_COEF_IDX_MAX]; /*< shadow of ATV_TOP_EQU3__A */
+ bool phase_correction_bypass;/*< flag: true=bypass */
+ s16 atv_top_vid_peak; /*< shadow of ATV_TOP_VID_PEAK__A */
+ u16 atv_top_noise_th; /*< shadow of ATV_TOP_NOISE_TH__A */
+ bool enable_cvbs_output; /*< flag CVBS ouput enable */
+ bool enable_sif_output; /*< flag SIF ouput enable */
enum drxjsif_attenuation sif_attenuation;
- /**< current SIF att setting */
+ /*< current SIF att setting */
/* Agc configuration for QAM and VSB */
- struct drxj_cfg_agc qam_rf_agc_cfg; /**< qam RF AGC config */
- struct drxj_cfg_agc qam_if_agc_cfg; /**< qam IF AGC config */
- struct drxj_cfg_agc vsb_rf_agc_cfg; /**< vsb RF AGC config */
- struct drxj_cfg_agc vsb_if_agc_cfg; /**< vsb IF AGC config */
+ struct drxj_cfg_agc qam_rf_agc_cfg; /*< qam RF AGC config */
+ struct drxj_cfg_agc qam_if_agc_cfg; /*< qam IF AGC config */
+ struct drxj_cfg_agc vsb_rf_agc_cfg; /*< vsb RF AGC config */
+ struct drxj_cfg_agc vsb_if_agc_cfg; /*< vsb IF AGC config */
/* PGA gain configuration for QAM and VSB */
- u16 qam_pga_cfg; /**< qam PGA config */
- u16 vsb_pga_cfg; /**< vsb PGA config */
+ u16 qam_pga_cfg; /*< qam PGA config */
+ u16 vsb_pga_cfg; /*< vsb PGA config */
/* Pre SAW configuration for QAM and VSB */
struct drxj_cfg_pre_saw qam_pre_saw_cfg;
- /**< qam pre SAW config */
+ /*< qam pre SAW config */
struct drxj_cfg_pre_saw vsb_pre_saw_cfg;
- /**< qam pre SAW config */
+ /*< qam pre SAW config */
/* Version information */
- char v_text[2][12]; /**< allocated text versions */
- struct drx_version v_version[2]; /**< allocated versions structs */
+ char v_text[2][12]; /*< allocated text versions */
+ struct drx_version v_version[2]; /*< allocated versions structs */
struct drx_version_list v_list_elements[2];
- /**< allocated version list */
+ /*< allocated version list */
/* smart antenna configuration */
bool smart_ant_inverted;
@@ -502,25 +502,25 @@ struct drxj_cfg_atv_output {
bool oob_power_on;
/* MPEG static bitrate setting */
- u32 mpeg_ts_static_bitrate; /**< bitrate static MPEG output */
- bool disable_te_ihandling; /**< MPEG TS TEI handling */
- bool bit_reverse_mpeg_outout;/**< MPEG output bit order */
+ u32 mpeg_ts_static_bitrate; /*< bitrate static MPEG output */
+ bool disable_te_ihandling; /*< MPEG TS TEI handling */
+ bool bit_reverse_mpeg_outout;/*< MPEG output bit order */
enum drxj_mpeg_output_clock_rate mpeg_output_clock_rate;
- /**< MPEG output clock rate */
+ /*< MPEG output clock rate */
enum drxj_mpeg_start_width mpeg_start_width;
- /**< MPEG Start width */
+ /*< MPEG Start width */
/* Pre SAW & Agc configuration for ATV */
struct drxj_cfg_pre_saw atv_pre_saw_cfg;
- /**< atv pre SAW config */
- struct drxj_cfg_agc atv_rf_agc_cfg; /**< atv RF AGC config */
- struct drxj_cfg_agc atv_if_agc_cfg; /**< atv IF AGC config */
- u16 atv_pga_cfg; /**< atv pga config */
+ /*< atv pre SAW config */
+ struct drxj_cfg_agc atv_rf_agc_cfg; /*< atv RF AGC config */
+ struct drxj_cfg_agc atv_if_agc_cfg; /*< atv IF AGC config */
+ u16 atv_pga_cfg; /*< atv pga config */
u32 curr_symbol_rate;
/* pin-safe mode */
- bool pdr_safe_mode; /**< PDR safe mode activated */
+ bool pdr_safe_mode; /*< PDR safe mode activated */
u16 pdr_safe_restore_val_gpio;
u16 pdr_safe_restore_val_v_sync;
u16 pdr_safe_restore_val_sma_rx;
@@ -531,12 +531,12 @@ struct drxj_cfg_atv_output {
enum drxj_cfg_oob_lo_power oob_lo_pow;
struct drx_aud_data aud_data;
- /**< audio storage */};
+ /*< audio storage */};
/*-------------------------------------------------------------------------
Access MACROS
-------------------------------------------------------------------------*/
-/**
+/*
* \brief Compilable references to attributes
* \param d pointer to demod instance
*
@@ -554,7 +554,7 @@ Access MACROS
DEFINES
-------------------------------------------------------------------------*/
-/**
+/*
* \def DRXJ_NTSC_CARRIER_FREQ_OFFSET
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
*
@@ -569,7 +569,7 @@ DEFINES
*/
#define DRXJ_NTSC_CARRIER_FREQ_OFFSET ((s32)(1750))
-/**
+/*
* \def DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
*
@@ -585,7 +585,7 @@ DEFINES
*/
#define DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET ((s32)(2375))
-/**
+/*
* \def DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
*
@@ -601,7 +601,7 @@ DEFINES
*/
#define DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET ((s32)(2775))
-/**
+/*
* \def DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
*
@@ -616,7 +616,7 @@ DEFINES
*/
#define DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET ((s32)(-3255))
-/**
+/*
* \def DRXJ_FM_CARRIER_FREQ_OFFSET
* \brief Offset from sound carrier to centre frequency in kHz, in RF domain
*
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index 7d04400b18dd..0696bc62dcc9 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -328,7 +328,7 @@ static int WriteTable(struct drxd_state *state, u8 * pTable)
{
int status = 0;
- if (pTable == NULL)
+ if (!pTable)
return 0;
while (!status) {
@@ -640,7 +640,7 @@ static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
const u16 maxRur = 8;
static const u16 slowIncrDecLUT[] = {
3, 4, 4, 5, 6 };
- const u16 fastIncrDecLUT[] = {
+ static const u16 fastIncrDecLUT[] = {
14, 15, 15, 16,
17, 18, 18, 19,
20, 21, 22, 23,
@@ -909,9 +909,8 @@ static int load_firmware(struct drxd_state *state, const char *fw_name)
}
state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL);
- if (state->microcode == NULL) {
+ if (!state->microcode) {
release_firmware(fw);
- printk(KERN_ERR "drxd: firmware load failure: no memory\n");
return -ENOMEM;
}
@@ -2630,7 +2629,7 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
break;
/* Apply I2c address patch to B1 */
- if (!state->type_A && state->m_HiI2cPatch != NULL) {
+ if (!state->type_A && state->m_HiI2cPatch) {
status = WriteTable(state, state->m_HiI2cPatch);
if (status < 0)
break;
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index a629897eb905..b16fedbb53a3 100644
--- a/drivers/media/dvb-frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DRXK_H_
#define _DRXK_H_
@@ -19,17 +20,18 @@
* @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1
* means that 1=DVBC, 0 = DVBT. Zero means the opposite.
* @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
+ * @chunk_size: maximum size for I2C messages
* @microcode_name: Name of the firmware file with the microcode
* @qam_demod_parameter_count: The number of parameters used for the command
* to set the demodulator parameters. All
* firmwares are using the 2-parameter commmand.
- * An exception is the "drxk_a3.mc" firmware,
+ * An exception is the ``drxk_a3.mc`` firmware,
* which uses the 4-parameter command.
* A value of 0 (default) or lower indicates that
* the correct number of parameters will be
* automatically detected.
*
- * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
+ * On the ``*_gpio`` vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
* UIO-3.
*/
struct drxk_config {
@@ -51,6 +53,14 @@ struct drxk_config {
};
#if IS_REACHABLE(CONFIG_DVB_DRXK)
+/**
+ * Attach a drxk demod
+ *
+ * @config: pointer to &struct drxk_config with demod configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c);
#else
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index 48a8aad47a74..f59ac2e91c59 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -207,9 +207,9 @@ static inline u32 log10times100(u32 value)
return (100L * intlog10(value)) >> 24;
}
-/****************************************************************************/
+/***************************************************************************/
/* I2C **********************************************************************/
-/****************************************************************************/
+/***************************************************************************/
static int drxk_i2c_lock(struct drxk_state *state)
{
@@ -3444,7 +3444,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Activate DVBT specific presets
* \param demod instance of demodulator.
* \return DRXStatus_t.
@@ -3484,7 +3484,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Initialize channelswitch-independent settings for DVBT.
* \param demod instance of demodulator.
* \return DRXStatus_t.
@@ -3696,7 +3696,7 @@ error:
}
/*============================================================================*/
-/**
+/*
* \brief start dvbt demodulating for channel.
* \param demod instance of demodulator.
* \return DRXStatus_t.
@@ -3732,7 +3732,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Set up dvbt demodulator for channel.
* \param demod instance of demodulator.
* \return DRXStatus_t.
@@ -4086,7 +4086,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Retrieve lock status .
* \param demod Pointer to demodulator instance.
* \param lockStat Pointer to lock status structure.
@@ -4148,7 +4148,7 @@ static int power_up_qam(struct drxk_state *state)
}
-/** Power Down QAM */
+/* Power Down QAM */
static int power_down_qam(struct drxk_state *state)
{
u16 data = 0;
@@ -4186,7 +4186,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Setup of the QAM Measurement intervals for signal quality
* \param demod instance of demod.
* \param modulation current modulation.
@@ -4461,7 +4461,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief QAM32 specific setup
* \param demod instance of demod.
* \return DRXStatus_t.
@@ -4657,7 +4657,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief QAM64 specific setup
* \param demod instance of demod.
* \return DRXStatus_t.
@@ -4852,7 +4852,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief QAM128 specific setup
* \param demod: instance of demod.
* \return DRXStatus_t.
@@ -5049,7 +5049,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief QAM256 specific setup
* \param demod: instance of demod.
* \return DRXStatus_t.
@@ -5244,7 +5244,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Reset QAM block.
* \param demod: instance of demod.
* \param channel: pointer to channel data.
@@ -5272,7 +5272,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Set QAM symbolrate.
* \param demod: instance of demod.
* \param channel: pointer to channel data.
@@ -5341,7 +5341,7 @@ error:
/*============================================================================*/
-/**
+/*
* \brief Get QAM lock status.
* \param demod: instance of demod.
* \param channel: pointer to channel data.
diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h
index 9ed88e014942..a850a876deee 100644
--- a/drivers/media/dvb-frontends/drxk_hard.h
+++ b/drivers/media/dvb-frontends/drxk_hard.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#include "drxk_map.h"
#define DRXK_VERSION_MAJOR 0
diff --git a/drivers/media/dvb-frontends/drxk_map.h b/drivers/media/dvb-frontends/drxk_map.h
index 761613f9fd5a..9234ef4fb68d 100644
--- a/drivers/media/dvb-frontends/drxk_map.h
+++ b/drivers/media/dvb-frontends/drxk_map.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define AUD_COMM_EXEC__A 0x1000000
#define AUD_COMM_EXEC_STOP 0x0
#define FEC_COMM_EXEC__A 0x1C00000
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
index 0b17a45c5640..bd4f8278c906 100644
--- a/drivers/media/dvb-frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -277,10 +277,8 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
u8 *buf;
buf = kmalloc(33, GFP_KERNEL);
- if (buf == NULL) {
- printk(KERN_ERR "Unable to kmalloc\n");
+ if (!buf)
return -ENOMEM;
- }
*(buf) = reg;
@@ -835,17 +833,15 @@ static const struct dvb_frontend_ops ds3000_ops;
struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
struct i2c_adapter *i2c)
{
- struct ds3000_state *state = NULL;
+ struct ds3000_state *state;
int ret;
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
- state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
- if (state == NULL) {
- printk(KERN_ERR "Unable to kmalloc\n");
- goto error2;
- }
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
state->config = config;
state->i2c = i2c;
@@ -854,8 +850,9 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
/* check if the demod is present */
ret = ds3000_readreg(state, 0x00) & 0xfe;
if (ret != 0xe0) {
+ kfree(state);
printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
- goto error3;
+ return NULL;
}
printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
@@ -873,11 +870,6 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
*/
ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF);
return &state->frontend;
-
-error3:
- kfree(state);
-error2:
- return NULL;
}
EXPORT_SYMBOL(ds3000_attach);
diff --git a/drivers/media/dvb-frontends/dvb-pll.h b/drivers/media/dvb-frontends/dvb-pll.h
index bf9602a88b6c..212e0730f154 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* descriptions + helper functions for simple dvb plls.
*/
@@ -29,16 +30,17 @@
#define DVB_PLL_TDEE4 18
#define DVB_PLL_THOMSON_DTT7520X 19
+#if IS_REACHABLE(CONFIG_DVB_PLL)
/**
* Attach a dvb-pll to the supplied frontend structure.
*
- * @param fe Frontend to attach to.
- * @param pll_addr i2c address of the PLL (if used).
- * @param i2c i2c adapter to use (set to NULL if not used).
- * @param pll_desc_id dvb_pll_desc to use.
- * @return Frontend pointer on success, NULL on failure
+ * @fe: Frontend to attach to.
+ * @pll_addr: i2c address of the PLL (if used).
+ * @i2c: i2c adapter to use (set to NULL if not used).
+ * @pll_desc_id: dvb_pll_desc to use.
+ *
+ * return: Frontend pointer on success, NULL on failure
*/
-#if IS_REACHABLE(CONFIG_DVB_PLL)
extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
int pll_addr,
struct i2c_adapter *i2c,
diff --git a/drivers/media/dvb-frontends/helene.h b/drivers/media/dvb-frontends/helene.h
index 333615491d9e..c9fc81c7e4e7 100644
--- a/drivers/media/dvb-frontends/helene.h
+++ b/drivers/media/dvb-frontends/helene.h
@@ -38,6 +38,7 @@ enum helene_xtal {
* @set_tuner_priv: Callback function private context
* @set_tuner_callback: Callback function that notifies the parent driver
* which tuner is active now
+ * @xtal: Cristal frequency as described by &enum helene_xtal
*/
struct helene_config {
u8 i2c_address;
@@ -48,9 +49,31 @@ struct helene_config {
};
#if IS_REACHABLE(CONFIG_DVB_HELENE)
+/**
+ * Attach a helene tuner (terrestrial and cable standards)
+ *
+ * @fe: frontend to be attached
+ * @config: pointer to &struct helene_config with tuner configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
const struct helene_config *config,
struct i2c_adapter *i2c);
+
+/**
+ * Attach a helene tuner (satellite standards)
+ *
+ * @fe: frontend to be attached
+ * @config: pointer to &struct helene_config with tuner configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
+extern struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
+ const struct helene_config *config,
+ struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
const struct helene_config *config,
@@ -59,13 +82,6 @@ static inline struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif
-
-#if IS_REACHABLE(CONFIG_DVB_HELENE)
-extern struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
- const struct helene_config *config,
- struct i2c_adapter *i2c);
-#else
static inline struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
const struct helene_config *config,
struct i2c_adapter *i2c)
diff --git a/drivers/media/dvb-frontends/horus3a.h b/drivers/media/dvb-frontends/horus3a.h
index 672a556df71a..9157fd037e2f 100644
--- a/drivers/media/dvb-frontends/horus3a.h
+++ b/drivers/media/dvb-frontends/horus3a.h
@@ -41,6 +41,15 @@ struct horus3a_config {
};
#if IS_REACHABLE(CONFIG_DVB_HORUS3A)
+/**
+ * Attach a horus3a tuner
+ *
+ * @fe: frontend to be attached
+ * @config: pointer to &struct helene_config with tuner configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
const struct horus3a_config *config,
struct i2c_adapter *i2c);
diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c
index 534b24fa2b95..965012ad5c59 100644
--- a/drivers/media/dvb-frontends/ix2505v.c
+++ b/drivers/media/dvb-frontends/ix2505v.c
@@ -1,4 +1,4 @@
-/**
+/*
* Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
*
* Copyright (C) 2010 Malcolm Priestley
@@ -36,7 +36,7 @@ struct ix2505v_state {
u32 frequency;
};
-/**
+/*
* Data read format of the Sharp IX2505V B0017
*
* byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1
@@ -99,7 +99,7 @@ static void ix2505v_release(struct dvb_frontend *fe)
}
-/**
+/*
* Data write format of the Sharp IX2505V B0017
*
* byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0
diff --git a/drivers/media/dvb-frontends/ix2505v.h b/drivers/media/dvb-frontends/ix2505v.h
index 0b0a431c74f6..49ed93e754ed 100644
--- a/drivers/media/dvb-frontends/ix2505v.h
+++ b/drivers/media/dvb-frontends/ix2505v.h
@@ -20,31 +20,33 @@
#include "dvb_frontend.h"
/**
- * Attach a ix2505v tuner to the supplied frontend structure.
+ * struct ix2505v_config - ix2505 attachment configuration
*
- * @param fe Frontend to attach to.
- * @param config ix2505v_config structure
- * @return FE pointer on success, NULL on failure.
+ * @tuner_address: tuner address
+ * @tuner_gain: Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB
+ * @tuner_chargepump: Charge pump output +/- 0=120 1=260 2=555 3=1200(default)
+ * @min_delay_ms: delay after tune
+ * @tuner_write_only: disables reads
*/
-
struct ix2505v_config {
u8 tuner_address;
-
- /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */
u8 tuner_gain;
-
- /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */
u8 tuner_chargepump;
-
- /* delay after tune */
int min_delay_ms;
-
- /* disables reads*/
u8 tuner_write_only;
};
#if IS_REACHABLE(CONFIG_DVB_IX2505V)
+/**
+ * Attach a ix2505v tuner to the supplied frontend structure.
+ *
+ * @fe: Frontend to attach to.
+ * @config: pointer to &struct ix2505v_config
+ * @i2c: pointer to &struct i2c_adapter.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
const struct ix2505v_config *config, struct i2c_adapter *i2c);
#else
diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c
index 68923c84679a..e5a6c1766664 100644
--- a/drivers/media/dvb-frontends/l64781.c
+++ b/drivers/media/dvb-frontends/l64781.c
@@ -517,7 +517,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
state->i2c = i2c;
state->first = 1;
- /**
+ /*
* the L64781 won't show up before we send the reset_and_configure()
* broadcast. If nothing responds there is no L64781 on the bus...
*/
diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c
index 5798079add10..9854096839ae 100644
--- a/drivers/media/dvb-frontends/lg2160.c
+++ b/drivers/media/dvb-frontends/lg2160.c
@@ -1048,16 +1048,6 @@ fail:
return ret;
}
-static int lg216x_get_property(struct dvb_frontend *fe,
- struct dtv_property *tvp)
-{
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
- return (DTV_ATSCMH_FIC_VER == tvp->cmd) ?
- lg216x_get_frontend(fe, c) : 0;
-}
-
-
static int lg2160_set_frontend(struct dvb_frontend *fe)
{
struct lg216x_state *state = fe->demodulator_priv;
@@ -1368,8 +1358,6 @@ static const struct dvb_frontend_ops lg2160_ops = {
.init = lg216x_init,
.sleep = lg216x_sleep,
#endif
- .get_property = lg216x_get_property,
-
.set_frontend = lg2160_set_frontend,
.get_frontend = lg216x_get_frontend,
.get_tune_settings = lg216x_get_tune_settings,
@@ -1396,8 +1384,6 @@ static const struct dvb_frontend_ops lg2161_ops = {
.init = lg216x_init,
.sleep = lg216x_sleep,
#endif
- .get_property = lg216x_get_property,
-
.set_frontend = lg2160_set_frontend,
.get_frontend = lg216x_get_frontend,
.get_tune_settings = lg216x_get_tune_settings,
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index c9b1eb38444e..724e9aac0f11 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -19,6 +19,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <asm/div64.h>
+#include <linux/kernel.h>
#include <linux/dvb/frontend.h>
#include "dvb_math.h"
#include "lgdt3306a.h"
@@ -2072,7 +2073,7 @@ static const short regtab[] = {
0x30aa, /* MPEGLOCK */
};
-#define numDumpRegs (sizeof(regtab)/sizeof(regtab[0]))
+#define numDumpRegs (ARRAY_SIZE(regtab))
static u8 regval1[numDumpRegs] = {0, };
static u8 regval2[numDumpRegs] = {0, };
diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h
index 04b355a005fb..1a8964a2265d 100644
--- a/drivers/media/dvb-frontends/m88ds3103.h
+++ b/drivers/media/dvb-frontends/m88ds3103.h
@@ -25,6 +25,34 @@
*/
/**
+ * enum m88ds3103_ts_mode - TS connection mode
+ * @M88DS3103_TS_SERIAL: TS output pin D0, normal
+ * @M88DS3103_TS_SERIAL_D7: TS output pin D7
+ * @M88DS3103_TS_PARALLEL: TS Parallel mode
+ * @M88DS3103_TS_CI: TS CI Mode
+ */
+enum m88ds3103_ts_mode {
+ M88DS3103_TS_SERIAL,
+ M88DS3103_TS_SERIAL_D7,
+ M88DS3103_TS_PARALLEL,
+ M88DS3103_TS_CI
+};
+
+/**
+ * enum m88ds3103_clock_out
+ * @M88DS3103_CLOCK_OUT_DISABLED: Clock output is disabled
+ * @M88DS3103_CLOCK_OUT_ENABLED: Clock output is enabled with crystal
+ * clock.
+ * @M88DS3103_CLOCK_OUT_ENABLED_DIV2: Clock output is enabled with half
+ * crystal clock.
+ */
+enum m88ds3103_clock_out {
+ M88DS3103_CLOCK_OUT_DISABLED,
+ M88DS3103_CLOCK_OUT_ENABLED,
+ M88DS3103_CLOCK_OUT_ENABLED_DIV2
+};
+
+/**
* struct m88ds3103_platform_data - Platform data for the m88ds3103 driver
* @clk: Clock frequency.
* @i2c_wr_max: Max bytes I2C adapter can write at once.
@@ -44,24 +72,16 @@
* @get_dvb_frontend: Get DVB frontend.
* @get_i2c_adapter: Get I2C adapter.
*/
-
struct m88ds3103_platform_data {
u32 clk;
u16 i2c_wr_max;
-#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */
-#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */
-#define M88DS3103_TS_PARALLEL 2 /* TS Parallel mode */
-#define M88DS3103_TS_CI 3 /* TS CI Mode */
- u8 ts_mode:2;
+ enum m88ds3103_ts_mode ts_mode;
u32 ts_clk;
+ enum m88ds3103_clock_out clk_out;
u8 ts_clk_pol:1;
u8 spec_inv:1;
u8 agc;
u8 agc_inv:1;
-#define M88DS3103_CLOCK_OUT_DISABLED 0
-#define M88DS3103_CLOCK_OUT_ENABLED 1
-#define M88DS3103_CLOCK_OUT_ENABLED_DIV2 2
- u8 clk_out:2;
u8 envelope_mode:1;
u8 lnb_hv_pol:1;
u8 lnb_en_pol:1;
@@ -73,105 +93,60 @@ struct m88ds3103_platform_data {
u8 attach_in_use:1;
};
-/*
- * Do not add new m88ds3103_attach() users! Use I2C bindings instead.
+/**
+ * struct m88ds3103_config - m88ds3102 configuration
+ *
+ * @i2c_addr: I2C address. Default: none, must set. Example: 0x68, ...
+ * @clock: Device's clock. Default: none, must set. Example: 27000000
+ * @i2c_wr_max: Max bytes I2C provider is asked to write at once.
+ * Default: none, must set. Example: 33, 65, ...
+ * @ts_mode: TS output mode, as defined by &enum m88ds3103_ts_mode.
+ * Default: M88DS3103_TS_SERIAL.
+ * @ts_clk: TS clk in KHz. Default: 0.
+ * @ts_clk_pol: TS clk polarity.Default: 0.
+ * 1-active at falling edge; 0-active at rising edge.
+ * @spec_inv: Spectrum inversion. Default: 0.
+ * @agc_inv: AGC polarity. Default: 0.
+ * @clock_out: Clock output, as defined by &enum m88ds3103_clock_out.
+ * Default: M88DS3103_CLOCK_OUT_DISABLED.
+ * @envelope_mode: DiSEqC envelope mode. Default: 0.
+ * @agc: AGC configuration. Default: none, must set.
+ * @lnb_hv_pol: LNB H/V pin polarity. Default: 0. Values:
+ * 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18;
+ * 0: pin high set to VOLTAGE_18, pin low to set VOLTAGE_13.
+ * @lnb_en_pol: LNB enable pin polarity. Default: 0. Values:
+ * 1: pin high to enable, pin low to disable;
+ * 0: pin high to disable, pin low to enable.
*/
struct m88ds3103_config {
- /*
- * I2C address
- * Default: none, must set
- * 0x68, ...
- */
u8 i2c_addr;
-
- /*
- * clock
- * Default: none, must set
- * 27000000
- */
u32 clock;
-
- /*
- * max bytes I2C provider is asked to write at once
- * Default: none, must set
- * 33, 65, ...
- */
u16 i2c_wr_max;
-
- /*
- * TS output mode
- * Default: M88DS3103_TS_SERIAL
- */
-#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */
-#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */
-#define M88DS3103_TS_PARALLEL 2 /* TS Parallel mode */
-#define M88DS3103_TS_CI 3 /* TS CI Mode */
u8 ts_mode;
-
- /*
- * TS clk in KHz
- * Default: 0.
- */
u32 ts_clk;
-
- /*
- * TS clk polarity.
- * Default: 0. 1-active at falling edge; 0-active at rising edge.
- */
u8 ts_clk_pol:1;
-
- /*
- * spectrum inversion
- * Default: 0
- */
u8 spec_inv:1;
-
- /*
- * AGC polarity
- * Default: 0
- */
u8 agc_inv:1;
-
- /*
- * clock output
- * Default: M88DS3103_CLOCK_OUT_DISABLED
- */
-#define M88DS3103_CLOCK_OUT_DISABLED 0
-#define M88DS3103_CLOCK_OUT_ENABLED 1
-#define M88DS3103_CLOCK_OUT_ENABLED_DIV2 2
u8 clock_out;
-
- /*
- * DiSEqC envelope mode
- * Default: 0
- */
u8 envelope_mode:1;
-
- /*
- * AGC configuration
- * Default: none, must set
- */
u8 agc;
-
- /*
- * LNB H/V pin polarity
- * Default: 0.
- * 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18.
- * 0: pin high set to VOLTAGE_18, pin low to set VOLTAGE_13.
- */
u8 lnb_hv_pol:1;
-
- /*
- * LNB enable pin polarity
- * Default: 0.
- * 1: pin high to enable, pin low to disable.
- * 0: pin high to disable, pin low to enable.
- */
u8 lnb_en_pol:1;
};
#if defined(CONFIG_DVB_M88DS3103) || \
(defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
+/**
+ * Attach a m88ds3103 demod
+ *
+ * @config: pointer to &struct m88ds3103_config with demod configuration.
+ * @i2c: i2c adapter to use.
+ * @tuner_i2c: on success, returns the I2C adapter associated with
+ * m88ds3103 tuner.
+ *
+ * return: FE pointer on success, NULL on failure.
+ * Note: Do not add new m88ds3103_attach() users! Use I2C bindings instead.
+ */
extern struct dvb_frontend *m88ds3103_attach(
const struct m88ds3103_config *config,
struct i2c_adapter *i2c,
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index e8ac8c3e2ec0..bdaf9d235fed 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -2071,12 +2071,9 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
dev_dbg(&i2c->dev, "%s called.\n", __func__);
/* allocate memory for the internal state */
- state = kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
- if (state == NULL) {
- dev_err(&i2c->dev,
- "%s: unable to allocate memory for state\n", __func__);
- goto error;
- }
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
/* setup the state */
state->config = config;
@@ -2089,22 +2086,16 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
/* Check if it is a mb86a20s frontend */
rev = mb86a20s_readreg(state, 0);
-
- if (rev == 0x13) {
- dev_info(&i2c->dev,
- "Detected a Fujitsu mb86a20s frontend\n");
- } else {
+ if (rev != 0x13) {
+ kfree(state);
dev_dbg(&i2c->dev,
"Frontend revision %d is unknown - aborting.\n",
rev);
- goto error;
+ return NULL;
}
+ dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n");
return &state->frontend;
-
-error:
- kfree(state);
- return NULL;
}
EXPORT_SYMBOL(mb86a20s_attach);
diff --git a/drivers/media/dvb-frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h
index dfb02db2126c..05c9725d1c5f 100644
--- a/drivers/media/dvb-frontends/mb86a20s.h
+++ b/drivers/media/dvb-frontends/mb86a20s.h
@@ -26,7 +26,6 @@
* @demod_address: the demodulator's i2c address
* @is_serial: if true, TS is serial. Otherwise, TS is parallel
*/
-
struct mb86a20s_config {
u32 fclk;
u8 demod_address;
@@ -34,9 +33,17 @@ struct mb86a20s_config {
};
#if IS_REACHABLE(CONFIG_DVB_MB86A20S)
+/**
+ * Attach a mb86a20s demod
+ *
+ * @config: pointer to &struct mb86a20s_config with demod configuration.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
struct i2c_adapter *i2c);
-extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
+
#else
static inline struct dvb_frontend *mb86a20s_attach(
const struct mb86a20s_config *config, struct i2c_adapter *i2c)
@@ -44,12 +51,6 @@ static inline struct dvb_frontend *mb86a20s_attach(
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-static inline struct i2c_adapter *
- mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
#endif
#endif /* MB86A20S */
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
index 323632523876..8cd5ef61903b 100644
--- a/drivers/media/dvb-frontends/mn88472.h
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -19,21 +19,21 @@
#include <linux/dvb/frontend.h>
+/* Define old names for backward compatibility */
+#define VARIABLE_TS_CLOCK MN88472_TS_CLK_VARIABLE
+#define FIXED_TS_CLOCK MN88472_TS_CLK_FIXED
+#define SERIAL_TS_MODE MN88472_TS_MODE_SERIAL
+#define PARALLEL_TS_MODE MN88472_TS_MODE_PARALLEL
+
/**
* struct mn88472_config - Platform data for the mn88472 driver
* @xtal: Clock frequency.
* @ts_mode: TS mode.
* @ts_clock: TS clock config.
* @i2c_wr_max: Max number of bytes driver writes to I2C at once.
- * @get_dvb_frontend: Get DVB frontend.
+ * @fe: pointer to a frontend pointer
+ * @get_dvb_frontend: Get DVB frontend callback.
*/
-
-/* Define old names for backward compatibility */
-#define VARIABLE_TS_CLOCK MN88472_TS_CLK_VARIABLE
-#define FIXED_TS_CLOCK MN88472_TS_CLK_FIXED
-#define SERIAL_TS_MODE MN88472_TS_MODE_SERIAL
-#define PARALLEL_TS_MODE MN88472_TS_MODE_PARALLEL
-
struct mn88472_config {
unsigned int xtal;
diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c
index 676c96c216c3..53064e11f5f1 100644
--- a/drivers/media/dvb-frontends/mxl5xx.c
+++ b/drivers/media/dvb-frontends/mxl5xx.c
@@ -43,7 +43,7 @@
#define BYTE2(v) ((v >> 16) & 0xff)
#define BYTE3(v) ((v >> 24) & 0xff)
-LIST_HEAD(mxllist);
+static LIST_HEAD(mxllist);
struct mxl_base {
struct list_head mxllist;
diff --git a/drivers/media/dvb-frontends/nxt6000_priv.h b/drivers/media/dvb-frontends/nxt6000_priv.h
index 0422e580038a..d317df02c8d7 100644
--- a/drivers/media/dvb-frontends/nxt6000_priv.h
+++ b/drivers/media/dvb-frontends/nxt6000_priv.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Public Include File for DRV6000 users
* (ie. NxtWave Communications - NXT6000 demodulator driver)
diff --git a/drivers/media/dvb-frontends/rtl2830.h b/drivers/media/dvb-frontends/rtl2830.h
index 0cde151e6608..458ac94e8a8b 100644
--- a/drivers/media/dvb-frontends/rtl2830.h
+++ b/drivers/media/dvb-frontends/rtl2830.h
@@ -32,7 +32,6 @@
* @pid_filter: Set PID to PID filter.
* @pid_filter_ctrl: Control PID filter.
*/
-
struct rtl2830_platform_data {
u32 clk;
bool spec_inv;
diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h
index 03c0de039fa9..6a124ff71c2b 100644
--- a/drivers/media/dvb-frontends/rtl2832.h
+++ b/drivers/media/dvb-frontends/rtl2832.h
@@ -35,7 +35,6 @@
* @pid_filter: Set PID to PID filter.
* @pid_filter_ctrl: Control PID filter.
*/
-
struct rtl2832_platform_data {
u32 clk;
/*
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.h b/drivers/media/dvb-frontends/rtl2832_sdr.h
index d8fc7e7212e3..8f88c2fb8627 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.h
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.h
@@ -33,15 +33,11 @@
* struct rtl2832_sdr_platform_data - Platform data for the rtl2832_sdr driver
* @clk: Clock frequency (4000000, 16000000, 25000000, 28800000).
* @tuner: Used tuner model.
- * @i2c_client: rtl2832 demod driver I2C client.
- * @bulk_read: rtl2832 driver private I/O interface.
- * @bulk_write: rtl2832 driver private I/O interface.
- * @update_bits: rtl2832 driver private I/O interface.
+ * @regmap: pointer to &struct regmap.
* @dvb_frontend: rtl2832 DVB frontend.
* @v4l2_subdev: Tuner v4l2 controls.
* @dvb_usb_device: DVB USB interface for USB streaming.
*/
-
struct rtl2832_sdr_platform_data {
u32 clk;
/*
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 172fc367ccaa..41d9c513b7e8 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -696,7 +696,6 @@ static int si2168_probe(struct i2c_client *client,
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
ret = -ENOMEM;
- dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
diff --git a/drivers/media/dvb-frontends/si21xx.h b/drivers/media/dvb-frontends/si21xx.h
index b1be62f1983a..43d480bb6ea2 100644
--- a/drivers/media/dvb-frontends/si21xx.h
+++ b/drivers/media/dvb-frontends/si21xx.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SI21XX_H
#define SI21XX_H
diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c
index 43d47dfcc7b8..53e66c232d3c 100644
--- a/drivers/media/dvb-frontends/sp2.c
+++ b/drivers/media/dvb-frontends/sp2.c
@@ -357,14 +357,14 @@ static int sp2_exit(struct i2c_client *client)
dev_dbg(&client->dev, "\n");
- if (client == NULL)
+ if (!client)
return 0;
s = i2c_get_clientdata(client);
- if (s == NULL)
+ if (!s)
return 0;
- if (s->ca.data == NULL)
+ if (!s->ca.data)
return 0;
dvb_ca_en50221_release(&s->ca);
@@ -381,10 +381,9 @@ static int sp2_probe(struct i2c_client *client,
dev_dbg(&client->dev, "\n");
- s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
- dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
index 7c511c3cd4ca..d2c402b52c6e 100644
--- a/drivers/media/dvb-frontends/sp887x.c
+++ b/drivers/media/dvb-frontends/sp887x.c
@@ -57,7 +57,7 @@ static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
int ret;
if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- /**
+ /*
* in case of soft reset we ignore ACK errors...
*/
if (!(reg == 0xf1a && data == 0x000 &&
@@ -130,7 +130,7 @@ static void sp887x_setup_agc (struct sp887x_state* state)
#define BLOCKSIZE 30
#define FW_SIZE 0x4000
-/**
+/*
* load firmware and setup MPEG interface...
*/
static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
@@ -279,7 +279,7 @@ static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
return 0;
}
-/**
+/*
* estimates division of two 24bit numbers,
* derived from the ves1820/stv0299 driver code
*/
diff --git a/drivers/media/dvb-frontends/sp887x.h b/drivers/media/dvb-frontends/sp887x.h
index 412f011e6dfd..a680cc22379c 100644
--- a/drivers/media/dvb-frontends/sp887x.h
+++ b/drivers/media/dvb-frontends/sp887x.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
Driver for the Spase sp887x demodulator
*/
diff --git a/drivers/media/dvb-frontends/stb6000.h b/drivers/media/dvb-frontends/stb6000.h
index 78e75dfc317f..e94a3d5facf6 100644
--- a/drivers/media/dvb-frontends/stb6000.h
+++ b/drivers/media/dvb-frontends/stb6000.h
@@ -26,15 +26,16 @@
#include <linux/i2c.h>
#include "dvb_frontend.h"
+#if IS_REACHABLE(CONFIG_DVB_STB6000)
/**
* Attach a stb6000 tuner to the supplied frontend structure.
*
- * @param fe Frontend to attach to.
- * @param addr i2c address of the tuner.
- * @param i2c i2c adapter to use.
- * @return FE pointer on success, NULL on failure.
+ * @fe: Frontend to attach to.
+ * @addr: i2c address of the tuner.
+ * @i2c: i2c adapter to use.
+ *
+ * return: FE pointer on success, NULL on failure.
*/
-#if IS_REACHABLE(CONFIG_DVB_STB6000)
extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
struct i2c_adapter *i2c);
#else
diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
index 45cbc898ad25..67f91814b9f7 100644
--- a/drivers/media/dvb-frontends/stv0288.c
+++ b/drivers/media/dvb-frontends/stv0288.c
@@ -447,12 +447,6 @@ static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
return 0;
}
-static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
-{
- dprintk("%s(..)\n", __func__);
- return 0;
-}
-
static int stv0288_set_frontend(struct dvb_frontend *fe)
{
struct stv0288_state *state = fe->demodulator_priv;
@@ -567,7 +561,6 @@ static const struct dvb_frontend_ops stv0288_ops = {
.set_tone = stv0288_set_tone,
.set_voltage = stv0288_set_voltage,
- .set_property = stv0288_set_property,
.set_frontend = stv0288_set_frontend,
};
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index b36b21a13201..b1f3d675d316 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -368,7 +368,7 @@ static int stv0299_set_voltage(struct dvb_frontend *fe,
reg0x08 = stv0299_readreg (state, 0x08);
reg0x0c = stv0299_readreg (state, 0x0c);
- /**
+ /*
* H/V switching over OP0, OP1 and OP2 are LNB power enable bits
*/
reg0x0c &= 0x0f;
diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c
index e4fd9c1b0560..6aad0efa3174 100644
--- a/drivers/media/dvb-frontends/stv6110.c
+++ b/drivers/media/dvb-frontends/stv6110.c
@@ -258,11 +258,9 @@ static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
struct stv6110_priv *priv = fe->tuner_priv;
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u8 ret = 0x04;
u32 divider, ref, p, presc, i, result_freq, vco_freq;
s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
- s32 srate;
dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
frequency, priv->mclk);
@@ -273,13 +271,6 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
/* BB_GAIN = db/2 */
- if (fe->ops.set_property && fe->ops.get_property) {
- srate = c->symbol_rate;
- dprintk("%s: Get Frontend parameters: srate=%d\n",
- __func__, srate);
- } else
- srate = 15000000;
-
priv->regs[RSTV6110_CTRL2] &= ~0x0f;
priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
diff --git a/drivers/media/dvb-frontends/tda10071.h b/drivers/media/dvb-frontends/tda10071.h
index 8f184026ee11..da1a87bc1603 100644
--- a/drivers/media/dvb-frontends/tda10071.h
+++ b/drivers/media/dvb-frontends/tda10071.h
@@ -38,7 +38,6 @@
* @tuner_i2c_addr: CX24118A tuner I2C address (0x14, 0x54, ...).
* @get_dvb_frontend: Get DVB frontend.
*/
-
struct tda10071_platform_data {
u32 clk;
u16 i2c_wr_max;
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h
index e6ccf240f54c..289653db68e4 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _TDA18271C2DD_H_
#define _TDA18271C2DD_H_
diff --git a/drivers/media/dvb-frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
index f3bca5c237d7..5f75516bc0cb 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd_maps.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
enum HF_S {
HF_None = 0, HF_B, HF_DK, HF_G, HF_I, HF_L, HF_L1, HF_MN, HF_FM_Radio,
HF_AnalogMax, HF_DVBT_6MHZ, HF_DVBT_7MHZ, HF_DVBT_8MHZ,
diff --git a/drivers/media/dvb-frontends/tda826x.h b/drivers/media/dvb-frontends/tda826x.h
index 81abe1aebe9f..6a7bed12e741 100644
--- a/drivers/media/dvb-frontends/tda826x.h
+++ b/drivers/media/dvb-frontends/tda826x.h
@@ -29,11 +29,12 @@
/**
* Attach a tda826x tuner to the supplied frontend structure.
*
- * @param fe Frontend to attach to.
- * @param addr i2c address of the tuner.
- * @param i2c i2c adapter to use.
- * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
- * @return FE pointer on success, NULL on failure.
+ * @fe: Frontend to attach to.
+ * @addr: i2c address of the tuner.
+ * @i2c: i2c adapter to use.
+ * @has_loopthrough: Set to 1 if the card has a loopthrough RF connector.
+ *
+ * return: FE pointer on success, NULL on failure.
*/
#if IS_REACHABLE(CONFIG_DVB_TDA826X)
extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr,
diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c
index 18e6d4c5be21..1d41abd47f04 100644
--- a/drivers/media/dvb-frontends/tua6100.c
+++ b/drivers/media/dvb-frontends/tua6100.c
@@ -1,4 +1,4 @@
-/**
+/*
* Driver for Infineon tua6100 pll.
*
* (c) 2006 Andrew de Quincey
diff --git a/drivers/media/dvb-frontends/tua6100.h b/drivers/media/dvb-frontends/tua6100.h
index 9f15cbdfdeca..6c098a894ea6 100644
--- a/drivers/media/dvb-frontends/tua6100.h
+++ b/drivers/media/dvb-frontends/tua6100.h
@@ -1,4 +1,4 @@
-/**
+/*
* Driver for Infineon tua6100 PLL.
*
* (c) 2006 Andrew de Quincey
diff --git a/drivers/media/dvb-frontends/zd1301_demod.h b/drivers/media/dvb-frontends/zd1301_demod.h
index ceb2e05e873c..6cd8f6f9c415 100644
--- a/drivers/media/dvb-frontends/zd1301_demod.h
+++ b/drivers/media/dvb-frontends/zd1301_demod.h
@@ -27,7 +27,6 @@
* @reg_read: Register read callback.
* @reg_write: Register write callback.
*/
-
struct zd1301_demod_platform_data {
void *reg_priv;
int (*reg_read)(void *, u16, u8 *);
@@ -41,8 +40,7 @@ struct zd1301_demod_platform_data {
*
* Return: Pointer to DVB frontend which given platform device owns.
*/
-
-struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *);
+struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *pdev);
/**
* zd1301_demod_get_i2c_adapter() - Get pointer to I2C adapter
@@ -50,11 +48,16 @@ struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *);
*
* Return: Pointer to I2C adapter which given platform device owns.
*/
-
-struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *);
+struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *pdev);
#else
+/**
+ * zd1301_demod_get_dvb_frontend() - Attach a zd1301 frontend
+ * @dev: Pointer to platform device
+ *
+ * Return: Pointer to %struct dvb_frontend or NULL if attach fails.
+ */
static inline struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *dev)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c
index 062282739ce5..89dd65ae88ad 100644
--- a/drivers/media/dvb-frontends/zl10036.c
+++ b/drivers/media/dvb-frontends/zl10036.c
@@ -1,4 +1,4 @@
-/**
+/*
* Driver for Zarlink zl10036 DVB-S silicon tuner
*
* Copyright (C) 2006 Tino Reichardt
@@ -157,7 +157,7 @@ static int zl10036_sleep(struct dvb_frontend *fe)
return ret;
}
-/**
+/*
* register map of the ZL10036/ZL10038
*
* reg[default] content
@@ -219,7 +219,7 @@ static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
if (fbw <= 28820) {
br = _BR_MAXIMUM;
} else {
- /**
+ /*
* f(bw)=34,6MHz f(xtal)=10.111MHz
* br = (10111/34600) * 63 * 1/K = 14;
*/
@@ -315,7 +315,7 @@ static int zl10036_set_params(struct dvb_frontend *fe)
|| (frequency > fe->ops.info.frequency_max))
return -EINVAL;
- /**
+ /*
* alpha = 1.35 for dvb-s
* fBW = (alpha*symbolrate)/(2*0.8)
* 1.35 / (2*0.8) = 27 / 32
diff --git a/drivers/media/dvb-frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h
index 88751adfecf7..ec90ca927739 100644
--- a/drivers/media/dvb-frontends/zl10036.h
+++ b/drivers/media/dvb-frontends/zl10036.h
@@ -20,20 +20,20 @@
#include <linux/i2c.h>
#include "dvb_frontend.h"
-/**
- * Attach a zl10036 tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param config zl10036_config structure
- * @return FE pointer on success, NULL on failure.
- */
-
struct zl10036_config {
u8 tuner_address;
int rf_loop_enable;
};
#if IS_REACHABLE(CONFIG_DVB_ZL10036)
+/**
+ * Attach a zl10036 tuner to the supplied frontend structure.
+ *
+ * @fe: Frontend to attach to.
+ * @config: zl10036_config structure.
+ * @i2c: pointer to struct i2c_adapter.
+ * return: FE pointer on success, NULL on failure.
+ */
extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
const struct zl10036_config *config, struct i2c_adapter *i2c);
#else
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 94153895fcd4..cb5d7ff82915 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -354,6 +354,14 @@ config VIDEO_TC358743
To compile this driver as a module, choose M here: the
module will be called tc358743.
+config VIDEO_TC358743_CEC
+ bool "Enable Toshiba TC358743 CEC support"
+ depends on VIDEO_TC358743
+ select CEC_CORE
+ ---help---
+ When selected the tc358743 will support the optional
+ HDMI CEC feature.
+
config VIDEO_TVP514X
tristate "Texas Instruments TVP514x video decoder"
depends on VIDEO_V4L2 && I2C
@@ -547,6 +555,14 @@ config VIDEO_APTINA_PLL
config VIDEO_SMIAPP_PLL
tristate
+config VIDEO_IMX274
+ tristate "Sony IMX274 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a V4L2 sensor-level driver for the Sony IMX274
+ CMOS image sensor.
+
config VIDEO_OV2640
tristate "OmniVision OV2640 sensor support"
depends on VIDEO_V4L2 && I2C
@@ -660,6 +676,7 @@ config VIDEO_OV13858
tristate "OmniVision OV13858 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT
+ select V4L2_FWNODE
---help---
This is a Video4Linux2 sensor-level driver for the OmniVision
OV13858 camera.
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index c843c181dfb9..548a9efce966 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
msp3400-objs := msp3400-driver.o msp3400-kthreads.o
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
@@ -92,5 +93,6 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
+obj-$(CONFIG_VIDEO_IMX274) += imx274.o
obj-$(CONFIG_SDR_MAX2175) += max2175.o
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 3df28f2f9b38..6fb818a775db 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1328,7 +1328,7 @@ static int adv7180_probe(struct i2c_client *client,
state->input = 0;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
- sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
ret = adv7180_init_controls(state);
if (ret)
diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c
index b33ccfc08708..4aa8e45b5cd3 100644
--- a/drivers/media/i2c/adv748x/adv748x-afe.c
+++ b/drivers/media/i2c/adv748x/adv748x-afe.c
@@ -217,6 +217,7 @@ static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
struct adv748x_state *state = adv748x_afe_to_state(afe);
+ int afe_std;
int ret;
mutex_lock(&state->mutex);
@@ -235,8 +236,12 @@ static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
/* Read detected standard */
ret = adv748x_afe_status(afe, NULL, std);
+ afe_std = adv748x_afe_std(afe->curr_norm);
+ if (afe_std < 0)
+ goto unlock;
+
/* Restore original state */
- adv748x_afe_set_video_standard(state, afe->curr_norm);
+ adv748x_afe_set_video_standard(state, afe_std);
unlock:
mutex_unlock(&state->mutex);
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index f289b8aca1da..c786cd125417 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1948,7 +1948,7 @@ static int adv76xx_set_format(struct v4l2_subdev *sd,
return -EINVAL;
info = adv76xx_format_info(state, format->format.code);
- if (info == NULL)
+ if (!info)
info = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8);
adv76xx_fill_format(state, &format->format);
@@ -2256,7 +2256,7 @@ static int adv76xx_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
return 0;
}
- if (data == NULL)
+ if (!data)
return -ENODATA;
if (edid->start_block >= state->edid.blocks)
@@ -3316,10 +3316,8 @@ static int adv76xx_probe(struct i2c_client *client,
client->addr << 1);
state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
- if (!state) {
- v4l_err(client, "Could not allocate adv76xx_state memory!\n");
+ if (!state)
return -ENOMEM;
- }
state->i2c_clients[ADV76XX_PAGE_IO] = client;
@@ -3482,7 +3480,7 @@ static int adv76xx_probe(struct i2c_client *client,
state->i2c_clients[i] =
adv76xx_dummy_client(sd, state->pdata.i2c_addresses[i],
0xf2 + i);
- if (state->i2c_clients[i] == NULL) {
+ if (!state->i2c_clients[i]) {
err = -ENOMEM;
v4l2_err(sd, "failed to create i2c client %u\n", i);
goto err_i2c;
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 65f34e7e146f..136aa80a834b 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -3467,11 +3467,9 @@ static int adv7842_probe(struct i2c_client *client,
return -ENODEV;
}
- state = devm_kzalloc(&client->dev, sizeof(struct adv7842_state), GFP_KERNEL);
- if (!state) {
- v4l_err(client, "Could not allocate adv7842_state memory!\n");
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+ if (!state)
return -ENOMEM;
- }
/* platform data */
state->pdata = *pdata;
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index 39f51daa7558..f38bf819d805 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -1745,7 +1745,7 @@ static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- v4l2_std_id stds[] = {
+ static const v4l2_std_id stds[] = {
/* 0000 */ V4L2_STD_UNKNOWN,
/* 0001 */ V4L2_STD_NTSC_M,
diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c
index 95af4fc99cd0..ed01e8bd4331 100644
--- a/drivers/media/i2c/dw9714.c
+++ b/drivers/media/i2c/dw9714.c
@@ -21,6 +21,11 @@
#define DW9714_NAME "dw9714"
#define DW9714_MAX_FOCUS_POS 1023
/*
+ * This sets the minimum granularity for the focus positions.
+ * A value of 1 gives maximum accuracy for a desired focus position
+ */
+#define DW9714_FOCUS_STEPS 1
+/*
* This acts as the minimum granularity of lens movement.
* Keep this value power of 2, so the control steps can be
* uniformly adjusted for gradual lens movement, with desired
@@ -137,7 +142,7 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm)
v4l2_ctrl_handler_init(hdl, 1);
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
- 0, DW9714_MAX_FOCUS_POS, DW9714_CTRL_STEPS, 0);
+ 0, DW9714_MAX_FOCUS_POS, DW9714_FOCUS_STEPS, 0);
if (hdl->error)
dev_err(&client->dev, "%s fail error: 0x%x\n",
diff --git a/drivers/media/i2c/et8ek8/Kconfig b/drivers/media/i2c/et8ek8/Kconfig
index 14399365ad7f..9fe409e95666 100644
--- a/drivers/media/i2c/et8ek8/Kconfig
+++ b/drivers/media/i2c/et8ek8/Kconfig
@@ -1,6 +1,7 @@
config VIDEO_ET8EK8
tristate "ET8EK8 camera sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ select V4L2_FWNODE
---help---
This is a driver for the Toshiba ET8EK8 5 MP camera sensor.
It is used for example in Nokia N900 (RX-51).
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index c14f0fd6ded3..e9eff9039ef5 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1453,7 +1453,7 @@ static int et8ek8_probe(struct i2c_client *client,
goto err_mutex;
}
- ret = v4l2_async_register_subdev(&sensor->subdev);
+ ret = v4l2_async_register_subdev_sensor_common(&sensor->subdev);
if (ret < 0)
goto err_entity;
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
new file mode 100644
index 000000000000..2f71af2f90bf
--- /dev/null
+++ b/drivers/media/i2c/imx274.c
@@ -0,0 +1,1810 @@
+/*
+ * imx274.c - IMX274 CMOS Image Sensor driver
+ *
+ * Copyright (C) 2017, Leopard Imaging, Inc.
+ *
+ * Leon Luo <leonl@leopardimaging.com>
+ * Edwin Zou <edwinz@leopardimaging.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+/*
+ * See "SHR, SVR Setting" in datasheet
+ */
+#define IMX274_DEFAULT_FRAME_LENGTH (4550)
+#define IMX274_MAX_FRAME_LENGTH (0x000fffff)
+
+/*
+ * See "Frame Rate Adjustment" in datasheet
+ */
+#define IMX274_PIXCLK_CONST1 (72000000)
+#define IMX274_PIXCLK_CONST2 (1000000)
+
+/*
+ * The input gain is shifted by IMX274_GAIN_SHIFT to get
+ * decimal number. The real gain is
+ * (float)input_gain_value / (1 << IMX274_GAIN_SHIFT)
+ */
+#define IMX274_GAIN_SHIFT (8)
+#define IMX274_GAIN_SHIFT_MASK ((1 << IMX274_GAIN_SHIFT) - 1)
+
+/*
+ * See "Analog Gain" and "Digital Gain" in datasheet
+ * min gain is 1X
+ * max gain is calculated based on IMX274_GAIN_REG_MAX
+ */
+#define IMX274_GAIN_REG_MAX (1957)
+#define IMX274_MIN_GAIN (0x01 << IMX274_GAIN_SHIFT)
+#define IMX274_MAX_ANALOG_GAIN ((2048 << IMX274_GAIN_SHIFT)\
+ / (2048 - IMX274_GAIN_REG_MAX))
+#define IMX274_MAX_DIGITAL_GAIN (8)
+#define IMX274_DEF_GAIN (20 << IMX274_GAIN_SHIFT)
+#define IMX274_GAIN_CONST (2048) /* for gain formula */
+
+/*
+ * 1 line time in us = (HMAX / 72), minimal is 4 lines
+ */
+#define IMX274_MIN_EXPOSURE_TIME (4 * 260 / 72)
+
+#define IMX274_DEFAULT_MODE IMX274_MODE_3840X2160
+#define IMX274_MAX_WIDTH (3840)
+#define IMX274_MAX_HEIGHT (2160)
+#define IMX274_MAX_FRAME_RATE (120)
+#define IMX274_MIN_FRAME_RATE (5)
+#define IMX274_DEF_FRAME_RATE (60)
+
+/*
+ * register SHR is limited to (SVR value + 1) x VMAX value - 4
+ */
+#define IMX274_SHR_LIMIT_CONST (4)
+
+/*
+ * Constants for sensor reset delay
+ */
+#define IMX274_RESET_DELAY1 (2000)
+#define IMX274_RESET_DELAY2 (2200)
+
+/*
+ * shift and mask constants
+ */
+#define IMX274_SHIFT_8_BITS (8)
+#define IMX274_SHIFT_16_BITS (16)
+#define IMX274_MASK_LSB_2_BITS (0x03)
+#define IMX274_MASK_LSB_3_BITS (0x07)
+#define IMX274_MASK_LSB_4_BITS (0x0f)
+#define IMX274_MASK_LSB_8_BITS (0x00ff)
+
+#define DRIVER_NAME "IMX274"
+
+/*
+ * IMX274 register definitions
+ */
+#define IMX274_FRAME_LENGTH_ADDR_1 0x30FA /* VMAX, MSB */
+#define IMX274_FRAME_LENGTH_ADDR_2 0x30F9 /* VMAX */
+#define IMX274_FRAME_LENGTH_ADDR_3 0x30F8 /* VMAX, LSB */
+#define IMX274_SVR_REG_MSB 0x300F /* SVR */
+#define IMX274_SVR_REG_LSB 0x300E /* SVR */
+#define IMX274_HMAX_REG_MSB 0x30F7 /* HMAX */
+#define IMX274_HMAX_REG_LSB 0x30F6 /* HMAX */
+#define IMX274_COARSE_TIME_ADDR_MSB 0x300D /* SHR */
+#define IMX274_COARSE_TIME_ADDR_LSB 0x300C /* SHR */
+#define IMX274_ANALOG_GAIN_ADDR_LSB 0x300A /* ANALOG GAIN LSB */
+#define IMX274_ANALOG_GAIN_ADDR_MSB 0x300B /* ANALOG GAIN MSB */
+#define IMX274_DIGITAL_GAIN_REG 0x3012 /* Digital Gain */
+#define IMX274_VFLIP_REG 0x301A /* VERTICAL FLIP */
+#define IMX274_TEST_PATTERN_REG 0x303D /* TEST PATTERN */
+#define IMX274_STANDBY_REG 0x3000 /* STANDBY */
+
+#define IMX274_TABLE_WAIT_MS 0
+#define IMX274_TABLE_END 1
+
+/*
+ * imx274 I2C operation related structure
+ */
+struct reg_8 {
+ u16 addr;
+ u8 val;
+};
+
+static const struct regmap_config imx274_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .cache_type = REGCACHE_RBTREE,
+};
+
+enum imx274_mode {
+ IMX274_MODE_3840X2160,
+ IMX274_MODE_1920X1080,
+ IMX274_MODE_1280X720,
+
+ IMX274_MODE_START_STREAM_1,
+ IMX274_MODE_START_STREAM_2,
+ IMX274_MODE_START_STREAM_3,
+ IMX274_MODE_START_STREAM_4,
+ IMX274_MODE_STOP_STREAM
+};
+
+/*
+ * imx274 format related structure
+ */
+struct imx274_frmfmt {
+ u32 mbus_code;
+ enum v4l2_colorspace colorspace;
+ struct v4l2_frmsize_discrete size;
+ enum imx274_mode mode;
+};
+
+/*
+ * imx274 test pattern related structure
+ */
+enum {
+ TEST_PATTERN_DISABLED = 0,
+ TEST_PATTERN_ALL_000H,
+ TEST_PATTERN_ALL_FFFH,
+ TEST_PATTERN_ALL_555H,
+ TEST_PATTERN_ALL_AAAH,
+ TEST_PATTERN_VSP_5AH, /* VERTICAL STRIPE PATTERN 555H/AAAH */
+ TEST_PATTERN_VSP_A5H, /* VERTICAL STRIPE PATTERN AAAH/555H */
+ TEST_PATTERN_VSP_05H, /* VERTICAL STRIPE PATTERN 000H/555H */
+ TEST_PATTERN_VSP_50H, /* VERTICAL STRIPE PATTERN 555H/000H */
+ TEST_PATTERN_VSP_0FH, /* VERTICAL STRIPE PATTERN 000H/FFFH */
+ TEST_PATTERN_VSP_F0H, /* VERTICAL STRIPE PATTERN FFFH/000H */
+ TEST_PATTERN_H_COLOR_BARS,
+ TEST_PATTERN_V_COLOR_BARS,
+};
+
+static const char * const tp_qmenu[] = {
+ "Disabled",
+ "All 000h Pattern",
+ "All FFFh Pattern",
+ "All 555h Pattern",
+ "All AAAh Pattern",
+ "Vertical Stripe (555h / AAAh)",
+ "Vertical Stripe (AAAh / 555h)",
+ "Vertical Stripe (000h / 555h)",
+ "Vertical Stripe (555h / 000h)",
+ "Vertical Stripe (000h / FFFh)",
+ "Vertical Stripe (FFFh / 000h)",
+ "Horizontal Color Bars",
+ "Vertical Color Bars",
+};
+
+/*
+ * All-pixel scan mode (10-bit)
+ * imx274 mode1(refer to datasheet) register configuration with
+ * 3840x2160 resolution, raw10 data and mipi four lane output
+ */
+static const struct reg_8 imx274_mode1_3840x2160_raw10[] = {
+ {0x3004, 0x01},
+ {0x3005, 0x01},
+ {0x3006, 0x00},
+ {0x3007, 0x02},
+
+ {0x3018, 0xA2}, /* output XVS, HVS */
+
+ {0x306B, 0x05},
+ {0x30E2, 0x01},
+ {0x30F6, 0x07}, /* HMAX, 263 */
+ {0x30F7, 0x01}, /* HMAX */
+
+ {0x30dd, 0x01}, /* crop to 2160 */
+ {0x30de, 0x06},
+ {0x30df, 0x00},
+ {0x30e0, 0x12},
+ {0x30e1, 0x00},
+ {0x3037, 0x01}, /* to crop to 3840 */
+ {0x3038, 0x0c},
+ {0x3039, 0x00},
+ {0x303a, 0x0c},
+ {0x303b, 0x0f},
+
+ {0x30EE, 0x01},
+ {0x3130, 0x86},
+ {0x3131, 0x08},
+ {0x3132, 0x7E},
+ {0x3133, 0x08},
+ {0x3342, 0x0A},
+ {0x3343, 0x00},
+ {0x3344, 0x16},
+ {0x3345, 0x00},
+ {0x33A6, 0x01},
+ {0x3528, 0x0E},
+ {0x3554, 0x1F},
+ {0x3555, 0x01},
+ {0x3556, 0x01},
+ {0x3557, 0x01},
+ {0x3558, 0x01},
+ {0x3559, 0x00},
+ {0x355A, 0x00},
+ {0x35BA, 0x0E},
+ {0x366A, 0x1B},
+ {0x366B, 0x1A},
+ {0x366C, 0x19},
+ {0x366D, 0x17},
+ {0x3A41, 0x08},
+
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * Horizontal/vertical 2/2-line binning
+ * (Horizontal and vertical weightedbinning, 10-bit)
+ * imx274 mode3(refer to datasheet) register configuration with
+ * 1920x1080 resolution, raw10 data and mipi four lane output
+ */
+static const struct reg_8 imx274_mode3_1920x1080_raw10[] = {
+ {0x3004, 0x02},
+ {0x3005, 0x21},
+ {0x3006, 0x00},
+ {0x3007, 0x11},
+
+ {0x3018, 0xA2}, /* output XVS, HVS */
+
+ {0x306B, 0x05},
+ {0x30E2, 0x02},
+
+ {0x30F6, 0x04}, /* HMAX, 260 */
+ {0x30F7, 0x01}, /* HMAX */
+
+ {0x30dd, 0x01}, /* to crop to 1920x1080 */
+ {0x30de, 0x05},
+ {0x30df, 0x00},
+ {0x30e0, 0x04},
+ {0x30e1, 0x00},
+ {0x3037, 0x01},
+ {0x3038, 0x0c},
+ {0x3039, 0x00},
+ {0x303a, 0x0c},
+ {0x303b, 0x0f},
+
+ {0x30EE, 0x01},
+ {0x3130, 0x4E},
+ {0x3131, 0x04},
+ {0x3132, 0x46},
+ {0x3133, 0x04},
+ {0x3342, 0x0A},
+ {0x3343, 0x00},
+ {0x3344, 0x1A},
+ {0x3345, 0x00},
+ {0x33A6, 0x01},
+ {0x3528, 0x0E},
+ {0x3554, 0x00},
+ {0x3555, 0x01},
+ {0x3556, 0x01},
+ {0x3557, 0x01},
+ {0x3558, 0x01},
+ {0x3559, 0x00},
+ {0x355A, 0x00},
+ {0x35BA, 0x0E},
+ {0x366A, 0x1B},
+ {0x366B, 0x1A},
+ {0x366C, 0x19},
+ {0x366D, 0x17},
+ {0x3A41, 0x08},
+
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * Vertical 2/3 subsampling binning horizontal 3 binning
+ * imx274 mode5(refer to datasheet) register configuration with
+ * 1280x720 resolution, raw10 data and mipi four lane output
+ */
+static const struct reg_8 imx274_mode5_1280x720_raw10[] = {
+ {0x3004, 0x03},
+ {0x3005, 0x31},
+ {0x3006, 0x00},
+ {0x3007, 0x09},
+
+ {0x3018, 0xA2}, /* output XVS, HVS */
+
+ {0x306B, 0x05},
+ {0x30E2, 0x03},
+
+ {0x30F6, 0x04}, /* HMAX, 260 */
+ {0x30F7, 0x01}, /* HMAX */
+
+ {0x30DD, 0x01},
+ {0x30DE, 0x07},
+ {0x30DF, 0x00},
+ {0x40E0, 0x04},
+ {0x30E1, 0x00},
+ {0x3030, 0xD4},
+ {0x3031, 0x02},
+ {0x3032, 0xD0},
+ {0x3033, 0x02},
+
+ {0x30EE, 0x01},
+ {0x3130, 0xE2},
+ {0x3131, 0x02},
+ {0x3132, 0xDE},
+ {0x3133, 0x02},
+ {0x3342, 0x0A},
+ {0x3343, 0x00},
+ {0x3344, 0x1B},
+ {0x3345, 0x00},
+ {0x33A6, 0x01},
+ {0x3528, 0x0E},
+ {0x3554, 0x00},
+ {0x3555, 0x01},
+ {0x3556, 0x01},
+ {0x3557, 0x01},
+ {0x3558, 0x01},
+ {0x3559, 0x00},
+ {0x355A, 0x00},
+ {0x35BA, 0x0E},
+ {0x366A, 0x1B},
+ {0x366B, 0x19},
+ {0x366C, 0x17},
+ {0x366D, 0x17},
+ {0x3A41, 0x04},
+
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 first step register configuration for
+ * starting stream
+ */
+static const struct reg_8 imx274_start_1[] = {
+ {IMX274_STANDBY_REG, 0x12},
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 second step register configuration for
+ * starting stream
+ */
+static const struct reg_8 imx274_start_2[] = {
+ {0x3120, 0xF0}, /* clock settings */
+ {0x3121, 0x00}, /* clock settings */
+ {0x3122, 0x02}, /* clock settings */
+ {0x3129, 0x9C}, /* clock settings */
+ {0x312A, 0x02}, /* clock settings */
+ {0x312D, 0x02}, /* clock settings */
+
+ {0x310B, 0x00},
+
+ /* PLSTMG */
+ {0x304C, 0x00}, /* PLSTMG01 */
+ {0x304D, 0x03},
+ {0x331C, 0x1A},
+ {0x331D, 0x00},
+ {0x3502, 0x02},
+ {0x3529, 0x0E},
+ {0x352A, 0x0E},
+ {0x352B, 0x0E},
+ {0x3538, 0x0E},
+ {0x3539, 0x0E},
+ {0x3553, 0x00},
+ {0x357D, 0x05},
+ {0x357F, 0x05},
+ {0x3581, 0x04},
+ {0x3583, 0x76},
+ {0x3587, 0x01},
+ {0x35BB, 0x0E},
+ {0x35BC, 0x0E},
+ {0x35BD, 0x0E},
+ {0x35BE, 0x0E},
+ {0x35BF, 0x0E},
+ {0x366E, 0x00},
+ {0x366F, 0x00},
+ {0x3670, 0x00},
+ {0x3671, 0x00},
+
+ /* PSMIPI */
+ {0x3304, 0x32}, /* PSMIPI1 */
+ {0x3305, 0x00},
+ {0x3306, 0x32},
+ {0x3307, 0x00},
+ {0x3590, 0x32},
+ {0x3591, 0x00},
+ {0x3686, 0x32},
+ {0x3687, 0x00},
+
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 third step register configuration for
+ * starting stream
+ */
+static const struct reg_8 imx274_start_3[] = {
+ {IMX274_STANDBY_REG, 0x00},
+ {0x303E, 0x02}, /* SYS_MODE = 2 */
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 forth step register configuration for
+ * starting stream
+ */
+static const struct reg_8 imx274_start_4[] = {
+ {0x30F4, 0x00},
+ {0x3018, 0xA2}, /* XHS VHS OUTUPT */
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 register configuration for stoping stream
+ */
+static const struct reg_8 imx274_stop[] = {
+ {IMX274_STANDBY_REG, 0x01},
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 disable test pattern register configuration
+ */
+static const struct reg_8 imx274_tp_disabled[] = {
+ {0x303C, 0x00},
+ {0x377F, 0x00},
+ {0x3781, 0x00},
+ {0x370B, 0x00},
+ {IMX274_TABLE_END, 0x00}
+};
+
+/*
+ * imx274 test pattern register configuration
+ * reg 0x303D defines the test pattern modes
+ */
+static const struct reg_8 imx274_tp_regs[] = {
+ {0x303C, 0x11},
+ {0x370E, 0x01},
+ {0x377F, 0x01},
+ {0x3781, 0x01},
+ {0x370B, 0x11},
+ {IMX274_TABLE_END, 0x00}
+};
+
+static const struct reg_8 *mode_table[] = {
+ [IMX274_MODE_3840X2160] = imx274_mode1_3840x2160_raw10,
+ [IMX274_MODE_1920X1080] = imx274_mode3_1920x1080_raw10,
+ [IMX274_MODE_1280X720] = imx274_mode5_1280x720_raw10,
+
+ [IMX274_MODE_START_STREAM_1] = imx274_start_1,
+ [IMX274_MODE_START_STREAM_2] = imx274_start_2,
+ [IMX274_MODE_START_STREAM_3] = imx274_start_3,
+ [IMX274_MODE_START_STREAM_4] = imx274_start_4,
+ [IMX274_MODE_STOP_STREAM] = imx274_stop,
+};
+
+/*
+ * imx274 format related structure
+ */
+static const struct imx274_frmfmt imx274_formats[] = {
+ {MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, {3840, 2160},
+ IMX274_MODE_3840X2160},
+ {MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, {1920, 1080},
+ IMX274_MODE_1920X1080},
+ {MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, {1280, 720},
+ IMX274_MODE_1280X720},
+};
+
+/*
+ * minimal frame length for each mode
+ * refer to datasheet section "Frame Rate Adjustment (CSI-2)"
+ */
+static const int min_frame_len[] = {
+ 4550, /* mode 1, 4K */
+ 2310, /* mode 3, 1080p */
+ 2310 /* mode 5, 720p */
+};
+
+/*
+ * minimal numbers of SHR register
+ * refer to datasheet table "Shutter Setting (CSI-2)"
+ */
+static const int min_SHR[] = {
+ 12, /* mode 1, 4K */
+ 8, /* mode 3, 1080p */
+ 8 /* mode 5, 720p */
+};
+
+static const int max_frame_rate[] = {
+ 60, /* mode 1 , 4K */
+ 120, /* mode 3, 1080p */
+ 120 /* mode 5, 720p */
+};
+
+/*
+ * Number of clocks per internal offset period
+ * a constant based on mode
+ * refer to section "Integration Time in Each Readout Drive Mode (CSI-2)"
+ * in the datasheet
+ * for the implemented 3 modes, it happens to be the same number
+ */
+static const int nocpiop[] = {
+ 112, /* mode 1 , 4K */
+ 112, /* mode 3, 1080p */
+ 112 /* mode 5, 720p */
+};
+
+/*
+ * struct imx274_ctrls - imx274 ctrl structure
+ * @handler: V4L2 ctrl handler structure
+ * @exposure: Pointer to expsure ctrl structure
+ * @gain: Pointer to gain ctrl structure
+ * @vflip: Pointer to vflip ctrl structure
+ * @test_pattern: Pointer to test pattern ctrl structure
+ */
+struct imx274_ctrls {
+ struct v4l2_ctrl_handler handler;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *gain;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *test_pattern;
+};
+
+/*
+ * struct stim274 - imx274 device structure
+ * @sd: V4L2 subdevice structure
+ * @pd: Media pad structure
+ * @client: Pointer to I2C client
+ * @ctrls: imx274 control structure
+ * @format: V4L2 media bus frame format structure
+ * @frame_rate: V4L2 frame rate structure
+ * @regmap: Pointer to regmap structure
+ * @reset_gpio: Pointer to reset gpio
+ * @lock: Mutex structure
+ * @mode_index: Resolution mode index
+ */
+struct stimx274 {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct i2c_client *client;
+ struct imx274_ctrls ctrls;
+ struct v4l2_mbus_framefmt format;
+ struct v4l2_fract frame_interval;
+ struct regmap *regmap;
+ struct gpio_desc *reset_gpio;
+ struct mutex lock; /* mutex lock for operations */
+ u32 mode_index;
+};
+
+/*
+ * Function declaration
+ */
+static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl);
+static int imx274_set_exposure(struct stimx274 *priv, int val);
+static int imx274_set_vflip(struct stimx274 *priv, int val);
+static int imx274_set_test_pattern(struct stimx274 *priv, int val);
+static int imx274_set_frame_interval(struct stimx274 *priv,
+ struct v4l2_fract frame_interval);
+
+static inline void msleep_range(unsigned int delay_base)
+{
+ usleep_range(delay_base * 1000, delay_base * 1000 + 500);
+}
+
+/*
+ * v4l2_ctrl and v4l2_subdev related operations
+ */
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
+{
+ return &container_of(ctrl->handler,
+ struct stimx274, ctrls.handler)->sd;
+}
+
+static inline struct stimx274 *to_imx274(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct stimx274, sd);
+}
+
+/*
+ * imx274_regmap_util_write_table_8 - Function for writing register table
+ * @regmap: Pointer to device reg map structure
+ * @table: Table containing register values
+ * @wait_ms_addr: Flag for performing delay
+ * @end_addr: Flag for incating end of table
+ *
+ * This is used to write register table into sensor's reg map.
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_regmap_util_write_table_8(struct regmap *regmap,
+ const struct reg_8 table[],
+ u16 wait_ms_addr, u16 end_addr)
+{
+ int err;
+ const struct reg_8 *next;
+ u8 val;
+
+ int range_start = -1;
+ int range_count = 0;
+ u8 range_vals[16];
+ int max_range_vals = ARRAY_SIZE(range_vals);
+
+ for (next = table;; next++) {
+ if ((next->addr != range_start + range_count) ||
+ (next->addr == end_addr) ||
+ (next->addr == wait_ms_addr) ||
+ (range_count == max_range_vals)) {
+ if (range_count == 1)
+ err = regmap_write(regmap,
+ range_start, range_vals[0]);
+ else if (range_count > 1)
+ err = regmap_bulk_write(regmap, range_start,
+ &range_vals[0],
+ range_count);
+
+ if (err)
+ return err;
+
+ range_start = -1;
+ range_count = 0;
+
+ /* Handle special address values */
+ if (next->addr == end_addr)
+ break;
+
+ if (next->addr == wait_ms_addr) {
+ msleep_range(next->val);
+ continue;
+ }
+ }
+
+ val = next->val;
+
+ if (range_start == -1)
+ range_start = next->addr;
+
+ range_vals[range_count++] = val;
+ }
+ return 0;
+}
+
+static inline int imx274_read_reg(struct stimx274 *priv, u16 addr, u8 *val)
+{
+ int err;
+
+ err = regmap_read(priv->regmap, addr, (unsigned int *)val);
+ if (err)
+ dev_err(&priv->client->dev,
+ "%s : i2c read failed, addr = %x\n", __func__, addr);
+ else
+ dev_dbg(&priv->client->dev,
+ "%s : addr 0x%x, val=0x%x\n", __func__,
+ addr, *val);
+ return err;
+}
+
+static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val)
+{
+ int err;
+
+ err = regmap_write(priv->regmap, addr, val);
+ if (err)
+ dev_err(&priv->client->dev,
+ "%s : i2c write failed, %x = %x\n", __func__,
+ addr, val);
+ else
+ dev_dbg(&priv->client->dev,
+ "%s : addr 0x%x, val=0x%x\n", __func__,
+ addr, val);
+ return err;
+}
+
+static int imx274_write_table(struct stimx274 *priv, const struct reg_8 table[])
+{
+ return imx274_regmap_util_write_table_8(priv->regmap,
+ table, IMX274_TABLE_WAIT_MS, IMX274_TABLE_END);
+}
+
+/*
+ * imx274_mode_regs - Function for set mode registers per mode index
+ * @priv: Pointer to device structure
+ * @mode: Mode index value
+ *
+ * This is used to start steam per mode index.
+ * mode = 0, start stream for sensor Mode 1: 4K/raw10
+ * mode = 1, start stream for sensor Mode 3: 1080p/raw10
+ * mode = 2, start stream for sensor Mode 5: 720p/raw10
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_mode_regs(struct stimx274 *priv, int mode)
+{
+ int err = 0;
+
+ err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_1]);
+ if (err)
+ return err;
+
+ err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_2]);
+ if (err)
+ return err;
+
+ err = imx274_write_table(priv, mode_table[mode]);
+
+ return err;
+}
+
+/*
+ * imx274_start_stream - Function for starting stream per mode index
+ * @priv: Pointer to device structure
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_start_stream(struct stimx274 *priv)
+{
+ int err = 0;
+
+ /*
+ * Refer to "Standby Cancel Sequence when using CSI-2" in
+ * imx274 datasheet, it should wait 10ms or more here.
+ * give it 1 extra ms for margin
+ */
+ msleep_range(11);
+ err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_3]);
+ if (err)
+ return err;
+
+ /*
+ * Refer to "Standby Cancel Sequence when using CSI-2" in
+ * imx274 datasheet, it should wait 7ms or more here.
+ * give it 1 extra ms for margin
+ */
+ msleep_range(8);
+ err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_4]);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+/*
+ * imx274_reset - Function called to reset the sensor
+ * @priv: Pointer to device structure
+ * @rst: Input value for determining the sensor's end state after reset
+ *
+ * Set the senor in reset and then
+ * if rst = 0, keep it in reset;
+ * if rst = 1, bring it out of reset.
+ *
+ */
+static void imx274_reset(struct stimx274 *priv, int rst)
+{
+ gpiod_set_value_cansleep(priv->reset_gpio, 0);
+ usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2);
+ gpiod_set_value_cansleep(priv->reset_gpio, !!rst);
+ usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2);
+}
+
+/**
+ * imx274_s_ctrl - This is used to set the imx274 V4L2 controls
+ * @ctrl: V4L2 control to be set
+ *
+ * This function is used to set the V4L2 controls for the imx274 sensor.
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+ struct stimx274 *imx274 = to_imx274(sd);
+ int ret = -EINVAL;
+
+ dev_dbg(&imx274->client->dev,
+ "%s : s_ctrl: %s, value: %d\n", __func__,
+ ctrl->name, ctrl->val);
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ dev_dbg(&imx274->client->dev,
+ "%s : set V4L2_CID_EXPOSURE\n", __func__);
+ ret = imx274_set_exposure(imx274, ctrl->val);
+ break;
+
+ case V4L2_CID_GAIN:
+ dev_dbg(&imx274->client->dev,
+ "%s : set V4L2_CID_GAIN\n", __func__);
+ ret = imx274_set_gain(imx274, ctrl);
+ break;
+
+ case V4L2_CID_VFLIP:
+ dev_dbg(&imx274->client->dev,
+ "%s : set V4L2_CID_VFLIP\n", __func__);
+ ret = imx274_set_vflip(imx274, ctrl->val);
+ break;
+
+ case V4L2_CID_TEST_PATTERN:
+ dev_dbg(&imx274->client->dev,
+ "%s : set V4L2_CID_TEST_PATTERN\n", __func__);
+ ret = imx274_set_test_pattern(imx274, ctrl->val);
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * imx274_get_fmt - Get the pad format
+ * @sd: Pointer to V4L2 Sub device structure
+ * @cfg: Pointer to sub device pad information structure
+ * @fmt: Pointer to pad level media bus format
+ *
+ * This function is used to get the pad format information.
+ *
+ * Return: 0 on success
+ */
+static int imx274_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct stimx274 *imx274 = to_imx274(sd);
+
+ mutex_lock(&imx274->lock);
+ fmt->format = imx274->format;
+ mutex_unlock(&imx274->lock);
+ return 0;
+}
+
+/**
+ * imx274_set_fmt - This is used to set the pad format
+ * @sd: Pointer to V4L2 Sub device structure
+ * @cfg: Pointer to sub device pad information structure
+ * @format: Pointer to pad level media bus format
+ *
+ * This function is used to set the pad format.
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct v4l2_mbus_framefmt *fmt = &format->format;
+ struct stimx274 *imx274 = to_imx274(sd);
+ struct i2c_client *client = imx274->client;
+ int index;
+
+ dev_dbg(&client->dev,
+ "%s: width = %d height = %d code = %d mbus_code = %d\n",
+ __func__, fmt->width, fmt->height, fmt->code,
+ imx274_formats[imx274->mode_index].mbus_code);
+
+ mutex_lock(&imx274->lock);
+
+ for (index = 0; index < ARRAY_SIZE(imx274_formats); index++) {
+ if (imx274_formats[index].size.width == fmt->width &&
+ imx274_formats[index].size.height == fmt->height)
+ break;
+ }
+
+ if (index >= ARRAY_SIZE(imx274_formats)) {
+ /* default to first format */
+ index = 0;
+ }
+
+ imx274->mode_index = index;
+
+ if (fmt->width > IMX274_MAX_WIDTH)
+ fmt->width = IMX274_MAX_WIDTH;
+ if (fmt->height > IMX274_MAX_HEIGHT)
+ fmt->height = IMX274_MAX_HEIGHT;
+ fmt->width = fmt->width & (~IMX274_MASK_LSB_2_BITS);
+ fmt->height = fmt->height & (~IMX274_MASK_LSB_2_BITS);
+ fmt->field = V4L2_FIELD_NONE;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ cfg->try_fmt = *fmt;
+ else
+ imx274->format = *fmt;
+
+ mutex_unlock(&imx274->lock);
+ return 0;
+}
+
+/**
+ * imx274_g_frame_interval - Get the frame interval
+ * @sd: Pointer to V4L2 Sub device structure
+ * @fi: Pointer to V4l2 Sub device frame interval structure
+ *
+ * This function is used to get the frame interval.
+ *
+ * Return: 0 on success
+ */
+static int imx274_g_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *fi)
+{
+ struct stimx274 *imx274 = to_imx274(sd);
+
+ fi->interval = imx274->frame_interval;
+ dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n",
+ __func__, imx274->frame_interval.numerator,
+ imx274->frame_interval.denominator);
+
+ return 0;
+}
+
+/**
+ * imx274_s_frame_interval - Set the frame interval
+ * @sd: Pointer to V4L2 Sub device structure
+ * @fi: Pointer to V4l2 Sub device frame interval structure
+ *
+ * This function is used to set the frame intervavl.
+ *
+ * Return: 0 on success
+ */
+static int imx274_s_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *fi)
+{
+ struct stimx274 *imx274 = to_imx274(sd);
+ struct v4l2_ctrl *ctrl = imx274->ctrls.exposure;
+ int min, max, def;
+ int ret;
+
+ mutex_lock(&imx274->lock);
+ ret = imx274_set_frame_interval(imx274, fi->interval);
+
+ if (!ret) {
+ /*
+ * exposure time range is decided by frame interval
+ * need to update it after frame interal changes
+ */
+ min = IMX274_MIN_EXPOSURE_TIME;
+ max = fi->interval.numerator * 1000000
+ / fi->interval.denominator;
+ def = max;
+ if (__v4l2_ctrl_modify_range(ctrl, min, max, 1, def)) {
+ dev_err(&imx274->client->dev,
+ "Exposure ctrl range update failed\n");
+ goto unlock;
+ }
+
+ /* update exposure time accordingly */
+ imx274_set_exposure(imx274, imx274->ctrls.exposure->val);
+
+ dev_dbg(&imx274->client->dev, "set frame interval to %uus\n",
+ fi->interval.numerator * 1000000
+ / fi->interval.denominator);
+ }
+
+unlock:
+ mutex_unlock(&imx274->lock);
+
+ return ret;
+}
+
+/**
+ * imx274_load_default - load default control values
+ * @priv: Pointer to device structure
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_load_default(struct stimx274 *priv)
+{
+ int ret;
+
+ /* load default control values */
+ priv->frame_interval.numerator = 1;
+ priv->frame_interval.denominator = IMX274_DEF_FRAME_RATE;
+ priv->ctrls.exposure->val = 1000000 / IMX274_DEF_FRAME_RATE;
+ priv->ctrls.gain->val = IMX274_DEF_GAIN;
+ priv->ctrls.vflip->val = 0;
+ priv->ctrls.test_pattern->val = TEST_PATTERN_DISABLED;
+
+ /* update frame rate */
+ ret = imx274_set_frame_interval(priv,
+ priv->frame_interval);
+ if (ret)
+ return ret;
+
+ /* update exposure time */
+ ret = v4l2_ctrl_s_ctrl(priv->ctrls.exposure, priv->ctrls.exposure->val);
+ if (ret)
+ return ret;
+
+ /* update gain */
+ ret = v4l2_ctrl_s_ctrl(priv->ctrls.gain, priv->ctrls.gain->val);
+ if (ret)
+ return ret;
+
+ /* update vflip */
+ ret = v4l2_ctrl_s_ctrl(priv->ctrls.vflip, priv->ctrls.vflip->val);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/**
+ * imx274_s_stream - It is used to start/stop the streaming.
+ * @sd: V4L2 Sub device
+ * @on: Flag (True / False)
+ *
+ * This function controls the start or stop of streaming for the
+ * imx274 sensor.
+ *
+ * Return: 0 on success, errors otherwise
+ */
+static int imx274_s_stream(struct v4l2_subdev *sd, int on)
+{
+ struct stimx274 *imx274 = to_imx274(sd);
+ int ret = 0;
+
+ dev_dbg(&imx274->client->dev, "%s : %s, mode index = %d\n", __func__,
+ on ? "Stream Start" : "Stream Stop", imx274->mode_index);
+
+ mutex_lock(&imx274->lock);
+
+ if (on) {
+ /* load mode registers */
+ ret = imx274_mode_regs(imx274, imx274->mode_index);
+ if (ret)
+ goto fail;
+
+ /*
+ * update frame rate & expsoure. if the last mode is different,
+ * HMAX could be changed. As the result, frame rate & exposure
+ * are changed.
+ * gain is not affected.
+ */
+ ret = imx274_set_frame_interval(imx274,
+ imx274->frame_interval);
+ if (ret)
+ goto fail;
+
+ /* update exposure time */
+ ret = __v4l2_ctrl_s_ctrl(imx274->ctrls.exposure,
+ imx274->ctrls.exposure->val);
+ if (ret)
+ goto fail;
+
+ /* start stream */
+ ret = imx274_start_stream(imx274);
+ if (ret)
+ goto fail;
+ } else {
+ /* stop stream */
+ ret = imx274_write_table(imx274,
+ mode_table[IMX274_MODE_STOP_STREAM]);
+ if (ret)
+ goto fail;
+ }
+
+ mutex_unlock(&imx274->lock);
+ dev_dbg(&imx274->client->dev,
+ "%s : Done: mode = %d\n", __func__, imx274->mode_index);
+ return 0;
+
+fail:
+ mutex_unlock(&imx274->lock);
+ dev_err(&imx274->client->dev, "s_stream failed\n");
+ return ret;
+}
+
+/*
+ * imx274_get_frame_length - Function for obtaining current frame length
+ * @priv: Pointer to device structure
+ * @val: Pointer to obainted value
+ *
+ * frame_length = vmax x (svr + 1), in unit of hmax.
+ *
+ * Return: 0 on success
+ */
+static int imx274_get_frame_length(struct stimx274 *priv, u32 *val)
+{
+ int err;
+ u16 svr;
+ u32 vmax;
+ u8 reg_val[3];
+
+ /* svr */
+ err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, &reg_val[0]);
+ if (err)
+ goto fail;
+
+ err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, &reg_val[1]);
+ if (err)
+ goto fail;
+
+ svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+
+ /* vmax */
+ err = imx274_read_reg(priv, IMX274_FRAME_LENGTH_ADDR_3, &reg_val[0]);
+ if (err)
+ goto fail;
+
+ err = imx274_read_reg(priv, IMX274_FRAME_LENGTH_ADDR_2, &reg_val[1]);
+ if (err)
+ goto fail;
+
+ err = imx274_read_reg(priv, IMX274_FRAME_LENGTH_ADDR_1, &reg_val[2]);
+ if (err)
+ goto fail;
+
+ vmax = ((reg_val[2] & IMX274_MASK_LSB_3_BITS) << IMX274_SHIFT_16_BITS)
+ + (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+
+ *val = vmax * (svr + 1);
+
+ return 0;
+
+fail:
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+ return err;
+}
+
+static int imx274_clamp_coarse_time(struct stimx274 *priv, u32 *val,
+ u32 *frame_length)
+{
+ int err;
+
+ err = imx274_get_frame_length(priv, frame_length);
+ if (err)
+ return err;
+
+ if (*frame_length < min_frame_len[priv->mode_index])
+ *frame_length = min_frame_len[priv->mode_index];
+
+ *val = *frame_length - *val; /* convert to raw shr */
+ if (*val > *frame_length - IMX274_SHR_LIMIT_CONST)
+ *val = *frame_length - IMX274_SHR_LIMIT_CONST;
+ else if (*val < min_SHR[priv->mode_index])
+ *val = min_SHR[priv->mode_index];
+
+ return 0;
+}
+
+/*
+ * imx274_set_digital gain - Function called when setting digital gain
+ * @priv: Pointer to device structure
+ * @dgain: Value of digital gain.
+ *
+ * Digital gain has only 4 steps: 1x, 2x, 4x, and 8x
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_digital_gain(struct stimx274 *priv, u32 dgain)
+{
+ u8 reg_val;
+
+ reg_val = ffs(dgain);
+
+ if (reg_val)
+ reg_val--;
+
+ reg_val = clamp(reg_val, (u8)0, (u8)3);
+
+ return imx274_write_reg(priv, IMX274_DIGITAL_GAIN_REG,
+ reg_val & IMX274_MASK_LSB_4_BITS);
+}
+
+static inline void imx274_calculate_gain_regs(struct reg_8 regs[2], u16 gain)
+{
+ regs->addr = IMX274_ANALOG_GAIN_ADDR_MSB;
+ regs->val = (gain >> IMX274_SHIFT_8_BITS) & IMX274_MASK_LSB_3_BITS;
+
+ (regs + 1)->addr = IMX274_ANALOG_GAIN_ADDR_LSB;
+ (regs + 1)->val = (gain) & IMX274_MASK_LSB_8_BITS;
+}
+
+/*
+ * imx274_set_gain - Function called when setting gain
+ * @priv: Pointer to device structure
+ * @val: Value of gain. the real value = val << IMX274_GAIN_SHIFT;
+ * @ctrl: v4l2 control pointer
+ *
+ * Set the gain based on input value.
+ * The caller should hold the mutex lock imx274->lock if necessary
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl)
+{
+ struct reg_8 reg_list[2];
+ int err;
+ u32 gain, analog_gain, digital_gain, gain_reg;
+ int i;
+
+ gain = (u32)(ctrl->val);
+
+ dev_dbg(&priv->client->dev,
+ "%s : input gain = %d.%d\n", __func__,
+ gain >> IMX274_GAIN_SHIFT,
+ ((gain & IMX274_GAIN_SHIFT_MASK) * 100) >> IMX274_GAIN_SHIFT);
+
+ if (gain > IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN)
+ gain = IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN;
+ else if (gain < IMX274_MIN_GAIN)
+ gain = IMX274_MIN_GAIN;
+
+ if (gain <= IMX274_MAX_ANALOG_GAIN)
+ digital_gain = 1;
+ else if (gain <= IMX274_MAX_ANALOG_GAIN * 2)
+ digital_gain = 2;
+ else if (gain <= IMX274_MAX_ANALOG_GAIN * 4)
+ digital_gain = 4;
+ else
+ digital_gain = IMX274_MAX_DIGITAL_GAIN;
+
+ analog_gain = gain / digital_gain;
+
+ dev_dbg(&priv->client->dev,
+ "%s : digital gain = %d, analog gain = %d.%d\n",
+ __func__, digital_gain, analog_gain >> IMX274_GAIN_SHIFT,
+ ((analog_gain & IMX274_GAIN_SHIFT_MASK) * 100)
+ >> IMX274_GAIN_SHIFT);
+
+ err = imx274_set_digital_gain(priv, digital_gain);
+ if (err)
+ goto fail;
+
+ /* convert to register value, refer to imx274 datasheet */
+ gain_reg = (u32)IMX274_GAIN_CONST -
+ (IMX274_GAIN_CONST << IMX274_GAIN_SHIFT) / analog_gain;
+ if (gain_reg > IMX274_GAIN_REG_MAX)
+ gain_reg = IMX274_GAIN_REG_MAX;
+
+ imx274_calculate_gain_regs(reg_list, (u16)gain_reg);
+
+ for (i = 0; i < ARRAY_SIZE(reg_list); i++) {
+ err = imx274_write_reg(priv, reg_list[i].addr,
+ reg_list[i].val);
+ if (err)
+ goto fail;
+ }
+
+ if (IMX274_GAIN_CONST - gain_reg == 0) {
+ err = -EINVAL;
+ goto fail;
+ }
+
+ /* convert register value back to gain value */
+ ctrl->val = (IMX274_GAIN_CONST << IMX274_GAIN_SHIFT)
+ / (IMX274_GAIN_CONST - gain_reg) * digital_gain;
+
+ dev_dbg(&priv->client->dev,
+ "%s : GAIN control success, gain_reg = %d, new gain = %d\n",
+ __func__, gain_reg, ctrl->val);
+
+ return 0;
+
+fail:
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+ return err;
+}
+
+static inline void imx274_calculate_coarse_time_regs(struct reg_8 regs[2],
+ u32 coarse_time)
+{
+ regs->addr = IMX274_COARSE_TIME_ADDR_MSB;
+ regs->val = (coarse_time >> IMX274_SHIFT_8_BITS)
+ & IMX274_MASK_LSB_8_BITS;
+ (regs + 1)->addr = IMX274_COARSE_TIME_ADDR_LSB;
+ (regs + 1)->val = (coarse_time) & IMX274_MASK_LSB_8_BITS;
+}
+
+/*
+ * imx274_set_coarse_time - Function called when setting SHR value
+ * @priv: Pointer to device structure
+ * @val: Value for exposure time in number of line_length, or [HMAX]
+ *
+ * Set SHR value based on input value.
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_coarse_time(struct stimx274 *priv, u32 *val)
+{
+ struct reg_8 reg_list[2];
+ int err;
+ u32 coarse_time, frame_length;
+ int i;
+
+ coarse_time = *val;
+
+ /* convert exposure_time to appropriate SHR value */
+ err = imx274_clamp_coarse_time(priv, &coarse_time, &frame_length);
+ if (err)
+ goto fail;
+
+ /* prepare SHR registers */
+ imx274_calculate_coarse_time_regs(reg_list, coarse_time);
+
+ /* write to SHR registers */
+ for (i = 0; i < ARRAY_SIZE(reg_list); i++) {
+ err = imx274_write_reg(priv, reg_list[i].addr,
+ reg_list[i].val);
+ if (err)
+ goto fail;
+ }
+
+ *val = frame_length - coarse_time;
+ return 0;
+
+fail:
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+ return err;
+}
+
+/*
+ * imx274_set_exposure - Function called when setting exposure time
+ * @priv: Pointer to device structure
+ * @val: Variable for exposure time, in the unit of micro-second
+ *
+ * Set exposure time based on input value.
+ * The caller should hold the mutex lock imx274->lock if necessary
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_exposure(struct stimx274 *priv, int val)
+{
+ int err;
+ u16 hmax;
+ u8 reg_val[2];
+ u32 coarse_time; /* exposure time in unit of line (HMAX)*/
+
+ dev_dbg(&priv->client->dev,
+ "%s : EXPOSURE control input = %d\n", __func__, val);
+
+ /* step 1: convert input exposure_time (val) into number of 1[HMAX] */
+
+ /* obtain HMAX value */
+ err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, &reg_val[0]);
+ if (err)
+ goto fail;
+ err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, &reg_val[1]);
+ if (err)
+ goto fail;
+ hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+ if (hmax == 0) {
+ err = -EINVAL;
+ goto fail;
+ }
+
+ coarse_time = (IMX274_PIXCLK_CONST1 / IMX274_PIXCLK_CONST2 * val
+ - nocpiop[priv->mode_index]) / hmax;
+
+ /* step 2: convert exposure_time into SHR value */
+
+ /* set SHR */
+ err = imx274_set_coarse_time(priv, &coarse_time);
+ if (err)
+ goto fail;
+
+ priv->ctrls.exposure->val =
+ (coarse_time * hmax + nocpiop[priv->mode_index])
+ / (IMX274_PIXCLK_CONST1 / IMX274_PIXCLK_CONST2);
+
+ dev_dbg(&priv->client->dev,
+ "%s : EXPOSURE control success\n", __func__);
+ return 0;
+
+fail:
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+
+ return err;
+}
+
+/*
+ * imx274_set_vflip - Function called when setting vertical flip
+ * @priv: Pointer to device structure
+ * @val: Value for vflip setting
+ *
+ * Set vertical flip based on input value.
+ * val = 0: normal, no vertical flip
+ * val = 1: vertical flip enabled
+ * The caller should hold the mutex lock imx274->lock if necessary
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_vflip(struct stimx274 *priv, int val)
+{
+ int err;
+
+ err = imx274_write_reg(priv, IMX274_VFLIP_REG, val);
+ if (err) {
+ dev_err(&priv->client->dev, "VFILP control error\n");
+ return err;
+ }
+
+ dev_dbg(&priv->client->dev,
+ "%s : VFLIP control success\n", __func__);
+
+ return 0;
+}
+
+/*
+ * imx274_set_test_pattern - Function called when setting test pattern
+ * @priv: Pointer to device structure
+ * @val: Variable for test pattern
+ *
+ * Set to different test patterns based on input value.
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_test_pattern(struct stimx274 *priv, int val)
+{
+ int err = 0;
+
+ if (val == TEST_PATTERN_DISABLED) {
+ err = imx274_write_table(priv, imx274_tp_disabled);
+ } else if (val <= TEST_PATTERN_V_COLOR_BARS) {
+ err = imx274_write_reg(priv, IMX274_TEST_PATTERN_REG, val - 1);
+ if (!err)
+ err = imx274_write_table(priv, imx274_tp_regs);
+ } else {
+ err = -EINVAL;
+ }
+
+ if (!err)
+ dev_dbg(&priv->client->dev,
+ "%s : TEST PATTERN control success\n", __func__);
+ else
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+
+ return err;
+}
+
+static inline void imx274_calculate_frame_length_regs(struct reg_8 regs[3],
+ u32 frame_length)
+{
+ regs->addr = IMX274_FRAME_LENGTH_ADDR_1;
+ regs->val = (frame_length >> IMX274_SHIFT_16_BITS)
+ & IMX274_MASK_LSB_4_BITS;
+ (regs + 1)->addr = IMX274_FRAME_LENGTH_ADDR_2;
+ (regs + 1)->val = (frame_length >> IMX274_SHIFT_8_BITS)
+ & IMX274_MASK_LSB_8_BITS;
+ (regs + 2)->addr = IMX274_FRAME_LENGTH_ADDR_3;
+ (regs + 2)->val = (frame_length) & IMX274_MASK_LSB_8_BITS;
+}
+
+/*
+ * imx274_set_frame_length - Function called when setting frame length
+ * @priv: Pointer to device structure
+ * @val: Variable for frame length (= VMAX, i.e. vertical drive period length)
+ *
+ * Set frame length based on input value.
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_frame_length(struct stimx274 *priv, u32 val)
+{
+ struct reg_8 reg_list[3];
+ int err;
+ u32 frame_length;
+ int i;
+
+ dev_dbg(&priv->client->dev, "%s : input length = %d\n",
+ __func__, val);
+
+ frame_length = (u32)val;
+
+ imx274_calculate_frame_length_regs(reg_list, frame_length);
+ for (i = 0; i < ARRAY_SIZE(reg_list); i++) {
+ err = imx274_write_reg(priv, reg_list[i].addr,
+ reg_list[i].val);
+ if (err)
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+ return err;
+}
+
+/*
+ * imx274_set_frame_interval - Function called when setting frame interval
+ * @priv: Pointer to device structure
+ * @frame_interval: Variable for frame interval
+ *
+ * Change frame interval by updating VMAX value
+ * The caller should hold the mutex lock imx274->lock if necessary
+ *
+ * Return: 0 on success
+ */
+static int imx274_set_frame_interval(struct stimx274 *priv,
+ struct v4l2_fract frame_interval)
+{
+ int err;
+ u32 frame_length, req_frame_rate;
+ u16 svr;
+ u16 hmax;
+ u8 reg_val[2];
+
+ dev_dbg(&priv->client->dev, "%s: input frame interval = %d / %d",
+ __func__, frame_interval.numerator,
+ frame_interval.denominator);
+
+ if (frame_interval.numerator == 0) {
+ err = -EINVAL;
+ goto fail;
+ }
+
+ req_frame_rate = (u32)(frame_interval.denominator
+ / frame_interval.numerator);
+
+ /* boundary check */
+ if (req_frame_rate > max_frame_rate[priv->mode_index]) {
+ frame_interval.numerator = 1;
+ frame_interval.denominator =
+ max_frame_rate[priv->mode_index];
+ } else if (req_frame_rate < IMX274_MIN_FRAME_RATE) {
+ frame_interval.numerator = 1;
+ frame_interval.denominator = IMX274_MIN_FRAME_RATE;
+ }
+
+ /*
+ * VMAX = 1/frame_rate x 72M / (SVR+1) / HMAX
+ * frame_length (i.e. VMAX) = (frame_interval) x 72M /(SVR+1) / HMAX
+ */
+
+ /* SVR */
+ err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, &reg_val[0]);
+ if (err)
+ goto fail;
+ err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, &reg_val[1]);
+ if (err)
+ goto fail;
+ svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+ dev_dbg(&priv->client->dev,
+ "%s : register SVR = %d\n", __func__, svr);
+
+ /* HMAX */
+ err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, &reg_val[0]);
+ if (err)
+ goto fail;
+ err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, &reg_val[1]);
+ if (err)
+ goto fail;
+ hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
+ dev_dbg(&priv->client->dev,
+ "%s : register HMAX = %d\n", __func__, hmax);
+
+ if (hmax == 0 || frame_interval.denominator == 0) {
+ err = -EINVAL;
+ goto fail;
+ }
+
+ frame_length = IMX274_PIXCLK_CONST1 / (svr + 1) / hmax
+ * frame_interval.numerator
+ / frame_interval.denominator;
+
+ err = imx274_set_frame_length(priv, frame_length);
+ if (err)
+ goto fail;
+
+ priv->frame_interval = frame_interval;
+ return 0;
+
+fail:
+ dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
+ return err;
+}
+
+static const struct v4l2_subdev_pad_ops imx274_pad_ops = {
+ .get_fmt = imx274_get_fmt,
+ .set_fmt = imx274_set_fmt,
+};
+
+static const struct v4l2_subdev_video_ops imx274_video_ops = {
+ .g_frame_interval = imx274_g_frame_interval,
+ .s_frame_interval = imx274_s_frame_interval,
+ .s_stream = imx274_s_stream,
+};
+
+static const struct v4l2_subdev_ops imx274_subdev_ops = {
+ .pad = &imx274_pad_ops,
+ .video = &imx274_video_ops,
+};
+
+static const struct v4l2_ctrl_ops imx274_ctrl_ops = {
+ .s_ctrl = imx274_s_ctrl,
+};
+
+static const struct of_device_id imx274_of_id_table[] = {
+ { .compatible = "sony,imx274" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx274_of_id_table);
+
+static const struct i2c_device_id imx274_id[] = {
+ { "IMX274", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, imx274_id);
+
+static int imx274_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct v4l2_subdev *sd;
+ struct stimx274 *imx274;
+ int ret;
+
+ /* initialize imx274 */
+ imx274 = devm_kzalloc(&client->dev, sizeof(*imx274), GFP_KERNEL);
+ if (!imx274)
+ return -ENOMEM;
+
+ mutex_init(&imx274->lock);
+
+ /* initialize regmap */
+ imx274->regmap = devm_regmap_init_i2c(client, &imx274_regmap_config);
+ if (IS_ERR(imx274->regmap)) {
+ dev_err(&client->dev,
+ "regmap init failed: %ld\n", PTR_ERR(imx274->regmap));
+ ret = -ENODEV;
+ goto err_regmap;
+ }
+
+ /* initialize subdevice */
+ imx274->client = client;
+ sd = &imx274->sd;
+ v4l2_i2c_subdev_init(sd, client, &imx274_subdev_ops);
+ strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+
+ /* initialize subdev media pad */
+ imx274->pad.flags = MEDIA_PAD_FL_SOURCE;
+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ret = media_entity_pads_init(&sd->entity, 1, &imx274->pad);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s : media entity init Failed %d\n", __func__, ret);
+ goto err_regmap;
+ }
+
+ /* initialize sensor reset gpio */
+ imx274->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(imx274->reset_gpio)) {
+ if (PTR_ERR(imx274->reset_gpio) != -EPROBE_DEFER)
+ dev_err(&client->dev, "Reset GPIO not setup in DT");
+ ret = PTR_ERR(imx274->reset_gpio);
+ goto err_me;
+ }
+
+ /* pull sensor out of reset */
+ imx274_reset(imx274, 1);
+
+ /* initialize controls */
+ ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 2);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s : ctrl handler init Failed\n", __func__);
+ goto err_me;
+ }
+
+ imx274->ctrls.handler.lock = &imx274->lock;
+
+ /* add new controls */
+ imx274->ctrls.test_pattern = v4l2_ctrl_new_std_menu_items(
+ &imx274->ctrls.handler, &imx274_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(tp_qmenu) - 1, 0, 0, tp_qmenu);
+
+ imx274->ctrls.gain = v4l2_ctrl_new_std(
+ &imx274->ctrls.handler,
+ &imx274_ctrl_ops,
+ V4L2_CID_GAIN, IMX274_MIN_GAIN,
+ IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN, 1,
+ IMX274_DEF_GAIN);
+
+ imx274->ctrls.exposure = v4l2_ctrl_new_std(
+ &imx274->ctrls.handler,
+ &imx274_ctrl_ops,
+ V4L2_CID_EXPOSURE, IMX274_MIN_EXPOSURE_TIME,
+ 1000000 / IMX274_DEF_FRAME_RATE, 1,
+ IMX274_MIN_EXPOSURE_TIME);
+
+ imx274->ctrls.vflip = v4l2_ctrl_new_std(
+ &imx274->ctrls.handler,
+ &imx274_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+ imx274->sd.ctrl_handler = &imx274->ctrls.handler;
+ if (imx274->ctrls.handler.error) {
+ ret = imx274->ctrls.handler.error;
+ goto err_ctrls;
+ }
+
+ /* setup default controls */
+ ret = v4l2_ctrl_handler_setup(&imx274->ctrls.handler);
+ if (ret) {
+ dev_err(&client->dev,
+ "Error %d setup default controls\n", ret);
+ goto err_ctrls;
+ }
+
+ /* initialize format */
+ imx274->mode_index = IMX274_MODE_3840X2160;
+ imx274->format.width = imx274_formats[0].size.width;
+ imx274->format.height = imx274_formats[0].size.height;
+ imx274->format.field = V4L2_FIELD_NONE;
+ imx274->format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
+ imx274->format.colorspace = V4L2_COLORSPACE_SRGB;
+ imx274->frame_interval.numerator = 1;
+ imx274->frame_interval.denominator = IMX274_DEF_FRAME_RATE;
+
+ /* load default control values */
+ ret = imx274_load_default(imx274);
+ if (ret) {
+ dev_err(&client->dev,
+ "%s : imx274_load_default failed %d\n",
+ __func__, ret);
+ goto err_ctrls;
+ }
+
+ /* register subdevice */
+ ret = v4l2_async_register_subdev(sd);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s : v4l2_async_register_subdev failed %d\n",
+ __func__, ret);
+ goto err_ctrls;
+ }
+
+ dev_info(&client->dev, "imx274 : imx274 probe success !\n");
+ return 0;
+
+err_ctrls:
+ v4l2_ctrl_handler_free(&imx274->ctrls.handler);
+err_me:
+ media_entity_cleanup(&sd->entity);
+err_regmap:
+ mutex_destroy(&imx274->lock);
+ return ret;
+}
+
+static int imx274_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct stimx274 *imx274 = to_imx274(sd);
+
+ /* stop stream */
+ imx274_write_table(imx274, mode_table[IMX274_MODE_STOP_STREAM]);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_ctrl_handler_free(&imx274->ctrls.handler);
+ media_entity_cleanup(&sd->entity);
+ mutex_destroy(&imx274->lock);
+ return 0;
+}
+
+static struct i2c_driver imx274_i2c_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = imx274_of_id_table,
+ },
+ .probe = imx274_probe,
+ .remove = imx274_remove,
+ .id_table = imx274_id,
+};
+
+module_i2c_driver(imx274_i2c_driver);
+
+MODULE_AUTHOR("Leon Luo <leonl@leopardimaging.com>");
+MODULE_DESCRIPTION("IMX274 CMOS Image Sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index a374e2a0ac3d..8b5f7d0435e4 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -460,7 +460,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
rc->map_name = ir->ir_codes;
rc->allowed_protocols = rc_proto;
- rc->enabled_protocols = rc_proto;
if (!rc->driver_name)
rc->driver_name = MODULE_NAME;
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 251a2aaf98c3..b600e03aa94b 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -50,6 +50,7 @@ enum led_enable {
/**
* struct lm3560_flash
*
+ * @dev: pointer to &struct device
* @pdata: platform data
* @regmap: reg. map for i2c
* @lock: muxtex for serial access.
diff --git a/drivers/media/i2c/m5mols/m5mols_capture.c b/drivers/media/i2c/m5mols/m5mols_capture.c
index a0cd6dc32eb0..0fb457f57995 100644
--- a/drivers/media/i2c/m5mols/m5mols_capture.c
+++ b/drivers/media/i2c/m5mols/m5mols_capture.c
@@ -33,6 +33,10 @@
/**
* m5mols_read_rational - I2C read of a rational number
+ * @sd: sub-device, as pointed by struct v4l2_subdev
+ * @addr_num: numerator register
+ * @addr_den: denominator register
+ * @val: place to store the division result
*
* Read numerator and denominator from registers @addr_num and @addr_den
* respectively and return the division result in @val.
@@ -53,6 +57,7 @@ static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
/**
* m5mols_capture_info - Gather captured image information
+ * @info: M-5MOLS driver data structure
*
* For now it gathers only EXIF information and file size.
*/
diff --git a/drivers/media/i2c/m5mols/m5mols_controls.c b/drivers/media/i2c/m5mols/m5mols_controls.c
index c2218c0a9e6f..82eab7c2bc8c 100644
--- a/drivers/media/i2c/m5mols/m5mols_controls.c
+++ b/drivers/media/i2c/m5mols/m5mols_controls.c
@@ -126,6 +126,7 @@ static struct m5mols_scenemode m5mols_default_scenemode[] = {
/**
* m5mols_do_scenemode() - Change current scenemode
+ * @info: M-5MOLS driver data structure
* @mode: Desired mode of the scenemode
*
* WARNING: The execution order is important. Do not change the order.
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index 463534d44756..12e79f9e32d5 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -114,7 +114,8 @@ static const struct m5mols_resolution m5mols_reg_res[] = {
/**
* m5mols_swap_byte - an byte array to integer conversion function
- * @size: size in bytes of I2C packet defined in the M-5MOLS datasheet
+ * @data: byte array
+ * @length: size in bytes of I2C packet defined in the M-5MOLS datasheet
*
* Convert I2C data byte array with performing any required byte
* reordering to assure proper values for each data type, regardless
@@ -132,8 +133,9 @@ static u32 m5mols_swap_byte(u8 *data, u8 length)
/**
* m5mols_read - I2C read function
- * @reg: combination of size, category and command for the I2C packet
+ * @sd: sub-device, as pointed by struct v4l2_subdev
* @size: desired size of I2C packet
+ * @reg: combination of size, category and command for the I2C packet
* @val: read value
*
* Returns 0 on success, or else negative errno.
@@ -232,6 +234,7 @@ int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
/**
* m5mols_write - I2C command write function
+ * @sd: sub-device, as pointed by struct v4l2_subdev
* @reg: combination of size, category and command for the I2C packet
* @val: value to write
*
@@ -284,6 +287,7 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
/**
* m5mols_busy_wait - Busy waiting with I2C register polling
+ * @sd: sub-device, as pointed by struct v4l2_subdev
* @reg: the I2C_REG() address of an 8-bit status register to check
* @value: expected status register value
* @mask: bit mask for the read status register value
@@ -316,6 +320,8 @@ int m5mols_busy_wait(struct v4l2_subdev *sd, u32 reg, u32 value, u32 mask,
/**
* m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
+ * @sd: sub-device, as pointed by struct v4l2_subdev
+ * @reg: combination of size, category and command for the I2C packet
*
* Before writing desired interrupt value the INT_FACTOR register should
* be read to clear pending interrupts.
@@ -349,6 +355,8 @@ int m5mols_wait_interrupt(struct v4l2_subdev *sd, u8 irq_mask, u32 timeout)
/**
* m5mols_reg_mode - Write the mode and check busy status
+ * @sd: sub-device, as pointed by struct v4l2_subdev
+ * @mode: the required operation mode
*
* It always accompanies a little delay changing the M-5MOLS mode, so it is
* needed checking current busy status to guarantee right mode.
@@ -364,6 +372,7 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
/**
* m5mols_set_mode - set the M-5MOLS controller mode
+ * @info: M-5MOLS driver data structure
* @mode: the required operation mode
*
* The commands of M-5MOLS are grouped into specific modes. Each functionality
@@ -421,6 +430,7 @@ int m5mols_set_mode(struct m5mols_info *info, u8 mode)
/**
* m5mols_get_version - retrieve full revisions information of M-5MOLS
+ * @sd: sub-device, as pointed by struct v4l2_subdev
*
* The version information includes revisions of hardware and firmware,
* AutoFocus alghorithm version and the version string.
@@ -489,6 +499,7 @@ static enum m5mols_restype __find_restype(u32 code)
/**
* __find_resolution - Lookup preset and type of M-5MOLS's resolution
+ * @sd: sub-device, as pointed by struct v4l2_subdev
* @mf: pixel format to find/negotiate the resolution preset for
* @type: M-5MOLS resolution type
* @resolution: M-5MOLS resolution preset register value
@@ -662,6 +673,7 @@ static const struct v4l2_subdev_pad_ops m5mols_pad_ops = {
/**
* m5mols_restore_controls - Apply current control values to the registers
+ * @info: M-5MOLS driver data structure
*
* m5mols_do_scenemode() handles all parameters for which there is yet no
* individual control. It should be replaced at some point by setting each
@@ -686,6 +698,7 @@ int m5mols_restore_controls(struct m5mols_info *info)
/**
* m5mols_start_monitor - Start the monitor mode
+ * @info: M-5MOLS driver data structure
*
* Before applying the controls setup the resolution and frame rate
* in PARAMETER mode, and then switch over to MONITOR mode.
@@ -789,6 +802,7 @@ int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
/**
* m5mols_fw_start - M-5MOLS internal ARM controller initialization
+ * @sd: sub-device, as pointed by struct v4l2_subdev
*
* Execute the M-5MOLS internal ARM controller initialization sequence.
* This function should be called after the supply voltage has been
@@ -844,6 +858,8 @@ static int m5mols_auto_focus_stop(struct m5mols_info *info)
/**
* m5mols_s_power - Main sensor power control function
+ * @sd: sub-device, as pointed by struct v4l2_subdev
+ * @on: if true, powers on the device; powers off otherwise.
*
* To prevent breaking the lens when the sensor is powered off the Soft-Landing
* algorithm is called where available. The Soft-Landing algorithm availability
diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c
index bf0e821a2b93..2f1966bdc473 100644
--- a/drivers/media/i2c/max2175.c
+++ b/drivers/media/i2c/max2175.c
@@ -1345,7 +1345,7 @@ static int max2175_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(sd, client, &max2175_ops);
ctx->client = client;
- sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
/* Controls */
hdl = &ctx->ctrl_hdl;
diff --git a/drivers/media/i2c/msp3400-driver.h b/drivers/media/i2c/msp3400-driver.h
index a8702aca187a..b6c7698bce5a 100644
--- a/drivers/media/i2c/msp3400-driver.h
+++ b/drivers/media/i2c/msp3400-driver.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
*/
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index 99b992e46702..b1665d97e0fd 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -945,7 +945,7 @@ static int mt9m111_probe(struct i2c_client *client,
mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
if (IS_ERR(mt9m111->clk))
- return -EPROBE_DEFER;
+ return PTR_ERR(mt9m111->clk);
/* Default HIGHPOWER context */
mt9m111->ctx = &context_b;
diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
index af7af0d14c69..bf7d06f3f21a 100644
--- a/drivers/media/i2c/ov13858.c
+++ b/drivers/media/i2c/ov13858.c
@@ -104,7 +104,6 @@ struct ov13858_reg_list {
/* Link frequency config */
struct ov13858_link_freq_config {
- u32 pixel_rate;
u32 pixels_per_line;
/* PLL registers for this link frequency */
@@ -238,11 +237,11 @@ static const struct ov13858_reg mode_4224x3136_regs[] = {
{0x3800, 0x00},
{0x3801, 0x00},
{0x3802, 0x00},
- {0x3803, 0x00},
+ {0x3803, 0x08},
{0x3804, 0x10},
{0x3805, 0x9f},
{0x3806, 0x0c},
- {0x3807, 0x5f},
+ {0x3807, 0x57},
{0x3808, 0x10},
{0x3809, 0x80},
{0x380a, 0x0c},
@@ -948,6 +947,18 @@ static const char * const ov13858_test_pattern_menu[] = {
#define OV13858_LINK_FREQ_INDEX_0 0
#define OV13858_LINK_FREQ_INDEX_1 1
+/*
+ * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
+ * data rate => double data rate; number of lanes => 4; bits per pixel => 10
+ */
+static u64 link_freq_to_pixel_rate(u64 f)
+{
+ f *= 2 * 4;
+ do_div(f, 10);
+
+ return f;
+}
+
/* Menu items for LINK_FREQ V4L2 control */
static const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = {
OV13858_LINK_FREQ_540MHZ,
@@ -958,8 +969,6 @@ static const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = {
static const struct ov13858_link_freq_config
link_freq_configs[OV13858_NUM_OF_LINK_FREQS] = {
{
- /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
- .pixel_rate = (OV13858_LINK_FREQ_540MHZ * 2 * 4) / 10,
.pixels_per_line = OV13858_PPL_540MHZ,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mipi_data_rate_1080mbps),
@@ -967,8 +976,6 @@ static const struct ov13858_link_freq_config
}
},
{
- /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
- .pixel_rate = (OV13858_LINK_FREQ_270MHZ * 2 * 4) / 10,
.pixels_per_line = OV13858_PPL_270MHZ,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mipi_data_rate_540mbps),
@@ -1385,6 +1392,8 @@ ov13858_set_pad_format(struct v4l2_subdev *sd,
s32 vblank_def;
s32 vblank_min;
s64 h_blank;
+ s64 pixel_rate;
+ s64 link_freq;
mutex_lock(&ov13858->mutex);
@@ -1400,9 +1409,10 @@ ov13858_set_pad_format(struct v4l2_subdev *sd,
} else {
ov13858->cur_mode = mode;
__v4l2_ctrl_s_ctrl(ov13858->link_freq, mode->link_freq_index);
- __v4l2_ctrl_s_ctrl_int64(
- ov13858->pixel_rate,
- link_freq_configs[mode->link_freq_index].pixel_rate);
+ link_freq = link_freq_menu_items[mode->link_freq_index];
+ pixel_rate = link_freq_to_pixel_rate(link_freq);
+ __v4l2_ctrl_s_ctrl_int64(ov13858->pixel_rate, pixel_rate);
+
/* Update limits and set FPS to default */
vblank_def = ov13858->cur_mode->vts_def -
ov13858->cur_mode->height;
@@ -1617,6 +1627,10 @@ static int ov13858_init_controls(struct ov13858 *ov13858)
s64 exposure_max;
s64 vblank_def;
s64 vblank_min;
+ s64 hblank;
+ s64 pixel_rate_min;
+ s64 pixel_rate_max;
+ const struct ov13858_mode *mode;
int ret;
ctrl_hdlr = &ov13858->ctrl_handler;
@@ -1634,29 +1648,30 @@ static int ov13858_init_controls(struct ov13858 *ov13858)
link_freq_menu_items);
ov13858->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
+ pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]);
/* By default, PIXEL_RATE is read only */
ov13858->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0,
- link_freq_configs[0].pixel_rate, 1,
- link_freq_configs[0].pixel_rate);
+ V4L2_CID_PIXEL_RATE,
+ pixel_rate_min, pixel_rate_max,
+ 1, pixel_rate_max);
- vblank_def = ov13858->cur_mode->vts_def - ov13858->cur_mode->height;
- vblank_min = ov13858->cur_mode->vts_min - ov13858->cur_mode->height;
+ mode = ov13858->cur_mode;
+ vblank_def = mode->vts_def - mode->height;
+ vblank_min = mode->vts_min - mode->height;
ov13858->vblank = v4l2_ctrl_new_std(
ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_VBLANK,
- vblank_min,
- OV13858_VTS_MAX - ov13858->cur_mode->height, 1,
+ vblank_min, OV13858_VTS_MAX - mode->height, 1,
vblank_def);
+ hblank = link_freq_configs[mode->link_freq_index].pixels_per_line -
+ mode->width;
ov13858->hblank = v4l2_ctrl_new_std(
ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK,
- OV13858_PPL_540MHZ - ov13858->cur_mode->width,
- OV13858_PPL_540MHZ - ov13858->cur_mode->width,
- 1,
- OV13858_PPL_540MHZ - ov13858->cur_mode->width);
+ hblank, hblank, 1, hblank);
ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- exposure_max = ov13858->cur_mode->vts_def - 8;
+ exposure_max = mode->vts_def - 8;
ov13858->exposure = v4l2_ctrl_new_std(
ctrl_hdlr, &ov13858_ctrl_ops,
V4L2_CID_EXPOSURE, OV13858_EXPOSURE_MIN,
@@ -1746,7 +1761,7 @@ static int ov13858_probe(struct i2c_client *client,
goto error_handler_free;
}
- ret = v4l2_async_register_subdev(&ov13858->sd);
+ ret = v4l2_async_register_subdev_sensor_common(&ov13858->sd);
if (ret < 0)
goto error_media_entity;
diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c
index e6d0c1f64f0b..518868388d65 100644
--- a/drivers/media/i2c/ov2640.c
+++ b/drivers/media/i2c/ov2640.c
@@ -685,7 +685,7 @@ static int ov2640_mask_set(struct i2c_client *client,
static int ov2640_reset(struct i2c_client *client)
{
int ret;
- const struct regval_list reset_seq[] = {
+ static const struct regval_list reset_seq[] = {
{BANK_SEL, BANK_SEL_SENS},
{COM7, COM7_SRST},
ENDMARKER,
@@ -1097,18 +1097,17 @@ static int ov2640_probe(struct i2c_client *client,
return -EIO;
}
- priv = devm_kzalloc(&client->dev, sizeof(struct ov2640_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&adapter->dev,
- "Failed to allocate memory for private data!\n");
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
- }
if (client->dev.of_node) {
priv->clk = devm_clk_get(&client->dev, "xvclk");
if (IS_ERR(priv->clk))
- return -EPROBE_DEFER;
- clk_prepare_enable(priv->clk);
+ return PTR_ERR(priv->clk);
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
}
ret = ov2640_probe_dt(client, priv);
@@ -1116,7 +1115,7 @@ static int ov2640_probe(struct i2c_client *client,
goto err_clk;
v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
- priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+ priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
v4l2_ctrl_handler_init(&priv->hdl, 2);
v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
V4L2_CID_VFLIP, 0, 1, 1, 0);
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 39a2269c0bee..c89ed6609738 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -2271,7 +2271,7 @@ static int ov5640_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&sensor->sd, client, &ov5640_subdev_ops);
- sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+ 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 = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 95ce90fdb876..da39c49de503 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -35,9 +35,18 @@
#define SENSOR_NAME "ov5647"
-#define OV5647_SW_RESET 0x0103
-#define OV5647_REG_CHIPID_H 0x300A
-#define OV5647_REG_CHIPID_L 0x300B
+#define MIPI_CTRL00_CLOCK_LANE_GATE BIT(5)
+#define MIPI_CTRL00_BUS_IDLE BIT(2)
+#define MIPI_CTRL00_CLOCK_LANE_DISABLE BIT(0)
+
+#define OV5647_SW_STANDBY 0x0100
+#define OV5647_SW_RESET 0x0103
+#define OV5647_REG_CHIPID_H 0x300A
+#define OV5647_REG_CHIPID_L 0x300B
+#define OV5640_REG_PAD_OUT 0x300D
+#define OV5647_REG_FRAME_OFF_NUMBER 0x4202
+#define OV5647_REG_MIPI_CTRL00 0x4800
+#define OV5647_REG_MIPI_CTRL14 0x4814
#define REG_TERM 0xfffe
#define VAL_TERM 0xfe
@@ -241,34 +250,43 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
u8 channel_id;
int ret;
- ret = ov5647_read(sd, 0x4814, &channel_id);
+ ret = ov5647_read(sd, OV5647_REG_MIPI_CTRL14, &channel_id);
if (ret < 0)
return ret;
channel_id &= ~(3 << 6);
- return ov5647_write(sd, 0x4814, channel_id | (channel << 6));
+ return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6));
}
static int ov5647_stream_on(struct v4l2_subdev *sd)
{
int ret;
- ret = ov5647_write(sd, 0x4202, 0x00);
+ ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_BUS_IDLE);
if (ret < 0)
return ret;
- return ov5647_write(sd, 0x300D, 0x00);
+ ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x00);
+ if (ret < 0)
+ return ret;
+
+ return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x00);
}
static int ov5647_stream_off(struct v4l2_subdev *sd)
{
int ret;
- ret = ov5647_write(sd, 0x4202, 0x0f);
+ ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_CLOCK_LANE_GATE
+ | MIPI_CTRL00_BUS_IDLE | MIPI_CTRL00_CLOCK_LANE_DISABLE);
if (ret < 0)
return ret;
- return ov5647_write(sd, 0x300D, 0x01);
+ ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x0f);
+ if (ret < 0)
+ return ret;
+
+ return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01);
}
static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
@@ -276,7 +294,7 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
int ret;
u8 rdval;
- ret = ov5647_read(sd, 0x0100, &rdval);
+ ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
if (ret < 0)
return ret;
@@ -285,7 +303,7 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
else
rdval |= 0x01;
- return ov5647_write(sd, 0x0100, rdval);
+ return ov5647_write(sd, OV5647_SW_STANDBY, rdval);
}
static int __sensor_init(struct v4l2_subdev *sd)
@@ -294,7 +312,7 @@ static int __sensor_init(struct v4l2_subdev *sd)
u8 resetval, rdval;
struct i2c_client *client = v4l2_get_subdevdata(sd);
- ret = ov5647_read(sd, 0x0100, &rdval);
+ ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
if (ret < 0)
return ret;
@@ -309,18 +327,21 @@ static int __sensor_init(struct v4l2_subdev *sd)
if (ret < 0)
return ret;
- ret = ov5647_read(sd, 0x0100, &resetval);
+ ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
if (ret < 0)
return ret;
if (!(resetval & 0x01)) {
dev_err(&client->dev, "Device was in SW standby");
- ret = ov5647_write(sd, 0x0100, 0x01);
+ ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
if (ret < 0)
return ret;
}
- return ov5647_write(sd, 0x4800, 0x04);
+ /*
+ * stream off to make the clock lane into LP-11 state.
+ */
+ return ov5647_stream_off(sd);
}
static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
@@ -407,8 +428,8 @@ static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
}
#endif
-/**
- * @short Subdev core operations registration
+/*
+ * Subdev core operations registration
*/
static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
.s_power = ov5647_sensor_power,
diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index 6f7a1d6d2200..9f9196568eb8 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -390,7 +390,10 @@ static const struct ov5670_reg mode_2592x1944_regs[] = {
{0x5792, 0x00},
{0x5793, 0x52},
{0x5794, 0xa3},
- {0x3503, 0x00}
+ {0x3503, 0x00},
+ {0x5045, 0x05},
+ {0x4003, 0x40},
+ {0x5048, 0x40}
};
static const struct ov5670_reg mode_1296x972_regs[] = {
@@ -653,7 +656,10 @@ static const struct ov5670_reg mode_1296x972_regs[] = {
{0x5792, 0x00},
{0x5793, 0x52},
{0x5794, 0xa3},
- {0x3503, 0x00}
+ {0x3503, 0x00},
+ {0x5045, 0x05},
+ {0x4003, 0x40},
+ {0x5048, 0x40}
};
static const struct ov5670_reg mode_648x486_regs[] = {
@@ -916,7 +922,10 @@ static const struct ov5670_reg mode_648x486_regs[] = {
{0x5792, 0x00},
{0x5793, 0x52},
{0x5794, 0xa3},
- {0x3503, 0x00}
+ {0x3503, 0x00},
+ {0x5045, 0x05},
+ {0x4003, 0x40},
+ {0x5048, 0x40}
};
static const struct ov5670_reg mode_2560x1440_regs[] = {
@@ -1178,7 +1187,10 @@ static const struct ov5670_reg mode_2560x1440_regs[] = {
{0x5791, 0x06},
{0x5792, 0x00},
{0x5793, 0x52},
- {0x5794, 0xa3}
+ {0x5794, 0xa3},
+ {0x5045, 0x05},
+ {0x4003, 0x40},
+ {0x5048, 0x40}
};
static const struct ov5670_reg mode_1280x720_regs[] = {
@@ -1441,7 +1453,10 @@ static const struct ov5670_reg mode_1280x720_regs[] = {
{0x5792, 0x00},
{0x5793, 0x52},
{0x5794, 0xa3},
- {0x3503, 0x00}
+ {0x3503, 0x00},
+ {0x5045, 0x05},
+ {0x4003, 0x40},
+ {0x5048, 0x40}
};
static const struct ov5670_reg mode_640x360_regs[] = {
@@ -1704,7 +1719,10 @@ static const struct ov5670_reg mode_640x360_regs[] = {
{0x5792, 0x00},
{0x5793, 0x52},
{0x5794, 0xa3},
- {0x3503, 0x00}
+ {0x3503, 0x00},
+ {0x5045, 0x05},
+ {0x4003, 0x40},
+ {0x5048, 0x40}
};
static const char * const ov5670_test_pattern_menu[] = {
@@ -2323,8 +2341,6 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
return ret;
}
- ov5670->streaming = true;
-
return 0;
}
@@ -2338,8 +2354,6 @@ static int ov5670_stop_streaming(struct ov5670 *ov5670)
if (ret)
dev_err(&client->dev, "%s failed to set stream\n", __func__);
- ov5670->streaming = false;
-
/* Return success even if it was an error, as there is nothing the
* caller can do about it.
*/
@@ -2370,6 +2384,7 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable)
ret = ov5670_stop_streaming(ov5670);
pm_runtime_put(&client->dev);
}
+ ov5670->streaming = enable;
goto unlock_and_return;
error:
@@ -2514,7 +2529,7 @@ static int ov5670_probe(struct i2c_client *client)
}
/* Async register for subdev */
- ret = v4l2_async_register_subdev(&ov5670->sd);
+ ret = v4l2_async_register_subdev_sensor_common(&ov5670->sd);
if (ret < 0) {
err_msg = "v4l2_async_register_subdev() error";
goto error_entity_cleanup;
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c
index 768f2950ea36..8975d16b2b24 100644
--- a/drivers/media/i2c/ov6650.c
+++ b/drivers/media/i2c/ov6650.c
@@ -951,11 +951,8 @@ static int ov6650_probe(struct i2c_client *client,
int ret;
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&client->dev,
- "Failed to allocate memory for private data!\n");
+ if (!priv)
return -ENOMEM;
- }
v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
v4l2_ctrl_handler_init(&priv->hdl, 13);
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index e88549f0e704..950a0acf85fb 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -213,6 +213,9 @@ struct ov7670_devtype {
struct ov7670_format_struct; /* coming later */
struct ov7670_info {
struct v4l2_subdev sd;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ struct media_pad pad;
+#endif
struct v4l2_ctrl_handler hdl;
struct {
/* gain cluster */
@@ -229,6 +232,7 @@ struct ov7670_info {
struct v4l2_ctrl *saturation;
struct v4l2_ctrl *hue;
};
+ struct v4l2_mbus_framefmt format;
struct ov7670_format_struct *fmt; /* Current format */
struct clk *clk;
struct gpio_desc *resetb_gpio;
@@ -972,6 +976,9 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
fmt->width = wsize->width;
fmt->height = wsize->height;
fmt->colorspace = ov7670_formats[index].colorspace;
+
+ info->format = *fmt;
+
return 0;
}
@@ -985,6 +992,9 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
struct ov7670_format_struct *ovfmt;
struct ov7670_win_size *wsize;
struct ov7670_info *info = to_state(sd);
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
unsigned char com7;
int ret;
@@ -995,8 +1005,13 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
ret = ov7670_try_fmt_internal(sd, &format->format, NULL, NULL);
if (ret)
return ret;
- cfg->try_fmt = format->format;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
+ *mbus_fmt = format->format;
return 0;
+#else
+ return -ENOTTY;
+#endif
}
ret = ov7670_try_fmt_internal(sd, &format->format, &ovfmt, &wsize);
@@ -1038,6 +1053,30 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
return 0;
}
+static int ov7670_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct ov7670_info *info = to_state(sd);
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+ format->format = *mbus_fmt;
+ return 0;
+#else
+ return -ENOTTY;
+#endif
+ } else {
+ format->format = info->format;
+ }
+
+ return 0;
+}
+
/*
* Implement G/S_PARM. There is a "high quality" mode we could try
* to do someday; for now, we just do the frame rate tweak.
@@ -1505,6 +1544,46 @@ static int ov7670_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regis
}
#endif
+static int ov7670_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct ov7670_info *info = to_state(sd);
+
+ if (info->pwdn_gpio)
+ gpiod_set_value(info->pwdn_gpio, !on);
+ if (on && info->resetb_gpio) {
+ gpiod_set_value(info->resetb_gpio, 1);
+ usleep_range(500, 1000);
+ gpiod_set_value(info->resetb_gpio, 0);
+ usleep_range(3000, 5000);
+ }
+
+ return 0;
+}
+
+static void ov7670_get_default_format(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *format)
+{
+ struct ov7670_info *info = to_state(sd);
+
+ format->width = info->devtype->win_sizes[0].width;
+ format->height = info->devtype->win_sizes[0].height;
+ format->colorspace = info->fmt->colorspace;
+ format->code = info->fmt->mbus_code;
+ format->field = V4L2_FIELD_NONE;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int ov7670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ struct v4l2_mbus_framefmt *format =
+ v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
+ ov7670_get_default_format(sd, format);
+
+ return 0;
+}
+#endif
+
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops ov7670_core_ops = {
@@ -1525,6 +1604,7 @@ static const struct v4l2_subdev_pad_ops ov7670_pad_ops = {
.enum_frame_interval = ov7670_enum_frame_interval,
.enum_frame_size = ov7670_enum_frame_size,
.enum_mbus_code = ov7670_enum_mbus_code,
+ .get_fmt = ov7670_get_fmt,
.set_fmt = ov7670_set_fmt,
};
@@ -1534,6 +1614,12 @@ static const struct v4l2_subdev_ops ov7670_ops = {
.pad = &ov7670_pad_ops,
};
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static const struct v4l2_subdev_internal_ops ov7670_subdev_internal_ops = {
+ .open = ov7670_open,
+};
+#endif
+
/* ----------------------------------------------------------------------- */
static const struct ov7670_devtype ov7670_devdata[] = {
@@ -1586,6 +1672,11 @@ static int ov7670_probe(struct i2c_client *client,
sd = &info->sd;
v4l2_i2c_subdev_init(sd, client, &ov7670_ops);
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ sd->internal_ops = &ov7670_subdev_internal_ops;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+
info->clock_speed = 30; /* default: a guess */
if (client->dev.platform_data) {
struct ov7670_config *config = client->dev.platform_data;
@@ -1619,29 +1710,34 @@ static int ov7670_probe(struct i2c_client *client,
if (ret)
return ret;
- ret = ov7670_init_gpio(client, info);
- if (ret)
- goto clk_disable;
-
info->clock_speed = clk_get_rate(info->clk) / 1000000;
if (info->clock_speed < 10 || info->clock_speed > 48) {
ret = -EINVAL;
goto clk_disable;
}
+ ret = ov7670_init_gpio(client, info);
+ if (ret)
+ goto clk_disable;
+
+ ov7670_s_power(sd, 1);
+
/* Make sure it's an ov7670 */
ret = ov7670_detect(sd);
if (ret) {
v4l_dbg(1, debug, client,
"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
client->addr << 1, client->adapter->name);
- goto clk_disable;
+ goto power_off;
}
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);
info->devtype = &ov7670_devdata[id->driver_data];
info->fmt = &ov7670_formats[0];
+
+ ov7670_get_default_format(sd, &info->format);
+
info->clkrc = 0;
/* Set default frame rate to 30 fps */
@@ -1688,16 +1784,31 @@ static int ov7670_probe(struct i2c_client *client,
v4l2_ctrl_auto_cluster(2, &info->auto_exposure,
V4L2_EXPOSURE_MANUAL, false);
v4l2_ctrl_cluster(2, &info->saturation);
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ info->pad.flags = MEDIA_PAD_FL_SOURCE;
+ info->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ret = media_entity_pads_init(&info->sd.entity, 1, &info->pad);
+ if (ret < 0)
+ goto hdl_free;
+#endif
+
v4l2_ctrl_handler_setup(&info->hdl);
ret = v4l2_async_register_subdev(&info->sd);
if (ret < 0)
- goto hdl_free;
+ goto entity_cleanup;
return 0;
+entity_cleanup:
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&info->sd.entity);
+#endif
hdl_free:
v4l2_ctrl_handler_free(&info->hdl);
+power_off:
+ ov7670_s_power(sd, 0);
clk_disable:
clk_disable_unprepare(info->clk);
return ret;
@@ -1712,6 +1823,10 @@ static int ov7670_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&info->hdl);
clk_disable_unprepare(info->clk);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&info->sd.entity);
+#endif
+ ov7670_s_power(sd, 0);
return 0;
}
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 6ffb460e8589..69433e1e2533 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -985,7 +985,6 @@ static const struct v4l2_ctrl_ops ov965x_ctrl_ops = {
static const char * const test_pattern_menu[] = {
"Disabled",
"Color bars",
- NULL
};
static int ov965x_initialize_controls(struct ov965x *ov965x)
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index 67dcca76f981..2e140272794b 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -53,6 +53,9 @@ enum {
* @gpio_reset: GPIO connected to the sensor's reset pin
* @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 {
struct device *dev;
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index 9fd254a8e20d..13c10b5e2b45 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -421,6 +421,7 @@ static int s5k6aa_set_ahb_address(struct i2c_client *client)
/**
* s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration
+ * @s5k6aa: pointer to &struct s5k6aa describing the device
*
* Configure the internal ISP PLL for the required output frequency.
* Locking: called with s5k6aa.lock mutex held.
@@ -669,6 +670,7 @@ static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
/**
* s5k6aa_configure_video_bus - configure the video output interface
+ * @s5k6aa: pointer to &struct s5k6aa describing the device
* @bus_type: video bus type: parallel or MIPI-CSI
* @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
*
@@ -724,6 +726,8 @@ static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
/**
* s5k6aa_set_prev_config - write user preview register set
+ * @s5k6aa: pointer to &struct s5k6aa describing the device
+ * @preset: s5kaa preset to be applied
*
* Configure output resolution and color fromat, pixel clock
* frequency range, device frame rate type and frame period range.
@@ -777,6 +781,7 @@ static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
/**
* s5k6aa_initialize_isp - basic ISP MCU initialization
+ * @sd: pointer to V4L2 sub-device descriptor
*
* Configure AHB addresses for registers read/write; configure PLLs for
* required output pixel clock. The ISP power supply needs to be already
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 700f433261d0..e6b717b83b18 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -1239,6 +1239,10 @@ static int smiapp_power_on(struct device *dev)
sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
usleep_range(sleep, sleep);
+ mutex_lock(&sensor->mutex);
+
+ sensor->active = true;
+
/*
* Failures to respond to the address change command have been noticed.
* Those failures seem to be caused by the sensor requiring a longer
@@ -1313,7 +1317,7 @@ static int smiapp_power_on(struct device *dev)
rval = smiapp_write(sensor, SMIAPP_REG_U8_DPHY_CTRL,
SMIAPP_DPHY_CTRL_UI);
if (rval < 0)
- return rval;
+ goto out_cci_addr_fail;
rval = smiapp_call_quirk(sensor, post_poweron);
if (rval) {
@@ -1321,28 +1325,28 @@ static int smiapp_power_on(struct device *dev)
goto out_cci_addr_fail;
}
- /* Are we still initialising...? If yes, return here. */
- if (!sensor->pixel_array)
- return 0;
+ /* Are we still initialising...? If not, proceed with control setup. */
+ if (sensor->pixel_array) {
+ rval = __v4l2_ctrl_handler_setup(
+ &sensor->pixel_array->ctrl_handler);
+ if (rval)
+ goto out_cci_addr_fail;
- rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler);
- if (rval)
- goto out_cci_addr_fail;
+ rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
+ if (rval)
+ goto out_cci_addr_fail;
- rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
- if (rval)
- goto out_cci_addr_fail;
+ rval = smiapp_update_mode(sensor);
+ if (rval < 0)
+ goto out_cci_addr_fail;
+ }
- mutex_lock(&sensor->mutex);
- rval = smiapp_update_mode(sensor);
mutex_unlock(&sensor->mutex);
- if (rval < 0)
- goto out_cci_addr_fail;
return 0;
out_cci_addr_fail:
-
+ mutex_unlock(&sensor->mutex);
gpiod_set_value(sensor->xshutdown, 0);
clk_disable_unprepare(sensor->ext_clk);
@@ -1360,6 +1364,8 @@ static int smiapp_power_off(struct device *dev)
struct smiapp_sensor *sensor =
container_of(ssd, struct smiapp_sensor, ssds[0]);
+ mutex_lock(&sensor->mutex);
+
/*
* Currently power/clock to lens are enable/disabled separately
* but they are essentially the same signals. So if the sensor is
@@ -1372,6 +1378,10 @@ static int smiapp_power_off(struct device *dev)
SMIAPP_REG_U8_SOFTWARE_RESET,
SMIAPP_SOFTWARE_RESET);
+ sensor->active = false;
+
+ mutex_unlock(&sensor->mutex);
+
gpiod_set_value(sensor->xshutdown, 0);
clk_disable_unprepare(sensor->ext_clk);
usleep_range(5000, 5000);
@@ -1381,29 +1391,6 @@ static int smiapp_power_off(struct device *dev)
return 0;
}
-static int smiapp_set_power(struct v4l2_subdev *subdev, int on)
-{
- int rval;
-
- if (!on) {
- pm_runtime_mark_last_busy(subdev->dev);
- pm_runtime_put_autosuspend(subdev->dev);
-
- return 0;
- }
-
- rval = pm_runtime_get_sync(subdev->dev);
- if (rval >= 0)
- return 0;
-
- if (rval != -EBUSY && rval != -EAGAIN)
- pm_runtime_set_active(subdev->dev);
-
- pm_runtime_put(subdev->dev);
-
- return rval;
-}
-
/* -----------------------------------------------------------------------------
* Video stream management
*/
@@ -1560,19 +1547,31 @@ out:
static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
{
struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
int rval;
if (sensor->streaming == enable)
return 0;
if (enable) {
+ rval = pm_runtime_get_sync(&client->dev);
+ if (rval < 0) {
+ if (rval != -EBUSY && rval != -EAGAIN)
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_put(&client->dev);
+ return rval;
+ }
+
sensor->streaming = true;
+
rval = smiapp_start_streaming(sensor);
if (rval < 0)
sensor->streaming = false;
} else {
rval = smiapp_stop_streaming(sensor);
sensor->streaming = false;
+ pm_runtime_mark_last_busy(&client->dev);
+ pm_runtime_put_autosuspend(&client->dev);
}
return rval;
@@ -2650,7 +2649,6 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
struct smiapp_subdev *ssd = to_smiapp_subdev(sd);
struct smiapp_sensor *sensor = ssd->sensor;
unsigned int i;
- int rval;
mutex_lock(&sensor->mutex);
@@ -2677,22 +2675,6 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
mutex_unlock(&sensor->mutex);
- rval = pm_runtime_get_sync(sd->dev);
- if (rval >= 0)
- return 0;
-
- if (rval != -EBUSY && rval != -EAGAIN)
- pm_runtime_set_active(sd->dev);
- pm_runtime_put(sd->dev);
-
- return rval;
-}
-
-static int smiapp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- pm_runtime_mark_last_busy(sd->dev);
- pm_runtime_put_autosuspend(sd->dev);
-
return 0;
}
@@ -2700,10 +2682,6 @@ static const struct v4l2_subdev_video_ops smiapp_video_ops = {
.s_stream = smiapp_set_stream,
};
-static const struct v4l2_subdev_core_ops smiapp_core_ops = {
- .s_power = smiapp_set_power,
-};
-
static const struct v4l2_subdev_pad_ops smiapp_pad_ops = {
.enum_mbus_code = smiapp_enum_mbus_code,
.get_fmt = smiapp_get_format,
@@ -2718,7 +2696,6 @@ static const struct v4l2_subdev_sensor_ops smiapp_sensor_ops = {
};
static const struct v4l2_subdev_ops smiapp_ops = {
- .core = &smiapp_core_ops,
.video = &smiapp_video_ops,
.pad = &smiapp_pad_ops,
.sensor = &smiapp_sensor_ops,
@@ -2732,12 +2709,10 @@ static const struct v4l2_subdev_internal_ops smiapp_internal_src_ops = {
.registered = smiapp_registered,
.unregistered = smiapp_unregistered,
.open = smiapp_open,
- .close = smiapp_close,
};
static const struct v4l2_subdev_internal_ops smiapp_internal_ops = {
.open = smiapp_open,
- .close = smiapp_close,
};
/* -----------------------------------------------------------------------------
@@ -2829,12 +2804,10 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
/* NVM size is not mandatory */
fwnode_property_read_u32(fwnode, "nokia,nvm-size", &hwcfg->nvm_size);
- rval = fwnode_property_read_u32(fwnode, "clock-frequency",
+ rval = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
&hwcfg->ext_clk);
- if (rval) {
- dev_warn(dev, "can't get clock-frequency\n");
- goto out_err;
- }
+ if (rval)
+ dev_info(dev, "can't get clock-frequency\n");
dev_dbg(dev, "nvm %d, clk %d, mode %d\n",
hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode);
@@ -2894,18 +2867,46 @@ static int smiapp_probe(struct i2c_client *client,
}
sensor->ext_clk = devm_clk_get(&client->dev, NULL);
- if (IS_ERR(sensor->ext_clk)) {
+ if (PTR_ERR(sensor->ext_clk) == -ENOENT) {
+ dev_info(&client->dev, "no clock defined, continuing...\n");
+ sensor->ext_clk = NULL;
+ } else if (IS_ERR(sensor->ext_clk)) {
dev_err(&client->dev, "could not get clock (%ld)\n",
PTR_ERR(sensor->ext_clk));
return -EPROBE_DEFER;
}
- rval = clk_set_rate(sensor->ext_clk, sensor->hwcfg->ext_clk);
- if (rval < 0) {
- dev_err(&client->dev,
- "unable to set clock freq to %u\n",
+ if (sensor->ext_clk) {
+ if (sensor->hwcfg->ext_clk) {
+ unsigned long rate;
+
+ rval = clk_set_rate(sensor->ext_clk,
+ sensor->hwcfg->ext_clk);
+ if (rval < 0) {
+ dev_err(&client->dev,
+ "unable to set clock freq to %u\n",
+ sensor->hwcfg->ext_clk);
+ return rval;
+ }
+
+ rate = clk_get_rate(sensor->ext_clk);
+ if (rate != sensor->hwcfg->ext_clk) {
+ dev_err(&client->dev,
+ "can't set clock freq, asked for %u but got %lu\n",
+ sensor->hwcfg->ext_clk, rate);
+ return rval;
+ }
+ } else {
+ sensor->hwcfg->ext_clk = clk_get_rate(sensor->ext_clk);
+ dev_dbg(&client->dev, "obtained clock freq %u\n",
+ sensor->hwcfg->ext_clk);
+ }
+ } else if (sensor->hwcfg->ext_clk) {
+ dev_dbg(&client->dev, "assuming clock freq %u\n",
sensor->hwcfg->ext_clk);
- return rval;
+ } else {
+ dev_err(&client->dev, "unable to obtain clock freq\n");
+ return -EINVAL;
}
sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown",
@@ -3092,7 +3093,7 @@ static int smiapp_probe(struct i2c_client *client,
if (rval < 0)
goto out_media_entity_cleanup;
- rval = v4l2_async_register_subdev(&sensor->src->sd);
+ rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd);
if (rval < 0)
goto out_media_entity_cleanup;
diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c
index d6779e35d36f..145653dc81da 100644
--- a/drivers/media/i2c/smiapp/smiapp-regs.c
+++ b/drivers/media/i2c/smiapp/smiapp-regs.c
@@ -231,6 +231,9 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
len != SMIAPP_REG_32BIT) || flags)
return -EINVAL;
+ if (!sensor->active)
+ return 0;
+
msg.addr = client->addr;
msg.flags = 0; /* Write */
msg.len = 2 + len;
diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h
index f74d695018b9..e6a5ab402d7f 100644
--- a/drivers/media/i2c/smiapp/smiapp.h
+++ b/drivers/media/i2c/smiapp/smiapp.h
@@ -206,6 +206,7 @@ struct smiapp_sensor {
u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
u8 frame_skip;
+ bool active; /* is the sensor powered on? */
u16 embedded_start; /* embedded data start line */
u16 embedded_end;
u16 image_start; /* image data start line */
diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
index 78532a7fb8e2..faa2df8901d2 100644
--- a/drivers/media/i2c/soc_camera/Makefile
+++ b/drivers/media/i2c/soc_camera/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 0146d1f7aacb..c63948989688 100644
--- a/drivers/media/i2c/soc_camera/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -335,8 +335,8 @@ static void ov9640_res_roundup(u32 *width, u32 *height)
{
int i;
enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA };
- int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
- int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
+ static const int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 };
+ static const int res_y[] = { 72, 120, 144, 240, 288, 480, 960 };
for (i = 0; i < ARRAY_SIZE(res_x); i++) {
if (res_x[i] >= *width && res_y[i] >= *height) {
@@ -675,12 +675,9 @@ static int ov9640_probe(struct i2c_client *client,
return -EINVAL;
}
- priv = devm_kzalloc(&client->dev, sizeof(struct ov9640_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&client->dev,
- "Failed to allocate memory for private data!\n");
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
- }
v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index cc07b7ae5407..755de2289c39 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -935,11 +935,9 @@ static int ov9740_probe(struct i2c_client *client,
return -EINVAL;
}
- priv = devm_kzalloc(&client->dev, sizeof(struct ov9740_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&client->dev, "Failed to allocate private data!\n");
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
- }
v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
v4l2_ctrl_handler_init(&priv->hdl, 13);
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index e6f5c363ccab..2b8181469b93 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -39,6 +39,7 @@
#include <linux/workqueue.h>
#include <linux/v4l2-dv-timings.h>
#include <linux/hdmi.h>
+#include <media/cec.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
@@ -63,6 +64,7 @@ MODULE_LICENSE("GPL");
#define I2C_MAX_XFER_SIZE (EDID_BLOCK_SIZE + 2)
+#define POLL_INTERVAL_CEC_MS 10
#define POLL_INTERVAL_MS 1000
static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
@@ -106,6 +108,8 @@ struct tc358743_state {
u8 csi_lanes_in_use;
struct gpio_desc *reset_gpio;
+
+ struct cec_adapter *cec_adap;
};
static void tc358743_enable_interrupts(struct v4l2_subdev *sd,
@@ -595,6 +599,7 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd)
struct tc358743_platform_data *pdata = &state->pdata;
u32 sys_freq;
u32 lockdet_ref;
+ u32 cec_freq;
u16 fh_min;
u16 fh_max;
@@ -626,6 +631,15 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd)
i2c_wr8_and_or(sd, NCO_F0_MOD, ~MASK_NCO_F0_MOD,
(pdata->refclk_hz == 27000000) ?
MASK_NCO_F0_MOD_27MHZ : 0x0);
+
+ /*
+ * Trial and error suggests that the default register value
+ * of 656 is for a 42 MHz reference clock. Use that to derive
+ * a new value based on the actual reference clock.
+ */
+ cec_freq = (656 * sys_freq) / 4200;
+ i2c_wr16(sd, CECHCLK, cec_freq);
+ i2c_wr16(sd, CECLCLK, cec_freq);
}
static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
@@ -814,11 +828,17 @@ static void tc358743_initial_setup(struct v4l2_subdev *sd)
struct tc358743_state *state = to_state(sd);
struct tc358743_platform_data *pdata = &state->pdata;
- /* CEC and IR are not supported by this driver */
- i2c_wr16_and_or(sd, SYSCTL, ~(MASK_CECRST | MASK_IRRST),
- (MASK_CECRST | MASK_IRRST));
+ /*
+ * IR is not supported by this driver.
+ * CEC is only enabled if needed.
+ */
+ i2c_wr16_and_or(sd, SYSCTL, ~(MASK_IRRST | MASK_CECRST),
+ (MASK_IRRST | MASK_CECRST));
tc358743_reset(sd, MASK_CTXRST | MASK_HDMIRST);
+#ifdef CONFIG_VIDEO_TC358743_CEC
+ tc358743_reset(sd, MASK_CECRST);
+#endif
tc358743_sleep_mode(sd, false);
i2c_wr16(sd, FIFOCTL, pdata->fifo_level);
@@ -842,6 +862,133 @@ static void tc358743_initial_setup(struct v4l2_subdev *sd)
i2c_wr8(sd, VOUT_SET3, MASK_VOUT_EXTCNT);
}
+/* --------------- CEC --------------- */
+
+#ifdef CONFIG_VIDEO_TC358743_CEC
+static int tc358743_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct tc358743_state *state = adap->priv;
+ struct v4l2_subdev *sd = &state->sd;
+
+ i2c_wr32(sd, CECIMSK, enable ? MASK_CECTIM | MASK_CECRIM : 0);
+ i2c_wr32(sd, CECICLR, MASK_CECTICLR | MASK_CECRICLR);
+ i2c_wr32(sd, CECEN, enable);
+ if (enable)
+ i2c_wr32(sd, CECREN, MASK_CECREN);
+ return 0;
+}
+
+static int tc358743_cec_adap_monitor_all_enable(struct cec_adapter *adap,
+ bool enable)
+{
+ struct tc358743_state *state = adap->priv;
+ struct v4l2_subdev *sd = &state->sd;
+ u32 reg;
+
+ reg = i2c_rd32(sd, CECRCTL1);
+ if (enable)
+ reg |= MASK_CECOTH;
+ else
+ reg &= ~MASK_CECOTH;
+ i2c_wr32(sd, CECRCTL1, reg);
+ return 0;
+}
+
+static int tc358743_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+ struct tc358743_state *state = adap->priv;
+ struct v4l2_subdev *sd = &state->sd;
+ unsigned int la = 0;
+
+ if (log_addr != CEC_LOG_ADDR_INVALID) {
+ la = i2c_rd32(sd, CECADD);
+ la |= 1 << log_addr;
+ }
+ i2c_wr32(sd, CECADD, la);
+ return 0;
+}
+
+static int tc358743_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct tc358743_state *state = adap->priv;
+ struct v4l2_subdev *sd = &state->sd;
+ unsigned int i;
+
+ i2c_wr32(sd, CECTCTL,
+ (cec_msg_is_broadcast(msg) ? MASK_CECBRD : 0) |
+ (signal_free_time - 1));
+ for (i = 0; i < msg->len; i++)
+ i2c_wr32(sd, CECTBUF1 + i * 4,
+ msg->msg[i] | ((i == msg->len - 1) ? MASK_CECTEOM : 0));
+ i2c_wr32(sd, CECTEN, MASK_CECTEN);
+ return 0;
+}
+
+static const struct cec_adap_ops tc358743_cec_adap_ops = {
+ .adap_enable = tc358743_cec_adap_enable,
+ .adap_log_addr = tc358743_cec_adap_log_addr,
+ .adap_transmit = tc358743_cec_adap_transmit,
+ .adap_monitor_all_enable = tc358743_cec_adap_monitor_all_enable,
+};
+
+static void tc358743_cec_isr(struct v4l2_subdev *sd, u16 intstatus,
+ bool *handled)
+{
+ struct tc358743_state *state = to_state(sd);
+ unsigned int cec_rxint, cec_txint;
+ unsigned int clr = 0;
+
+ cec_rxint = i2c_rd32(sd, CECRSTAT);
+ cec_txint = i2c_rd32(sd, CECTSTAT);
+
+ if (intstatus & MASK_CEC_RINT)
+ clr |= MASK_CECRICLR;
+ if (intstatus & MASK_CEC_TINT)
+ clr |= MASK_CECTICLR;
+ i2c_wr32(sd, CECICLR, clr);
+
+ if ((intstatus & MASK_CEC_TINT) && cec_txint) {
+ if (cec_txint & MASK_CECTIEND)
+ cec_transmit_attempt_done(state->cec_adap,
+ CEC_TX_STATUS_OK);
+ else if (cec_txint & MASK_CECTIAL)
+ cec_transmit_attempt_done(state->cec_adap,
+ CEC_TX_STATUS_ARB_LOST);
+ else if (cec_txint & MASK_CECTIACK)
+ cec_transmit_attempt_done(state->cec_adap,
+ CEC_TX_STATUS_NACK);
+ else if (cec_txint & MASK_CECTIUR) {
+ /*
+ * Not sure when this bit is set. Treat
+ * it as an error for now.
+ */
+ cec_transmit_attempt_done(state->cec_adap,
+ CEC_TX_STATUS_ERROR);
+ }
+ *handled = true;
+ }
+ if ((intstatus & MASK_CEC_RINT) &&
+ (cec_rxint & MASK_CECRIEND)) {
+ struct cec_msg msg = {};
+ unsigned int i;
+ unsigned int v;
+
+ v = i2c_rd32(sd, CECRCTR);
+ msg.len = v & 0x1f;
+ for (i = 0; i < msg.len; i++) {
+ v = i2c_rd32(sd, CECRBUF1 + i * 4);
+ msg.msg[i] = v & 0xff;
+ }
+ cec_received_msg(state->cec_adap, &msg);
+ *handled = true;
+ }
+ i2c_wr16(sd, INTSTATUS,
+ intstatus & (MASK_CEC_RINT | MASK_CEC_TINT));
+}
+
+#endif
+
/* --------------- IRQ --------------- */
static void tc358743_format_change(struct v4l2_subdev *sd)
@@ -1296,6 +1443,15 @@ static int tc358743_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
intstatus &= ~MASK_HDMI_INT;
}
+#ifdef CONFIG_VIDEO_TC358743_CEC
+ if (intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)) {
+ tc358743_cec_isr(sd, intstatus, handled);
+ i2c_wr16(sd, INTSTATUS,
+ intstatus & (MASK_CEC_RINT | MASK_CEC_TINT));
+ intstatus &= ~(MASK_CEC_RINT | MASK_CEC_TINT);
+ }
+#endif
+
if (intstatus & MASK_CSI_INT) {
u32 csi_int = i2c_rd32(sd, CSI_INT);
@@ -1325,13 +1481,18 @@ static irqreturn_t tc358743_irq_handler(int irq, void *dev_id)
return handled ? IRQ_HANDLED : IRQ_NONE;
}
-static void tc358743_irq_poll_timer(unsigned long arg)
+static void tc358743_irq_poll_timer(struct timer_list *t)
{
- struct tc358743_state *state = (struct tc358743_state *)arg;
+ struct tc358743_state *state = from_timer(state, t, timer);
+ unsigned int msecs;
schedule_work(&state->work_i2c_poll);
-
- mod_timer(&state->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
+ /*
+ * If CEC is present, then we need to poll more frequently,
+ * otherwise we will miss CEC messages.
+ */
+ msecs = state->cec_adap ? POLL_INTERVAL_CEC_MS : POLL_INTERVAL_MS;
+ mod_timer(&state->timer, jiffies + msecs_to_jiffies(msecs));
}
static void tc358743_work_i2c_poll(struct work_struct *work)
@@ -1488,7 +1649,7 @@ static int tc358743_s_stream(struct v4l2_subdev *sd, int enable)
{
enable_stream(sd, enable);
if (!enable) {
- /* Put all lanes in PL-11 state (STOPSTATE) */
+ /* Put all lanes in LP-11 state (STOPSTATE) */
tc358743_set_csi(sd);
}
@@ -1621,6 +1782,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
{
struct tc358743_state *state = to_state(sd);
u16 edid_len = edid->blocks * EDID_BLOCK_SIZE;
+ u16 pa;
+ int err;
int i;
v4l2_dbg(2, debug, sd, "%s, pad %d, start block %d, blocks %d\n",
@@ -1638,6 +1801,12 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
edid->blocks = EDID_NUM_BLOCKS_MAX;
return -E2BIG;
}
+ pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL);
+ err = cec_phys_addr_validate(pa, &pa, NULL);
+ if (err)
+ return err;
+
+ cec_phys_addr_invalidate(state->cec_adap);
tc358743_disable_edid(sd);
@@ -1654,6 +1823,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
state->edid_blocks_written = edid->blocks;
+ cec_s_phys_addr(state->cec_adap, pa, false);
+
if (tx_5v_power_present(sd))
tc358743_enable_edid(sd);
@@ -1770,6 +1941,11 @@ static int tc358743_probe_of(struct tc358743_state *state)
goto free_endpoint;
}
+ if (endpoint->bus.mipi_csi2.num_data_lanes > 4) {
+ dev_err(dev, "invalid number of lanes\n");
+ goto free_endpoint;
+ }
+
state->bus = endpoint->bus.mipi_csi2;
ret = clk_prepare_enable(refclk);
@@ -1867,6 +2043,7 @@ static int tc358743_probe(struct i2c_client *client,
struct tc358743_state *state;
struct tc358743_platform_data *pdata = client->dev.platform_data;
struct v4l2_subdev *sd;
+ u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -1929,6 +2106,7 @@ static int tc358743_probe(struct i2c_client *client,
}
state->pad.flags = MEDIA_PAD_FL_SOURCE;
+ sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
err = media_entity_pads_init(&sd->entity, 1, &state->pad);
if (err < 0)
goto err_hdl;
@@ -1945,6 +2123,17 @@ static int tc358743_probe(struct i2c_client *client,
INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,
tc358743_delayed_work_enable_hotplug);
+#ifdef CONFIG_VIDEO_TC358743_CEC
+ state->cec_adap = cec_allocate_adapter(&tc358743_cec_adap_ops,
+ state, dev_name(&client->dev),
+ CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL, CEC_MAX_LOG_ADDRS);
+ if (IS_ERR(state->cec_adap)) {
+ err = PTR_ERR(state->cec_adap);
+ goto err_hdl;
+ }
+ irq_mask |= MASK_CEC_RMSK | MASK_CEC_TMSK;
+#endif
+
tc358743_initial_setup(sd);
tc358743_s_dv_timings(sd, &default_timing);
@@ -1964,15 +2153,22 @@ static int tc358743_probe(struct i2c_client *client,
} else {
INIT_WORK(&state->work_i2c_poll,
tc358743_work_i2c_poll);
- state->timer.data = (unsigned long)state;
- state->timer.function = tc358743_irq_poll_timer;
+ timer_setup(&state->timer, tc358743_irq_poll_timer, 0);
state->timer.expires = jiffies +
msecs_to_jiffies(POLL_INTERVAL_MS);
add_timer(&state->timer);
}
+ err = cec_register_adapter(state->cec_adap, &client->dev);
+ if (err < 0) {
+ pr_err("%s: failed to register the cec device\n", __func__);
+ cec_delete_adapter(state->cec_adap);
+ state->cec_adap = NULL;
+ goto err_work_queues;
+ }
+
tc358743_enable_interrupts(sd, tx_5v_power_present(sd));
- i2c_wr16(sd, INTMASK, ~(MASK_HDMI_MSK | MASK_CSI_MSK) & 0xffff);
+ i2c_wr16(sd, INTMASK, ~irq_mask);
err = v4l2_ctrl_handler_setup(sd->ctrl_handler);
if (err)
@@ -1984,6 +2180,7 @@ static int tc358743_probe(struct i2c_client *client,
return 0;
err_work_queues:
+ cec_unregister_adapter(state->cec_adap);
if (!state->i2c_client->irq)
flush_work(&state->work_i2c_poll);
cancel_delayed_work(&state->delayed_work_enable_hotplug);
@@ -2004,6 +2201,7 @@ static int tc358743_remove(struct i2c_client *client)
flush_work(&state->work_i2c_poll);
}
cancel_delayed_work(&state->delayed_work_enable_hotplug);
+ cec_unregister_adapter(state->cec_adap);
v4l2_async_unregister_subdev(sd);
v4l2_device_unregister_subdev(sd);
mutex_destroy(&state->confctl_mutex);
diff --git a/drivers/media/i2c/tc358743_regs.h b/drivers/media/i2c/tc358743_regs.h
index 657ef50f215f..227b46471793 100644
--- a/drivers/media/i2c/tc358743_regs.h
+++ b/drivers/media/i2c/tc358743_regs.h
@@ -193,8 +193,98 @@
#define CSI_START 0x0518
#define MASK_STRT 0x00000001
-#define CECEN 0x0600
-#define MASK_CECEN 0x0001
+/* *** CEC (32 bit) *** */
+#define CECHCLK 0x0028 /* 16 bits */
+#define MASK_CECHCLK (0x7ff << 0)
+
+#define CECLCLK 0x002a /* 16 bits */
+#define MASK_CECLCLK (0x7ff << 0)
+
+#define CECEN 0x0600
+#define MASK_CECEN 0x0001
+
+#define CECADD 0x0604
+#define CECRST 0x0608
+#define MASK_CECRESET 0x0001
+
+#define CECREN 0x060c
+#define MASK_CECREN 0x0001
+
+#define CECRCTL1 0x0614
+#define MASK_CECACKDIS (1 << 24)
+#define MASK_CECHNC (3 << 20)
+#define MASK_CECLNC (7 << 16)
+#define MASK_CECMIN (7 << 12)
+#define MASK_CECMAX (7 << 8)
+#define MASK_CECDAT (7 << 4)
+#define MASK_CECTOUT (3 << 2)
+#define MASK_CECRIHLD (1 << 1)
+#define MASK_CECOTH (1 << 0)
+
+#define CECRCTL2 0x0618
+#define MASK_CECSWAV3 (7 << 12)
+#define MASK_CECSWAV2 (7 << 8)
+#define MASK_CECSWAV1 (7 << 4)
+#define MASK_CECSWAV0 (7 << 0)
+
+#define CECRCTL3 0x061c
+#define MASK_CECWAV3 (7 << 20)
+#define MASK_CECWAV2 (7 << 16)
+#define MASK_CECWAV1 (7 << 12)
+#define MASK_CECWAV0 (7 << 8)
+#define MASK_CECACKEI (1 << 4)
+#define MASK_CECMINEI (1 << 3)
+#define MASK_CECMAXEI (1 << 2)
+#define MASK_CECRSTEI (1 << 1)
+#define MASK_CECWAVEI (1 << 0)
+
+#define CECTEN 0x0620
+#define MASK_CECTBUSY (1 << 1)
+#define MASK_CECTEN (1 << 0)
+
+#define CECTCTL 0x0628
+#define MASK_CECSTRS (7 << 20)
+#define MASK_CECSPRD (7 << 16)
+#define MASK_CECDTRS (7 << 12)
+#define MASK_CECDPRD (15 << 8)
+#define MASK_CECBRD (1 << 4)
+#define MASK_CECFREE (15 << 0)
+
+#define CECRSTAT 0x062c
+#define MASK_CECRIWA (1 << 6)
+#define MASK_CECRIOR (1 << 5)
+#define MASK_CECRIACK (1 << 4)
+#define MASK_CECRIMIN (1 << 3)
+#define MASK_CECRIMAX (1 << 2)
+#define MASK_CECRISTA (1 << 1)
+#define MASK_CECRIEND (1 << 0)
+
+#define CECTSTAT 0x0630
+#define MASK_CECTIUR (1 << 4)
+#define MASK_CECTIACK (1 << 3)
+#define MASK_CECTIAL (1 << 2)
+#define MASK_CECTIEND (1 << 1)
+
+#define CECRBUF1 0x0634
+#define MASK_CECRACK (1 << 9)
+#define MASK_CECEOM (1 << 8)
+#define MASK_CECRBYTE (0xff << 0)
+
+#define CECTBUF1 0x0674
+#define MASK_CECTEOM (1 << 8)
+#define MASK_CECTBYTE (0xff << 0)
+
+#define CECRCTR 0x06b4
+#define MASK_CECRCTR (0x1f << 0)
+
+#define CECIMSK 0x06c0
+#define MASK_CECTIM (1 << 1)
+#define MASK_CECRIM (1 << 0)
+
+#define CECICLR 0x06cc
+#define MASK_CECTICLR (1 << 1)
+#define MASK_CECRICLR (1 << 0)
+
#define HDMI_INT0 0x8500
#define MASK_I_KEY 0x80
diff --git a/drivers/media/i2c/tea6415c.h b/drivers/media/i2c/tea6415c.h
index 3a47d697536e..f43228207445 100644
--- a/drivers/media/i2c/tea6415c.h
+++ b/drivers/media/i2c/tea6415c.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __INCLUDED_TEA6415C__
#define __INCLUDED_TEA6415C__
diff --git a/drivers/media/i2c/tea6420.h b/drivers/media/i2c/tea6420.h
index 4aa3edb3e193..07f9d72a86bb 100644
--- a/drivers/media/i2c/tea6420.h
+++ b/drivers/media/i2c/tea6420.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __INCLUDED_TEA6420__
#define __INCLUDED_TEA6420__
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index ce86534450ac..16a1e08ce06c 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -300,9 +300,9 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
* if available, ...
*/
-static void chip_thread_wake(unsigned long data)
+static void chip_thread_wake(struct timer_list *t)
{
- struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
+ struct CHIPSTATE *chip = from_timer(chip, t, wt);
wake_up_process(chip->thread);
}
@@ -1995,7 +1995,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
v4l2_ctrl_handler_setup(&chip->hdl);
chip->thread = NULL;
- init_timer(&chip->wt);
+ timer_setup(&chip->wt, chip_thread_wake, 0);
if (desc->flags & CHIP_NEED_CHECKMODE) {
if (!desc->getrxsubchans || !desc->setaudmode) {
/* This shouldn't be happen. Warn user, but keep working
@@ -2005,8 +2005,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
return 0;
}
/* start async thread */
- chip->wt.function = chip_thread_wake;
- chip->wt.data = (unsigned long)chip;
chip->thread = kthread_run(chip_thread, chip, "%s",
client->name);
if (IS_ERR(chip->thread)) {
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index ad2df998f9c5..d575b3e7e835 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -86,6 +86,7 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
/**
* struct tvp514x_decoder - TVP5146/47 decoder object
* @sd: Subdevice Slave handle
+ * @hdl: embedded &struct v4l2_ctrl_handler
* @tvp514x_regs: copy of hw's regs with preset values.
* @pdata: Board specific
* @ver: Chip version
@@ -98,6 +99,9 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
* @std_list: Standards list
* @input: Input routing at chip level
* @output: Output routing at chip level
+ * @pad: subdev media pad associated with the decoder
+ * @format: media bus frame format
+ * @int_seq: driver's register init sequence
*/
struct tvp514x_decoder {
struct v4l2_subdev sd;
@@ -211,7 +215,7 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
{TOK_TERM, 0, 0},
};
-/**
+/*
* List of image formats supported by TVP5146/47 decoder
* Currently we are using 8 bit mode only, but can be
* extended to 10/20 bit mode.
@@ -226,7 +230,7 @@ static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
},
};
-/**
+/*
* Supported standards -
*
* Currently supports two standards only, need to add support for rest of the
@@ -931,7 +935,7 @@ static int tvp514x_get_pad_format(struct v4l2_subdev *sd,
* tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format
* @sd: pointer to standard V4L2 sub-device structure
* @cfg: pad configuration
- * @format: pointer to v4l2_subdev_format structure
+ * @fmt: pointer to v4l2_subdev_format structure
*
* Set pad format for the output pad
*/
@@ -1199,7 +1203,7 @@ static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
{TOK_TERM, 0, 0},
};
-/**
+/*
* I2C Device Table -
*
* name - Name of the actual device/chip.
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 2ace0410d277..f7c6d64e6031 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -214,12 +214,20 @@ void media_gobj_destroy(struct media_gobj *gobj)
gobj->mdev = NULL;
}
+/*
+ * TODO: Get rid of this.
+ */
+#define MEDIA_ENTITY_MAX_PADS 512
+
int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
struct media_pad *pads)
{
struct media_device *mdev = entity->graph_obj.mdev;
unsigned int i;
+ if (num_pads >= MEDIA_ENTITY_MAX_PADS)
+ return -E2BIG;
+
entity->num_pads = num_pads;
entity->pads = pads;
@@ -280,11 +288,6 @@ static struct media_entity *stack_pop(struct media_graph *graph)
#define link_top(en) ((en)->stack[(en)->top].link)
#define stack_top(en) ((en)->stack[(en)->top].entity)
-/*
- * TODO: Get rid of this.
- */
-#define MEDIA_ENTITY_MAX_PADS 512
-
/**
* media_graph_walk_init - Allocate resources for graph walk
* @graph: Media graph structure that will be used to walk the graph
diff --git a/drivers/media/mmc/Makefile b/drivers/media/mmc/Makefile
index 31e297a202fb..e847aa82ae41 100644
--- a/drivers/media/mmc/Makefile
+++ b/drivers/media/mmc/Makefile
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
obj-y += siano/
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index a7e8af0f64a7..1ab759e9b1bb 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel multimedia device drivers.
#
diff --git a/drivers/media/pci/b2c2/Kconfig b/drivers/media/pci/b2c2/Kconfig
index 58761a21caa0..7b818d445f39 100644
--- a/drivers/media/pci/b2c2/Kconfig
+++ b/drivers/media/pci/b2c2/Kconfig
@@ -11,5 +11,5 @@ config DVB_B2C2_FLEXCOP_PCI_DEBUG
depends on DVB_B2C2_FLEXCOP_PCI
select DVB_B2C2_FLEXCOP_DEBUG
help
- Say Y if you want to enable the module option to control debug messages
- of all B2C2 FlexCop drivers.
+ Say Y if you want to enable the module option to control debug messages
+ of all B2C2 FlexCop drivers.
diff --git a/drivers/media/pci/b2c2/Makefile b/drivers/media/pci/b2c2/Makefile
index b894320a5f21..35d6835ae43e 100644
--- a/drivers/media/pci/b2c2/Makefile
+++ b/drivers/media/pci/b2c2/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
b2c2-flexcop-pci-objs += flexcop-dma.o
endif
diff --git a/drivers/media/pci/b2c2/flexcop-dma.c b/drivers/media/pci/b2c2/flexcop-dma.c
index 913dc97f8b49..f07610a1646d 100644
--- a/drivers/media/pci/b2c2/flexcop-dma.c
+++ b/drivers/media/pci/b2c2/flexcop-dma.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-dma.c - configuring and controlling the DMA of the FlexCop
diff --git a/drivers/media/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
index 2d4c3dd88be1..009f1dc1521f 100644
--- a/drivers/media/pci/bt8xx/Makefile
+++ b/drivers/media/pci/bt8xx/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
bttv-input.o bttv-audio-hook.o btcx-risc.o
diff --git a/drivers/media/pci/bt8xx/btcx-risc.h b/drivers/media/pci/bt8xx/btcx-risc.h
index 1ed7a000160a..dc774a64cd1f 100644
--- a/drivers/media/pci/bt8xx/btcx-risc.h
+++ b/drivers/media/pci/bt8xx/btcx-risc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
struct btcx_riscmem {
unsigned int size;
__le32 *cpu;
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 227086a2e99c..b366a7e1d976 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3652,9 +3652,9 @@ bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
wake_up(&wakeup->vb.done);
}
-static void bttv_irq_timeout(unsigned long data)
+static void bttv_irq_timeout(struct timer_list *t)
{
- struct bttv *btv = (struct bttv *)data;
+ struct bttv *btv = from_timer(btv, t, timeout);
struct bttv_buffer_set old,new;
struct bttv_buffer *ovbi;
struct bttv_buffer *item;
@@ -4043,7 +4043,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
INIT_LIST_HEAD(&btv->capture);
INIT_LIST_HEAD(&btv->vcapture);
- setup_timer(&btv->timeout, bttv_irq_timeout, (unsigned long)btv);
+ timer_setup(&btv->timeout, bttv_irq_timeout, 0);
btv->i2c_rc = -1;
btv->tuner_type = UNSET;
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index 73d655d073d6..ac7674700685 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -133,10 +133,10 @@ void bttv_input_irq(struct bttv *btv)
ir_handle_key(btv);
}
-static void bttv_input_timer(unsigned long data)
+static void bttv_input_timer(struct timer_list *t)
{
- struct bttv *btv = (struct bttv*)data;
- struct bttv_ir *ir = btv->remote;
+ struct bttv_ir *ir = from_timer(ir, t, timer);
+ struct bttv *btv = ir->btv;
if (btv->c.type == BTTV_BOARD_ENLTV_FM_2)
ir_enltv_handle_key(btv);
@@ -189,9 +189,9 @@ static u32 bttv_rc5_decode(unsigned int code)
return rc5;
}
-static void bttv_rc5_timer_end(unsigned long data)
+static void bttv_rc5_timer_end(struct timer_list *t)
{
- struct bttv_ir *ir = (struct bttv_ir *)data;
+ struct bttv_ir *ir = from_timer(ir, t, timer);
ktime_t tv;
u32 gap, rc5, scancode;
u8 toggle, command, system;
@@ -296,15 +296,15 @@ static int bttv_rc5_irq(struct bttv *btv)
/* ---------------------------------------------------------------------- */
-static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
+static void bttv_ir_start(struct bttv_ir *ir)
{
if (ir->polling) {
- setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv);
+ timer_setup(&ir->timer, bttv_input_timer, 0);
ir->timer.expires = jiffies + msecs_to_jiffies(1000);
add_timer(&ir->timer);
} else if (ir->rc5_gpio) {
/* set timer_end for code completion */
- setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir);
+ timer_setup(&ir->timer, bttv_rc5_timer_end, 0);
ir->shift_by = 1;
ir->rc5_remote_gap = ir_rc5_remote_gap;
}
@@ -531,6 +531,7 @@ int bttv_input_init(struct bttv *btv)
/* init input device */
ir->dev = rc;
+ ir->btv = btv;
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
btv->c.type);
@@ -553,7 +554,7 @@ int bttv_input_init(struct bttv *btv)
rc->driver_name = MODULE_NAME;
btv->remote = ir;
- bttv_ir_start(btv, ir);
+ bttv_ir_start(ir);
/* all done */
err = rc_register_device(rc);
diff --git a/drivers/media/pci/bt8xx/bttv-vbi.c b/drivers/media/pci/bt8xx/bttv-vbi.c
index e77129c92fa0..67c6583f1d79 100644
--- a/drivers/media/pci/bt8xx/bttv-vbi.c
+++ b/drivers/media/pci/bt8xx/bttv-vbi.c
@@ -233,7 +233,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer
bttv_dma_free(q,fh->btv,buf);
}
-struct videobuf_queue_ops bttv_vbi_qops = {
+const struct videobuf_queue_ops bttv_vbi_qops = {
.buf_setup = vbi_buffer_setup,
.buf_prepare = vbi_buffer_prepare,
.buf_queue = vbi_buffer_queue,
diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h
index 91301c3cad1e..eb67e362acf7 100644
--- a/drivers/media/pci/bt8xx/bttv.h
+++ b/drivers/media/pci/bt8xx/bttv.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
*
* bttv - Bt848 frame grabber driver
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index 9efc4559fa8e..cb1b5e611130 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -122,6 +122,7 @@ struct bttv_format {
struct bttv_ir {
struct rc_dev *dev;
+ struct bttv *btv;
struct timer_list timer;
char name[32];
@@ -281,7 +282,7 @@ int bttv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
int bttv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
-extern struct videobuf_queue_ops bttv_vbi_qops;
+extern const struct videobuf_queue_ops bttv_vbi_qops;
/* ---------------------------------------------------------- */
/* bttv-gpio.c */
diff --git a/drivers/media/pci/bt8xx/dst_priv.h b/drivers/media/pci/bt8xx/dst_priv.h
index 3974a4c6ebe7..a4319d41d141 100644
--- a/drivers/media/pci/bt8xx/dst_priv.h
+++ b/drivers/media/pci/bt8xx/dst_priv.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
*
diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c
index 98b6cb9505d1..3f16cf3f6d74 100644
--- a/drivers/media/pci/cobalt/cobalt-driver.c
+++ b/drivers/media/pci/cobalt/cobalt-driver.c
@@ -738,9 +738,6 @@ static int cobalt_probe(struct pci_dev *pci_dev,
goto err_i2c;
}
- retval = v4l2_device_register_subdev_nodes(&cobalt->v4l2_dev);
- if (retval)
- goto err_i2c;
retval = cobalt_nodes_register(cobalt);
if (retval) {
cobalt_err("Error %d registering device nodes\n", retval);
@@ -767,8 +764,6 @@ err_pci:
err_wq:
destroy_workqueue(cobalt->irq_work_queues);
err:
- if (retval == 0)
- retval = -ENODEV;
cobalt_err("error %d on initialization\n", retval);
v4l2_device_unregister(&cobalt->v4l2_dev);
diff --git a/drivers/media/pci/cx18/Makefile b/drivers/media/pci/cx18/Makefile
index d3ff1545c2c5..98914a40f6ac 100644
--- a/drivers/media/pci/cx18/Makefile
+++ b/drivers/media/pci/cx18/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
index 8654710464cc..8f314ca320c7 100644
--- a/drivers/media/pci/cx18/cx18-driver.c
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -255,7 +255,7 @@ static void request_module_async(struct work_struct *work)
request_module("cx18-alsa");
/* Initialize cx18-alsa for this instance of the cx18 device */
- if (cx18_ext_init != NULL)
+ if (cx18_ext_init)
cx18_ext_init(dev);
}
@@ -291,11 +291,11 @@ int cx18_msleep_timeout(unsigned int msecs, int intr)
/* Release ioremapped memory */
static void cx18_iounmap(struct cx18 *cx)
{
- if (cx == NULL)
+ if (!cx)
return;
/* Release io memory */
- if (cx->enc_mem != NULL) {
+ if (cx->enc_mem) {
CX18_DEBUG_INFO("releasing enc_mem\n");
iounmap(cx->enc_mem);
cx->enc_mem = NULL;
@@ -649,15 +649,15 @@ static void cx18_process_options(struct cx18 *cx)
CX18_INFO("User specified %s card\n", cx->card->name);
else if (cx->options.cardtype != 0)
CX18_ERR("Unknown user specified type, trying to autodetect card\n");
- if (cx->card == NULL) {
+ if (!cx->card) {
if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_INFO("Autodetected Hauppauge card\n");
}
}
- if (cx->card == NULL) {
+ if (!cx->card) {
for (i = 0; (cx->card = cx18_get_card(i)); i++) {
- if (cx->card->pci_list == NULL)
+ if (!cx->card->pci_list)
continue;
for (j = 0; cx->card->pci_list[j].device; j++) {
if (cx->pci_dev->device !=
@@ -676,7 +676,7 @@ static void cx18_process_options(struct cx18 *cx)
}
done:
- if (cx->card == NULL) {
+ if (!cx->card) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
cx->pci_dev->vendor, cx->pci_dev->device);
@@ -698,7 +698,7 @@ static int cx18_create_in_workq(struct cx18 *cx)
snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
cx->v4l2_dev.name);
cx->in_work_queue = alloc_ordered_workqueue("%s", 0, cx->in_workq_name);
- if (cx->in_work_queue == NULL) {
+ if (!cx->in_work_queue) {
CX18_ERR("Unable to create incoming mailbox handler thread\n");
return -ENOMEM;
}
@@ -909,12 +909,10 @@ static int cx18_probe(struct pci_dev *pci_dev,
return -ENOMEM;
}
- cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
- if (cx == NULL) {
- printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
- i);
+ cx = kzalloc(sizeof(*cx), GFP_ATOMIC);
+ if (!cx)
return -ENOMEM;
- }
+
cx->pci_dev = pci_dev;
cx->instance = i;
@@ -1256,7 +1254,7 @@ static void cx18_cancel_out_work_orders(struct cx18 *cx)
{
int i;
for (i = 0; i < CX18_MAX_STREAMS; i++)
- if (&cx->streams[i].video_dev != NULL)
+ if (&cx->streams[i].video_dev)
cancel_work_sync(&cx->streams[i].out_work_order);
}
@@ -1301,7 +1299,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
pci_disable_device(cx->pci_dev);
- if (cx->vbi.sliced_mpeg_data[0] != NULL)
+ if (cx->vbi.sliced_mpeg_data[0])
for (i = 0; i < CX18_VBI_FRAMES; i++)
kfree(cx->vbi.sliced_mpeg_data[i]);
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c
index 98467b2089fa..4f9c2395941b 100644
--- a/drivers/media/pci/cx18/cx18-fileops.c
+++ b/drivers/media/pci/cx18/cx18-fileops.c
@@ -684,9 +684,9 @@ int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
return -EINVAL;
}
-void cx18_vb_timeout(unsigned long data)
+void cx18_vb_timeout(struct timer_list *t)
{
- struct cx18_stream *s = (struct cx18_stream *)data;
+ struct cx18_stream *s = from_timer(s, t, vb_timeout);
struct cx18_videobuf_buffer *buf;
unsigned long flags;
diff --git a/drivers/media/pci/cx18/cx18-fileops.h b/drivers/media/pci/cx18/cx18-fileops.h
index 58b00b433708..37ef34e866cb 100644
--- a/drivers/media/pci/cx18/cx18-fileops.h
+++ b/drivers/media/pci/cx18/cx18-fileops.h
@@ -29,7 +29,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
void cx18_mute(struct cx18 *cx);
void cx18_unmute(struct cx18 *cx);
int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
-void cx18_vb_timeout(unsigned long data);
+void cx18_vb_timeout(struct timer_list *t);
/* Shared with cx18-alsa module */
int cx18_claim_stream(struct cx18_open_id *id, int type);
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index 8385411af641..f35f78d66985 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -282,7 +282,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
INIT_WORK(&s->out_work_order, cx18_out_work_handler);
INIT_LIST_HEAD(&s->vb_capture);
- setup_timer(&s->vb_timeout, cx18_vb_timeout, (unsigned long)s);
+ timer_setup(&s->vb_timeout, cx18_vb_timeout, 0);
spin_lock_init(&s->vb_lock);
if (type == CX18_ENC_STREAM_TYPE_YUV) {
spin_lock_init(&s->vbuf_q_lock);
diff --git a/drivers/media/pci/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index a2cbdcf15a8c..b8bf7806124b 100644
--- a/drivers/media/pci/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
cx23885-ioctl.o cx23885-ir.o cx23885-av.o cx23885-input.o \
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 78a8836d03e4..28eab9c518c5 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -1323,7 +1323,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
static void tbs_card_init(struct cx23885_dev *dev)
{
int i;
- const u8 buf[] = {
+ static const u8 buf[] = {
0xe0, 0x06, 0x66, 0x33, 0x65,
0x01, 0x17, 0x06, 0xde};
diff --git a/drivers/media/pci/cx23885/cx23885-f300.h b/drivers/media/pci/cx23885/cx23885-f300.h
index be14d7de7cd8..34aef3610aa9 100644
--- a/drivers/media/pci/cx23885/cx23885-f300.h
+++ b/drivers/media/pci/cx23885/cx23885-f300.h
@@ -1,2 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0 */
extern int f300_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage voltage);
diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c
index 0f21467ae88e..ef863492c0ac 100644
--- a/drivers/media/pci/cx23885/cx23885-i2c.c
+++ b/drivers/media/pci/cx23885/cx23885-i2c.c
@@ -270,7 +270,7 @@ static const struct i2c_adapter cx23885_i2c_adap_template = {
.algo = &cx23885_i2c_algo_template,
};
-static struct i2c_client cx23885_i2c_client_template = {
+static const struct i2c_client cx23885_i2c_client_template = {
.name = "cx23885 internal",
};
diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index 369e545cac04..70f9f13bded3 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -254,7 +254,7 @@ static void cx23885_stop_streaming(struct vb2_queue *q)
}
-struct vb2_ops cx23885_vbi_qops = {
+const struct vb2_ops cx23885_vbi_qops = {
.queue_setup = queue_setup,
.buf_prepare = buffer_prepare,
.buf_finish = buffer_finish,
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index cb714ab60d69..6aab713e0476 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -591,7 +591,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm);
extern int cx23885_vbi_fmt(struct file *file, void *priv,
struct v4l2_format *f);
extern void cx23885_vbi_timeout(unsigned long data);
-extern struct vb2_ops cx23885_vbi_qops;
+extern const struct vb2_ops cx23885_vbi_qops;
extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status);
/* cx23885-i2c.c */
diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile
index c8f8598a2b86..d14d65b1b042 100644
--- a/drivers/media/pci/cx25821/Makefile
+++ b/drivers/media/pci/cx25821/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \
cx25821-gpio.o cx25821-medusa-video.o \
cx25821-video.o
diff --git a/drivers/media/pci/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c
index 000049d3c71b..31479a41f359 100644
--- a/drivers/media/pci/cx25821/cx25821-i2c.c
+++ b/drivers/media/pci/cx25821/cx25821-i2c.c
@@ -291,7 +291,7 @@ static const struct i2c_adapter cx25821_i2c_adap_template = {
.algo = &cx25821_i2c_algo_template,
};
-static struct i2c_client cx25821_i2c_client_template = {
+static const struct i2c_client cx25821_i2c_client_template = {
.name = "cx25821 internal",
};
diff --git a/drivers/media/pci/cx88/Makefile b/drivers/media/pci/cx88/Makefile
index d3679c3ee248..86646eee4e6b 100644
--- a/drivers/media/pci/cx88/Makefile
+++ b/drivers/media/pci/cx88/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
cx88-dsp.o cx88-input.o
cx8800-objs := cx88-video.o cx88-vbi.o
diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
index e02449bf2041..4e9953e61a12 100644
--- a/drivers/media/pci/cx88/cx88-input.c
+++ b/drivers/media/pci/cx88/cx88-input.c
@@ -593,11 +593,11 @@ static int get_key_pvr2000(struct IR_i2c *ir, enum rc_proto *protocol,
void cx88_i2c_init_ir(struct cx88_core *core)
{
struct i2c_board_info info;
- const unsigned short default_addr_list[] = {
+ static const unsigned short default_addr_list[] = {
0x18, 0x6b, 0x71,
I2C_CLIENT_END
};
- const unsigned short pvr2000_addr_list[] = {
+ static const unsigned short pvr2000_addr_list[] = {
0x18, 0x1a,
I2C_CLIENT_END
};
diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
index 2d0ef19e6d65..c637679b01b2 100644
--- a/drivers/media/pci/cx88/cx88-vbi.c
+++ b/drivers/media/pci/cx88/cx88-vbi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
*/
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
index 09703312a3f1..7453b65104ff 100644
--- a/drivers/media/pci/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the ddbridge device driver
#
diff --git a/drivers/media/pci/ddbridge/ddbridge-io.h b/drivers/media/pci/ddbridge/ddbridge-io.h
index a4c6bbe09168..b3646c04f1a7 100644
--- a/drivers/media/pci/ddbridge/ddbridge-io.h
+++ b/drivers/media/pci/ddbridge/ddbridge-io.h
@@ -47,12 +47,12 @@ static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr)
static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
{
- return memcpy_toio(dev->regs + adr, src, count);
+ memcpy_toio(dev->regs + adr, src, count);
}
static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
{
- return memcpy_fromio(dst, dev->regs + adr, count);
+ memcpy_fromio(dst, dev->regs + adr, count);
}
static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr)
diff --git a/drivers/media/pci/ivtv/Makefile b/drivers/media/pci/ivtv/Makefile
index 0eaa88298b7e..48f8a23f9a0f 100644
--- a/drivers/media/pci/ivtv/Makefile
+++ b/drivers/media/pci/ivtv/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
ivtv-objs := ivtv-routing.o ivtv-cards.o ivtv-controls.o \
ivtv-driver.o ivtv-fileops.o ivtv-firmware.o \
ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index 54dcac4b2229..6b2ffdc96961 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -770,8 +770,7 @@ static int ivtv_init_struct1(struct ivtv *itv)
init_waitqueue_head(&itv->event_waitq);
init_waitqueue_head(&itv->vsync_waitq);
init_waitqueue_head(&itv->dma_waitq);
- setup_timer(&itv->dma_timer, ivtv_unfinished_dma,
- (unsigned long)itv);
+ timer_setup(&itv->dma_timer, ivtv_unfinished_dma, 0);
itv->cur_dma_stream = -1;
itv->cur_pio_stream = -1;
diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c
index 5a35e366f4c0..893962ac85de 100644
--- a/drivers/media/pci/ivtv/ivtv-i2c.c
+++ b/drivers/media/pci/ivtv/ivtv-i2c.c
@@ -700,7 +700,7 @@ static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
.timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */
};
-static struct i2c_client ivtv_i2c_client_template = {
+static const struct i2c_client ivtv_i2c_client_template = {
.name = "ivtv internal",
};
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c
index 6efe1f71262c..63b09bf73bf0 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -1074,9 +1074,9 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
return vsync_force ? IRQ_NONE : IRQ_HANDLED;
}
-void ivtv_unfinished_dma(unsigned long arg)
+void ivtv_unfinished_dma(struct timer_list *t)
{
- struct ivtv *itv = (struct ivtv *)arg;
+ struct ivtv *itv = from_timer(itv, t, dma_timer);
if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
return;
diff --git a/drivers/media/pci/ivtv/ivtv-irq.h b/drivers/media/pci/ivtv/ivtv-irq.h
index 1e84433737cc..bcab5f07d37f 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.h
+++ b/drivers/media/pci/ivtv/ivtv-irq.h
@@ -48,6 +48,6 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
void ivtv_irq_work_handler(struct kthread_work *work);
void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
-void ivtv_unfinished_dma(unsigned long arg);
+void ivtv_unfinished_dma(struct timer_list *t);
#endif
diff --git a/drivers/media/pci/mantis/Makefile b/drivers/media/pci/mantis/Makefile
index f715051e4453..a684dc2ec79e 100644
--- a/drivers/media/pci/mantis/Makefile
+++ b/drivers/media/pci/mantis/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
mantis_core-objs := mantis_ioc.o \
mantis_uart.o \
mantis_dma.o \
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index 11e987860b23..ed855e3df558 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -72,7 +72,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
struct mantis_ca *ca;
mantis = (struct mantis_pci *) dev_id;
- if (unlikely(mantis == NULL)) {
+ if (unlikely(!mantis)) {
dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
return IRQ_NONE;
}
@@ -161,11 +161,10 @@ static int hopper_pci_probe(struct pci_dev *pdev,
struct mantis_pci_drvdata *drvdata;
struct mantis_pci *mantis;
struct mantis_hwconfig *config;
- int err = 0;
+ int err;
- mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
- if (mantis == NULL) {
- printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
+ mantis = kzalloc(sizeof(*mantis), GFP_KERNEL);
+ if (!mantis) {
err = -ENOMEM;
goto fail0;
}
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index adc980d33711..4ce8a90d69dc 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -171,13 +171,11 @@ static int mantis_pci_probe(struct pci_dev *pdev,
struct mantis_pci_drvdata *drvdata;
struct mantis_pci *mantis;
struct mantis_hwconfig *config;
- int err = 0;
+ int err;
- mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
- if (mantis == NULL) {
- printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
+ mantis = kzalloc(sizeof(*mantis), GFP_KERNEL);
+ if (!mantis)
return -ENOMEM;
- }
drvdata = (void *)pci_id->driver_data;
mantis->num = devs;
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index 49e047e4a81e..23999a8cef37 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1626,35 +1626,31 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
meye.mchip_dev = pcidev;
meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
- if (!meye.grab_temp) {
- v4l2_err(v4l2_dev, "grab buffer allocation failed\n");
+ if (!meye.grab_temp)
goto outvmalloc;
- }
spin_lock_init(&meye.grabq_lock);
if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
- GFP_KERNEL)) {
- v4l2_err(v4l2_dev, "fifo allocation failed\n");
+ GFP_KERNEL))
goto outkfifoalloc1;
- }
+
spin_lock_init(&meye.doneq_lock);
if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
- GFP_KERNEL)) {
- v4l2_err(v4l2_dev, "fifo allocation failed\n");
+ GFP_KERNEL))
goto outkfifoalloc2;
- }
meye.vdev = meye_template;
meye.vdev.v4l2_dev = &meye.v4l2_dev;
- ret = -EIO;
- if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
+ ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1);
+ if (ret) {
v4l2_err(v4l2_dev, "meye: unable to power on the camera\n");
v4l2_err(v4l2_dev, "meye: did you enable the camera in sonypi using the module options ?\n");
goto outsonypienable;
}
- if ((ret = pci_enable_device(meye.mchip_dev))) {
+ ret = pci_enable_device(meye.mchip_dev);
+ if (ret) {
v4l2_err(v4l2_dev, "meye: pci_enable_device failed\n");
goto outenabledev;
}
diff --git a/drivers/media/pci/netup_unidvb/Kconfig b/drivers/media/pci/netup_unidvb/Kconfig
index 0ad37714c7fd..b663154d0cc4 100644
--- a/drivers/media/pci/netup_unidvb/Kconfig
+++ b/drivers/media/pci/netup_unidvb/Kconfig
@@ -1,8 +1,8 @@
config DVB_NETUP_UNIDVB
tristate "NetUP Universal DVB card support"
depends on DVB_CORE && VIDEO_DEV && PCI && I2C && SPI_MASTER
- select VIDEOBUF2_DVB
- select VIDEOBUF2_VMALLOC
+ select VIDEOBUF2_DVB
+ select VIDEOBUF2_VMALLOC
select DVB_HORUS3A if MEDIA_SUBDRV_AUTOSELECT
select DVB_ASCOT2E if MEDIA_SUBDRV_AUTOSELECT
select DVB_HELENE if MEDIA_SUBDRV_AUTOSELECT
@@ -10,8 +10,8 @@ config DVB_NETUP_UNIDVB
select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT
---help---
Support for NetUP PCI express Universal DVB card.
- help
- Say Y when you want to support NetUP Dual Universal DVB card
- Card can receive two independent streams in following standards:
+
+ Say Y when you want to support NetUP Dual Universal DVB card.
+ Card can receive two independent streams in following standards:
DVB-S/S2, T/T2, C/C2
- Two CI slots available for CAM modules.
+ Two CI slots available for CAM modules.
diff --git a/drivers/media/pci/netup_unidvb/Makefile b/drivers/media/pci/netup_unidvb/Makefile
index ee6ae0501eae..07d3f1eb728b 100644
--- a/drivers/media/pci/netup_unidvb/Makefile
+++ b/drivers/media/pci/netup_unidvb/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
netup-unidvb-objs += netup_unidvb_core.o
netup-unidvb-objs += netup_unidvb_i2c.o
netup-unidvb-objs += netup_unidvb_ci.o
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 60e6cd5b3a03..509d69e6ca4a 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -82,11 +82,11 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
* @start_addr_lo: DMA ring buffer start address, lower part
* @start_addr_hi: DMA ring buffer start address, higher part
* @size: DMA ring buffer size register
- Bits [0-7]: DMA packet size, 188 bytes
- Bits [16-23]: packets count in block, 128 packets
- Bits [24-31]: blocks count, 8 blocks
+ * * Bits [0-7]: DMA packet size, 188 bytes
+ * * Bits [16-23]: packets count in block, 128 packets
+ * * Bits [24-31]: blocks count, 8 blocks
* @timeout: DMA timeout in units of 8ns
- For example, value of 375000000 equals to 3 sec
+ * For example, value of 375000000 equals to 3 sec
* @curr_addr_lo: Current ring buffer head address, lower part
* @curr_addr_hi: Current ring buffer head address, higher part
* @stat_pkt_received: Statistic register, not tested
@@ -638,9 +638,9 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma)
spin_unlock_irqrestore(&dma->lock, flags);
}
-static void netup_unidvb_dma_timeout(unsigned long data)
+static void netup_unidvb_dma_timeout(struct timer_list *t)
{
- struct netup_dma *dma = (struct netup_dma *)data;
+ struct netup_dma *dma = from_timer(dma, t, timeout);
struct netup_unidvb_dev *ndev = dma->ndev;
dev_dbg(&ndev->pci_dev->dev, "%s()\n", __func__);
@@ -664,8 +664,7 @@ static int netup_unidvb_dma_init(struct netup_unidvb_dev *ndev, int num)
spin_lock_init(&dma->lock);
INIT_WORK(&dma->work, netup_unidvb_dma_worker);
INIT_LIST_HEAD(&dma->free_buffers);
- setup_timer(&dma->timeout, netup_unidvb_dma_timeout,
- (unsigned long)dma);
+ timer_setup(&dma->timeout, netup_unidvb_dma_timeout, 0);
dma->ring_buffer_size = ndev->dma_size / 2;
dma->addr_virt = ndev->dma_virt + dma->ring_buffer_size * num;
dma->addr_phys = (dma_addr_t)((u64)ndev->dma_phys +
diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile
index 5c0b5d6b9d69..dbdf284970f8 100644
--- a/drivers/media/pci/ngene/Makefile
+++ b/drivers/media/pci/ngene/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the nGene device driver
#
diff --git a/drivers/media/pci/pt3/Makefile b/drivers/media/pci/pt3/Makefile
index 396f146b1c18..aded8752ac2b 100644
--- a/drivers/media/pci/pt3/Makefile
+++ b/drivers/media/pci/pt3/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
earth-pt3-objs += pt3.o pt3_i2c.o pt3_dma.o
diff --git a/drivers/media/pci/saa7134/Makefile b/drivers/media/pci/saa7134/Makefile
index 09c43da67588..dbaadddf4320 100644
--- a/drivers/media/pci/saa7134/Makefile
+++ b/drivers/media/pci/saa7134/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
saa7134-y += saa7134-cards.o saa7134-core.o saa7134-i2c.o
saa7134-y += saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index 7976c5a12ca8..9e76de2411ae 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -338,9 +338,9 @@ void saa7134_buffer_next(struct saa7134_dev *dev,
}
}
-void saa7134_buffer_timeout(unsigned long data)
+void saa7134_buffer_timeout(struct timer_list *t)
{
- struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue *)data;
+ struct saa7134_dmaqueue *q = from_timer(q, t, timeout);
struct saa7134_dev *dev = q->dev;
unsigned long flags;
@@ -378,7 +378,7 @@ void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q)
}
}
spin_unlock_irqrestore(&dev->slock, flags);
- saa7134_buffer_timeout((unsigned long)q); /* also calls del_timer(&q->timeout) */
+ saa7134_buffer_timeout(&q->timeout); /* also calls del_timer(&q->timeout) */
}
EXPORT_SYMBOL_GPL(saa7134_stop_streaming);
diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c
index 8f2ed632840f..cf1e526de56a 100644
--- a/drivers/media/pci/saa7134/saa7134-i2c.c
+++ b/drivers/media/pci/saa7134/saa7134-i2c.c
@@ -345,7 +345,7 @@ static const struct i2c_adapter saa7134_adap_template = {
.algo = &saa7134_algo,
};
-static struct i2c_client saa7134_client_template = {
+static const struct i2c_client saa7134_client_template = {
.name = "saa7134 internal",
};
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 9337e4615519..2d5abeddc079 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -447,10 +447,10 @@ void saa7134_input_irq(struct saa7134_dev *dev)
}
}
-static void saa7134_input_timer(unsigned long data)
+static void saa7134_input_timer(struct timer_list *t)
{
- struct saa7134_dev *dev = (struct saa7134_dev *)data;
- struct saa7134_card_ir *ir = dev->remote;
+ struct saa7134_card_ir *ir = from_timer(ir, t, timer);
+ struct saa7134_dev *dev = ir->dev->priv;
build_key(dev);
mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
@@ -507,8 +507,7 @@ static int __saa7134_ir_start(void *priv)
ir->running = true;
if (ir->polling) {
- setup_timer(&ir->timer, saa7134_input_timer,
- (unsigned long)dev);
+ timer_setup(&ir->timer, saa7134_input_timer, 0);
ir->timer.expires = jiffies + HZ;
add_timer(&ir->timer);
}
diff --git a/drivers/media/pci/saa7134/saa7134-reg.h b/drivers/media/pci/saa7134/saa7134-reg.h
index b6ea6f4f9b6c..56b12641d733 100644
--- a/drivers/media/pci/saa7134/saa7134-reg.h
+++ b/drivers/media/pci/saa7134/saa7134-reg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
*
* philips saa7134 registers
diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c
index 7414878af9e0..2be703617e29 100644
--- a/drivers/media/pci/saa7134/saa7134-ts.c
+++ b/drivers/media/pci/saa7134/saa7134-ts.c
@@ -223,8 +223,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
dev->ts.nr_packets = ts_nr_packets;
INIT_LIST_HEAD(&dev->ts_q.queue);
- setup_timer(&dev->ts_q.timeout, saa7134_buffer_timeout,
- (unsigned long)(&dev->ts_q));
+ timer_setup(&dev->ts_q.timeout, saa7134_buffer_timeout, 0);
dev->ts_q.dev = dev;
dev->ts_q.need_two = 1;
dev->ts_started = 0;
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index bcad9b2d9bb3..57bea543c39b 100644
--- a/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -165,7 +165,7 @@ static int buffer_init(struct vb2_buffer *vb2)
return 0;
}
-struct vb2_ops saa7134_vbi_qops = {
+const struct vb2_ops saa7134_vbi_qops = {
.queue_setup = queue_setup,
.buf_init = buffer_init,
.buf_prepare = buffer_prepare,
@@ -181,8 +181,7 @@ struct vb2_ops saa7134_vbi_qops = {
int saa7134_vbi_init1(struct saa7134_dev *dev)
{
INIT_LIST_HEAD(&dev->vbi_q.queue);
- setup_timer(&dev->vbi_q.timeout, saa7134_buffer_timeout,
- (unsigned long)(&dev->vbi_q));
+ timer_setup(&dev->vbi_q.timeout, saa7134_buffer_timeout, 0);
dev->vbi_q.dev = dev;
if (vbibufs < 2)
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 51d42bbf969e..82d2a24644e4 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -2145,8 +2145,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
dev->automute = 0;
INIT_LIST_HEAD(&dev->video_q.queue);
- setup_timer(&dev->video_q.timeout, saa7134_buffer_timeout,
- (unsigned long)(&dev->video_q));
+ timer_setup(&dev->video_q.timeout, saa7134_buffer_timeout, 0);
dev->video_q.dev = dev;
dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
dev->width = 720;
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 816b5282d671..39c36e6aefbe 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -773,7 +773,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
unsigned int state);
void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
-void saa7134_buffer_timeout(unsigned long data);
+void saa7134_buffer_timeout(struct timer_list *t);
void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
int saa7134_set_dmabits(struct saa7134_dev *dev);
@@ -870,7 +870,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev);
/* ----------------------------------------------------------- */
/* saa7134-vbi.c */
-extern struct vb2_ops saa7134_vbi_qops;
+extern const struct vb2_ops saa7134_vbi_qops;
extern struct video_device saa7134_vbi_template;
int saa7134_vbi_init1(struct saa7134_dev *dev);
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index f708cab01fef..d31a2d4494d1 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -260,11 +260,10 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
DEB_EE("\n");
- hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
- if (NULL == hexium) {
- pr_err("not enough kernel memory in hexium_attach()\n");
+ hexium = kzalloc(sizeof(*hexium), GFP_KERNEL);
+ if (!hexium)
return -ENOMEM;
- }
+
dev->ext_priv = hexium;
/* enable i2c-port pins */
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 01f01580c7ca..043318aa19e2 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -219,11 +219,9 @@ static int hexium_probe(struct saa7146_dev *dev)
return -EFAULT;
}
- hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
- if (NULL == hexium) {
- pr_err("hexium_probe: not enough kernel memory\n");
+ hexium = kzalloc(sizeof(*hexium), GFP_KERNEL);
+ if (!hexium)
return -ENOMEM;
- }
/* enable i2c-port pins */
saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
@@ -268,7 +266,9 @@ static int hexium_probe(struct saa7146_dev *dev)
/* check if this is an old hexium Orion card by looking at
a saa7110 at address 0x4e */
- if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) {
+ err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ,
+ 0x00, I2C_SMBUS_BYTE_DATA, &data);
+ if (err == 0) {
pr_info("device is a Hexium HV-PCI6/Orion (old)\n");
/* we store the pointer in our private data field */
dev->ext_priv = hexium;
diff --git a/drivers/media/pci/saa7164/Makefile b/drivers/media/pci/saa7164/Makefile
index ba0e33a1ee24..3896bcdb99d2 100644
--- a/drivers/media/pci/saa7164/Makefile
+++ b/drivers/media/pci/saa7164/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
saa7164-buffer.o saa7164-encoder.o saa7164-vbi.o
diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c
index a0d2129c6ca9..c83b2e914dcb 100644
--- a/drivers/media/pci/saa7164/saa7164-buffer.c
+++ b/drivers/media/pci/saa7164/saa7164-buffer.c
@@ -98,11 +98,9 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
goto ret;
}
- buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
- if (!buf) {
- log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
+ buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+ if (!buf)
goto ret;
- }
buf->idx = -1;
buf->port = port;
@@ -283,7 +281,7 @@ struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
{
struct saa7164_user_buffer *buf;
- buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL);
+ buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (!buf)
return NULL;
diff --git a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c
index 4bcde7c79dc3..6d13cbb9d010 100644
--- a/drivers/media/pci/saa7164/saa7164-i2c.c
+++ b/drivers/media/pci/saa7164/saa7164-i2c.c
@@ -84,7 +84,7 @@ static const struct i2c_adapter saa7164_i2c_adap_template = {
.algo = &saa7164_i2c_algo_template,
};
-static struct i2c_client saa7164_i2c_client_template = {
+static const struct i2c_client saa7164_i2c_client_template = {
.name = "saa7164 internal",
};
diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
index 013bc3fe4294..6006aac3c41f 100644
--- a/drivers/media/pci/smipcie/Makefile
+++ b/drivers/media/pci/smipcie/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
smipcie-objs := smipcie-main.o smipcie-ir.o
diff --git a/drivers/media/pci/solo6x10/solo6x10-enc.c b/drivers/media/pci/solo6x10/solo6x10-enc.c
index d28211bb9674..58d6b5131dd0 100644
--- a/drivers/media/pci/solo6x10/solo6x10-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-enc.c
@@ -175,7 +175,7 @@ out:
return 0;
}
-/**
+/*
* Set channel Quality Profile (0-3).
*/
void solo_s_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch,
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index eb5a9eae7c8e..dd199bfc1d45 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -404,6 +404,7 @@ static const struct v4l2_file_operations vip_fops = {
* vidioc_querycap - return capabilities of device
* @file: descriptor of device
* @cap: contains return values
+ * @priv: unused
*
* the capabilities of the device are returned
*
@@ -429,6 +430,7 @@ static int vidioc_querycap(struct file *file, void *priv,
* vidioc_s_std - set video standard
* @file: descriptor of device
* @std: contains standard to be set
+ * @priv: unused
*
* the video standard is set
*
@@ -466,6 +468,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
/**
* vidioc_g_std - get video standard
* @file: descriptor of device
+ * @priv: unused
* @std: contains return values
*
* the current video standard is returned
@@ -483,6 +486,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
/**
* vidioc_querystd - get possible video standards
* @file: descriptor of device
+ * @priv: unused
* @std: contains return values
*
* all possible video standards are returned
@@ -512,6 +516,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
/**
* vidioc_s_input - set input line
* @file: descriptor of device
+ * @priv: unused
* @i: new input line number
*
* the current active input line is set
@@ -538,6 +543,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
/**
* vidioc_g_input - return input line
* @file: descriptor of device
+ * @priv: unused
* @i: returned input line number
*
* the current active input line is returned
@@ -554,6 +560,8 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
/**
* vidioc_enum_fmt_vid_cap - return video capture format
+ * @file: descriptor of device
+ * @priv: unused
* @f: returned format information
*
* returns name and format of video capture
@@ -577,6 +585,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
/**
* vidioc_try_fmt_vid_cap - set video capture format
* @file: descriptor of device
+ * @priv: unused
* @f: new format
*
* new video format is set which includes width and
@@ -639,6 +648,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
/**
* vidioc_s_fmt_vid_cap - set current video format parameters
* @file: descriptor of device
+ * @priv: unused
* @f: returned format information
*
* set new capture format
@@ -706,6 +716,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
/**
* vidioc_g_fmt_vid_cap - get current video format parameters
* @file: descriptor of device
+ * @priv: unused
* @f: contains format information
*
* returns current video format parameters
diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile
index 3cf617737f7c..0b805339c123 100644
--- a/drivers/media/pci/ttpci/Makefile
+++ b/drivers/media/pci/ttpci/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel SAA7146 FULL TS DVB device driver
# and the AV7110 DVB device driver
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
index f46947d8adf8..6d415bdeef18 100644
--- a/drivers/media/pci/ttpci/av7110.c
+++ b/drivers/media/pci/ttpci/av7110.c
@@ -347,9 +347,9 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
static inline void print_time(char *s)
{
#ifdef DEBUG_TIMING
- struct timeval tv;
- do_gettimeofday(&tv);
- printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
+ struct timespec64 ts;
+ ktime_get_real_ts64(&ts);
+ printk("%s: %lld.%09ld\n", s, (s64)ts.tv_sec, ts.tv_nsec);
#endif
}
@@ -1224,7 +1224,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
dprintk(2, "av7110: %p\n", budget);
spin_lock(&budget->feedlock1);
- feed->pusi_seen = 0; /* have a clean section start */
+ feed->pusi_seen = false; /* have a clean section start */
status = start_ts_capture(budget);
spin_unlock(&budget->feedlock1);
return status;
diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h
index 347827925c14..cbb150d6cbb1 100644
--- a/drivers/media/pci/ttpci/av7110.h
+++ b/drivers/media/pci/ttpci/av7110.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _AV7110_H_
#define _AV7110_H_
@@ -93,7 +94,7 @@ struct infrared {
u8 inversion;
u16 last_key;
u16 last_toggle;
- u8 delay_timer_finished;
+ bool keypressed;
};
diff --git a/drivers/media/pci/ttpci/av7110_av.h b/drivers/media/pci/ttpci/av7110_av.h
index f52276f47709..71bbd4391f57 100644
--- a/drivers/media/pci/ttpci/av7110_av.h
+++ b/drivers/media/pci/ttpci/av7110_av.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _AV7110_AV_H_
#define _AV7110_AV_H_
diff --git a/drivers/media/pci/ttpci/av7110_ca.h b/drivers/media/pci/ttpci/av7110_ca.h
index 70ee855ece1b..a6e3f2955730 100644
--- a/drivers/media/pci/ttpci/av7110_ca.h
+++ b/drivers/media/pci/ttpci/av7110_ca.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _AV7110_CA_H_
#define _AV7110_CA_H_
diff --git a/drivers/media/pci/ttpci/av7110_hw.h b/drivers/media/pci/ttpci/av7110_hw.h
index ccb148059406..6380d8950c69 100644
--- a/drivers/media/pci/ttpci/av7110_hw.h
+++ b/drivers/media/pci/ttpci/av7110_hw.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _AV7110_HW_H_
#define _AV7110_HW_H_
diff --git a/drivers/media/pci/ttpci/av7110_ipack.c b/drivers/media/pci/ttpci/av7110_ipack.c
index 699ef8b5b99a..5aff26574fe1 100644
--- a/drivers/media/pci/ttpci/av7110_ipack.c
+++ b/drivers/media/pci/ttpci/av7110_ipack.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include "dvb_filter.h"
#include "av7110_ipack.h"
#include <linux/string.h> /* for memcpy() */
diff --git a/drivers/media/pci/ttpci/av7110_ipack.h b/drivers/media/pci/ttpci/av7110_ipack.h
index becf94d3fdfa..943ec899bb93 100644
--- a/drivers/media/pci/ttpci/av7110_ipack.h
+++ b/drivers/media/pci/ttpci/av7110_ipack.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _AV7110_IPACK_H_
#define _AV7110_IPACK_H_
diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
index ca05198de2c2..ee414803e6b5 100644
--- a/drivers/media/pci/ttpci/av7110_ir.c
+++ b/drivers/media/pci/ttpci/av7110_ir.c
@@ -84,15 +84,16 @@ static u16 default_key_map [256] = {
/* key-up timer */
-static void av7110_emit_keyup(unsigned long parm)
+static void av7110_emit_keyup(struct timer_list *t)
{
- struct infrared *ir = (struct infrared *) parm;
+ struct infrared *ir = from_timer(ir, t, keyup_timer);
- if (!ir || !test_bit(ir->last_key, ir->input_dev->key))
+ if (!ir || !ir->keypressed)
return;
input_report_key(ir->input_dev, ir->last_key, 0);
input_sync(ir->input_dev);
+ ir->keypressed = false;
}
@@ -152,29 +153,18 @@ static void av7110_emit_key(unsigned long parm)
return;
}
- if (timer_pending(&ir->keyup_timer)) {
- del_timer(&ir->keyup_timer);
- if (ir->last_key != keycode || toggle != ir->last_toggle) {
- ir->delay_timer_finished = 0;
- input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
- input_event(ir->input_dev, EV_KEY, keycode, 1);
- input_sync(ir->input_dev);
- } else if (ir->delay_timer_finished) {
- input_event(ir->input_dev, EV_KEY, keycode, 2);
- input_sync(ir->input_dev);
- }
- } else {
- ir->delay_timer_finished = 0;
- input_event(ir->input_dev, EV_KEY, keycode, 1);
- input_sync(ir->input_dev);
- }
+ if (ir->keypressed &&
+ (ir->last_key != keycode || toggle != ir->last_toggle))
+ input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
+ input_event(ir->input_dev, EV_KEY, keycode, 1);
+ input_sync(ir->input_dev);
+
+ ir->keypressed = true;
ir->last_key = keycode;
ir->last_toggle = toggle;
- ir->keyup_timer.expires = jiffies + UP_TIMEOUT;
- add_timer(&ir->keyup_timer);
-
+ mod_timer(&ir->keyup_timer, jiffies + UP_TIMEOUT);
}
@@ -204,16 +194,6 @@ static void input_register_keys(struct infrared *ir)
ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
}
-
-/* called by the input driver after rep[REP_DELAY] ms */
-static void input_repeat_key(unsigned long parm)
-{
- struct infrared *ir = (struct infrared *) parm;
-
- ir->delay_timer_finished = 1;
-}
-
-
/* check for configuration changes */
int av7110_check_ir_config(struct av7110 *av7110, int force)
{
@@ -333,8 +313,7 @@ int av7110_ir_init(struct av7110 *av7110)
av_list[av_cnt++] = av7110;
av7110_check_ir_config(av7110, true);
- setup_timer(&av7110->ir.keyup_timer, av7110_emit_keyup,
- (unsigned long)&av7110->ir);
+ timer_setup(&av7110->ir.keyup_timer, av7110_emit_keyup, 0);
input_dev = input_allocate_device();
if (!input_dev)
@@ -365,8 +344,13 @@ int av7110_ir_init(struct av7110 *av7110)
input_free_device(input_dev);
return err;
}
- input_dev->timer.function = input_repeat_key;
- input_dev->timer.data = (unsigned long) &av7110->ir;
+
+ /*
+ * Input core's default autorepeat is 33 cps with 250 msec
+ * delay, let's adjust to numbers more suitable for remote
+ * control.
+ */
+ input_enable_softrepeat(input_dev, 250, 125);
if (av_cnt == 1) {
e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c
index 97499b2af714..b3dc45b91101 100644
--- a/drivers/media/pci/ttpci/budget-core.c
+++ b/drivers/media/pci/ttpci/budget-core.c
@@ -330,7 +330,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
return -EINVAL;
spin_lock(&budget->feedlock);
- feed->pusi_seen = 0; /* have a clean section start */
+ feed->pusi_seen = false; /* have a clean section start */
if (budget->feeding++ == 0)
status = start_ts_capture(budget);
spin_unlock(&budget->feedlock);
diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h
index d5ae4438153e..fae83866b199 100644
--- a/drivers/media/pci/ttpci/budget.h
+++ b/drivers/media/pci/ttpci/budget.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __BUDGET_DVB__
#define __BUDGET_DVB__
diff --git a/drivers/media/pci/ttpci/dvb_filter.c b/drivers/media/pci/ttpci/dvb_filter.c
index b67127b67d4e..8c2eca5dcdc9 100644
--- a/drivers/media/pci/ttpci/dvb_filter.c
+++ b/drivers/media/pci/ttpci/dvb_filter.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
diff --git a/drivers/media/pci/tw5864/tw5864-util.c b/drivers/media/pci/tw5864/tw5864-util.c
index 771eef235755..b9cebe9d1740 100644
--- a/drivers/media/pci/tw5864/tw5864-util.c
+++ b/drivers/media/pci/tw5864/tw5864-util.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include "tw5864.h"
void tw5864_indir_writeb(struct tw5864_dev *dev, u16 addr, u8 data)
diff --git a/drivers/media/pci/tw68/tw68-risc.c b/drivers/media/pci/tw68/tw68-risc.c
index 7439db212a69..82ff9c9494f3 100644
--- a/drivers/media/pci/tw68/tw68-risc.c
+++ b/drivers/media/pci/tw68/tw68-risc.c
@@ -29,14 +29,15 @@
#include "tw68.h"
/**
- * @rp pointer to current risc program position
- * @sglist pointer to "scatter-gather list" of buffer pointers
- * @offset offset to target memory buffer
- * @sync_line 0 -> no sync, 1 -> odd sync, 2 -> even sync
- * @bpl number of bytes per scan line
- * @padding number of bytes of padding to add
- * @lines number of lines in field
- * @jump insert a jump at the start
+ * tw68_risc_field
+ * @rp: pointer to current risc program position
+ * @sglist: pointer to "scatter-gather list" of buffer pointers
+ * @offset: offset to target memory buffer
+ * @sync_line: 0 -> no sync, 1 -> odd sync, 2 -> even sync
+ * @bpl: number of bytes per scan line
+ * @padding: number of bytes of padding to add
+ * @lines: number of lines in field
+ * @jump: insert a jump at the start
*/
static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
unsigned int offset, u32 sync_line,
@@ -120,18 +121,18 @@ static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
* memory for the dma controller "program" and then fills in that
* memory with the appropriate "instructions".
*
- * @pci_dev structure with info about the pci
+ * @pci: structure with info about the pci
* slot which our device is in.
- * @risc structure with info about the memory
+ * @buf: structure with info about the memory
* used for our controller program.
- * @sglist scatter-gather list entry
- * @top_offset offset within the risc program area for the
+ * @sglist: scatter-gather list entry
+ * @top_offset: offset within the risc program area for the
* first odd frame line
- * @bottom_offset offset within the risc program area for the
+ * @bottom_offset: offset within the risc program area for the
* first even frame line
- * @bpl number of data bytes per scan line
- * @padding number of extra bytes to add at end of line
- * @lines number of scan lines
+ * @bpl: number of data bytes per scan line
+ * @padding: number of extra bytes to add at end of line
+ * @lines: number of scan lines
*/
int tw68_risc_buffer(struct pci_dev *pci,
struct tw68_buf *buf,
diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c
index 336e2f9bc1b6..7fb3f07bf022 100644
--- a/drivers/media/pci/tw686x/tw686x-core.c
+++ b/drivers/media/pci/tw686x/tw686x-core.c
@@ -72,12 +72,12 @@ static const char *dma_mode_name(unsigned int mode)
}
}
-static int tw686x_dma_mode_get(char *buffer, struct kernel_param *kp)
+static int tw686x_dma_mode_get(char *buffer, const struct kernel_param *kp)
{
return sprintf(buffer, "%s", dma_mode_name(dma_mode));
}
-static int tw686x_dma_mode_set(const char *val, struct kernel_param *kp)
+static int tw686x_dma_mode_set(const char *val, const struct kernel_param *kp)
{
if (!strcasecmp(val, dma_mode_name(TW686X_DMA_MODE_MEMCPY)))
dma_mode = TW686X_DMA_MODE_MEMCPY;
@@ -126,9 +126,9 @@ void tw686x_enable_channel(struct tw686x_dev *dev, unsigned int channel)
* channels "too fast" which makes some TW686x devices very
* angry and freeze the CPU (see note 1).
*/
-static void tw686x_dma_delay(unsigned long data)
+static void tw686x_dma_delay(struct timer_list *t)
{
- struct tw686x_dev *dev = (struct tw686x_dev *)data;
+ struct tw686x_dev *dev = from_timer(dev, t, dma_delay_timer);
unsigned long flags;
spin_lock_irqsave(&dev->lock, flags);
@@ -325,8 +325,7 @@ static int tw686x_probe(struct pci_dev *pci_dev,
goto iounmap;
}
- setup_timer(&dev->dma_delay_timer,
- tw686x_dma_delay, (unsigned long) dev);
+ timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0);
/*
* This must be set right before initializing v4l2_dev.
diff --git a/drivers/media/pci/tw686x/tw686x-regs.h b/drivers/media/pci/tw686x/tw686x-regs.h
index 15a956642ef4..8adacc928be1 100644
--- a/drivers/media/pci/tw686x/tw686x-regs.h
+++ b/drivers/media/pci/tw686x/tw686x-regs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* DMA controller registers */
#define REG8_1(a0) ((const u16[8]) { a0, a0 + 1, a0 + 2, a0 + 3, \
a0 + 4, a0 + 5, a0 + 6, a0 + 7})
diff --git a/drivers/media/pci/zoran/Makefile b/drivers/media/pci/zoran/Makefile
index 44cc13352c88..21ac29a71458 100644
--- a/drivers/media/pci/zoran/Makefile
+++ b/drivers/media/pci/zoran/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
zr36067-objs := zoran_procfs.o zoran_device.o \
zoran_driver.o zoran_card.o
diff --git a/drivers/media/pci/zoran/zoran_card.h b/drivers/media/pci/zoran/zoran_card.h
index 81cba177cd90..0cdb7d34926d 100644
--- a/drivers/media/pci/zoran/zoran_card.h
+++ b/drivers/media/pci/zoran/zoran_card.h
@@ -37,7 +37,7 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */
#define BUZ_MAX 4
-extern struct video_device zoran_template;
+extern const struct video_device zoran_template;
extern int zoran_check_jpg_settings(struct zoran *zr,
struct zoran_jpg_settings *settings,
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index a11cb501c550..d07840072337 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -2839,7 +2839,7 @@ static const struct v4l2_file_operations zoran_fops = {
.poll = zoran_poll,
};
-struct video_device zoran_template = {
+const struct video_device zoran_template = {
.name = ZORAN_NAME,
.fops = &zoran_fops,
.ioctl_ops = &zoran_ioctl_ops,
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 3c4f7fa7b9d8..fd0c99859d6f 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -458,6 +458,21 @@ config VIDEO_RENESAS_VSP1
To compile this driver as a module, choose M here: the module
will be called vsp1.
+config VIDEO_ROCKCHIP_RGA
+ tristate "Rockchip Raster 2d Graphic Acceleration Unit"
+ depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
+ depends on ARCH_ROCKCHIP || COMPILE_TEST
+ select VIDEOBUF2_DMA_SG
+ select V4L2_MEM2MEM_DEV
+ default n
+ ---help---
+ This is a v4l2 driver for Rockchip SOC RGA 2d graphics accelerator.
+ Rockchip RGA is a separate 2D raster graphic acceleration unit.
+ It accelerates 2D graphics operations, such as point/line drawing,
+ image scaling, rotation, BitBLT, alpha blending and image blur/sharpness.
+
+ To compile this driver as a module choose m here.
+
config VIDEO_TI_VPE
tristate "TI VPE (Video Processing Engine) driver"
depends on VIDEO_DEV && VIDEO_V4L2
@@ -553,6 +568,16 @@ config VIDEO_MESON_AO_CEC
This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the
generic CEC framework interface.
CEC bus is present in the HDMI connector and enables communication
+
+config CEC_GPIO
+ tristate "Generic GPIO-based CEC driver"
+ depends on PREEMPT
+ select CEC_CORE
+ select CEC_PIN
+ select GPIOLIB
+ ---help---
+ This is a generic GPIO-based CEC driver.
+ The CEC bus is present in the HDMI connector and enables communication
between compatible devices.
config VIDEO_SAMSUNG_S5P_CEC
@@ -589,6 +614,17 @@ config VIDEO_STM32_HDMI_CEC
CEC bus is present in the HDMI connector and enables communication
between compatible devices.
+config VIDEO_TEGRA_HDMI_CEC
+ tristate "Tegra HDMI CEC driver"
+ depends on ARCH_TEGRA || COMPILE_TEST
+ select CEC_CORE
+ select CEC_NOTIFIER
+ ---help---
+ This is a driver for the Tegra HDMI CEC interface. It uses the
+ generic CEC framework interface.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
+
endif #CEC_PLATFORM_DRIVERS
menuconfig SDR_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index c1ef946bf032..003b0bb2cddf 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the video capture/playback device drivers.
#
@@ -26,6 +27,8 @@ obj-$(CONFIG_VIDEO_CODA) += coda/
obj-$(CONFIG_VIDEO_SH_VEU) += sh_veu.o
+obj-$(CONFIG_CEC_GPIO) += cec-gpio/
+
obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o
obj-$(CONFIG_VIDEO_MUX) += video-mux.o
@@ -46,6 +49,8 @@ obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/
obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/
+obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC) += tegra-cec/
+
obj-y += stm32/
obj-y += blackfin/
@@ -62,6 +67,8 @@ obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o
obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
+obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/
+
obj-y += omap/
obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index dfcc484cab89..0997c640191d 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -2417,6 +2417,11 @@ static int vpfe_async_complete(struct v4l2_async_notifier *notifier)
return vpfe_probe_complete(vpfe);
}
+static const struct v4l2_async_notifier_operations vpfe_async_ops = {
+ .bound = vpfe_async_bound,
+ .complete = vpfe_async_complete,
+};
+
static struct vpfe_config *
vpfe_get_pdata(struct platform_device *pdev)
{
@@ -2590,8 +2595,7 @@ static int vpfe_probe(struct platform_device *pdev)
vpfe->notifier.subdevs = vpfe->cfg->asd;
vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd);
- vpfe->notifier.bound = vpfe_async_bound;
- vpfe->notifier.complete = vpfe_async_complete;
+ vpfe->notifier.ops = &vpfe_async_ops;
ret = v4l2_async_notifier_register(&vpfe->v4l2_dev,
&vpfe->notifier);
if (ret) {
diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h
index 6936ac467609..2aadc19235ea 100644
--- a/drivers/media/platform/atmel/atmel-isc-regs.h
+++ b/drivers/media/platform/atmel/atmel-isc-regs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ATMEL_ISC_REGS_H
#define __ATMEL_ISC_REGS_H
@@ -42,6 +43,7 @@
/* ISC Clock Status Register */
#define ISC_CLKSR 0x00000020
+#define ISC_CLKSR_SIP BIT(31)
#define ISC_CLK(n) BIT(n)
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index d7103c5f92c3..13f1c1c797b0 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -65,6 +65,7 @@ struct isc_clk {
struct clk_hw hw;
struct clk *clk;
struct regmap *regmap;
+ spinlock_t lock;
u8 id;
u8 parent_id;
u32 div;
@@ -82,41 +83,69 @@ struct isc_subdev_entity {
struct v4l2_subdev *sd;
struct v4l2_async_subdev *asd;
struct v4l2_async_notifier notifier;
- struct v4l2_subdev_pad_config *config;
u32 pfe_cfg0;
struct list_head list;
};
+/* Indicate the format is generated by the sensor */
+#define FMT_FLAG_FROM_SENSOR BIT(0)
+/* Indicate the format is produced by ISC itself */
+#define FMT_FLAG_FROM_CONTROLLER BIT(1)
+/* Indicate a Raw Bayer format */
+#define FMT_FLAG_RAW_FORMAT BIT(2)
+
+#define FMT_FLAG_RAW_FROM_SENSOR (FMT_FLAG_FROM_SENSOR | \
+ FMT_FLAG_RAW_FORMAT)
+
/*
* struct isc_format - ISC media bus format information
* @fourcc: Fourcc code for this format
* @mbus_code: V4L2 media bus format code.
+ * flags: Indicate format from sensor or converted by controller
* @bpp: Bits per pixel (when stored in memory)
- * @reg_bps: reg value for bits per sample
* (when transferred over a bus)
- * @pipeline: pipeline switch
* @sd_support: Subdev supports this format
* @isc_support: ISC can convert raw format to this format
*/
+
struct isc_format {
u32 fourcc;
u32 mbus_code;
+ u32 flags;
u8 bpp;
- u32 reg_bps;
- u32 reg_bay_cfg;
- u32 reg_rlp_mode;
- u32 reg_dcfg_imode;
- u32 reg_dctrl_dview;
-
- u32 pipeline;
-
bool sd_support;
bool isc_support;
};
+/* Pipeline bitmap */
+#define WB_ENABLE BIT(0)
+#define CFA_ENABLE BIT(1)
+#define CC_ENABLE BIT(2)
+#define GAM_ENABLE BIT(3)
+#define GAM_BENABLE BIT(4)
+#define GAM_GENABLE BIT(5)
+#define GAM_RENABLE BIT(6)
+#define CSC_ENABLE BIT(7)
+#define CBC_ENABLE BIT(8)
+#define SUB422_ENABLE BIT(9)
+#define SUB420_ENABLE BIT(10)
+
+#define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE)
+
+struct fmt_config {
+ u32 fourcc;
+
+ u32 pfe_cfg0_bps;
+ u32 cfa_baycfg;
+ u32 rlp_cfg_mode;
+ u32 dcfg_imode;
+ u32 dctrl_dview;
+
+ u32 bits_pipeline;
+};
#define HIST_ENTRIES 512
#define HIST_BAYER (ISC_HIS_CFG_MODE_B + 1)
@@ -181,80 +210,320 @@ struct isc_device {
struct list_head subdev_entities;
};
-#define RAW_FMT_IND_START 0
-#define RAW_FMT_IND_END 11
-#define ISC_FMT_IND_START 12
-#define ISC_FMT_IND_END 14
-
-static struct isc_format isc_formats[] = {
- { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 8,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-
- { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10, 16,
- ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT10,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-
- { V4L2_PIX_FMT_SBGGR12, MEDIA_BUS_FMT_SBGGR12_1X12, 16,
- ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT12,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SGBRG12, MEDIA_BUS_FMT_SGBRG12_1X12, 16,
- ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT12,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SGRBG12, MEDIA_BUS_FMT_SGRBG12_1X12, 16,
- ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT12,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
- { V4L2_PIX_FMT_SRGGB12, MEDIA_BUS_FMT_SRGGB12_1X12, 16,
- ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT12,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
-
- { V4L2_PIX_FMT_YUV420, 0x0, 12,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_YYCC,
- ISC_DCFG_IMODE_YC420P, ISC_DCTRL_DVIEW_PLANAR, 0x7fb,
- false, false },
- { V4L2_PIX_FMT_YUV422P, 0x0, 16,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_YYCC,
- ISC_DCFG_IMODE_YC422P, ISC_DCTRL_DVIEW_PLANAR, 0x3fb,
- false, false },
- { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_RGB565_2X8_LE, 16,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_RGB565,
- ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x7b,
- false, false },
-
- { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_YUYV8_2X8, 16,
- ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8,
- ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
- false, false },
+static struct isc_format formats_list[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 8,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG8,
+ .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 8,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG8,
+ .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 8,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB8,
+ .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 8,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR10,
+ .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG10,
+ .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG10,
+ .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB10,
+ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR12,
+ .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG12,
+ .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG12,
+ .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB12,
+ .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+ .flags = FMT_FLAG_RAW_FROM_SENSOR,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .mbus_code = 0x0,
+ .flags = FMT_FLAG_FROM_CONTROLLER,
+ .bpp = 12,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .mbus_code = 0x0,
+ .flags = FMT_FLAG_FROM_CONTROLLER,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .mbus_code = MEDIA_BUS_FMT_Y8_1X8,
+ .flags = FMT_FLAG_FROM_CONTROLLER |
+ FMT_FLAG_FROM_SENSOR,
+ .bpp = 8,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB444,
+ .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE,
+ .flags = FMT_FLAG_FROM_CONTROLLER,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB555,
+ .mbus_code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+ .flags = FMT_FLAG_FROM_CONTROLLER,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE,
+ .flags = FMT_FLAG_FROM_CONTROLLER,
+ .bpp = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB32,
+ .mbus_code = MEDIA_BUS_FMT_ARGB8888_1X32,
+ .flags = FMT_FLAG_FROM_CONTROLLER,
+ .bpp = 32,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .flags = FMT_FLAG_FROM_CONTROLLER |
+ FMT_FLAG_FROM_SENSOR,
+ .bpp = 16,
+ },
+};
+
+struct fmt_config fmt_configs_list[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG8,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_GBGB,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG8,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_GRGR,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB8,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_RGRG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR10,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG10,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .cfa_baycfg = ISC_BAY_CFG_GBGB,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG10,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .cfa_baycfg = ISC_BAY_CFG_GRGR,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB10,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .cfa_baycfg = ISC_BAY_CFG_RGRG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SBGGR12,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGBRG12,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .cfa_baycfg = ISC_BAY_CFG_GBGB,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SGRBG12,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .cfa_baycfg = ISC_BAY_CFG_GRGR,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB12,
+ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .cfa_baycfg = ISC_BAY_CFG_RGRG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC,
+ .dcfg_imode = ISC_DCFG_IMODE_YC420P,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR,
+ .bits_pipeline = SUB420_ENABLE | SUB422_ENABLE |
+ CBC_ENABLE | CSC_ENABLE |
+ GAM_ENABLES |
+ CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC,
+ .dcfg_imode = ISC_DCFG_IMODE_YC422P,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR,
+ .bits_pipeline = SUB422_ENABLE |
+ CBC_ENABLE | CSC_ENABLE |
+ GAM_ENABLES |
+ CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = CBC_ENABLE | CSC_ENABLE |
+ GAM_ENABLES |
+ CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB444,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB555,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED16,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB32,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED32,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
+ .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8,
+ .dcfg_imode = ISC_DCFG_IMODE_PACKED8,
+ .dctrl_dview = ISC_DCTRL_DVIEW_PACKED,
+ .bits_pipeline = 0x0
+ },
};
#define GAMMA_MAX 2
@@ -307,31 +576,80 @@ module_param(sensor_preferred, uint, 0644);
MODULE_PARM_DESC(sensor_preferred,
"Sensor is preferred to output the specified format (1-on 0-off), default 1");
+static int isc_wait_clk_stable(struct clk_hw *hw)
+{
+ struct isc_clk *isc_clk = to_isc_clk(hw);
+ struct regmap *regmap = isc_clk->regmap;
+ unsigned long timeout = jiffies + usecs_to_jiffies(1000);
+ unsigned int status;
+
+ while (time_before(jiffies, timeout)) {
+ regmap_read(regmap, ISC_CLKSR, &status);
+ if (!(status & ISC_CLKSR_SIP))
+ return 0;
+
+ usleep_range(10, 250);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int isc_clk_prepare(struct clk_hw *hw)
+{
+ struct isc_clk *isc_clk = to_isc_clk(hw);
+
+ if (isc_clk->id == ISC_ISPCK)
+ pm_runtime_get_sync(isc_clk->dev);
+
+ return isc_wait_clk_stable(hw);
+}
+
+static void isc_clk_unprepare(struct clk_hw *hw)
+{
+ struct isc_clk *isc_clk = to_isc_clk(hw);
+
+ isc_wait_clk_stable(hw);
+
+ if (isc_clk->id == ISC_ISPCK)
+ pm_runtime_put_sync(isc_clk->dev);
+}
+
static int isc_clk_enable(struct clk_hw *hw)
{
struct isc_clk *isc_clk = to_isc_clk(hw);
u32 id = isc_clk->id;
struct regmap *regmap = isc_clk->regmap;
+ unsigned long flags;
+ unsigned int status;
dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n",
__func__, isc_clk->div, isc_clk->parent_id);
+ spin_lock_irqsave(&isc_clk->lock, flags);
regmap_update_bits(regmap, ISC_CLKCFG,
ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id),
(isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) |
(isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id)));
regmap_write(regmap, ISC_CLKEN, ISC_CLK(id));
+ spin_unlock_irqrestore(&isc_clk->lock, flags);
- return 0;
+ regmap_read(regmap, ISC_CLKSR, &status);
+ if (status & ISC_CLK(id))
+ return 0;
+ else
+ return -EINVAL;
}
static void isc_clk_disable(struct clk_hw *hw)
{
struct isc_clk *isc_clk = to_isc_clk(hw);
u32 id = isc_clk->id;
+ unsigned long flags;
+ spin_lock_irqsave(&isc_clk->lock, flags);
regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id));
+ spin_unlock_irqrestore(&isc_clk->lock, flags);
}
static int isc_clk_is_enabled(struct clk_hw *hw)
@@ -339,8 +657,14 @@ static int isc_clk_is_enabled(struct clk_hw *hw)
struct isc_clk *isc_clk = to_isc_clk(hw);
u32 status;
+ if (isc_clk->id == ISC_ISPCK)
+ pm_runtime_get_sync(isc_clk->dev);
+
regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
+ if (isc_clk->id == ISC_ISPCK)
+ pm_runtime_put_sync(isc_clk->dev);
+
return status & ISC_CLK(isc_clk->id) ? 1 : 0;
}
@@ -447,6 +771,8 @@ static int isc_clk_set_rate(struct clk_hw *hw,
}
static const struct clk_ops isc_clk_ops = {
+ .prepare = isc_clk_prepare,
+ .unprepare = isc_clk_unprepare,
.enable = isc_clk_enable,
.disable = isc_clk_disable,
.is_enabled = isc_clk_is_enabled,
@@ -492,6 +818,7 @@ static int isc_clk_register(struct isc_device *isc, unsigned int id)
isc_clk->regmap = regmap;
isc_clk->id = id;
isc_clk->dev = isc->dev;
+ spin_lock_init(&isc_clk->lock);
isc_clk->clk = clk_register(isc->dev, &isc_clk->hw);
if (IS_ERR(isc_clk->clk)) {
@@ -575,11 +902,27 @@ static inline bool sensor_is_preferred(const struct isc_format *isc_fmt)
!isc_fmt->isc_support;
}
+static struct fmt_config *get_fmt_config(u32 fourcc)
+{
+ struct fmt_config *config;
+ int i;
+
+ config = &fmt_configs_list[0];
+ for (i = 0; i < ARRAY_SIZE(fmt_configs_list); i++) {
+ if (config->fourcc == fourcc)
+ return config;
+
+ config++;
+ }
+ return NULL;
+}
+
static void isc_start_dma(struct isc_device *isc)
{
struct regmap *regmap = isc->regmap;
struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
u32 sizeimage = pixfmt->sizeimage;
+ struct fmt_config *config = get_fmt_config(isc->current_fmt->fourcc);
u32 dctrl_dview;
dma_addr_t addr0;
@@ -602,7 +945,7 @@ static void isc_start_dma(struct isc_device *isc)
if (sensor_is_preferred(isc->current_fmt))
dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
else
- dctrl_dview = isc->current_fmt->reg_dctrl_dview;
+ dctrl_dview = config->dctrl_dview;
regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS);
regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE);
@@ -612,6 +955,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
{
struct regmap *regmap = isc->regmap;
struct isc_ctrls *ctrls = &isc->ctrls;
+ struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
u32 val, bay_cfg;
const u32 *gamma;
unsigned int i;
@@ -625,7 +969,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
if (!pipeline)
return;
- bay_cfg = isc->raw_fmt->reg_bay_cfg;
+ bay_cfg = config->cfa_baycfg;
regmap_write(regmap, ISC_WB_CFG, bay_cfg);
regmap_write(regmap, ISC_WB_O_RGR, 0x0);
@@ -678,11 +1022,13 @@ static void isc_set_histogram(struct isc_device *isc)
{
struct regmap *regmap = isc->regmap;
struct isc_ctrls *ctrls = &isc->ctrls;
+ struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
if (ctrls->awb && (ctrls->hist_stat != HIST_ENABLED)) {
- regmap_write(regmap, ISC_HIS_CFG, ISC_HIS_CFG_MODE_R |
- (isc->raw_fmt->reg_bay_cfg << ISC_HIS_CFG_BAYSEL_SHIFT) |
- ISC_HIS_CFG_RAR);
+ regmap_write(regmap, ISC_HIS_CFG,
+ ISC_HIS_CFG_MODE_R |
+ (config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT) |
+ ISC_HIS_CFG_RAR);
regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN);
regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE);
ctrls->hist_id = ISC_HIS_CFG_MODE_R;
@@ -699,8 +1045,10 @@ static void isc_set_histogram(struct isc_device *isc)
}
static inline void isc_get_param(const struct isc_format *fmt,
- u32 *rlp_mode, u32 *dcfg)
+ u32 *rlp_mode, u32 *dcfg)
{
+ struct fmt_config *config = get_fmt_config(fmt->fourcc);
+
*dcfg = ISC_DCFG_YMBSIZE_BEATS8;
switch (fmt->fourcc) {
@@ -712,8 +1060,8 @@ static inline void isc_get_param(const struct isc_format *fmt,
case V4L2_PIX_FMT_SGBRG12:
case V4L2_PIX_FMT_SGRBG12:
case V4L2_PIX_FMT_SRGGB12:
- *rlp_mode = fmt->reg_rlp_mode;
- *dcfg |= fmt->reg_dcfg_imode;
+ *rlp_mode = config->rlp_cfg_mode;
+ *dcfg |= config->dcfg_imode;
break;
default:
*rlp_mode = ISC_RLP_CFG_MODE_DAT8;
@@ -726,20 +1074,22 @@ static int isc_configure(struct isc_device *isc)
{
struct regmap *regmap = isc->regmap;
const struct isc_format *current_fmt = isc->current_fmt;
+ struct fmt_config *curfmt_config = get_fmt_config(current_fmt->fourcc);
+ struct fmt_config *rawfmt_config = get_fmt_config(isc->raw_fmt->fourcc);
struct isc_subdev_entity *subdev = isc->current_subdev;
u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline;
if (sensor_is_preferred(current_fmt)) {
- pfe_cfg0 = current_fmt->reg_bps;
+ pfe_cfg0 = curfmt_config->pfe_cfg0_bps;
pipeline = 0x0;
isc_get_param(current_fmt, &rlp_mode, &dcfg);
isc->ctrls.hist_stat = HIST_INIT;
} else {
- pfe_cfg0 = isc->raw_fmt->reg_bps;
- pipeline = current_fmt->pipeline;
- rlp_mode = current_fmt->reg_rlp_mode;
- dcfg = current_fmt->reg_dcfg_imode | ISC_DCFG_YMBSIZE_BEATS8 |
- ISC_DCFG_CMBSIZE_BEATS8;
+ pfe_cfg0 = rawfmt_config->pfe_cfg0_bps;
+ pipeline = curfmt_config->bits_pipeline;
+ rlp_mode = curfmt_config->rlp_cfg_mode;
+ dcfg = curfmt_config->dcfg_imode |
+ ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8;
}
pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE;
@@ -941,6 +1291,7 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
{
struct isc_format *isc_fmt;
struct v4l2_pix_format *pixfmt = &f->fmt.pix;
+ struct v4l2_subdev_pad_config pad_cfg;
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_TRY,
};
@@ -971,7 +1322,7 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
- isc->current_subdev->config, &format);
+ &pad_cfg, &format);
if (ret < 0)
return ret;
@@ -1323,6 +1674,7 @@ static void isc_awb_work(struct work_struct *w)
struct isc_device *isc =
container_of(w, struct isc_device, awb_work);
struct regmap *regmap = isc->regmap;
+ struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
struct isc_ctrls *ctrls = &isc->ctrls;
u32 hist_id = ctrls->hist_id;
u32 baysel;
@@ -1340,7 +1692,7 @@ static void isc_awb_work(struct work_struct *w)
}
ctrls->hist_id = hist_id;
- baysel = isc->raw_fmt->reg_bay_cfg << ISC_HIS_CFG_BAYSEL_SHIFT;
+ baysel = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
pm_runtime_get_sync(isc->dev);
@@ -1436,17 +1788,15 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
struct isc_device, v4l2_dev);
cancel_work_sync(&isc->awb_work);
video_unregister_device(&isc->video_dev);
- if (isc->current_subdev->config)
- v4l2_subdev_free_pad_config(isc->current_subdev->config);
v4l2_ctrl_handler_free(&isc->ctrls.handler);
}
static struct isc_format *find_format_by_code(unsigned int code, int *index)
{
- struct isc_format *fmt = &isc_formats[0];
+ struct isc_format *fmt = &formats_list[0];
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(isc_formats); i++) {
+ for (i = 0; i < ARRAY_SIZE(formats_list); i++) {
if (fmt->mbus_code == code) {
*index = i;
return fmt;
@@ -1463,37 +1813,36 @@ static int isc_formats_init(struct isc_device *isc)
struct isc_format *fmt;
struct v4l2_subdev *subdev = isc->current_subdev->sd;
unsigned int num_fmts, i, j;
+ u32 list_size = ARRAY_SIZE(formats_list);
struct v4l2_subdev_mbus_code_enum mbus_code = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
- fmt = &isc_formats[0];
- for (i = 0; i < ARRAY_SIZE(isc_formats); i++) {
- fmt->isc_support = false;
- fmt->sd_support = false;
-
- fmt++;
- }
-
while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
NULL, &mbus_code)) {
mbus_code.index++;
+
fmt = find_format_by_code(mbus_code.code, &i);
- if (!fmt)
+ if ((!fmt) || (!(fmt->flags & FMT_FLAG_FROM_SENSOR)))
continue;
fmt->sd_support = true;
- if (i <= RAW_FMT_IND_END) {
- for (j = ISC_FMT_IND_START; j <= ISC_FMT_IND_END; j++)
- isc_formats[j].isc_support = true;
-
+ if (fmt->flags & FMT_FLAG_RAW_FORMAT)
isc->raw_fmt = fmt;
- }
}
- fmt = &isc_formats[0];
- for (i = 0, num_fmts = 0; i < ARRAY_SIZE(isc_formats); i++) {
+ fmt = &formats_list[0];
+ for (i = 0; i < list_size; i++) {
+ if (fmt->flags & FMT_FLAG_FROM_CONTROLLER)
+ fmt->isc_support = true;
+
+ fmt++;
+ }
+
+ fmt = &formats_list[0];
+ num_fmts = 0;
+ for (i = 0; i < list_size; i++) {
if (fmt->isc_support || fmt->sd_support)
num_fmts++;
@@ -1505,15 +1854,13 @@ static int isc_formats_init(struct isc_device *isc)
isc->num_user_formats = num_fmts;
isc->user_formats = devm_kcalloc(isc->dev,
- num_fmts, sizeof(struct isc_format *),
+ num_fmts, sizeof(*isc->user_formats),
GFP_KERNEL);
- if (!isc->user_formats) {
- v4l2_err(&isc->v4l2_dev, "could not allocate memory\n");
+ if (!isc->user_formats)
return -ENOMEM;
- }
- fmt = &isc_formats[0];
- for (i = 0, j = 0; i < ARRAY_SIZE(isc_formats); i++) {
+ fmt = &formats_list[0];
+ for (i = 0, j = 0; i < list_size; i++) {
if (fmt->isc_support || fmt->sd_support)
isc->user_formats[j++] = fmt;
@@ -1550,7 +1897,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
{
struct isc_device *isc = container_of(notifier->v4l2_dev,
struct isc_device, v4l2_dev);
- struct isc_subdev_entity *sd_entity;
struct video_device *vdev = &isc->video_dev;
struct vb2_queue *q = &isc->vb2_vidq;
int ret;
@@ -1563,8 +1909,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
isc->current_subdev = container_of(notifier,
struct isc_subdev_entity, notifier);
- sd_entity = isc->current_subdev;
-
mutex_init(&isc->lock);
init_completion(&isc->comp);
@@ -1591,10 +1935,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
INIT_LIST_HEAD(&isc->dma_queue);
spin_lock_init(&isc->dma_queue_lock);
- sd_entity->config = v4l2_subdev_alloc_pad_config(sd_entity->sd);
- if (sd_entity->config == NULL)
- return -ENOMEM;
-
ret = isc_formats_init(isc);
if (ret < 0) {
v4l2_err(&isc->v4l2_dev,
@@ -1639,6 +1979,12 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
return 0;
}
+static const struct v4l2_async_notifier_operations isc_async_ops = {
+ .bound = isc_async_bound,
+ .unbind = isc_async_unbind,
+ .complete = isc_async_complete,
+};
+
static void isc_subdev_cleanup(struct isc_device *isc)
{
struct isc_subdev_entity *subdev_entity;
@@ -1716,7 +2062,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
subdev_entity = devm_kzalloc(dev,
sizeof(*subdev_entity), GFP_KERNEL);
- if (subdev_entity == NULL) {
+ if (!subdev_entity) {
of_node_put(rem);
ret = -ENOMEM;
break;
@@ -1724,7 +2070,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
subdev_entity->asd = devm_kzalloc(dev,
sizeof(*subdev_entity->asd), GFP_KERNEL);
- if (subdev_entity->asd == NULL) {
+ if (!subdev_entity->asd) {
of_node_put(rem);
ret = -ENOMEM;
break;
@@ -1815,25 +2161,37 @@ static int atmel_isc_probe(struct platform_device *pdev)
return ret;
}
+ ret = clk_prepare_enable(isc->hclock);
+ if (ret) {
+ dev_err(dev, "failed to enable hclock: %d\n", ret);
+ return ret;
+ }
+
ret = isc_clk_init(isc);
if (ret) {
dev_err(dev, "failed to init isc clock: %d\n", ret);
- goto clean_isc_clk;
+ goto unprepare_hclk;
}
isc->ispck = isc->isc_clks[ISC_ISPCK].clk;
+ ret = clk_prepare_enable(isc->ispck);
+ if (ret) {
+ dev_err(dev, "failed to enable ispck: %d\n", ret);
+ goto unprepare_hclk;
+ }
+
/* ispck should be greater or equal to hclock */
ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock));
if (ret) {
dev_err(dev, "failed to set ispck rate: %d\n", ret);
- goto clean_isc_clk;
+ goto unprepare_clk;
}
ret = v4l2_device_register(dev, &isc->v4l2_dev);
if (ret) {
dev_err(dev, "unable to register v4l2 device.\n");
- goto clean_isc_clk;
+ goto unprepare_clk;
}
ret = isc_parse_dt(dev, isc);
@@ -1851,9 +2209,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
subdev_entity->notifier.subdevs = &subdev_entity->asd;
subdev_entity->notifier.num_subdevs = 1;
- subdev_entity->notifier.bound = isc_async_bound;
- subdev_entity->notifier.unbind = isc_async_unbind;
- subdev_entity->notifier.complete = isc_async_complete;
+ subdev_entity->notifier.ops = &isc_async_ops;
ret = v4l2_async_notifier_register(&isc->v4l2_dev,
&subdev_entity->notifier);
@@ -1866,7 +2222,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
break;
}
+ pm_runtime_set_active(dev);
pm_runtime_enable(dev);
+ pm_request_idle(dev);
return 0;
@@ -1876,7 +2234,11 @@ cleanup_subdev:
unregister_v4l2_device:
v4l2_device_unregister(&isc->v4l2_dev);
-clean_isc_clk:
+unprepare_clk:
+ clk_disable_unprepare(isc->ispck);
+unprepare_hclk:
+ clk_disable_unprepare(isc->hclock);
+
isc_clk_cleanup(isc);
return ret;
@@ -1887,6 +2249,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
struct isc_device *isc = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev);
+ clk_disable_unprepare(isc->ispck);
+ clk_disable_unprepare(isc->hclock);
isc_subdev_cleanup(isc);
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index 891fa2505efa..e900995143a3 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -411,7 +411,7 @@ static void buffer_queue(struct vb2_buffer *vb)
spin_lock_irqsave(&isi->irqlock, flags);
list_add_tail(&buf->list, &isi->video_buffer_list);
- if (isi->active == NULL) {
+ if (!isi->active) {
isi->active = buf;
if (vb2_is_streaming(vb->vb2_queue))
start_dma(isi, buf);
@@ -1038,10 +1038,8 @@ static int isi_formats_init(struct atmel_isi *isi)
isi->user_formats = devm_kcalloc(isi->dev,
num_fmts, sizeof(struct isi_format *),
GFP_KERNEL);
- if (!isi->user_formats) {
- dev_err(isi->dev, "could not allocate memory\n");
+ if (!isi->user_formats)
return -ENOMEM;
- }
memcpy(isi->user_formats, isi_fmts,
num_fmts * sizeof(struct isi_format *));
@@ -1105,6 +1103,12 @@ static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
return 0;
}
+static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
+ .bound = isi_graph_notify_bound,
+ .unbind = isi_graph_notify_unbind,
+ .complete = isi_graph_notify_complete,
+};
+
static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
{
struct device_node *ep = NULL;
@@ -1143,7 +1147,7 @@ static int isi_graph_init(struct atmel_isi *isi)
/* Register the subdevices notifier. */
subdevs = devm_kzalloc(isi->dev, sizeof(*subdevs), GFP_KERNEL);
- if (subdevs == NULL) {
+ if (!subdevs) {
of_node_put(isi->entity.node);
return -ENOMEM;
}
@@ -1152,9 +1156,7 @@ static int isi_graph_init(struct atmel_isi *isi)
isi->notifier.subdevs = subdevs;
isi->notifier.num_subdevs = 1;
- isi->notifier.bound = isi_graph_notify_bound;
- isi->notifier.unbind = isi_graph_notify_unbind;
- isi->notifier.complete = isi_graph_notify_complete;
+ isi->notifier.ops = &isi_graph_notify_ops;
ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
if (ret < 0) {
@@ -1176,10 +1178,8 @@ static int atmel_isi_probe(struct platform_device *pdev)
int ret, i;
isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
- if (!isi) {
- dev_err(&pdev->dev, "Can't allocate interface!\n");
+ if (!isi)
return -ENOMEM;
- }
isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
if (IS_ERR(isi->pclk))
@@ -1204,7 +1204,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
return ret;
isi->vdev = video_device_alloc();
- if (isi->vdev == NULL) {
+ if (!isi->vdev) {
ret = -ENOMEM;
goto err_vdev_alloc;
}
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 37169054b828..478eb2f7d723 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -338,7 +338,6 @@ struct ppi_if *ppi_create_instance(struct platform_device *pdev,
ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
if (!ppi) {
peripheral_free_list(info->pin_req);
- dev_err(&pdev->dev, "unable to allocate memory for ppi handle\n");
return NULL;
}
ppi->ops = &ppi_ops;
diff --git a/drivers/media/platform/cec-gpio/Makefile b/drivers/media/platform/cec-gpio/Makefile
new file mode 100644
index 000000000000..e82b258afa55
--- /dev/null
+++ b/drivers/media/platform/cec-gpio/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CEC_GPIO) += cec-gpio.o
diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c b/drivers/media/platform/cec-gpio/cec-gpio.c
new file mode 100644
index 000000000000..5debdf08fbe7
--- /dev/null
+++ b/drivers/media/platform/cec-gpio/cec-gpio.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
+#include <media/cec-pin.h>
+
+struct cec_gpio {
+ struct cec_adapter *adap;
+ struct device *dev;
+
+ struct gpio_desc *cec_gpio;
+ int cec_irq;
+ bool cec_is_low;
+ bool cec_have_irq;
+
+ struct gpio_desc *hpd_gpio;
+ int hpd_irq;
+ bool hpd_is_high;
+ ktime_t hpd_ts;
+};
+
+static bool cec_gpio_read(struct cec_adapter *adap)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ if (cec->cec_is_low)
+ return false;
+ return gpiod_get_value(cec->cec_gpio);
+}
+
+static void cec_gpio_high(struct cec_adapter *adap)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ if (!cec->cec_is_low)
+ return;
+ cec->cec_is_low = false;
+ gpiod_set_value(cec->cec_gpio, 1);
+}
+
+static void cec_gpio_low(struct cec_adapter *adap)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ if (cec->cec_is_low)
+ return;
+ if (WARN_ON_ONCE(cec->cec_have_irq))
+ free_irq(cec->cec_irq, cec);
+ cec->cec_have_irq = false;
+ cec->cec_is_low = true;
+ gpiod_set_value(cec->cec_gpio, 0);
+}
+
+static irqreturn_t cec_hpd_gpio_irq_handler_thread(int irq, void *priv)
+{
+ struct cec_gpio *cec = priv;
+
+ cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t cec_hpd_gpio_irq_handler(int irq, void *priv)
+{
+ struct cec_gpio *cec = priv;
+ bool is_high = gpiod_get_value(cec->hpd_gpio);
+
+ if (is_high == cec->hpd_is_high)
+ return IRQ_HANDLED;
+ cec->hpd_ts = ktime_get();
+ cec->hpd_is_high = is_high;
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t cec_gpio_irq_handler(int irq, void *priv)
+{
+ struct cec_gpio *cec = priv;
+
+ cec_pin_changed(cec->adap, gpiod_get_value(cec->cec_gpio));
+ return IRQ_HANDLED;
+}
+
+static bool cec_gpio_enable_irq(struct cec_adapter *adap)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ if (cec->cec_have_irq)
+ return true;
+
+ if (request_irq(cec->cec_irq, cec_gpio_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ adap->name, cec))
+ return false;
+ cec->cec_have_irq = true;
+ return true;
+}
+
+static void cec_gpio_disable_irq(struct cec_adapter *adap)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ if (cec->cec_have_irq)
+ free_irq(cec->cec_irq, cec);
+ cec->cec_have_irq = false;
+}
+
+static void cec_gpio_status(struct cec_adapter *adap, struct seq_file *file)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ seq_printf(file, "mode: %s\n", cec->cec_is_low ? "low-drive" : "read");
+ if (cec->cec_have_irq)
+ seq_printf(file, "using irq: %d\n", cec->cec_irq);
+ if (cec->hpd_gpio)
+ seq_printf(file, "hpd: %s\n",
+ cec->hpd_is_high ? "high" : "low");
+}
+
+static int cec_gpio_read_hpd(struct cec_adapter *adap)
+{
+ struct cec_gpio *cec = cec_get_drvdata(adap);
+
+ if (!cec->hpd_gpio)
+ return -ENOTTY;
+ return gpiod_get_value(cec->hpd_gpio);
+}
+
+static void cec_gpio_free(struct cec_adapter *adap)
+{
+ cec_gpio_disable_irq(adap);
+}
+
+static const struct cec_pin_ops cec_gpio_pin_ops = {
+ .read = cec_gpio_read,
+ .low = cec_gpio_low,
+ .high = cec_gpio_high,
+ .enable_irq = cec_gpio_enable_irq,
+ .disable_irq = cec_gpio_disable_irq,
+ .status = cec_gpio_status,
+ .free = cec_gpio_free,
+ .read_hpd = cec_gpio_read_hpd,
+};
+
+static int cec_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct cec_gpio *cec;
+ int ret;
+
+ cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
+ if (!cec)
+ return -ENOMEM;
+
+ cec->dev = dev;
+
+ cec->cec_gpio = devm_gpiod_get(dev, "cec", GPIOD_IN);
+ if (IS_ERR(cec->cec_gpio))
+ return PTR_ERR(cec->cec_gpio);
+ cec->cec_irq = gpiod_to_irq(cec->cec_gpio);
+
+ cec->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
+ if (IS_ERR(cec->hpd_gpio))
+ return PTR_ERR(cec->hpd_gpio);
+
+ cec->adap = cec_pin_allocate_adapter(&cec_gpio_pin_ops,
+ cec, pdev->name, CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR |
+ CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN);
+ if (IS_ERR(cec->adap))
+ return PTR_ERR(cec->adap);
+
+ if (cec->hpd_gpio) {
+ cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);
+ ret = devm_request_threaded_irq(dev, cec->hpd_irq,
+ cec_hpd_gpio_irq_handler,
+ cec_hpd_gpio_irq_handler_thread,
+ IRQF_ONESHOT |
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "hpd-gpio", cec);
+ if (ret)
+ return ret;
+ }
+
+ ret = cec_register_adapter(cec->adap, &pdev->dev);
+ if (ret) {
+ cec_delete_adapter(cec->adap);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, cec);
+ return 0;
+}
+
+static int cec_gpio_remove(struct platform_device *pdev)
+{
+ struct cec_gpio *cec = platform_get_drvdata(pdev);
+
+ cec_unregister_adapter(cec->adap);
+ return 0;
+}
+
+static const struct of_device_id cec_gpio_match[] = {
+ {
+ .compatible = "cec-gpio",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, cec_gpio_match);
+
+static struct platform_driver cec_gpio_pdrv = {
+ .probe = cec_gpio_probe,
+ .remove = cec_gpio_remove,
+ .driver = {
+ .name = "cec-gpio",
+ .of_match_table = cec_gpio_match,
+ },
+};
+
+module_platform_driver(cec_gpio_pdrv);
+
+MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CEC GPIO driver");
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index 291c40933935..bfc4ecf6f068 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -417,6 +417,10 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
dev->devtype->product != CODA_DX6)
size += ysize / 4;
name = kasprintf(GFP_KERNEL, "fb%d", i);
+ if (!name) {
+ coda_free_framebuffers(ctx);
+ return -ENOMEM;
+ }
ret = coda_alloc_context_buf(ctx, &ctx->internal_frames[i],
size, name);
kfree(name);
diff --git a/drivers/media/platform/coda/trace.h b/drivers/media/platform/coda/trace.h
index f20666a4aa89..ca671e315ad0 100644
--- a/drivers/media/platform/coda/trace.h
+++ b/drivers/media/platform/coda/trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM coda
diff --git a/drivers/media/platform/davinci/Makefile b/drivers/media/platform/davinci/Makefile
index d74d9eeb0e9e..05c45bf371aa 100644
--- a/drivers/media/platform/davinci/Makefile
+++ b/drivers/media/platform/davinci/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the davinci video device drivers.
#
diff --git a/drivers/media/platform/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h
index f1b521045d64..3482178cbf01 100644
--- a/drivers/media/platform/davinci/ccdc_hw_device.h
+++ b/drivers/media/platform/davinci/ccdc_hw_device.h
@@ -82,8 +82,8 @@ struct ccdc_hw_device {
};
/* Used by CCDC module to register & unregister with vpfe capture driver */
-int vpfe_register_ccdc_device(struct ccdc_hw_device *dev);
-void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev);
+int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev);
+void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev);
#endif
#endif
diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c
index 6d492dc4c3a9..89cb3094d7e6 100644
--- a/drivers/media/platform/davinci/dm355_ccdc.c
+++ b/drivers/media/platform/davinci/dm355_ccdc.c
@@ -841,7 +841,7 @@ static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
return 0;
}
-static struct ccdc_hw_device ccdc_hw_dev = {
+static const struct ccdc_hw_device ccdc_hw_dev = {
.name = "DM355 CCDC",
.owner = THIS_MODULE,
.hw_ops = {
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
index 3b2d8a9317b8..5fa0a1f32536 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc.c
+++ b/drivers/media/platform/davinci/dm644x_ccdc.c
@@ -776,7 +776,7 @@ static void ccdc_restore_context(void)
regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
}
-static struct ccdc_hw_device ccdc_hw_dev = {
+static const struct ccdc_hw_device ccdc_hw_dev = {
.name = "DM6446 CCDC",
.owner = THIS_MODULE,
.hw_ops = {
diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c
index 5813b49391ed..d5ff58494c1e 100644
--- a/drivers/media/platform/davinci/isif.c
+++ b/drivers/media/platform/davinci/isif.c
@@ -1000,7 +1000,7 @@ static int isif_close(struct device *device)
return 0;
}
-static struct ccdc_hw_device isif_hw_dev = {
+static const struct ccdc_hw_device isif_hw_dev = {
.name = "ISIF",
.owner = THIS_MODULE,
.hw_ops = {
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 13d027031ff0..6aabd21fe69f 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -122,7 +122,7 @@ static irqreturn_t venc_isr(int irq, void *arg)
int fid;
int i;
- if ((NULL == arg) || (NULL == disp_dev->dev[0]))
+ if (!arg || !disp_dev->dev[0])
return IRQ_HANDLED;
if (venc_is_second_field(disp_dev))
@@ -337,10 +337,10 @@ static void vpbe_stop_streaming(struct vb2_queue *vq)
vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
} else {
- if (layer->cur_frm != NULL)
+ if (layer->cur_frm)
vb2_buffer_done(&layer->cur_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
- if (layer->next_frm != NULL)
+ if (layer->next_frm)
vb2_buffer_done(&layer->next_frm->vb.vb2_buf,
VB2_BUF_STATE_ERROR);
}
@@ -947,7 +947,7 @@ static int vpbe_display_s_std(struct file *file, void *priv,
if (vb2_is_busy(&layer->buffer_queue))
return -EBUSY;
- if (NULL != vpbe_dev->ops.s_std) {
+ if (vpbe_dev->ops.s_std) {
ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
if (ret) {
v4l2_err(&vpbe_dev->v4l2_dev,
@@ -1000,8 +1000,7 @@ static int vpbe_display_enum_output(struct file *file, void *priv,
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
/* Enumerate outputs */
-
- if (NULL == vpbe_dev->ops.enum_outputs)
+ if (!vpbe_dev->ops.enum_outputs)
return -EINVAL;
ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
@@ -1030,7 +1029,7 @@ static int vpbe_display_s_output(struct file *file, void *priv,
if (vb2_is_busy(&layer->buffer_queue))
return -EBUSY;
- if (NULL == vpbe_dev->ops.set_output)
+ if (!vpbe_dev->ops.set_output)
return -EINVAL;
ret = vpbe_dev->ops.set_output(vpbe_dev, i);
@@ -1077,7 +1076,7 @@ vpbe_display_enum_dv_timings(struct file *file, void *priv,
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n");
/* Enumerate outputs */
- if (NULL == vpbe_dev->ops.enum_dv_timings)
+ if (!vpbe_dev->ops.enum_dv_timings)
return -EINVAL;
ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings);
@@ -1292,7 +1291,7 @@ static int vpbe_device_get(struct device *dev, void *data)
if (strcmp("vpbe_controller", pdev->name) == 0)
vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
- if (strstr(pdev->name, "vpbe-osd") != NULL)
+ if (strstr(pdev->name, "vpbe-osd"))
vpbe_disp->osd_device = platform_get_drvdata(pdev);
return 0;
@@ -1305,15 +1304,10 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
struct video_device *vbd = NULL;
/* Allocate memory for four plane display objects */
-
- disp_dev->dev[i] =
- kzalloc(sizeof(struct vpbe_layer), GFP_KERNEL);
-
- /* If memory allocation fails, return error */
- if (!disp_dev->dev[i]) {
- printk(KERN_ERR "ran out of memory\n");
+ disp_dev->dev[i] = kzalloc(sizeof(*disp_dev->dev[i]), GFP_KERNEL);
+ if (!disp_dev->dev[i])
return -ENOMEM;
- }
+
spin_lock_init(&disp_dev->dev[i]->irqlock);
mutex_init(&disp_dev->dev[i]->opslock);
@@ -1397,8 +1391,7 @@ static int vpbe_display_probe(struct platform_device *pdev)
printk(KERN_DEBUG "vpbe_display_probe\n");
/* Allocate memory for vpbe_display */
- disp_dev = devm_kzalloc(&pdev->dev, sizeof(struct vpbe_display),
- GFP_KERNEL);
+ disp_dev = devm_kzalloc(&pdev->dev, sizeof(*disp_dev), GFP_KERNEL);
if (!disp_dev)
return -ENOMEM;
@@ -1414,7 +1407,7 @@ static int vpbe_display_probe(struct platform_device *pdev)
v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
/* Initialize the vpbe display controller */
- if (NULL != disp_dev->vpbe_dev->ops.initialize) {
+ if (disp_dev->vpbe_dev->ops.initialize) {
err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
disp_dev->vpbe_dev);
if (err) {
@@ -1482,7 +1475,7 @@ static int vpbe_display_probe(struct platform_device *pdev)
probe_out:
for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
/* Unregister video device */
- if (disp_dev->dev[k] != NULL) {
+ if (disp_dev->dev[k]) {
video_unregister_device(&disp_dev->dev[k]->video_dev);
kfree(disp_dev->dev[k]);
}
@@ -1504,7 +1497,7 @@ static int vpbe_display_remove(struct platform_device *pdev)
v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
/* deinitialize the vpbe display controller */
- if (NULL != vpbe_dev->ops.deinitialize)
+ if (vpbe_dev->ops.deinitialize)
vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
/* un-register device */
for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 6792da16d9c7..7b3f6f8e3dc8 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -115,7 +115,7 @@ static struct vpfe_config_params config_params = {
};
/* ccdc device registered */
-static struct ccdc_hw_device *ccdc_dev;
+static const struct ccdc_hw_device *ccdc_dev;
/* lock for accessing ccdc information */
static DEFINE_MUTEX(ccdc_lock);
/* ccdc configuration */
@@ -203,7 +203,7 @@ static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
* vpfe_register_ccdc_device. CCDC module calls this to
* register with vpfe capture
*/
-int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
+int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev)
{
int ret = 0;
printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
@@ -259,7 +259,7 @@ EXPORT_SYMBOL(vpfe_register_ccdc_device);
* vpfe_unregister_ccdc_device. CCDC module calls this to
* unregister with vpfe capture
*/
-void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
+void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev)
{
if (!dev) {
printk(KERN_ERR "invalid ccdc device ptr\n");
diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c
index 07e89a4985a6..16352e2263d2 100644
--- a/drivers/media/platform/davinci/vpif.c
+++ b/drivers/media/platform/davinci/vpif.c
@@ -47,8 +47,9 @@ EXPORT_SYMBOL_GPL(vpif_lock);
void __iomem *vpif_base;
EXPORT_SYMBOL_GPL(vpif_base);
-/**
+/*
* vpif_ch_params: video standard configuration parameters for vpif
+ *
* The table must include all presets from supported subdevices.
*/
const struct vpif_channel_config_params vpif_ch_params[] = {
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 0ef36cec21d1..fca4dc829f73 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -109,7 +109,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
* @vq: vb2_queue ptr
* @nbuffers: ptr to number of buffers requested by application
* @nplanes:: contains number of distinct video planes needed to hold a frame
- * @sizes[]: contains the size (in bytes) of each plane.
+ * @sizes: contains the size (in bytes) of each plane.
* @alloc_devs: ptr to allocation context
*
* This callback function is called when reqbuf() is called to adjust
@@ -167,7 +167,7 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
/**
* vpif_start_streaming : Starts the DMA engine for streaming
- * @vb: ptr to vb2_buffer
+ * @vq: ptr to vb2_buffer
* @count: number of buffers
*/
static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
@@ -629,7 +629,7 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
/**
* vpif_get_default_field() - Get default field type based on interface
- * @vpif_params - ptr to vpif params
+ * @iface: ptr to vpif interface
*/
static inline enum v4l2_field vpif_get_default_field(
struct vpif_interface *iface)
@@ -640,8 +640,8 @@ static inline enum v4l2_field vpif_get_default_field(
/**
* vpif_config_addr() - function to configure buffer address in vpif
- * @ch - channel ptr
- * @muxmode - channel mux mode
+ * @ch: channel ptr
+ * @muxmode: channel mux mode
*/
static void vpif_config_addr(struct channel_obj *ch, int muxmode)
{
@@ -661,9 +661,9 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
/**
* vpif_input_to_subdev() - Maps input to sub device
- * @vpif_cfg - global config ptr
- * @chan_cfg - channel config ptr
- * @input_index - Given input index from application
+ * @vpif_cfg: global config ptr
+ * @chan_cfg: channel config ptr
+ * @input_index: Given input index from application
*
* lookup the sub device information for a given input index.
* we report all the inputs to application. inputs table also
@@ -699,9 +699,9 @@ static int vpif_input_to_subdev(
/**
* vpif_set_input() - Select an input
- * @vpif_cfg - global config ptr
- * @ch - channel
- * @_index - Given input index from application
+ * @vpif_cfg: global config ptr
+ * @ch: channel
+ * @index: Given input index from application
*
* Select the given input.
*/
@@ -792,7 +792,7 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
* vpif_g_std() - get STD handler
* @file: file ptr
* @priv: file handle
- * @std_id: ptr to std id
+ * @std: ptr to std id
*/
static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
{
@@ -933,7 +933,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
* vpif_enum_fmt_vid_cap() - ENUM_FMT handler
* @file: file ptr
* @priv: file handle
- * @index: input index
+ * @fmt: ptr to V4L2 format descriptor
*/
static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *fmt)
@@ -1500,6 +1500,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
return vpif_probe_complete();
}
+static const struct v4l2_async_notifier_operations vpif_async_ops = {
+ .bound = vpif_async_bound,
+ .complete = vpif_async_complete,
+};
+
static struct vpif_capture_config *
vpif_capture_get_pdata(struct platform_device *pdev)
{
@@ -1691,8 +1696,7 @@ static __init int vpif_probe(struct platform_device *pdev)
} else {
vpif_obj.notifier.subdevs = vpif_obj.config->asd;
vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
- vpif_obj.notifier.bound = vpif_async_bound;
- vpif_obj.notifier.complete = vpif_async_complete;
+ vpif_obj.notifier.ops = &vpif_async_ops;
err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
&vpif_obj.notifier);
if (err) {
@@ -1741,6 +1745,7 @@ static int vpif_remove(struct platform_device *device)
#ifdef CONFIG_PM_SLEEP
/**
* vpif_suspend: vpif device suspend
+ * @dev: pointer to &struct device
*/
static int vpif_suspend(struct device *dev)
{
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 56fe4e5b396e..7be636237acf 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -102,7 +102,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
* @vq: vb2_queue ptr
* @nbuffers: ptr to number of buffers requested by application
* @nplanes:: contains number of distinct video planes needed to hold a frame
- * @sizes[]: contains the size (in bytes) of each plane.
+ * @sizes: contains the size (in bytes) of each plane.
* @alloc_devs: ptr to allocation context
*
* This callback function is called when reqbuf() is called to adjust
@@ -158,7 +158,7 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
/**
* vpif_start_streaming : Starts the DMA engine for streaming
- * @vb: ptr to vb2_buffer
+ * @vq: ptr to vb2_buffer
* @count: number of buffers
*/
static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
@@ -766,9 +766,9 @@ static int vpif_enum_output(struct file *file, void *fh,
/**
* vpif_output_to_subdev() - Maps output to sub device
- * @vpif_cfg - global config ptr
- * @chan_cfg - channel config ptr
- * @index - Given output index from application
+ * @vpif_cfg: global config ptr
+ * @chan_cfg: channel config ptr
+ * @index: Given output index from application
*
* lookup the sub device information for a given output index.
* we report all the output to application. output table also
@@ -802,9 +802,9 @@ vpif_output_to_subdev(struct vpif_display_config *vpif_cfg,
/**
* vpif_set_output() - Select an output
- * @vpif_cfg - global config ptr
- * @ch - channel
- * @index - Given output index from application
+ * @vpif_cfg: global config ptr
+ * @ch: channel
+ * @index: Given output index from application
*
* Select the given output.
*/
@@ -1232,6 +1232,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
return vpif_probe_complete();
}
+static const struct v4l2_async_notifier_operations vpif_async_ops = {
+ .bound = vpif_async_bound,
+ .complete = vpif_async_complete,
+};
+
/*
* vpif_probe: This function creates device entries by register itself to the
* V4L2 driver and initializes fields of each channel objects
@@ -1313,8 +1318,7 @@ static __init int vpif_probe(struct platform_device *pdev)
} else {
vpif_obj.notifier.subdevs = vpif_obj.config->asd;
vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0];
- vpif_obj.notifier.bound = vpif_async_bound;
- vpif_obj.notifier.complete = vpif_async_complete;
+ vpif_obj.notifier.ops = &vpif_async_ops;
err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
&vpif_obj.notifier);
if (err) {
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index 43801509dabb..17854a379243 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -958,6 +958,51 @@ static struct gsc_pix_max gsc_v_100_max = {
.target_rot_en_h = 2016,
};
+static struct gsc_pix_max gsc_v_5250_max = {
+ .org_scaler_bypass_w = 8192,
+ .org_scaler_bypass_h = 8192,
+ .org_scaler_input_w = 4800,
+ .org_scaler_input_h = 3344,
+ .real_rot_dis_w = 4800,
+ .real_rot_dis_h = 3344,
+ .real_rot_en_w = 2016,
+ .real_rot_en_h = 2016,
+ .target_rot_dis_w = 4800,
+ .target_rot_dis_h = 3344,
+ .target_rot_en_w = 2016,
+ .target_rot_en_h = 2016,
+};
+
+static struct gsc_pix_max gsc_v_5420_max = {
+ .org_scaler_bypass_w = 8192,
+ .org_scaler_bypass_h = 8192,
+ .org_scaler_input_w = 4800,
+ .org_scaler_input_h = 3344,
+ .real_rot_dis_w = 4800,
+ .real_rot_dis_h = 3344,
+ .real_rot_en_w = 2048,
+ .real_rot_en_h = 2048,
+ .target_rot_dis_w = 4800,
+ .target_rot_dis_h = 3344,
+ .target_rot_en_w = 2016,
+ .target_rot_en_h = 2016,
+};
+
+static struct gsc_pix_max gsc_v_5433_max = {
+ .org_scaler_bypass_w = 8192,
+ .org_scaler_bypass_h = 8192,
+ .org_scaler_input_w = 4800,
+ .org_scaler_input_h = 3344,
+ .real_rot_dis_w = 4800,
+ .real_rot_dis_h = 3344,
+ .real_rot_en_w = 2047,
+ .real_rot_en_h = 2047,
+ .target_rot_dis_w = 4800,
+ .target_rot_dis_h = 3344,
+ .target_rot_en_w = 2016,
+ .target_rot_en_h = 2016,
+};
+
static struct gsc_pix_min gsc_v_100_min = {
.org_w = 64,
.org_h = 32,
@@ -992,6 +1037,45 @@ static struct gsc_variant gsc_v_100_variant = {
.local_sc_down = 2,
};
+static struct gsc_variant gsc_v_5250_variant = {
+ .pix_max = &gsc_v_5250_max,
+ .pix_min = &gsc_v_100_min,
+ .pix_align = &gsc_v_100_align,
+ .in_buf_cnt = 32,
+ .out_buf_cnt = 32,
+ .sc_up_max = 8,
+ .sc_down_max = 16,
+ .poly_sc_down_max = 4,
+ .pre_sc_down_max = 4,
+ .local_sc_down = 2,
+};
+
+static struct gsc_variant gsc_v_5420_variant = {
+ .pix_max = &gsc_v_5420_max,
+ .pix_min = &gsc_v_100_min,
+ .pix_align = &gsc_v_100_align,
+ .in_buf_cnt = 32,
+ .out_buf_cnt = 32,
+ .sc_up_max = 8,
+ .sc_down_max = 16,
+ .poly_sc_down_max = 4,
+ .pre_sc_down_max = 4,
+ .local_sc_down = 2,
+};
+
+static struct gsc_variant gsc_v_5433_variant = {
+ .pix_max = &gsc_v_5433_max,
+ .pix_min = &gsc_v_100_min,
+ .pix_align = &gsc_v_100_align,
+ .in_buf_cnt = 32,
+ .out_buf_cnt = 32,
+ .sc_up_max = 8,
+ .sc_down_max = 16,
+ .poly_sc_down_max = 4,
+ .pre_sc_down_max = 4,
+ .local_sc_down = 2,
+};
+
static struct gsc_driverdata gsc_v_100_drvdata = {
.variant = {
[0] = &gsc_v_100_variant,
@@ -1004,11 +1088,33 @@ static struct gsc_driverdata gsc_v_100_drvdata = {
.num_clocks = 1,
};
+static struct gsc_driverdata gsc_v_5250_drvdata = {
+ .variant = {
+ [0] = &gsc_v_5250_variant,
+ [1] = &gsc_v_5250_variant,
+ [2] = &gsc_v_5250_variant,
+ [3] = &gsc_v_5250_variant,
+ },
+ .num_entities = 4,
+ .clk_names = { "gscl" },
+ .num_clocks = 1,
+};
+
+static struct gsc_driverdata gsc_v_5420_drvdata = {
+ .variant = {
+ [0] = &gsc_v_5420_variant,
+ [1] = &gsc_v_5420_variant,
+ },
+ .num_entities = 2,
+ .clk_names = { "gscl" },
+ .num_clocks = 1,
+};
+
static struct gsc_driverdata gsc_5433_drvdata = {
.variant = {
- [0] = &gsc_v_100_variant,
- [1] = &gsc_v_100_variant,
- [2] = &gsc_v_100_variant,
+ [0] = &gsc_v_5433_variant,
+ [1] = &gsc_v_5433_variant,
+ [2] = &gsc_v_5433_variant,
},
.num_entities = 3,
.clk_names = { "pclk", "aclk", "aclk_xiu", "aclk_gsclbend" },
@@ -1017,13 +1123,21 @@ static struct gsc_driverdata gsc_5433_drvdata = {
static const struct of_device_id exynos_gsc_match[] = {
{
- .compatible = "samsung,exynos5-gsc",
- .data = &gsc_v_100_drvdata,
+ .compatible = "samsung,exynos5250-gsc",
+ .data = &gsc_v_5250_drvdata,
+ },
+ {
+ .compatible = "samsung,exynos5420-gsc",
+ .data = &gsc_v_5420_drvdata,
},
{
.compatible = "samsung,exynos5433-gsc",
.data = &gsc_5433_drvdata,
},
+ {
+ .compatible = "samsung,exynos5-gsc",
+ .data = &gsc_v_100_drvdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, exynos_gsc_match);
@@ -1045,6 +1159,9 @@ static int gsc_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ if (drv_data == &gsc_v_100_drvdata)
+ dev_info(dev, "compatible 'exynos5-gsc' is deprecated\n");
+
gsc->id = ret;
if (gsc->id >= drv_data->num_entities) {
dev_err(dev, "Invalid platform device id: %d\n", gsc->id);
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index c480efb755f5..46a7d242a1a5 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -76,7 +76,7 @@ config VIDEO_EXYNOS4_ISP_DMA_CAPTURE
depends on VIDEO_EXYNOS4_FIMC_IS
select VIDEO_EXYNOS4_IS_COMMON
default y
- help
+ help
This option enables an additional video device node exposing a V4L2
video capture interface for the FIMC-IS ISP raw (Bayer) capture DMA.
diff --git a/drivers/media/platform/exynos4-is/Makefile b/drivers/media/platform/exynos4-is/Makefile
index eed1b185d813..a5ab01c73b95 100644
--- a/drivers/media/platform/exynos4-is/Makefile
+++ b/drivers/media/platform/exynos4-is/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o media-dev.o
exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
s5p-csis-objs := mipi-csis.o
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 948fe01f6c96..ed9302caa004 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -146,6 +146,7 @@ static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
/**
* fimc_capture_config_update - apply the camera interface configuration
+ * @ctx: FIMC capture context
*
* To be called from within the interrupt handler with fimc.slock
* spinlock held. It updates the camera pixel crop, rotation and
@@ -858,6 +859,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
* fimc_get_sensor_frame_desc - query the sensor for media bus frame parameters
* @sensor: pointer to the sensor subdev
* @plane_fmt: provides plane sizes corresponding to the frame layout entries
+ * @num_planes: number of planes
* @try: true to set the frame parameters, false to query only
*
* This function is used by this driver only for compressed/blob data formats.
@@ -1101,6 +1103,7 @@ static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
/**
* fimc_pipeline_validate - check for formats inconsistencies
* between source and sink pad of each link
+ * @fimc: the FIMC device this context applies to
*
* Return 0 if all formats match or -EPIPE otherwise.
*/
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index d4656d5175d7..0ef583cfc424 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -60,6 +60,7 @@ static void __setup_sensor_notification(struct fimc_md *fmd,
/**
* fimc_pipeline_prepare - update pipeline information with subdevice pointers
+ * @p: fimc pipeline
* @me: media entity terminating the pipeline
*
* Caller holds the graph mutex.
@@ -151,8 +152,8 @@ static int __subdev_set_power(struct v4l2_subdev *sd, int on)
/**
* fimc_pipeline_s_power - change power state of all pipeline subdevs
- * @fimc: fimc device terminating the pipeline
- * @state: true to power on, false to power off
+ * @p: fimc device terminating the pipeline
+ * @on: true to power on, false to power off
*
* Needs to be called with the graph mutex held.
*/
@@ -219,6 +220,7 @@ static int __fimc_pipeline_enable(struct exynos_media_pipeline *ep,
/**
* __fimc_pipeline_open - update the pipeline information, enable power
* of all pipeline subdevs and the sensor clock
+ * @ep: fimc device terminating the pipeline
* @me: media entity to start graph walk with
* @prepare: true to walk the current pipeline and acquire all subdevs
*
@@ -252,7 +254,7 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
/**
* __fimc_pipeline_close - disable the sensor clock and pipeline power
- * @fimc: fimc device terminating the pipeline
+ * @ep: fimc device terminating the pipeline
*
* Disable power of all subdevs and turn the external sensor clock off.
*/
@@ -281,7 +283,7 @@ static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
/**
* __fimc_pipeline_s_stream - call s_stream() on pipeline subdevs
- * @pipeline: video pipeline structure
+ * @ep: video pipeline structure
* @on: passed as the s_stream() callback argument
*/
static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
@@ -902,6 +904,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
/**
* fimc_md_create_links - create default links between registered entities
+ * @fmd: fimc media device
*
* Parallel interface sensor entities are connected directly to FIMC capture
* entities. The sensors using MIPI CSIS bus are connected through immutable
@@ -1405,6 +1408,11 @@ unlock:
return media_device_register(&fmd->media_dev);
}
+static const struct v4l2_async_notifier_operations subdev_notifier_ops = {
+ .bound = subdev_notifier_bound,
+ .complete = subdev_notifier_complete,
+};
+
static int fimc_md_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1479,8 +1487,7 @@ static int fimc_md_probe(struct platform_device *pdev)
if (fmd->num_sensors > 0) {
fmd->subdev_notifier.subdevs = fmd->async_subdevs;
fmd->subdev_notifier.num_subdevs = fmd->num_sensors;
- fmd->subdev_notifier.bound = subdev_notifier_bound;
- fmd->subdev_notifier.complete = subdev_notifier_complete;
+ fmd->subdev_notifier.ops = &subdev_notifier_ops;
fmd->num_sensors = 0;
ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 560aadabcb11..cba46a656338 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -189,7 +189,7 @@ struct csis_drvdata {
* @irq: requested s5p-mipi-csis irq number
* @interrupt_mask: interrupt mask of the all used interrupts
* @flags: the state variable for power and streaming control
- * @clock_frequency: device bus clock frequency
+ * @clk_frequency: device bus clock frequency
* @hs_settle: HS-RX settle time
* @num_lanes: number of MIPI-CSI data lanes used
* @max_num_lanes: maximum number of MIPI-CSI data lanes supported
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index fb43025df573..dba21215dc84 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -339,9 +339,9 @@ static int restart_video_queue(struct viu_dmaqueue *vidq)
}
}
-static void viu_vid_timeout(unsigned long data)
+static void viu_vid_timeout(struct timer_list *t)
{
- struct viu_dev *dev = (struct viu_dev *)data;
+ struct viu_dev *dev = from_timer(dev, t, vidq.timeout);
struct viu_buf *buf;
struct viu_dmaqueue *vidq = &dev->vidq;
@@ -1466,8 +1466,7 @@ static int viu_of_probe(struct platform_device *op)
viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
"saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
- setup_timer(&viu_dev->vidq.timeout, viu_vid_timeout,
- (unsigned long)viu_dev);
+ timer_setup(&viu_dev->vidq.timeout, viu_vid_timeout, 0);
viu_dev->std = V4L2_STD_NTSC_M;
viu_dev->first = 1;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index b07a251e8857..7b7250b1cff8 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* The Marvell camera core. This device appears in a number of settings,
* so it needs platform-specific support outside of the core.
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h
index beb339f5561f..ad8955f9f0a1 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.h
+++ b/drivers/media/platform/marvell-ccic/mcam-core.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Marvell camera core structures.
*
diff --git a/drivers/media/platform/mtk-mdp/Makefile b/drivers/media/platform/mtk-mdp/Makefile
index f8025699af99..5982d65c9971 100644
--- a/drivers/media/platform/mtk-mdp/Makefile
+++ b/drivers/media/platform/mtk-mdp/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
mtk-mdp-y += mtk_mdp_core.o
mtk-mdp-y += mtk_mdp_comp.o
mtk-mdp-y += mtk_mdp_m2m.o
diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 852d9697ccfa..37b94b555fa1 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
mtk-vcodec-enc.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index b7731b18ecae..aa3ce41898bc 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -59,6 +59,7 @@ struct h264_fb {
* @read_idx : read index
* @write_idx : write index
* @count : buffer count in list
+ * @reserved : for 8 bytes alignment
*/
struct h264_ring_fb_list {
struct h264_fb fb_list[H264_MAX_FB_NUM];
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
index b9fad6a48879..3e84a761db3a 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
@@ -155,7 +155,6 @@ struct vdec_vp8_vpu_inst {
* @reg_base : HW register base address
* @frm_cnt : decode frame count
* @ctx : V4L2 context
- * @dev : platform device
* @vpu : VPU instance for decoder
* @vsi : VPU share information
*/
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index 4eb3be37ba14..6cf31b366aad 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -34,7 +34,7 @@ static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc};
#define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker)
#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
-/**
+/*
* enum venc_h264_vpu_work_buf - h264 encoder buffer index
*/
enum venc_h264_vpu_work_buf {
@@ -50,7 +50,7 @@ enum venc_h264_vpu_work_buf {
VENC_H264_VPU_WORK_BUF_MAX,
};
-/**
+/*
* enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode
*/
enum venc_h264_bs_mode {
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index acb639c4abd2..957420dd60de 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -34,7 +34,7 @@
/* This ac_tag is vp8 frame tag. */
#define MAX_AC_TAG_SIZE 10
-/**
+/*
* enum venc_vp8_vpu_work_buf - vp8 encoder buffer index
*/
enum venc_vp8_vpu_work_buf {
diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
index 853d598937f6..1ff6a93262b7 100644
--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
+++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
@@ -181,6 +181,7 @@ struct share_obj {
* @extmem: VPU extended memory information
* @reg: VPU TCM and configuration registers
* @run: VPU initialization status
+ * @wdt: VPU watchdog workqueue
* @ipi_desc: VPU IPI descriptor
* @recv_buf: VPU DTCM share buffer for receiving. The
* receive buffer is only accessed in interrupt context.
@@ -194,7 +195,7 @@ struct share_obj {
* suppose a client is using VPU to decode VP8.
* If the other client wants to encode VP8,
* it has to wait until VP8 decode completes.
- * @wdt_refcnt WDT reference count to make sure the watchdog can be
+ * @wdt_refcnt: WDT reference count to make sure the watchdog can be
* disabled if no other client is using VPU service
* @ack_wq: The wait queue for each codec and mdp. When sleeping
* processes wake up, they will check the condition
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 4d29860d27b4..6f1b0c799e58 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -1004,11 +1004,12 @@ static int omap_vout_open(struct file *file)
struct omap_vout_device *vout = NULL;
vout = video_drvdata(file);
- v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
if (vout == NULL)
return -ENODEV;
+ v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
+
/* for now, we only support single open */
if (vout->opened)
return -EBUSY;
diff --git a/drivers/media/platform/omap3isp/Makefile b/drivers/media/platform/omap3isp/Makefile
index 254975a9174e..56e99b4f7d23 100644
--- a/drivers/media/platform/omap3isp/Makefile
+++ b/drivers/media/platform/omap3isp/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Makefile for OMAP3 ISP driver
ccflags-$(CONFIG_VIDEO_OMAP3_DEBUG) += -DDEBUG
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1a428fe9f070..b7ff3842afc0 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1669,8 +1669,8 @@ static int isp_link_entity(
break;
}
if (i == entity->num_pads) {
- dev_err(isp->dev, "%s: no source pad in external entity\n",
- __func__);
+ dev_err(isp->dev, "%s: no source pad in external entity %s\n",
+ __func__, entity->name);
return -EINVAL;
}
@@ -2001,6 +2001,7 @@ static int isp_remove(struct platform_device *pdev)
__omap3isp_put(isp, false);
media_entity_enum_cleanup(&isp->crashed);
+ v4l2_async_notifier_cleanup(&isp->notifier);
return 0;
}
@@ -2011,44 +2012,41 @@ enum isp_of_phy {
ISP_OF_PHY_CSIPHY2,
};
-static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode,
- struct isp_async_subdev *isd)
+static int isp_fwnode_parse(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd)
{
+ struct isp_async_subdev *isd =
+ container_of(asd, struct isp_async_subdev, asd);
struct isp_bus_cfg *buscfg = &isd->bus;
- struct v4l2_fwnode_endpoint vep;
- unsigned int i;
- int ret;
bool csi1 = false;
-
- ret = v4l2_fwnode_endpoint_parse(fwnode, &vep);
- if (ret)
- return ret;
+ unsigned int i;
dev_dbg(dev, "parsing endpoint %pOF, interface %u\n",
- to_of_node(fwnode), vep.base.port);
+ to_of_node(vep->base.local_fwnode), vep->base.port);
- switch (vep.base.port) {
+ switch (vep->base.port) {
case ISP_OF_PHY_PARALLEL:
buscfg->interface = ISP_INTERFACE_PARALLEL;
buscfg->bus.parallel.data_lane_shift =
- vep.bus.parallel.data_shift;
+ vep->bus.parallel.data_shift;
buscfg->bus.parallel.clk_pol =
- !!(vep.bus.parallel.flags
+ !!(vep->bus.parallel.flags
& V4L2_MBUS_PCLK_SAMPLE_FALLING);
buscfg->bus.parallel.hs_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+ !!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
buscfg->bus.parallel.vs_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+ !!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
buscfg->bus.parallel.fld_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+ !!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
buscfg->bus.parallel.data_pol =
- !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
- buscfg->bus.parallel.bt656 = vep.bus_type == V4L2_MBUS_BT656;
+ !!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+ buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656;
break;
case ISP_OF_PHY_CSIPHY1:
case ISP_OF_PHY_CSIPHY2:
- switch (vep.bus_type) {
+ switch (vep->bus_type) {
case V4L2_MBUS_CCP2:
case V4L2_MBUS_CSI1:
dev_dbg(dev, "CSI-1/CCP-2 configuration\n");
@@ -2060,11 +2058,11 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode,
break;
default:
dev_err(dev, "unsupported bus type %u\n",
- vep.bus_type);
+ vep->bus_type);
return -EINVAL;
}
- switch (vep.base.port) {
+ switch (vep->base.port) {
case ISP_OF_PHY_CSIPHY1:
if (csi1)
buscfg->interface = ISP_INTERFACE_CCP2B_PHY1;
@@ -2080,47 +2078,47 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode,
}
if (csi1) {
buscfg->bus.ccp2.lanecfg.clk.pos =
- vep.bus.mipi_csi1.clock_lane;
+ vep->bus.mipi_csi1.clock_lane;
buscfg->bus.ccp2.lanecfg.clk.pol =
- vep.bus.mipi_csi1.lane_polarity[0];
+ vep->bus.mipi_csi1.lane_polarity[0];
dev_dbg(dev, "clock lane polarity %u, pos %u\n",
buscfg->bus.ccp2.lanecfg.clk.pol,
buscfg->bus.ccp2.lanecfg.clk.pos);
buscfg->bus.ccp2.lanecfg.data[0].pos =
- vep.bus.mipi_csi1.data_lane;
+ vep->bus.mipi_csi1.data_lane;
buscfg->bus.ccp2.lanecfg.data[0].pol =
- vep.bus.mipi_csi1.lane_polarity[1];
+ vep->bus.mipi_csi1.lane_polarity[1];
dev_dbg(dev, "data lane polarity %u, pos %u\n",
buscfg->bus.ccp2.lanecfg.data[0].pol,
buscfg->bus.ccp2.lanecfg.data[0].pos);
buscfg->bus.ccp2.strobe_clk_pol =
- vep.bus.mipi_csi1.clock_inv;
- buscfg->bus.ccp2.phy_layer = vep.bus.mipi_csi1.strobe;
+ vep->bus.mipi_csi1.clock_inv;
+ buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe;
buscfg->bus.ccp2.ccp2_mode =
- vep.bus_type == V4L2_MBUS_CCP2;
+ vep->bus_type == V4L2_MBUS_CCP2;
buscfg->bus.ccp2.vp_clk_pol = 1;
buscfg->bus.ccp2.crc = 1;
} else {
buscfg->bus.csi2.lanecfg.clk.pos =
- vep.bus.mipi_csi2.clock_lane;
+ vep->bus.mipi_csi2.clock_lane;
buscfg->bus.csi2.lanecfg.clk.pol =
- vep.bus.mipi_csi2.lane_polarities[0];
+ vep->bus.mipi_csi2.lane_polarities[0];
dev_dbg(dev, "clock lane polarity %u, pos %u\n",
buscfg->bus.csi2.lanecfg.clk.pol,
buscfg->bus.csi2.lanecfg.clk.pos);
buscfg->bus.csi2.num_data_lanes =
- vep.bus.mipi_csi2.num_data_lanes;
+ vep->bus.mipi_csi2.num_data_lanes;
for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) {
buscfg->bus.csi2.lanecfg.data[i].pos =
- vep.bus.mipi_csi2.data_lanes[i];
+ vep->bus.mipi_csi2.data_lanes[i];
buscfg->bus.csi2.lanecfg.data[i].pol =
- vep.bus.mipi_csi2.lane_polarities[i + 1];
+ vep->bus.mipi_csi2.lane_polarities[i + 1];
dev_dbg(dev,
"data lane %u polarity %u, pos %u\n", i,
buscfg->bus.csi2.lanecfg.data[i].pol,
@@ -2137,57 +2135,13 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode,
default:
dev_warn(dev, "%pOF: invalid interface %u\n",
- to_of_node(fwnode), vep.base.port);
+ to_of_node(vep->base.local_fwnode), vep->base.port);
return -EINVAL;
}
return 0;
}
-static int isp_fwnodes_parse(struct device *dev,
- struct v4l2_async_notifier *notifier)
-{
- struct fwnode_handle *fwnode = NULL;
-
- notifier->subdevs = devm_kcalloc(
- dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
- if (!notifier->subdevs)
- return -ENOMEM;
-
- while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
- (fwnode = fwnode_graph_get_next_endpoint(
- of_fwnode_handle(dev->of_node), fwnode))) {
- struct isp_async_subdev *isd;
-
- isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
- if (!isd)
- goto error;
-
- if (isp_fwnode_parse(dev, fwnode, isd)) {
- devm_kfree(dev, isd);
- continue;
- }
-
- notifier->subdevs[notifier->num_subdevs] = &isd->asd;
-
- isd->asd.match.fwnode.fwnode =
- fwnode_graph_get_remote_port_parent(fwnode);
- if (!isd->asd.match.fwnode.fwnode) {
- dev_warn(dev, "bad remote port parent\n");
- goto error;
- }
-
- isd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- notifier->num_subdevs++;
- }
-
- return notifier->num_subdevs;
-
-error:
- fwnode_handle_put(fwnode);
- return -EINVAL;
-}
-
static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
{
struct isp_device *isp = container_of(async, struct isp_device,
@@ -2201,7 +2155,7 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
return ret;
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
- if (!sd->asd)
+ if (sd->notifier != &isp->notifier)
continue;
ret = isp_link_entity(isp, &sd->entity,
@@ -2217,6 +2171,10 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
return media_device_register(&isp->media_dev);
}
+static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = {
+ .complete = isp_subdev_notifier_complete,
+};
+
/*
* isp_probe - Probe ISP platform device
* @pdev: Pointer to ISP platform device
@@ -2256,15 +2214,17 @@ static int isp_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = isp_fwnodes_parse(&pdev->dev, &isp->notifier);
- if (ret < 0)
- return ret;
-
isp->autoidle = autoidle;
mutex_init(&isp->isp_mutex);
spin_lock_init(&isp->stat_lock);
+ ret = v4l2_async_notifier_parse_fwnode_endpoints(
+ &pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev),
+ isp_fwnode_parse);
+ if (ret < 0)
+ goto error;
+
isp->dev = &pdev->dev;
isp->ref_count = 0;
@@ -2385,7 +2345,7 @@ static int isp_probe(struct platform_device *pdev)
if (ret < 0)
goto error_register_entities;
- isp->notifier.complete = isp_subdev_notifier_complete;
+ isp->notifier.ops = &isp_subdev_notifier_ops;
ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier);
if (ret)
@@ -2406,6 +2366,7 @@ error_isp:
isp_xclk_cleanup(isp);
__omap3isp_put(isp, false);
error:
+ v4l2_async_notifier_cleanup(&isp->notifier);
mutex_destroy(&isp->isp_mutex);
return ret;
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index e528df6efc09..8b9043db94b3 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -220,14 +220,11 @@ struct isp_device {
unsigned int sbl_resources;
unsigned int subclk_resources;
-
-#define ISP_MAX_SUBDEVS 8
- struct v4l2_subdev *subdevs[ISP_MAX_SUBDEVS];
};
struct isp_async_subdev {
- struct isp_bus_cfg bus;
struct v4l2_async_subdev asd;
+ struct isp_bus_cfg bus;
};
#define v4l2_subdev_to_bus_cfg(sd) \
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index edca993c2b1f..295f34ad1080 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -235,6 +235,7 @@ enum pxa_mbus_layout {
* stored in memory in the following way:
* @packing: Type of sample-packing, that has to be used
* @order: Sample order when storing in memory
+ * @layout: Planes layout in memory
* @bits_per_sample: How many bits the bridge has to sample
*/
struct pxa_mbus_pixelfmt {
@@ -852,10 +853,10 @@ static void pxa_camera_dma_irq_v(void *data)
/**
* pxa_init_dma_channel - init dma descriptors
* @pcdev: pxa camera device
- * @vb: videobuffer2 buffer
- * @dma: dma video buffer
+ * @buf: pxa camera buffer
* @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
- * @cibr: camera Receive Buffer Register
+ * @sg: dma scatter list
+ * @sglen: dma scatter list length
*
* Prepares the pxa dma descriptors to transfer one camera channel.
*
@@ -1010,6 +1011,8 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
/**
* pxa_camera_check_link_miss - check missed DMA linking
* @pcdev: camera device
+ * @last_submitted: an opaque DMA cookie for last submitted
+ * @last_issued: an opaque DMA cookie for last issued
*
* The DMA chaining is done with DMA running. This means a tiny temporal window
* remains, where a buffer is queued on the chain, while the chain is already
@@ -2221,6 +2224,11 @@ static void pxa_camera_sensor_unbind(struct v4l2_async_notifier *notifier,
mutex_unlock(&pcdev->mlock);
}
+static const struct v4l2_async_notifier_operations pxa_camera_sensor_ops = {
+ .bound = pxa_camera_sensor_bound,
+ .unbind = pxa_camera_sensor_unbind,
+};
+
/*
* Driver probe, remove, suspend and resume operations
*/
@@ -2489,8 +2497,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev->asds[0] = &pcdev->asd;
pcdev->notifier.subdevs = pcdev->asds;
pcdev->notifier.num_subdevs = 1;
- pcdev->notifier.bound = pxa_camera_sensor_bound;
- pcdev->notifier.unbind = pxa_camera_sensor_unbind;
+ pcdev->notifier.ops = &pxa_camera_sensor_ops;
if (!of_have_populated_dt())
pcdev->asd.match_type = V4L2_ASYNC_MATCH_I2C;
diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c
index b22d2dfcd3c2..55232a912950 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c
@@ -622,6 +622,9 @@ static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
+ } else {
+ /* On current devices output->wm_num is always <= 2 */
+ break;
}
if (output->wm_idx[i] % 2 == 1)
diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c b/drivers/media/platform/qcom/camss-8x16/camss-video.c
index cf4219e871bd..ffaa2849e0c1 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss-video.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c
@@ -21,7 +21,6 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
-#include <media/videobuf-core.h>
#include <media/videobuf2-dma-sg.h>
#include "camss-video.h"
diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c
index a3760b5dd1d1..390a42c17b66 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss.c
@@ -601,6 +601,11 @@ static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async)
return media_device_register(&camss->media_dev);
}
+static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
+ .bound = camss_subdev_notifier_bound,
+ .complete = camss_subdev_notifier_complete,
+};
+
static const struct media_device_ops camss_media_ops = {
.link_notify = v4l2_pipeline_link_notify,
};
@@ -655,8 +660,7 @@ static int camss_probe(struct platform_device *pdev)
goto err_register_entities;
if (camss->notifier.num_subdevs) {
- camss->notifier.bound = camss_subdev_notifier_bound;
- camss->notifier.complete = camss_subdev_notifier_complete;
+ camss->notifier.ops = &camss_subdev_notifier_ops;
ret = v4l2_async_notifier_register(&camss->v4l2_dev,
&camss->notifier);
diff --git a/drivers/media/platform/qcom/venus/Makefile b/drivers/media/platform/qcom/venus/Makefile
index 0fe9afb83697..bfd4edf7c83f 100644
--- a/drivers/media/platform/qcom/venus/Makefile
+++ b/drivers/media/platform/qcom/venus/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Makefile for Qualcomm Venus driver
venus-core-objs += core.o helpers.o firmware.o \
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index cba092bcb76d..a0fe80df0cbd 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -194,7 +194,6 @@ struct venus_buffer {
* @fh: a holder of v4l file handle structure
* @streamon_cap: stream on flag for capture queue
* @streamon_out: stream on flag for output queue
- * @cmd_stop: a flag to signal encoder/decoder commands
* @width: current capture width
* @height: current capture height
* @out_width: current output width
@@ -258,7 +257,6 @@ struct venus_inst {
} controls;
struct v4l2_fh fh;
unsigned int streamon_cap, streamon_out;
- bool cmd_stop;
u32 width;
u32 height;
u32 out_width;
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index 9b2a401a4891..0ce9559a2924 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -623,13 +623,6 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
mutex_lock(&inst->lock);
- if (inst->cmd_stop) {
- vbuf->flags |= V4L2_BUF_FLAG_LAST;
- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
- inst->cmd_stop = false;
- goto unlock;
- }
-
v4l2_m2m_buf_queue(m2m_ctx, vbuf);
if (!(inst->streamon_out & inst->streamon_cap))
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
index c09490876516..1baf78d3c02d 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -88,12 +88,6 @@ unlock:
return ret;
}
-static int core_deinit_wait_atomic_t(atomic_t *p)
-{
- schedule();
- return 0;
-}
-
int hfi_core_deinit(struct venus_core *core, bool blocking)
{
int ret = 0, empty;
@@ -112,7 +106,7 @@ int hfi_core_deinit(struct venus_core *core, bool blocking)
if (!empty) {
mutex_unlock(&core->lock);
- wait_on_atomic_t(&core->insts_count, core_deinit_wait_atomic_t,
+ wait_on_atomic_t(&core->insts_count, atomic_t_wait,
TASK_UNINTERRUPTIBLE);
mutex_lock(&core->lock);
}
@@ -484,6 +478,7 @@ int hfi_session_process_buf(struct venus_inst *inst, struct hfi_frame_data *fd)
return -EINVAL;
}
+EXPORT_SYMBOL_GPL(hfi_session_process_buf);
irqreturn_t hfi_isr_thread(int irq, void *dev_id)
{
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index 1caae8feaa36..734ce11b0ed0 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -344,7 +344,7 @@ static int venus_alloc(struct venus_hfi_device *hdev, struct mem_desc *desc,
desc->attrs = DMA_ATTR_WRITE_COMBINE;
desc->size = ALIGN(size, SZ_4K);
- desc->kva = dma_alloc_attrs(dev, size, &desc->da, GFP_KERNEL,
+ desc->kva = dma_alloc_attrs(dev, desc->size, &desc->da, GFP_KERNEL,
desc->attrs);
if (!desc->kva)
return -ENOMEM;
@@ -710,10 +710,8 @@ static int venus_interface_queues_init(struct venus_hfi_device *hdev)
if (ret)
return ret;
- hdev->ifaceq_table.kva = desc.kva;
- hdev->ifaceq_table.da = desc.da;
- hdev->ifaceq_table.size = IFACEQ_TABLE_SIZE;
- offset = hdev->ifaceq_table.size;
+ hdev->ifaceq_table = desc;
+ offset = IFACEQ_TABLE_SIZE;
for (i = 0; i < IFACEQ_NUM; i++) {
queue = &hdev->queues[i];
@@ -755,9 +753,7 @@ static int venus_interface_queues_init(struct venus_hfi_device *hdev)
if (ret) {
hdev->sfr.da = 0;
} else {
- hdev->sfr.da = desc.da;
- hdev->sfr.kva = desc.kva;
- hdev->sfr.size = ALIGNED_SFR_SIZE;
+ hdev->sfr = desc;
sfr = hdev->sfr.kva;
sfr->buf_size = ALIGNED_SFR_SIZE;
}
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index da611a5eb670..c9e9576bb08a 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -469,8 +469,14 @@ static int vdec_subscribe_event(struct v4l2_fh *fh,
static int
vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
{
- if (cmd->cmd != V4L2_DEC_CMD_STOP)
+ switch (cmd->cmd) {
+ case V4L2_DEC_CMD_STOP:
+ if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
+ return -EINVAL;
+ break;
+ default:
return -EINVAL;
+ }
return 0;
}
@@ -479,6 +485,7 @@ static int
vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
{
struct venus_inst *inst = to_inst(file);
+ struct hfi_frame_data fdata = {0};
int ret;
ret = vdec_try_decoder_cmd(file, fh, cmd);
@@ -486,12 +493,23 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
return ret;
mutex_lock(&inst->lock);
- inst->cmd_stop = true;
- mutex_unlock(&inst->lock);
- hfi_session_flush(inst);
+ /*
+ * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder
+ * input to signal EOS.
+ */
+ if (!(inst->streamon_out & inst->streamon_cap))
+ goto unlock;
+
+ fdata.buffer_type = HFI_BUFFER_INPUT;
+ fdata.flags |= HFI_BUFFERFLAG_EOS;
+ fdata.device_addr = 0xdeadbeef;
- return 0;
+ ret = hfi_session_process_buf(inst, &fdata);
+
+unlock:
+ mutex_unlock(&inst->lock);
+ return ret;
}
static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
@@ -718,7 +736,6 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
inst->reconfig = false;
inst->sequence_cap = 0;
inst->sequence_out = 0;
- inst->cmd_stop = false;
ret = vdec_init_session(inst);
if (ret)
@@ -807,11 +824,6 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
vb->timestamp = timestamp_us * NSEC_PER_USEC;
vbuf->sequence = inst->sequence_cap++;
- if (inst->cmd_stop) {
- vbuf->flags |= V4L2_BUF_FLAG_LAST;
- inst->cmd_stop = false;
- }
-
if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index 6f123a387cf9..3fcf0e9b7b29 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -963,13 +963,12 @@ static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type,
if (!vbuf)
return;
- vb = &vbuf->vb2_buf;
- vb->planes[0].bytesused = bytesused;
- vb->planes[0].data_offset = data_offset;
-
vbuf->flags = flags;
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ vb = &vbuf->vb2_buf;
+ vb2_set_plane_payload(vb, 0, bytesused + data_offset);
+ vb->planes[0].data_offset = data_offset;
vb->timestamp = timestamp_us * NSEC_PER_USEC;
vbuf->sequence = inst->sequence_cap++;
} else {
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 142de447aaaa..108d776f3265 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <media/v4l2-async.h>
#include <media/v4l2-fwnode.h>
#include "rcar-vin.h"
@@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier)
int ret;
/* Verify subdevices mbus format */
- if (!rvin_mbus_supported(&vin->digital)) {
+ if (!rvin_mbus_supported(vin->digital)) {
vin_err(vin, "Unsupported media bus format for %s\n",
- vin->digital.subdev->name);
+ vin->digital->subdev->name);
return -EINVAL;
}
vin_dbg(vin, "Found media bus format for %s: %d\n",
- vin->digital.subdev->name, vin->digital.code);
+ vin->digital->subdev->name, vin->digital->code);
ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
if (ret < 0) {
@@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier,
vin_dbg(vin, "unbind digital subdev %s\n", subdev->name);
rvin_v4l2_remove(vin);
- vin->digital.subdev = NULL;
+ vin->digital->subdev = NULL;
}
static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,
@@ -120,117 +121,75 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier,
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
if (ret < 0)
return ret;
- vin->digital.source_pad = ret;
+ vin->digital->source_pad = ret;
ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
- vin->digital.sink_pad = ret < 0 ? 0 : ret;
+ vin->digital->sink_pad = ret < 0 ? 0 : ret;
- vin->digital.subdev = subdev;
+ vin->digital->subdev = subdev;
vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
- subdev->name, vin->digital.source_pad,
- vin->digital.sink_pad);
+ subdev->name, vin->digital->source_pad,
+ vin->digital->sink_pad);
return 0;
}
+static const struct v4l2_async_notifier_operations rvin_digital_notify_ops = {
+ .bound = rvin_digital_notify_bound,
+ .unbind = rvin_digital_notify_unbind,
+ .complete = rvin_digital_notify_complete,
+};
+
-static int rvin_digitial_parse_v4l2(struct rvin_dev *vin,
- struct device_node *ep,
- struct v4l2_mbus_config *mbus_cfg)
+static int rvin_digital_parse_v4l2(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd)
{
- struct v4l2_fwnode_endpoint v4l2_ep;
- int ret;
+ struct rvin_dev *vin = dev_get_drvdata(dev);
+ struct rvin_graph_entity *rvge =
+ container_of(asd, struct rvin_graph_entity, asd);
- ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
- if (ret) {
- vin_err(vin, "Could not parse v4l2 endpoint\n");
- return -EINVAL;
- }
+ if (vep->base.port || vep->base.id)
+ return -ENOTCONN;
- mbus_cfg->type = v4l2_ep.bus_type;
+ rvge->mbus_cfg.type = vep->bus_type;
- switch (mbus_cfg->type) {
+ switch (rvge->mbus_cfg.type) {
case V4L2_MBUS_PARALLEL:
vin_dbg(vin, "Found PARALLEL media bus\n");
- mbus_cfg->flags = v4l2_ep.bus.parallel.flags;
+ rvge->mbus_cfg.flags = vep->bus.parallel.flags;
break;
case V4L2_MBUS_BT656:
vin_dbg(vin, "Found BT656 media bus\n");
- mbus_cfg->flags = 0;
+ rvge->mbus_cfg.flags = 0;
break;
default:
vin_err(vin, "Unknown media bus type\n");
return -EINVAL;
}
- return 0;
-}
-
-static int rvin_digital_graph_parse(struct rvin_dev *vin)
-{
- struct device_node *ep, *np;
- int ret;
-
- vin->digital.asd.match.fwnode.fwnode = NULL;
- vin->digital.subdev = NULL;
-
- /*
- * Port 0 id 0 is local digital input, try to get it.
- * Not all instances can or will have this, that is OK
- */
- ep = of_graph_get_endpoint_by_regs(vin->dev->of_node, 0, 0);
- if (!ep)
- return 0;
-
- np = of_graph_get_remote_port_parent(ep);
- if (!np) {
- vin_err(vin, "No remote parent for digital input\n");
- of_node_put(ep);
- return -EINVAL;
- }
- of_node_put(np);
-
- ret = rvin_digitial_parse_v4l2(vin, ep, &vin->digital.mbus_cfg);
- of_node_put(ep);
- if (ret)
- return ret;
-
- vin->digital.asd.match.fwnode.fwnode = of_fwnode_handle(np);
- vin->digital.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ vin->digital = rvge;
return 0;
}
static int rvin_digital_graph_init(struct rvin_dev *vin)
{
- struct v4l2_async_subdev **subdevs = NULL;
int ret;
- ret = rvin_digital_graph_parse(vin);
+ ret = v4l2_async_notifier_parse_fwnode_endpoints(
+ vin->dev, &vin->notifier,
+ sizeof(struct rvin_graph_entity), rvin_digital_parse_v4l2);
if (ret)
return ret;
- if (!vin->digital.asd.match.fwnode.fwnode) {
- vin_dbg(vin, "No digital subdevice found\n");
+ if (!vin->digital)
return -ENODEV;
- }
-
- /* Register the subdevices notifier. */
- subdevs = devm_kzalloc(vin->dev, sizeof(*subdevs), GFP_KERNEL);
- if (subdevs == NULL)
- return -ENOMEM;
-
- subdevs[0] = &vin->digital.asd;
vin_dbg(vin, "Found digital subdevice %pOF\n",
- to_of_node(subdevs[0]->match.fwnode.fwnode));
-
- vin->notifier.num_subdevs = 1;
- vin->notifier.subdevs = subdevs;
- vin->notifier.bound = rvin_digital_notify_bound;
- vin->notifier.unbind = rvin_digital_notify_unbind;
- vin->notifier.complete = rvin_digital_notify_complete;
+ to_of_node(vin->digital->asd.match.fwnode.fwnode));
+ vin->notifier.ops = &rvin_digital_notify_ops;
ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
if (ret < 0) {
vin_err(vin, "Notifier registration failed\n");
@@ -290,6 +249,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
if (ret)
return ret;
+ platform_set_drvdata(pdev, vin);
+
ret = rvin_digital_graph_init(vin);
if (ret < 0)
goto error;
@@ -297,11 +258,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
- platform_set_drvdata(pdev, vin);
-
return 0;
error:
rvin_dma_remove(vin);
+ v4l2_async_notifier_cleanup(&vin->notifier);
return ret;
}
@@ -313,6 +273,7 @@ static int rcar_vin_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
v4l2_async_notifier_unregister(&vin->notifier);
+ v4l2_async_notifier_cleanup(&vin->notifier);
rvin_dma_remove(vin);
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index b136844499f6..23fdff7a7370 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -183,7 +183,7 @@ static int rvin_setup(struct rvin_dev *vin)
/*
* Input interface
*/
- switch (vin->digital.code) {
+ switch (vin->digital->code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
/* BT.601/BT.1358 16bit YCbCr422 */
vnmc |= VNMC_INF_YUV16;
@@ -191,7 +191,7 @@ static int rvin_setup(struct rvin_dev *vin)
break;
case MEDIA_BUS_FMT_UYVY8_2X8:
/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
- vnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?
+ vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?
VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
input_is_yuv = true;
break;
@@ -200,7 +200,7 @@ static int rvin_setup(struct rvin_dev *vin)
break;
case MEDIA_BUS_FMT_UYVY10_2X10:
/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
- vnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ?
+ vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ?
VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
input_is_yuv = true;
break;
@@ -212,11 +212,11 @@ static int rvin_setup(struct rvin_dev *vin)
dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
/* Hsync Signal Polarity Select */
- if (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
+ if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
dmr2 |= VNDMR2_HPS;
/* Vsync Signal Polarity Select */
- if (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
+ if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
dmr2 |= VNDMR2_VPS;
/*
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index dd37ea811680..b479b882da12 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -111,7 +111,7 @@ static int rvin_reset_format(struct rvin_dev *vin)
struct v4l2_mbus_framefmt *mf = &fmt.format;
int ret;
- fmt.pad = vin->digital.source_pad;
+ fmt.pad = vin->digital->source_pad;
ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
if (ret)
@@ -172,13 +172,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
sd = vin_to_source(vin);
- v4l2_fill_mbus_format(&format.format, pix, vin->digital.code);
+ v4l2_fill_mbus_format(&format.format, pix, vin->digital->code);
pad_cfg = v4l2_subdev_alloc_pad_config(sd);
if (pad_cfg == NULL)
return -ENOMEM;
- format.pad = vin->digital.source_pad;
+ format.pad = vin->digital->source_pad;
field = pix->field;
@@ -555,7 +555,7 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh,
if (timings->pad)
return -EINVAL;
- timings->pad = vin->digital.sink_pad;
+ timings->pad = vin->digital->sink_pad;
ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);
@@ -607,7 +607,7 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh,
if (cap->pad)
return -EINVAL;
- cap->pad = vin->digital.sink_pad;
+ cap->pad = vin->digital->sink_pad;
ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
@@ -625,7 +625,7 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
if (edid->pad)
return -EINVAL;
- edid->pad = vin->digital.sink_pad;
+ edid->pad = vin->digital->sink_pad;
ret = v4l2_subdev_call(sd, pad, get_edid, edid);
@@ -643,7 +643,7 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
if (edid->pad)
return -EINVAL;
- edid->pad = vin->digital.sink_pad;
+ edid->pad = vin->digital->sink_pad;
ret = v4l2_subdev_call(sd, pad, set_edid, edid);
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 9bfb5a7c4dc4..5382078143fb 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -126,7 +126,7 @@ struct rvin_dev {
struct v4l2_device v4l2_dev;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_async_notifier notifier;
- struct rvin_graph_entity digital;
+ struct rvin_graph_entity *digital;
struct mutex lock;
struct vb2_queue queue;
@@ -145,7 +145,7 @@ struct rvin_dev {
struct v4l2_rect compose;
};
-#define vin_to_source(vin) vin->digital.subdev
+#define vin_to_source(vin) ((vin)->digital->subdev)
/* Debug */
#define vin_dbg(d, fmt, arg...) dev_dbg(d->dev, fmt, ##arg)
diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c
index 522364ff0d5d..63c94f4028a7 100644
--- a/drivers/media/platform/rcar_drif.c
+++ b/drivers/media/platform/rcar_drif.c
@@ -630,7 +630,7 @@ static int rcar_drif_enable_rx(struct rcar_drif_sdr *sdr)
{
unsigned int i;
u32 ctr;
- int ret;
+ int ret = -EINVAL;
/*
* When both internal channels are enabled, they can be synchronized
@@ -1185,6 +1185,12 @@ error:
return ret;
}
+static const struct v4l2_async_notifier_operations rcar_drif_notify_ops = {
+ .bound = rcar_drif_notify_bound,
+ .unbind = rcar_drif_notify_unbind,
+ .complete = rcar_drif_notify_complete,
+};
+
/* Read endpoint properties */
static void rcar_drif_get_ep_properties(struct rcar_drif_sdr *sdr,
struct fwnode_handle *fwnode)
@@ -1347,9 +1353,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr)
if (ret)
goto error;
- sdr->notifier.bound = rcar_drif_notify_bound;
- sdr->notifier.unbind = rcar_drif_notify_unbind;
- sdr->notifier.complete = rcar_drif_notify_complete;
+ sdr->notifier.ops = &rcar_drif_notify_ops;
/* Register notifier */
ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier);
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c
index 3245bc45f4a0..b13dec3081e5 100644
--- a/drivers/media/platform/rcar_fdp1.c
+++ b/drivers/media/platform/rcar_fdp1.c
@@ -1132,7 +1132,7 @@ static int fdp1_device_process(struct fdp1_ctx *ctx)
* mem2mem callbacks
*/
-/**
+/*
* job_ready() - check whether an instance is ready to be scheduled to run
*/
static int fdp1_m2m_job_ready(void *priv)
diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c
index 070bac36d766..f6092ae45912 100644
--- a/drivers/media/platform/rcar_jpu.c
+++ b/drivers/media/platform/rcar_jpu.c
@@ -257,7 +257,7 @@ struct jpu_fmt {
};
/**
- * jpu_q_data - parameters of one queue
+ * struct jpu_q_data - parameters of one queue
* @fmtinfo: driver-specific format of this queue
* @format: multiplanar format of this queue
* @sequence: sequence number
@@ -269,7 +269,7 @@ struct jpu_q_data {
};
/**
- * jpu_ctx - the device context data
+ * struct jpu_ctx - the device context data
* @jpu: JPEG IP device for this context
* @encoder: compression (encode) operation or decompression (decode)
* @compr_quality: destination image quality in compression (encode) mode
diff --git a/drivers/media/platform/rockchip/rga/Makefile b/drivers/media/platform/rockchip/rga/Makefile
new file mode 100644
index 000000000000..92fe25490ccd
--- /dev/null
+++ b/drivers/media/platform/rockchip/rga/Makefile
@@ -0,0 +1,3 @@
+rockchip-rga-objs := rga.o rga-hw.o rga-buf.o
+
+obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip-rga.o
diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c
new file mode 100644
index 000000000000..49cacc7a48d1
--- /dev/null
+++ b/drivers/media/platform/rockchip/rga/rga-buf.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Jacob Chen <jacob-chen@iotwrt.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/pm_runtime.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-sg.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "rga-hw.h"
+#include "rga.h"
+
+static int
+rga_queue_setup(struct vb2_queue *vq,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct rga_ctx *ctx = vb2_get_drv_priv(vq);
+ struct rga_frame *f = rga_get_frame(ctx, vq->type);
+
+ if (IS_ERR(f))
+ return PTR_ERR(f);
+
+ if (*nplanes)
+ return sizes[0] < f->size ? -EINVAL : 0;
+
+ sizes[0] = f->size;
+ *nplanes = 1;
+
+ return 0;
+}
+
+static int rga_buf_prepare(struct vb2_buffer *vb)
+{
+ struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct rga_frame *f = rga_get_frame(ctx, vb->vb2_queue->type);
+
+ if (IS_ERR(f))
+ return PTR_ERR(f);
+
+ vb2_set_plane_payload(vb, 0, f->size);
+
+ return 0;
+}
+
+static void rga_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static int rga_buf_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct rga_ctx *ctx = vb2_get_drv_priv(q);
+ struct rockchip_rga *rga = ctx->rga;
+ int ret, i;
+
+ ret = pm_runtime_get_sync(rga->dev);
+
+ if (!ret)
+ return 0;
+
+ for (i = 0; i < q->num_buffers; ++i) {
+ if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) {
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q->bufs[i]),
+ VB2_BUF_STATE_QUEUED);
+ }
+ }
+
+ return ret;
+}
+
+static void rga_buf_stop_streaming(struct vb2_queue *q)
+{
+ struct rga_ctx *ctx = vb2_get_drv_priv(q);
+ struct rockchip_rga *rga = ctx->rga;
+ struct vb2_v4l2_buffer *vbuf;
+
+ for (;;) {
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
+ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ else
+ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ if (!vbuf)
+ break;
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+ }
+
+ pm_runtime_put(rga->dev);
+}
+
+const struct vb2_ops rga_qops = {
+ .queue_setup = rga_queue_setup,
+ .buf_prepare = rga_buf_prepare,
+ .buf_queue = rga_buf_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .start_streaming = rga_buf_start_streaming,
+ .stop_streaming = rga_buf_stop_streaming,
+};
+
+/* RGA MMU is a 1-Level MMU, so it can't be used through the IOMMU API.
+ * We use it more like a scatter-gather list.
+ */
+void rga_buf_map(struct vb2_buffer *vb)
+{
+ struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct rockchip_rga *rga = ctx->rga;
+ struct sg_table *sgt;
+ struct scatterlist *sgl;
+ unsigned int *pages;
+ unsigned int address, len, i, p;
+ unsigned int mapped_size = 0;
+
+ if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ pages = rga->src_mmu_pages;
+ else
+ pages = rga->dst_mmu_pages;
+
+ /* Create local MMU table for RGA */
+ sgt = vb2_plane_cookie(vb, 0);
+
+ for_each_sg(sgt->sgl, sgl, sgt->nents, i) {
+ len = sg_dma_len(sgl) >> PAGE_SHIFT;
+ address = sg_phys(sgl);
+
+ for (p = 0; p < len; p++) {
+ dma_addr_t phys = address + (p << PAGE_SHIFT);
+
+ pages[mapped_size + p] = phys;
+ }
+
+ mapped_size += len;
+ }
+
+ /* sync local MMU table for RGA */
+ dma_sync_single_for_device(rga->dev, virt_to_phys(pages),
+ 8 * PAGE_SIZE, DMA_BIDIRECTIONAL);
+}
diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c
new file mode 100644
index 000000000000..96d1b1b3fe8e
--- /dev/null
+++ b/drivers/media/platform/rockchip/rga/rga-hw.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Jacob Chen <jacob-chen@iotwrt.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/pm_runtime.h>
+
+#include "rga-hw.h"
+#include "rga.h"
+
+enum e_rga_start_pos {
+ LT = 0,
+ LB = 1,
+ RT = 2,
+ RB = 3,
+};
+
+struct rga_addr_offset {
+ unsigned int y_off;
+ unsigned int u_off;
+ unsigned int v_off;
+};
+
+struct rga_corners_addr_offset {
+ struct rga_addr_offset left_top;
+ struct rga_addr_offset right_top;
+ struct rga_addr_offset left_bottom;
+ struct rga_addr_offset right_bottom;
+};
+
+static unsigned int rga_get_scaling(unsigned int src, unsigned int dst)
+{
+ /*
+ * The rga hw scaling factor is a normalized inverse of the
+ * scaling factor.
+ * For example: When source width is 100 and destination width is 200
+ * (scaling of 2x), then the hw factor is NC * 100 / 200.
+ * The normalization factor (NC) is 2^16 = 0x10000.
+ */
+
+ return (src > dst) ? ((dst << 16) / src) : ((src << 16) / dst);
+}
+
+static struct rga_corners_addr_offset
+rga_get_addr_offset(struct rga_frame *frm, unsigned int x, unsigned int y,
+ unsigned int w, unsigned int h)
+{
+ struct rga_corners_addr_offset offsets;
+ struct rga_addr_offset *lt, *lb, *rt, *rb;
+ unsigned int x_div = 0,
+ y_div = 0, uv_stride = 0, pixel_width = 0, uv_factor = 0;
+
+ lt = &offsets.left_top;
+ lb = &offsets.left_bottom;
+ rt = &offsets.right_top;
+ rb = &offsets.right_bottom;
+
+ x_div = frm->fmt->x_div;
+ y_div = frm->fmt->y_div;
+ uv_factor = frm->fmt->uv_factor;
+ uv_stride = frm->stride / x_div;
+ pixel_width = frm->stride / frm->width;
+
+ lt->y_off = y * frm->stride + x * pixel_width;
+ lt->u_off =
+ frm->width * frm->height + (y / y_div) * uv_stride + x / x_div;
+ lt->v_off = lt->u_off + frm->width * frm->height / uv_factor;
+
+ lb->y_off = lt->y_off + (h - 1) * frm->stride;
+ lb->u_off = lt->u_off + (h / y_div - 1) * uv_stride;
+ lb->v_off = lt->v_off + (h / y_div - 1) * uv_stride;
+
+ rt->y_off = lt->y_off + (w - 1) * pixel_width;
+ rt->u_off = lt->u_off + w / x_div - 1;
+ rt->v_off = lt->v_off + w / x_div - 1;
+
+ rb->y_off = lb->y_off + (w - 1) * pixel_width;
+ rb->u_off = lb->u_off + w / x_div - 1;
+ rb->v_off = lb->v_off + w / x_div - 1;
+
+ return offsets;
+}
+
+static struct rga_addr_offset *rga_lookup_draw_pos(struct
+ rga_corners_addr_offset
+ * offsets, u32 rotate_mode,
+ u32 mirr_mode)
+{
+ static enum e_rga_start_pos rot_mir_point_matrix[4][4] = {
+ {
+ LT, RT, LB, RB,
+ },
+ {
+ RT, LT, RB, LB,
+ },
+ {
+ RB, LB, RT, LT,
+ },
+ {
+ LB, RB, LT, RT,
+ },
+ };
+
+ if (!offsets)
+ return NULL;
+
+ switch (rot_mir_point_matrix[rotate_mode][mirr_mode]) {
+ case LT:
+ return &offsets->left_top;
+ case LB:
+ return &offsets->left_bottom;
+ case RT:
+ return &offsets->right_top;
+ case RB:
+ return &offsets->right_bottom;
+ }
+
+ return NULL;
+}
+
+static void rga_cmd_set_src_addr(struct rga_ctx *ctx, void *mmu_pages)
+{
+ struct rockchip_rga *rga = ctx->rga;
+ u32 *dest = rga->cmdbuf_virt;
+ unsigned int reg;
+
+ reg = RGA_MMU_SRC_BASE - RGA_MODE_BASE_REG;
+ dest[reg >> 2] = virt_to_phys(mmu_pages) >> 4;
+
+ reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG;
+ dest[reg >> 2] |= 0x7;
+}
+
+static void rga_cmd_set_src1_addr(struct rga_ctx *ctx, void *mmu_pages)
+{
+ struct rockchip_rga *rga = ctx->rga;
+ u32 *dest = rga->cmdbuf_virt;
+ unsigned int reg;
+
+ reg = RGA_MMU_SRC1_BASE - RGA_MODE_BASE_REG;
+ dest[reg >> 2] = virt_to_phys(mmu_pages) >> 4;
+
+ reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG;
+ dest[reg >> 2] |= 0x7 << 4;
+}
+
+static void rga_cmd_set_dst_addr(struct rga_ctx *ctx, void *mmu_pages)
+{
+ struct rockchip_rga *rga = ctx->rga;
+ u32 *dest = rga->cmdbuf_virt;
+ unsigned int reg;
+
+ reg = RGA_MMU_DST_BASE - RGA_MODE_BASE_REG;
+ dest[reg >> 2] = virt_to_phys(mmu_pages) >> 4;
+
+ reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG;
+ dest[reg >> 2] |= 0x7 << 8;
+}
+
+static void rga_cmd_set_trans_info(struct rga_ctx *ctx)
+{
+ struct rockchip_rga *rga = ctx->rga;
+ u32 *dest = rga->cmdbuf_virt;
+ unsigned int scale_dst_w, scale_dst_h;
+ unsigned int src_h, src_w, src_x, src_y, dst_h, dst_w, dst_x, dst_y;
+ union rga_src_info src_info;
+ union rga_dst_info dst_info;
+ union rga_src_x_factor x_factor;
+ union rga_src_y_factor y_factor;
+ union rga_src_vir_info src_vir_info;
+ union rga_src_act_info src_act_info;
+ union rga_dst_vir_info dst_vir_info;
+ union rga_dst_act_info dst_act_info;
+
+ struct rga_addr_offset *dst_offset;
+ struct rga_corners_addr_offset offsets;
+ struct rga_corners_addr_offset src_offsets;
+
+ src_h = ctx->in.crop.height;
+ src_w = ctx->in.crop.width;
+ src_x = ctx->in.crop.left;
+ src_y = ctx->in.crop.top;
+ dst_h = ctx->out.crop.height;
+ dst_w = ctx->out.crop.width;
+ dst_x = ctx->out.crop.left;
+ dst_y = ctx->out.crop.top;
+
+ src_info.val = dest[(RGA_SRC_INFO - RGA_MODE_BASE_REG) >> 2];
+ dst_info.val = dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2];
+ x_factor.val = dest[(RGA_SRC_X_FACTOR - RGA_MODE_BASE_REG) >> 2];
+ y_factor.val = dest[(RGA_SRC_Y_FACTOR - RGA_MODE_BASE_REG) >> 2];
+ src_vir_info.val = dest[(RGA_SRC_VIR_INFO - RGA_MODE_BASE_REG) >> 2];
+ src_act_info.val = dest[(RGA_SRC_ACT_INFO - RGA_MODE_BASE_REG) >> 2];
+ dst_vir_info.val = dest[(RGA_DST_VIR_INFO - RGA_MODE_BASE_REG) >> 2];
+ dst_act_info.val = dest[(RGA_DST_ACT_INFO - RGA_MODE_BASE_REG) >> 2];
+
+ src_info.data.format = ctx->in.fmt->hw_format;
+ src_info.data.swap = ctx->in.fmt->color_swap;
+ dst_info.data.format = ctx->out.fmt->hw_format;
+ dst_info.data.swap = ctx->out.fmt->color_swap;
+
+ if (ctx->in.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) {
+ if (ctx->out.fmt->hw_format < RGA_COLOR_FMT_YUV422SP) {
+ switch (ctx->in.colorspace) {
+ case V4L2_COLORSPACE_REC709:
+ src_info.data.csc_mode =
+ RGA_SRC_CSC_MODE_BT709_R0;
+ break;
+ default:
+ src_info.data.csc_mode =
+ RGA_SRC_CSC_MODE_BT601_R0;
+ break;
+ }
+ }
+ }
+
+ if (ctx->out.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) {
+ switch (ctx->out.colorspace) {
+ case V4L2_COLORSPACE_REC709:
+ dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0;
+ break;
+ default:
+ dst_info.data.csc_mode = RGA_DST_CSC_MODE_BT601_R0;
+ break;
+ }
+ }
+
+ if (ctx->vflip)
+ src_info.data.mir_mode |= RGA_SRC_MIRR_MODE_X;
+
+ if (ctx->hflip)
+ src_info.data.mir_mode |= RGA_SRC_MIRR_MODE_Y;
+
+ switch (ctx->rotate) {
+ case 90:
+ src_info.data.rot_mode = RGA_SRC_ROT_MODE_90_DEGREE;
+ break;
+ case 180:
+ src_info.data.rot_mode = RGA_SRC_ROT_MODE_180_DEGREE;
+ break;
+ case 270:
+ src_info.data.rot_mode = RGA_SRC_ROT_MODE_270_DEGREE;
+ break;
+ default:
+ src_info.data.rot_mode = RGA_SRC_ROT_MODE_0_DEGREE;
+ break;
+ }
+
+ /*
+ * Cacluate the up/down scaling mode/factor.
+ *
+ * RGA used to scale the picture first, and then rotate second,
+ * so we need to swap the w/h when rotate degree is 90/270.
+ */
+ if (src_info.data.rot_mode == RGA_SRC_ROT_MODE_90_DEGREE ||
+ src_info.data.rot_mode == RGA_SRC_ROT_MODE_270_DEGREE) {
+ if (rga->version.major == 0 || rga->version.minor == 0) {
+ if (dst_w == src_h)
+ src_h -= 8;
+ if (abs(src_w - dst_h) < 16)
+ src_w -= 16;
+ }
+
+ scale_dst_h = dst_w;
+ scale_dst_w = dst_h;
+ } else {
+ scale_dst_w = dst_w;
+ scale_dst_h = dst_h;
+ }
+
+ if (src_w == scale_dst_w) {
+ src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_NO;
+ x_factor.val = 0;
+ } else if (src_w > scale_dst_w) {
+ src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_DOWN;
+ x_factor.data.down_scale_factor =
+ rga_get_scaling(src_w, scale_dst_w) + 1;
+ } else {
+ src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_UP;
+ x_factor.data.up_scale_factor =
+ rga_get_scaling(src_w - 1, scale_dst_w - 1);
+ }
+
+ if (src_h == scale_dst_h) {
+ src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_NO;
+ y_factor.val = 0;
+ } else if (src_h > scale_dst_h) {
+ src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_DOWN;
+ y_factor.data.down_scale_factor =
+ rga_get_scaling(src_h, scale_dst_h) + 1;
+ } else {
+ src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_UP;
+ y_factor.data.up_scale_factor =
+ rga_get_scaling(src_h - 1, scale_dst_h - 1);
+ }
+
+ /*
+ * Cacluate the framebuffer virtual strides and active size,
+ * note that the step of vir_stride / vir_width is 4 byte words
+ */
+ src_vir_info.data.vir_stride = ctx->in.stride >> 2;
+ src_vir_info.data.vir_width = ctx->in.stride >> 2;
+
+ src_act_info.data.act_height = src_h - 1;
+ src_act_info.data.act_width = src_w - 1;
+
+ dst_vir_info.data.vir_stride = ctx->out.stride >> 2;
+ dst_act_info.data.act_height = dst_h - 1;
+ dst_act_info.data.act_width = dst_w - 1;
+
+ /*
+ * Cacluate the source framebuffer base address with offset pixel.
+ */
+ src_offsets = rga_get_addr_offset(&ctx->in, src_x, src_y,
+ src_w, src_h);
+
+ /*
+ * Configure the dest framebuffer base address with pixel offset.
+ */
+ offsets = rga_get_addr_offset(&ctx->out, dst_x, dst_y, dst_w, dst_h);
+ dst_offset = rga_lookup_draw_pos(&offsets, src_info.data.rot_mode,
+ src_info.data.mir_mode);
+
+ dest[(RGA_SRC_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
+ src_offsets.left_top.y_off;
+ dest[(RGA_SRC_CB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
+ src_offsets.left_top.u_off;
+ dest[(RGA_SRC_CR_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
+ src_offsets.left_top.v_off;
+
+ dest[(RGA_SRC_X_FACTOR - RGA_MODE_BASE_REG) >> 2] = x_factor.val;
+ dest[(RGA_SRC_Y_FACTOR - RGA_MODE_BASE_REG) >> 2] = y_factor.val;
+ dest[(RGA_SRC_VIR_INFO - RGA_MODE_BASE_REG) >> 2] = src_vir_info.val;
+ dest[(RGA_SRC_ACT_INFO - RGA_MODE_BASE_REG) >> 2] = src_act_info.val;
+
+ dest[(RGA_SRC_INFO - RGA_MODE_BASE_REG) >> 2] = src_info.val;
+
+ dest[(RGA_DST_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
+ dst_offset->y_off;
+ dest[(RGA_DST_CB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
+ dst_offset->u_off;
+ dest[(RGA_DST_CR_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] =
+ dst_offset->v_off;
+
+ dest[(RGA_DST_VIR_INFO - RGA_MODE_BASE_REG) >> 2] = dst_vir_info.val;
+ dest[(RGA_DST_ACT_INFO - RGA_MODE_BASE_REG) >> 2] = dst_act_info.val;
+
+ dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2] = dst_info.val;
+}
+
+static void rga_cmd_set_mode(struct rga_ctx *ctx)
+{
+ struct rockchip_rga *rga = ctx->rga;
+ u32 *dest = rga->cmdbuf_virt;
+ union rga_mode_ctrl mode;
+ union rga_alpha_ctrl0 alpha_ctrl0;
+ union rga_alpha_ctrl1 alpha_ctrl1;
+
+ mode.val = 0;
+ alpha_ctrl0.val = 0;
+ alpha_ctrl1.val = 0;
+
+ mode.data.gradient_sat = 1;
+ mode.data.render = RGA_MODE_RENDER_BITBLT;
+ mode.data.bitblt = RGA_MODE_BITBLT_MODE_SRC_TO_DST;
+
+ /* disable alpha blending */
+ dest[(RGA_ALPHA_CTRL0 - RGA_MODE_BASE_REG) >> 2] = alpha_ctrl0.val;
+ dest[(RGA_ALPHA_CTRL1 - RGA_MODE_BASE_REG) >> 2] = alpha_ctrl1.val;
+
+ dest[(RGA_MODE_CTRL - RGA_MODE_BASE_REG) >> 2] = mode.val;
+}
+
+static void rga_cmd_set(struct rga_ctx *ctx)
+{
+ struct rockchip_rga *rga = ctx->rga;
+
+ memset(rga->cmdbuf_virt, 0, RGA_CMDBUF_SIZE * 4);
+
+ rga_cmd_set_src_addr(ctx, rga->src_mmu_pages);
+ /*
+ * Due to hardware bug,
+ * src1 mmu also should be configured when using alpha blending.
+ */
+ rga_cmd_set_src1_addr(ctx, rga->dst_mmu_pages);
+
+ rga_cmd_set_dst_addr(ctx, rga->dst_mmu_pages);
+ rga_cmd_set_mode(ctx);
+
+ rga_cmd_set_trans_info(ctx);
+
+ rga_write(rga, RGA_CMD_BASE, rga->cmdbuf_phy);
+
+ /* sync CMD buf for RGA */
+ dma_sync_single_for_device(rga->dev, rga->cmdbuf_phy,
+ PAGE_SIZE, DMA_BIDIRECTIONAL);
+}
+
+void rga_hw_start(struct rockchip_rga *rga)
+{
+ struct rga_ctx *ctx = rga->curr;
+
+ rga_cmd_set(ctx);
+
+ rga_write(rga, RGA_SYS_CTRL, 0x00);
+
+ rga_write(rga, RGA_SYS_CTRL, 0x22);
+
+ rga_write(rga, RGA_INT, 0x600);
+
+ rga_write(rga, RGA_CMD_CTRL, 0x1);
+}
diff --git a/drivers/media/platform/rockchip/rga/rga-hw.h b/drivers/media/platform/rockchip/rga/rga-hw.h
new file mode 100644
index 000000000000..ca3c204abe42
--- /dev/null
+++ b/drivers/media/platform/rockchip/rga/rga-hw.h
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Jacob Chen <jacob-chen@iotwrt.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+#ifndef __RGA_HW_H__
+#define __RGA_HW_H__
+
+#define RGA_CMDBUF_SIZE 0x20
+
+/* Hardware limits */
+#define MAX_WIDTH 8192
+#define MAX_HEIGHT 8192
+
+#define MIN_WIDTH 34
+#define MIN_HEIGHT 34
+
+#define DEFAULT_WIDTH 100
+#define DEFAULT_HEIGHT 100
+
+#define RGA_TIMEOUT 500
+
+/* Registers address */
+#define RGA_SYS_CTRL 0x0000
+#define RGA_CMD_CTRL 0x0004
+#define RGA_CMD_BASE 0x0008
+#define RGA_INT 0x0010
+#define RGA_MMU_CTRL0 0x0014
+#define RGA_VERSION_INFO 0x0028
+
+#define RGA_MODE_BASE_REG 0x0100
+#define RGA_MODE_MAX_REG 0x017C
+
+#define RGA_MODE_CTRL 0x0100
+#define RGA_SRC_INFO 0x0104
+#define RGA_SRC_Y_RGB_BASE_ADDR 0x0108
+#define RGA_SRC_CB_BASE_ADDR 0x010c
+#define RGA_SRC_CR_BASE_ADDR 0x0110
+#define RGA_SRC1_RGB_BASE_ADDR 0x0114
+#define RGA_SRC_VIR_INFO 0x0118
+#define RGA_SRC_ACT_INFO 0x011c
+#define RGA_SRC_X_FACTOR 0x0120
+#define RGA_SRC_Y_FACTOR 0x0124
+#define RGA_SRC_BG_COLOR 0x0128
+#define RGA_SRC_FG_COLOR 0x012c
+#define RGA_SRC_TR_COLOR0 0x0130
+#define RGA_SRC_TR_COLOR1 0x0134
+
+#define RGA_DST_INFO 0x0138
+#define RGA_DST_Y_RGB_BASE_ADDR 0x013c
+#define RGA_DST_CB_BASE_ADDR 0x0140
+#define RGA_DST_CR_BASE_ADDR 0x0144
+#define RGA_DST_VIR_INFO 0x0148
+#define RGA_DST_ACT_INFO 0x014c
+
+#define RGA_ALPHA_CTRL0 0x0150
+#define RGA_ALPHA_CTRL1 0x0154
+#define RGA_FADING_CTRL 0x0158
+#define RGA_PAT_CON 0x015c
+#define RGA_ROP_CON0 0x0160
+#define RGA_ROP_CON1 0x0164
+#define RGA_MASK_BASE 0x0168
+
+#define RGA_MMU_CTRL1 0x016C
+#define RGA_MMU_SRC_BASE 0x0170
+#define RGA_MMU_SRC1_BASE 0x0174
+#define RGA_MMU_DST_BASE 0x0178
+
+/* Registers value */
+#define RGA_MODE_RENDER_BITBLT 0
+#define RGA_MODE_RENDER_COLOR_PALETTE 1
+#define RGA_MODE_RENDER_RECTANGLE_FILL 2
+#define RGA_MODE_RENDER_UPDATE_PALETTE_LUT_RAM 3
+
+#define RGA_MODE_BITBLT_MODE_SRC_TO_DST 0
+#define RGA_MODE_BITBLT_MODE_SRC_SRC1_TO_DST 1
+
+#define RGA_MODE_CF_ROP4_SOLID 0
+#define RGA_MODE_CF_ROP4_PATTERN 1
+
+#define RGA_COLOR_FMT_ABGR8888 0
+#define RGA_COLOR_FMT_XBGR8888 1
+#define RGA_COLOR_FMT_RGB888 2
+#define RGA_COLOR_FMT_BGR565 4
+#define RGA_COLOR_FMT_ABGR1555 5
+#define RGA_COLOR_FMT_ABGR4444 6
+#define RGA_COLOR_FMT_YUV422SP 8
+#define RGA_COLOR_FMT_YUV422P 9
+#define RGA_COLOR_FMT_YUV420SP 10
+#define RGA_COLOR_FMT_YUV420P 11
+/* SRC_COLOR Palette */
+#define RGA_COLOR_FMT_CP_1BPP 12
+#define RGA_COLOR_FMT_CP_2BPP 13
+#define RGA_COLOR_FMT_CP_4BPP 14
+#define RGA_COLOR_FMT_CP_8BPP 15
+#define RGA_COLOR_FMT_MASK 15
+
+#define RGA_COLOR_NONE_SWAP 0
+#define RGA_COLOR_RB_SWAP 1
+#define RGA_COLOR_ALPHA_SWAP 2
+#define RGA_COLOR_UV_SWAP 4
+
+#define RGA_SRC_CSC_MODE_BYPASS 0
+#define RGA_SRC_CSC_MODE_BT601_R0 1
+#define RGA_SRC_CSC_MODE_BT601_R1 2
+#define RGA_SRC_CSC_MODE_BT709_R0 3
+#define RGA_SRC_CSC_MODE_BT709_R1 4
+
+#define RGA_SRC_ROT_MODE_0_DEGREE 0
+#define RGA_SRC_ROT_MODE_90_DEGREE 1
+#define RGA_SRC_ROT_MODE_180_DEGREE 2
+#define RGA_SRC_ROT_MODE_270_DEGREE 3
+
+#define RGA_SRC_MIRR_MODE_NO 0
+#define RGA_SRC_MIRR_MODE_X 1
+#define RGA_SRC_MIRR_MODE_Y 2
+#define RGA_SRC_MIRR_MODE_X_Y 3
+
+#define RGA_SRC_HSCL_MODE_NO 0
+#define RGA_SRC_HSCL_MODE_DOWN 1
+#define RGA_SRC_HSCL_MODE_UP 2
+
+#define RGA_SRC_VSCL_MODE_NO 0
+#define RGA_SRC_VSCL_MODE_DOWN 1
+#define RGA_SRC_VSCL_MODE_UP 2
+
+#define RGA_SRC_TRANS_ENABLE_R 1
+#define RGA_SRC_TRANS_ENABLE_G 2
+#define RGA_SRC_TRANS_ENABLE_B 4
+#define RGA_SRC_TRANS_ENABLE_A 8
+
+#define RGA_SRC_BIC_COE_SELEC_CATROM 0
+#define RGA_SRC_BIC_COE_SELEC_MITCHELL 1
+#define RGA_SRC_BIC_COE_SELEC_HERMITE 2
+#define RGA_SRC_BIC_COE_SELEC_BSPLINE 3
+
+#define RGA_DST_DITHER_MODE_888_TO_666 0
+#define RGA_DST_DITHER_MODE_888_TO_565 1
+#define RGA_DST_DITHER_MODE_888_TO_555 2
+#define RGA_DST_DITHER_MODE_888_TO_444 3
+
+#define RGA_DST_CSC_MODE_BYPASS 0
+#define RGA_DST_CSC_MODE_BT601_R0 1
+#define RGA_DST_CSC_MODE_BT601_R1 2
+#define RGA_DST_CSC_MODE_BT709_R0 3
+
+#define RGA_ALPHA_ROP_MODE_2 0
+#define RGA_ALPHA_ROP_MODE_3 1
+#define RGA_ALPHA_ROP_MODE_4 2
+
+#define RGA_ALPHA_SELECT_ALPHA 0
+#define RGA_ALPHA_SELECT_ROP 1
+
+#define RGA_ALPHA_MASK_BIG_ENDIAN 0
+#define RGA_ALPHA_MASK_LITTLE_ENDIAN 1
+
+#define RGA_ALPHA_NORMAL 0
+#define RGA_ALPHA_REVERSE 1
+
+#define RGA_ALPHA_BLEND_GLOBAL 0
+#define RGA_ALPHA_BLEND_NORMAL 1
+#define RGA_ALPHA_BLEND_MULTIPLY 2
+
+#define RGA_ALPHA_CAL_CUT 0
+#define RGA_ALPHA_CAL_NORMAL 1
+
+#define RGA_ALPHA_FACTOR_ZERO 0
+#define RGA_ALPHA_FACTOR_ONE 1
+#define RGA_ALPHA_FACTOR_OTHER 2
+#define RGA_ALPHA_FACTOR_OTHER_REVERSE 3
+#define RGA_ALPHA_FACTOR_SELF 4
+
+#define RGA_ALPHA_COLOR_NORMAL 0
+#define RGA_ALPHA_COLOR_MULTIPLY_CAL 1
+
+/* Registers union */
+union rga_mode_ctrl {
+ unsigned int val;
+ struct {
+ /* [0:2] */
+ unsigned int render:3;
+ /* [3:6] */
+ unsigned int bitblt:1;
+ unsigned int cf_rop4_pat:1;
+ unsigned int alpha_zero_key:1;
+ unsigned int gradient_sat:1;
+ /* [7:31] */
+ unsigned int reserved:25;
+ } data;
+};
+
+union rga_src_info {
+ unsigned int val;
+ struct {
+ /* [0:3] */
+ unsigned int format:4;
+ /* [4:7] */
+ unsigned int swap:3;
+ unsigned int cp_endian:1;
+ /* [8:17] */
+ unsigned int csc_mode:2;
+ unsigned int rot_mode:2;
+ unsigned int mir_mode:2;
+ unsigned int hscl_mode:2;
+ unsigned int vscl_mode:2;
+ /* [18:22] */
+ unsigned int trans_mode:1;
+ unsigned int trans_enable:4;
+ /* [23:25] */
+ unsigned int dither_up_en:1;
+ unsigned int bic_coe_sel:2;
+ /* [26:31] */
+ unsigned int reserved:6;
+ } data;
+};
+
+union rga_src_vir_info {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int vir_width:15;
+ unsigned int reserved:1;
+ /* [16:25] */
+ unsigned int vir_stride:10;
+ /* [26:31] */
+ unsigned int reserved1:6;
+ } data;
+};
+
+union rga_src_act_info {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int act_width:13;
+ unsigned int reserved:3;
+ /* [16:31] */
+ unsigned int act_height:13;
+ unsigned int reserved1:3;
+ } data;
+};
+
+union rga_src_x_factor {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int down_scale_factor:16;
+ /* [16:31] */
+ unsigned int up_scale_factor:16;
+ } data;
+};
+
+union rga_src_y_factor {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int down_scale_factor:16;
+ /* [16:31] */
+ unsigned int up_scale_factor:16;
+ } data;
+};
+
+/* Alpha / Red / Green / Blue */
+union rga_src_cp_gr_color {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int gradient_x:16;
+ /* [16:31] */
+ unsigned int gradient_y:16;
+ } data;
+};
+
+union rga_src_transparency_color0 {
+ unsigned int val;
+ struct {
+ /* [0:7] */
+ unsigned int trans_rmin:8;
+ /* [8:15] */
+ unsigned int trans_gmin:8;
+ /* [16:23] */
+ unsigned int trans_bmin:8;
+ /* [24:31] */
+ unsigned int trans_amin:8;
+ } data;
+};
+
+union rga_src_transparency_color1 {
+ unsigned int val;
+ struct {
+ /* [0:7] */
+ unsigned int trans_rmax:8;
+ /* [8:15] */
+ unsigned int trans_gmax:8;
+ /* [16:23] */
+ unsigned int trans_bmax:8;
+ /* [24:31] */
+ unsigned int trans_amax:8;
+ } data;
+};
+
+union rga_dst_info {
+ unsigned int val;
+ struct {
+ /* [0:3] */
+ unsigned int format:4;
+ /* [4:6] */
+ unsigned int swap:3;
+ /* [7:9] */
+ unsigned int src1_format:3;
+ /* [10:11] */
+ unsigned int src1_swap:2;
+ /* [12:15] */
+ unsigned int dither_up_en:1;
+ unsigned int dither_down_en:1;
+ unsigned int dither_down_mode:2;
+ /* [16:18] */
+ unsigned int csc_mode:2;
+ unsigned int csc_clip:1;
+ /* [19:31] */
+ unsigned int reserved:13;
+ } data;
+};
+
+union rga_dst_vir_info {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int vir_stride:15;
+ unsigned int reserved:1;
+ /* [16:31] */
+ unsigned int src1_vir_stride:15;
+ unsigned int reserved1:1;
+ } data;
+};
+
+union rga_dst_act_info {
+ unsigned int val;
+ struct {
+ /* [0:15] */
+ unsigned int act_width:12;
+ unsigned int reserved:4;
+ /* [16:31] */
+ unsigned int act_height:12;
+ unsigned int reserved1:4;
+ } data;
+};
+
+union rga_alpha_ctrl0 {
+ unsigned int val;
+ struct {
+ /* [0:3] */
+ unsigned int rop_en:1;
+ unsigned int rop_select:1;
+ unsigned int rop_mode:2;
+ /* [4:11] */
+ unsigned int src_fading_val:8;
+ /* [12:20] */
+ unsigned int dst_fading_val:8;
+ unsigned int mask_endian:1;
+ /* [21:31] */
+ unsigned int reserved:11;
+ } data;
+};
+
+union rga_alpha_ctrl1 {
+ unsigned int val;
+ struct {
+ /* [0:1] */
+ unsigned int dst_color_m0:1;
+ unsigned int src_color_m0:1;
+ /* [2:7] */
+ unsigned int dst_factor_m0:3;
+ unsigned int src_factor_m0:3;
+ /* [8:9] */
+ unsigned int dst_alpha_cal_m0:1;
+ unsigned int src_alpha_cal_m0:1;
+ /* [10:13] */
+ unsigned int dst_blend_m0:2;
+ unsigned int src_blend_m0:2;
+ /* [14:15] */
+ unsigned int dst_alpha_m0:1;
+ unsigned int src_alpha_m0:1;
+ /* [16:21] */
+ unsigned int dst_factor_m1:3;
+ unsigned int src_factor_m1:3;
+ /* [22:23] */
+ unsigned int dst_alpha_cal_m1:1;
+ unsigned int src_alpha_cal_m1:1;
+ /* [24:27] */
+ unsigned int dst_blend_m1:2;
+ unsigned int src_blend_m1:2;
+ /* [28:29] */
+ unsigned int dst_alpha_m1:1;
+ unsigned int src_alpha_m1:1;
+ /* [30:31] */
+ unsigned int reserved:2;
+ } data;
+};
+
+union rga_fading_ctrl {
+ unsigned int val;
+ struct {
+ /* [0:7] */
+ unsigned int fading_offset_r:8;
+ /* [8:15] */
+ unsigned int fading_offset_g:8;
+ /* [16:23] */
+ unsigned int fading_offset_b:8;
+ /* [24:31] */
+ unsigned int fading_en:1;
+ unsigned int reserved:7;
+ } data;
+};
+
+union rga_pat_con {
+ unsigned int val;
+ struct {
+ /* [0:7] */
+ unsigned int width:8;
+ /* [8:15] */
+ unsigned int height:8;
+ /* [16:23] */
+ unsigned int offset_x:8;
+ /* [24:31] */
+ unsigned int offset_y:8;
+ } data;
+};
+
+#endif
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
new file mode 100644
index 000000000000..89296de9cf4a
--- /dev/null
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -0,0 +1,1010 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Jacob Chen <jacob-chen@iotwrt.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-sg.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "rga-hw.h"
+#include "rga.h"
+
+static int debug;
+module_param(debug, int, 0644);
+
+static void job_abort(void *prv)
+{
+ struct rga_ctx *ctx = prv;
+ struct rockchip_rga *rga = ctx->rga;
+
+ if (!rga->curr) /* No job currently running */
+ return;
+
+ wait_event_timeout(rga->irq_queue,
+ !rga->curr, msecs_to_jiffies(RGA_TIMEOUT));
+}
+
+static void device_run(void *prv)
+{
+ struct rga_ctx *ctx = prv;
+ struct rockchip_rga *rga = ctx->rga;
+ struct vb2_buffer *src, *dst;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rga->ctrl_lock, flags);
+
+ rga->curr = ctx;
+
+ src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+ rga_buf_map(src);
+ rga_buf_map(dst);
+
+ rga_hw_start(rga);
+
+ spin_unlock_irqrestore(&rga->ctrl_lock, flags);
+}
+
+static irqreturn_t rga_isr(int irq, void *prv)
+{
+ struct rockchip_rga *rga = prv;
+ int intr;
+
+ intr = rga_read(rga, RGA_INT) & 0xf;
+
+ rga_mod(rga, RGA_INT, intr << 4, 0xf << 4);
+
+ if (intr & 0x04) {
+ struct vb2_v4l2_buffer *src, *dst;
+ struct rga_ctx *ctx = rga->curr;
+
+ WARN_ON(!ctx);
+
+ rga->curr = NULL;
+
+ src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+
+ WARN_ON(!src);
+ WARN_ON(!dst);
+
+ dst->timecode = src->timecode;
+ dst->vb2_buf.timestamp = src->vb2_buf.timestamp;
+ dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+ dst->flags |= src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+
+ v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
+ v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx);
+
+ wake_up(&rga->irq_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct v4l2_m2m_ops rga_m2m_ops = {
+ .device_run = device_run,
+ .job_abort = job_abort,
+};
+
+static int
+queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+{
+ struct rga_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ src_vq->drv_priv = ctx;
+ src_vq->ops = &rga_qops;
+ src_vq->mem_ops = &vb2_dma_sg_memops;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &ctx->rga->mutex;
+ src_vq->dev = ctx->rga->v4l2_dev.dev;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ dst_vq->drv_priv = ctx;
+ dst_vq->ops = &rga_qops;
+ dst_vq->mem_ops = &vb2_dma_sg_memops;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &ctx->rga->mutex;
+ dst_vq->dev = ctx->rga->v4l2_dev.dev;
+
+ return vb2_queue_init(dst_vq);
+}
+
+static int rga_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct rga_ctx *ctx = container_of(ctrl->handler, struct rga_ctx,
+ ctrl_handler);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->rga->ctrl_lock, flags);
+ switch (ctrl->id) {
+ case V4L2_CID_HFLIP:
+ ctx->hflip = ctrl->val;
+ break;
+ case V4L2_CID_VFLIP:
+ ctx->vflip = ctrl->val;
+ break;
+ case V4L2_CID_ROTATE:
+ ctx->rotate = ctrl->val;
+ break;
+ case V4L2_CID_BG_COLOR:
+ ctx->fill_color = ctrl->val;
+ break;
+ }
+ spin_unlock_irqrestore(&ctx->rga->ctrl_lock, flags);
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops rga_ctrl_ops = {
+ .s_ctrl = rga_s_ctrl,
+};
+
+static int rga_setup_ctrls(struct rga_ctx *ctx)
+{
+ struct rockchip_rga *rga = ctx->rga;
+
+ v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
+
+ v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+ v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+ v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
+ V4L2_CID_ROTATE, 0, 270, 90, 0);
+
+ v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
+ V4L2_CID_BG_COLOR, 0, 0xffffffff, 1, 0);
+
+ if (ctx->ctrl_handler.error) {
+ int err = ctx->ctrl_handler.error;
+
+ v4l2_err(&rga->v4l2_dev, "%s failed\n", __func__);
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ return err;
+ }
+
+ return 0;
+}
+
+struct rga_fmt formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB32,
+ .color_swap = RGA_COLOR_RB_SWAP,
+ .hw_format = RGA_COLOR_FMT_ABGR8888,
+ .depth = 32,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_XRGB32,
+ .color_swap = RGA_COLOR_RB_SWAP,
+ .hw_format = RGA_COLOR_FMT_XBGR8888,
+ .depth = 32,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ABGR32,
+ .color_swap = RGA_COLOR_ALPHA_SWAP,
+ .hw_format = RGA_COLOR_FMT_ABGR8888,
+ .depth = 32,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_XBGR32,
+ .color_swap = RGA_COLOR_ALPHA_SWAP,
+ .hw_format = RGA_COLOR_FMT_XBGR8888,
+ .depth = 32,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_RGB24,
+ .color_swap = RGA_COLOR_NONE_SWAP,
+ .hw_format = RGA_COLOR_FMT_RGB888,
+ .depth = 24,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_BGR24,
+ .color_swap = RGA_COLOR_RB_SWAP,
+ .hw_format = RGA_COLOR_FMT_RGB888,
+ .depth = 24,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB444,
+ .color_swap = RGA_COLOR_RB_SWAP,
+ .hw_format = RGA_COLOR_FMT_ABGR4444,
+ .depth = 16,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB555,
+ .color_swap = RGA_COLOR_RB_SWAP,
+ .hw_format = RGA_COLOR_FMT_ABGR1555,
+ .depth = 16,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .color_swap = RGA_COLOR_RB_SWAP,
+ .hw_format = RGA_COLOR_FMT_BGR565,
+ .depth = 16,
+ .uv_factor = 1,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .color_swap = RGA_COLOR_UV_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV420SP,
+ .depth = 12,
+ .uv_factor = 4,
+ .y_div = 2,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV61,
+ .color_swap = RGA_COLOR_UV_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV422SP,
+ .depth = 16,
+ .uv_factor = 2,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .color_swap = RGA_COLOR_NONE_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV420SP,
+ .depth = 12,
+ .uv_factor = 4,
+ .y_div = 2,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV16,
+ .color_swap = RGA_COLOR_NONE_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV422SP,
+ .depth = 16,
+ .uv_factor = 2,
+ .y_div = 1,
+ .x_div = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .color_swap = RGA_COLOR_NONE_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV420P,
+ .depth = 12,
+ .uv_factor = 4,
+ .y_div = 2,
+ .x_div = 2,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .color_swap = RGA_COLOR_NONE_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV422P,
+ .depth = 16,
+ .uv_factor = 2,
+ .y_div = 1,
+ .x_div = 2,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU420,
+ .color_swap = RGA_COLOR_UV_SWAP,
+ .hw_format = RGA_COLOR_FMT_YUV420P,
+ .depth = 12,
+ .uv_factor = 4,
+ .y_div = 2,
+ .x_div = 2,
+ },
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static struct rga_fmt *rga_fmt_find(struct v4l2_format *f)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].fourcc == f->fmt.pix.pixelformat)
+ return &formats[i];
+ }
+ return NULL;
+}
+
+static struct rga_frame def_frame = {
+ .width = DEFAULT_WIDTH,
+ .height = DEFAULT_HEIGHT,
+ .colorspace = V4L2_COLORSPACE_DEFAULT,
+ .crop.left = 0,
+ .crop.top = 0,
+ .crop.width = DEFAULT_WIDTH,
+ .crop.height = DEFAULT_HEIGHT,
+ .fmt = &formats[0],
+};
+
+struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type)
+{
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ return &ctx->in;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return &ctx->out;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+}
+
+static int rga_open(struct file *file)
+{
+ struct rockchip_rga *rga = video_drvdata(file);
+ struct rga_ctx *ctx = NULL;
+ int ret = 0;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->rga = rga;
+ /* Set default formats */
+ ctx->in = def_frame;
+ ctx->out = def_frame;
+
+ if (mutex_lock_interruptible(&rga->mutex)) {
+ kfree(ctx);
+ return -ERESTARTSYS;
+ }
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rga->m2m_dev, ctx, &queue_init);
+ if (IS_ERR(ctx->fh.m2m_ctx)) {
+ ret = PTR_ERR(ctx->fh.m2m_ctx);
+ mutex_unlock(&rga->mutex);
+ kfree(ctx);
+ return ret;
+ }
+ v4l2_fh_init(&ctx->fh, video_devdata(file));
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ rga_setup_ctrls(ctx);
+
+ /* Write the default values to the ctx struct */
+ v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
+
+ ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+ mutex_unlock(&rga->mutex);
+
+ return 0;
+}
+
+static int rga_release(struct file *file)
+{
+ struct rga_ctx *ctx =
+ container_of(file->private_data, struct rga_ctx, fh);
+ struct rockchip_rga *rga = ctx->rga;
+
+ mutex_lock(&rga->mutex);
+
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ kfree(ctx);
+
+ mutex_unlock(&rga->mutex);
+
+ return 0;
+}
+
+static const struct v4l2_file_operations rga_fops = {
+ .owner = THIS_MODULE,
+ .open = rga_open,
+ .release = rga_release,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+};
+
+static int
+vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+ strlcpy(cap->driver, RGA_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, "rockchip-rga", sizeof(cap->card));
+ strlcpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info));
+
+ return 0;
+}
+
+static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
+{
+ struct rga_fmt *fmt;
+
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+
+ fmt = &formats[f->index];
+ f->pixelformat = fmt->fourcc;
+
+ return 0;
+}
+
+static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+ struct rga_ctx *ctx = prv;
+ struct vb2_queue *vq;
+ struct rga_frame *frm;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+ frm = rga_get_frame(ctx, f->type);
+ if (IS_ERR(frm))
+ return PTR_ERR(frm);
+
+ f->fmt.pix.width = frm->width;
+ f->fmt.pix.height = frm->height;
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+ f->fmt.pix.pixelformat = frm->fmt->fourcc;
+ f->fmt.pix.bytesperline = frm->stride;
+ f->fmt.pix.sizeimage = frm->size;
+ f->fmt.pix.colorspace = frm->colorspace;
+
+ return 0;
+}
+
+static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+ struct rga_fmt *fmt;
+
+ fmt = rga_fmt_find(f);
+ if (!fmt) {
+ fmt = &formats[0];
+ f->fmt.pix.pixelformat = fmt->fourcc;
+ }
+
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+
+ if (f->fmt.pix.width > MAX_WIDTH)
+ f->fmt.pix.width = MAX_WIDTH;
+ if (f->fmt.pix.height > MAX_HEIGHT)
+ f->fmt.pix.height = MAX_HEIGHT;
+
+ if (f->fmt.pix.width < MIN_WIDTH)
+ f->fmt.pix.width = MIN_WIDTH;
+ if (f->fmt.pix.height < MIN_HEIGHT)
+ f->fmt.pix.height = MIN_HEIGHT;
+
+ if (fmt->hw_format >= RGA_COLOR_FMT_YUV422SP)
+ f->fmt.pix.bytesperline = f->fmt.pix.width;
+ else
+ f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
+
+ f->fmt.pix.sizeimage =
+ f->fmt.pix.height * (f->fmt.pix.width * fmt->depth) >> 3;
+
+ return 0;
+}
+
+static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+ struct rga_ctx *ctx = prv;
+ struct rockchip_rga *rga = ctx->rga;
+ struct vb2_queue *vq;
+ struct rga_frame *frm;
+ struct rga_fmt *fmt;
+ int ret = 0;
+
+ /* Adjust all values accordingly to the hardware capabilities
+ * and chosen format.
+ */
+ ret = vidioc_try_fmt(file, prv, f);
+ if (ret)
+ return ret;
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (vb2_is_busy(vq)) {
+ v4l2_err(&rga->v4l2_dev, "queue (%d) bust\n", f->type);
+ return -EBUSY;
+ }
+ frm = rga_get_frame(ctx, f->type);
+ if (IS_ERR(frm))
+ return PTR_ERR(frm);
+ fmt = rga_fmt_find(f);
+ if (!fmt)
+ return -EINVAL;
+ frm->width = f->fmt.pix.width;
+ frm->height = f->fmt.pix.height;
+ frm->size = f->fmt.pix.sizeimage;
+ frm->fmt = fmt;
+ frm->stride = f->fmt.pix.bytesperline;
+ frm->colorspace = f->fmt.pix.colorspace;
+
+ /* Reset crop settings */
+ frm->crop.left = 0;
+ frm->crop.top = 0;
+ frm->crop.width = frm->width;
+ frm->crop.height = frm->height;
+
+ return 0;
+}
+
+static int vidioc_g_selection(struct file *file, void *prv,
+ struct v4l2_selection *s)
+{
+ struct rga_ctx *ctx = prv;
+ struct rga_frame *f;
+ bool use_frame = false;
+
+ f = rga_get_frame(ctx, s->type);
+ if (IS_ERR(f))
+ return PTR_ERR(f);
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ break;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ break;
+ case V4L2_SEL_TGT_COMPOSE:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ use_frame = true;
+ break;
+ case V4L2_SEL_TGT_CROP:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ use_frame = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (use_frame) {
+ s->r = f->crop;
+ } else {
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = f->width;
+ s->r.height = f->height;
+ }
+
+ return 0;
+}
+
+static int vidioc_s_selection(struct file *file, void *prv,
+ struct v4l2_selection *s)
+{
+ struct rga_ctx *ctx = prv;
+ struct rockchip_rga *rga = ctx->rga;
+ struct rga_frame *f;
+ int ret = 0;
+
+ f = rga_get_frame(ctx, s->type);
+ if (IS_ERR(f))
+ return PTR_ERR(f);
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_COMPOSE:
+ /*
+ * COMPOSE target is only valid for capture buffer type, return
+ * error for output buffer type
+ */
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ break;
+ case V4L2_SEL_TGT_CROP:
+ /*
+ * CROP target is only valid for output buffer type, return
+ * error for capture buffer type
+ */
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ break;
+ /*
+ * bound and default crop/compose targets are invalid targets to
+ * try/set
+ */
+ default:
+ return -EINVAL;
+ }
+
+ if (s->r.top < 0 || s->r.left < 0) {
+ v4l2_dbg(debug, 1, &rga->v4l2_dev,
+ "doesn't support negative values for top & left.\n");
+ return -EINVAL;
+ }
+
+ if (s->r.left + s->r.width > f->width ||
+ s->r.top + s->r.height > f->height ||
+ s->r.width < MIN_WIDTH || s->r.height < MIN_HEIGHT) {
+ v4l2_dbg(debug, 1, &rga->v4l2_dev, "unsupported crop value.\n");
+ return -EINVAL;
+ }
+
+ f->crop = s->r;
+
+ return ret;
+}
+
+static const struct v4l2_ioctl_ops rga_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
+
+ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt,
+ .vidioc_g_fmt_vid_out = vidioc_g_fmt,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt,
+ .vidioc_s_fmt_vid_out = vidioc_s_fmt,
+
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+
+ .vidioc_g_selection = vidioc_g_selection,
+ .vidioc_s_selection = vidioc_s_selection,
+};
+
+static struct video_device rga_videodev = {
+ .name = "rockchip-rga",
+ .fops = &rga_fops,
+ .ioctl_ops = &rga_ioctl_ops,
+ .minor = -1,
+ .release = video_device_release,
+ .vfl_dir = VFL_DIR_M2M,
+ .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
+};
+
+static int rga_enable_clocks(struct rockchip_rga *rga)
+{
+ int ret;
+
+ ret = clk_prepare_enable(rga->sclk);
+ if (ret) {
+ dev_err(rga->dev, "Cannot enable rga sclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(rga->aclk);
+ if (ret) {
+ dev_err(rga->dev, "Cannot enable rga aclk: %d\n", ret);
+ goto err_disable_sclk;
+ }
+
+ ret = clk_prepare_enable(rga->hclk);
+ if (ret) {
+ dev_err(rga->dev, "Cannot enable rga hclk: %d\n", ret);
+ goto err_disable_aclk;
+ }
+
+ return 0;
+
+err_disable_sclk:
+ clk_disable_unprepare(rga->sclk);
+err_disable_aclk:
+ clk_disable_unprepare(rga->aclk);
+
+ return ret;
+}
+
+static void rga_disable_clocks(struct rockchip_rga *rga)
+{
+ clk_disable_unprepare(rga->sclk);
+ clk_disable_unprepare(rga->hclk);
+ clk_disable_unprepare(rga->aclk);
+}
+
+static int rga_parse_dt(struct rockchip_rga *rga)
+{
+ struct reset_control *core_rst, *axi_rst, *ahb_rst;
+
+ core_rst = devm_reset_control_get(rga->dev, "core");
+ if (IS_ERR(core_rst)) {
+ dev_err(rga->dev, "failed to get core reset controller\n");
+ return PTR_ERR(core_rst);
+ }
+
+ axi_rst = devm_reset_control_get(rga->dev, "axi");
+ if (IS_ERR(axi_rst)) {
+ dev_err(rga->dev, "failed to get axi reset controller\n");
+ return PTR_ERR(axi_rst);
+ }
+
+ ahb_rst = devm_reset_control_get(rga->dev, "ahb");
+ if (IS_ERR(ahb_rst)) {
+ dev_err(rga->dev, "failed to get ahb reset controller\n");
+ return PTR_ERR(ahb_rst);
+ }
+
+ reset_control_assert(core_rst);
+ udelay(1);
+ reset_control_deassert(core_rst);
+
+ reset_control_assert(axi_rst);
+ udelay(1);
+ reset_control_deassert(axi_rst);
+
+ reset_control_assert(ahb_rst);
+ udelay(1);
+ reset_control_deassert(ahb_rst);
+
+ rga->sclk = devm_clk_get(rga->dev, "sclk");
+ if (IS_ERR(rga->sclk)) {
+ dev_err(rga->dev, "failed to get sclk clock\n");
+ return PTR_ERR(rga->sclk);
+ }
+
+ rga->aclk = devm_clk_get(rga->dev, "aclk");
+ if (IS_ERR(rga->aclk)) {
+ dev_err(rga->dev, "failed to get aclk clock\n");
+ return PTR_ERR(rga->aclk);
+ }
+
+ rga->hclk = devm_clk_get(rga->dev, "hclk");
+ if (IS_ERR(rga->hclk)) {
+ dev_err(rga->dev, "failed to get hclk clock\n");
+ return PTR_ERR(rga->hclk);
+ }
+
+ return 0;
+}
+
+static int rga_probe(struct platform_device *pdev)
+{
+ struct rockchip_rga *rga;
+ struct video_device *vfd;
+ struct resource *res;
+ int ret = 0;
+ int irq;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ rga = devm_kzalloc(&pdev->dev, sizeof(*rga), GFP_KERNEL);
+ if (!rga)
+ return -ENOMEM;
+
+ rga->dev = &pdev->dev;
+ spin_lock_init(&rga->ctrl_lock);
+ mutex_init(&rga->mutex);
+
+ init_waitqueue_head(&rga->irq_queue);
+
+ ret = rga_parse_dt(rga);
+ if (ret)
+ dev_err(&pdev->dev, "Unable to parse OF data\n");
+
+ pm_runtime_enable(rga->dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ rga->regs = devm_ioremap_resource(rga->dev, res);
+ if (IS_ERR(rga->regs)) {
+ ret = PTR_ERR(rga->regs);
+ goto err_put_clk;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(rga->dev, "failed to get irq\n");
+ ret = irq;
+ goto err_put_clk;
+ }
+
+ ret = devm_request_irq(rga->dev, irq, rga_isr, 0,
+ dev_name(rga->dev), rga);
+ if (ret < 0) {
+ dev_err(rga->dev, "failed to request irq\n");
+ goto err_put_clk;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &rga->v4l2_dev);
+ if (ret)
+ goto err_put_clk;
+ vfd = video_device_alloc();
+ if (!vfd) {
+ v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n");
+ ret = -ENOMEM;
+ goto unreg_v4l2_dev;
+ }
+ *vfd = rga_videodev;
+ vfd->lock = &rga->mutex;
+ vfd->v4l2_dev = &rga->v4l2_dev;
+
+ video_set_drvdata(vfd, rga);
+ snprintf(vfd->name, sizeof(vfd->name), "%s", rga_videodev.name);
+ rga->vfd = vfd;
+
+ platform_set_drvdata(pdev, rga);
+ rga->m2m_dev = v4l2_m2m_init(&rga_m2m_ops);
+ if (IS_ERR(rga->m2m_dev)) {
+ v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n");
+ ret = PTR_ERR(rga->m2m_dev);
+ goto unreg_video_dev;
+ }
+
+ pm_runtime_get_sync(rga->dev);
+
+ rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
+ rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
+
+ v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n",
+ rga->version.major, rga->version.minor);
+
+ pm_runtime_put(rga->dev);
+
+ /* Create CMD buffer */
+ rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE,
+ &rga->cmdbuf_phy, GFP_KERNEL,
+ DMA_ATTR_WRITE_COMBINE);
+
+ rga->src_mmu_pages =
+ (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
+ rga->dst_mmu_pages =
+ (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
+
+ def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
+ def_frame.size = def_frame.stride * def_frame.height;
+
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+ if (ret) {
+ v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
+ goto rel_vdev;
+ }
+
+ v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n",
+ vfd->name, video_device_node_name(vfd));
+
+ return 0;
+
+rel_vdev:
+ video_device_release(vfd);
+unreg_video_dev:
+ video_unregister_device(rga->vfd);
+unreg_v4l2_dev:
+ v4l2_device_unregister(&rga->v4l2_dev);
+err_put_clk:
+ pm_runtime_disable(rga->dev);
+
+ return ret;
+}
+
+static int rga_remove(struct platform_device *pdev)
+{
+ struct rockchip_rga *rga = platform_get_drvdata(pdev);
+
+ dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, &rga->cmdbuf_virt,
+ rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
+
+ free_pages((unsigned long)rga->src_mmu_pages, 3);
+ free_pages((unsigned long)rga->dst_mmu_pages, 3);
+
+ v4l2_info(&rga->v4l2_dev, "Removing\n");
+
+ v4l2_m2m_release(rga->m2m_dev);
+ video_unregister_device(rga->vfd);
+ v4l2_device_unregister(&rga->v4l2_dev);
+
+ pm_runtime_disable(rga->dev);
+
+ return 0;
+}
+
+static int __maybe_unused rga_runtime_suspend(struct device *dev)
+{
+ struct rockchip_rga *rga = dev_get_drvdata(dev);
+
+ rga_disable_clocks(rga);
+
+ return 0;
+}
+
+static int __maybe_unused rga_runtime_resume(struct device *dev)
+{
+ struct rockchip_rga *rga = dev_get_drvdata(dev);
+
+ return rga_enable_clocks(rga);
+}
+
+static const struct dev_pm_ops rga_pm = {
+ SET_RUNTIME_PM_OPS(rga_runtime_suspend,
+ rga_runtime_resume, NULL)
+};
+
+static const struct of_device_id rockchip_rga_match[] = {
+ {
+ .compatible = "rockchip,rk3288-rga",
+ },
+ {
+ .compatible = "rockchip,rk3399-rga",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, rockchip_rga_match);
+
+static struct platform_driver rga_pdrv = {
+ .probe = rga_probe,
+ .remove = rga_remove,
+ .driver = {
+ .name = RGA_NAME,
+ .pm = &rga_pm,
+ .of_match_table = rockchip_rga_match,
+ },
+};
+
+module_platform_driver(rga_pdrv);
+
+MODULE_AUTHOR("Jacob Chen <jacob-chen@iotwrt.com>");
+MODULE_DESCRIPTION("Rockchip Raster 2d Graphic Acceleration Unit");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
new file mode 100644
index 000000000000..5d43e7ea88af
--- /dev/null
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Jacob Chen <jacob-chen@iotwrt.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+#ifndef __RGA_H__
+#define __RGA_H__
+
+#include <linux/platform_device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+
+#define RGA_NAME "rockchip-rga"
+
+struct rga_fmt {
+ u32 fourcc;
+ int depth;
+ u8 uv_factor;
+ u8 y_div;
+ u8 x_div;
+ u8 color_swap;
+ u8 hw_format;
+};
+
+struct rga_frame {
+ /* Original dimensions */
+ u32 width;
+ u32 height;
+ u32 colorspace;
+
+ /* Crop */
+ struct v4l2_rect crop;
+
+ /* Image format */
+ struct rga_fmt *fmt;
+
+ /* Variables that can calculated once and reused */
+ u32 stride;
+ u32 size;
+};
+
+struct rockchip_rga_version {
+ u32 major;
+ u32 minor;
+};
+
+struct rga_ctx {
+ struct v4l2_fh fh;
+ struct rockchip_rga *rga;
+ struct rga_frame in;
+ struct rga_frame out;
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ /* Control values */
+ u32 op;
+ u32 hflip;
+ u32 vflip;
+ u32 rotate;
+ u32 fill_color;
+};
+
+struct rockchip_rga {
+ struct v4l2_device v4l2_dev;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct video_device *vfd;
+
+ struct device *dev;
+ struct regmap *grf;
+ void __iomem *regs;
+ struct clk *sclk;
+ struct clk *aclk;
+ struct clk *hclk;
+ struct rockchip_rga_version version;
+
+ /* vfd lock */
+ struct mutex mutex;
+ /* ctrl parm lock */
+ spinlock_t ctrl_lock;
+
+ wait_queue_head_t irq_queue;
+
+ struct rga_ctx *curr;
+ dma_addr_t cmdbuf_phy;
+ void *cmdbuf_virt;
+ unsigned int *src_mmu_pages;
+ unsigned int *dst_mmu_pages;
+};
+
+struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type);
+
+/* RGA Buffers Manage */
+extern const struct vb2_ops rga_qops;
+void rga_buf_map(struct vb2_buffer *vb);
+
+/* RGA Hardware */
+static inline void rga_write(struct rockchip_rga *rga, u32 reg, u32 value)
+{
+ writel(value, rga->regs + reg);
+};
+
+static inline u32 rga_read(struct rockchip_rga *rga, u32 reg)
+{
+ return readl(rga->regs + reg);
+};
+
+static inline void rga_mod(struct rockchip_rga *rga, u32 reg, u32 val, u32 mask)
+{
+ u32 temp = rga_read(rga, reg) & ~(mask);
+
+ temp |= val & mask;
+ rga_write(rga, reg, temp);
+};
+
+void rga_hw_start(struct rockchip_rga *rga);
+
+#endif
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index c4ab63986c8f..79bc0ef6bb41 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -103,6 +103,7 @@ static const struct camif_fmt camif_formats[] = {
/**
* s3c_camif_find_format() - lookup camif color format by fourcc or an index
+ * @vp: video path (DMA) description (codec/preview)
* @pixelformat: fourcc to match, ignored if null
* @index: index to the camif_formats array, ignored if negative
*/
diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile
index 15f59b324fef..0b324af2ab00 100644
--- a/drivers/media/platform/s5p-mfc/Makefile
+++ b/drivers/media/platform/s5p-mfc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc.o
s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o
s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 1afde5021ca6..bc68dbbcaec1 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -145,9 +145,9 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
}
}
-static void s5p_mfc_watchdog(unsigned long arg)
+static void s5p_mfc_watchdog(struct timer_list *t)
{
- struct s5p_mfc_dev *dev = (struct s5p_mfc_dev *)arg;
+ struct s5p_mfc_dev *dev = from_timer(dev, t, watchdog_timer);
if (test_bit(0, &dev->hw_lock))
atomic_inc(&dev->watchdog_cnt);
@@ -470,7 +470,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
{
mfc_err("Interrupt Error: %08x\n", err);
- if (ctx != NULL) {
+ if (ctx) {
/* Error recovery is dependent on the state of context */
switch (ctx->state) {
case MFCINST_RES_CHANGE_INIT:
@@ -508,7 +508,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
{
struct s5p_mfc_dev *dev;
- if (ctx == NULL)
+ if (!ctx)
return;
dev = ctx->dev;
if (ctx->c_ops->post_seq_start) {
@@ -562,7 +562,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
struct s5p_mfc_buf *src_buf;
struct s5p_mfc_dev *dev;
- if (ctx == NULL)
+ if (!ctx)
return;
dev = ctx->dev;
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
@@ -1043,12 +1043,9 @@ end:
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_dev *dev = ctx->dev;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
int ret;
- if (mutex_lock_interruptible(&dev->mfc_mutex))
- return -ERESTARTSYS;
if (offset < DST_QUEUE_OFF_BASE) {
mfc_debug(2, "mmaping source\n");
ret = vb2_mmap(&ctx->vq_src, vma);
@@ -1057,7 +1054,6 @@ static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
ret = vb2_mmap(&ctx->vq_dst, vma);
}
- mutex_unlock(&dev->mfc_mutex);
return ret;
}
@@ -1083,7 +1079,7 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev,
struct device *child;
int ret;
- child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
+ child = devm_kzalloc(dev, sizeof(*child), GFP_KERNEL);
if (!child)
return NULL;
@@ -1270,10 +1266,8 @@ static int s5p_mfc_probe(struct platform_device *pdev)
pr_debug("%s++\n", __func__);
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- dev_err(&pdev->dev, "Not enough memory for MFC device\n");
+ if (!dev)
return -ENOMEM;
- }
spin_lock_init(&dev->irqlock);
spin_lock_init(&dev->condlock);
@@ -1291,7 +1285,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
return PTR_ERR(dev->regs_base);
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
+ if (!res) {
dev_err(&pdev->dev, "failed to get irq resource\n");
return -ENOENT;
}
@@ -1320,9 +1314,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
dev->hw_lock = 0;
INIT_WORK(&dev->watchdog_work, s5p_mfc_watchdog_worker);
atomic_set(&dev->watchdog_cnt, 0);
- init_timer(&dev->watchdog_timer);
- dev->watchdog_timer.data = (unsigned long)dev;
- dev->watchdog_timer.function = s5p_mfc_watchdog;
+ timer_setup(&dev->watchdog_timer, s5p_mfc_watchdog, 0);
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret)
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index 15a562af13c7..dedc1b024f6f 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -267,7 +267,7 @@ static void sh_veu_process(struct sh_veu_dev *veu,
sh_veu_reg_write(veu, VEU_EIER, 1); /* enable interrupt in VEU */
}
-/**
+/*
* sh_veu_device_run() - prepares and starts the device
*
* This will be called by the framework when it decides to schedule a particular
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 1f3c450c7a69..916ff68b73d4 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -1391,6 +1391,12 @@ static int soc_camera_async_complete(struct v4l2_async_notifier *notifier)
return 0;
}
+static const struct v4l2_async_notifier_operations soc_camera_async_ops = {
+ .bound = soc_camera_async_bound,
+ .unbind = soc_camera_async_unbind,
+ .complete = soc_camera_async_complete,
+};
+
static int scan_async_group(struct soc_camera_host *ici,
struct v4l2_async_subdev **asd, unsigned int size)
{
@@ -1437,9 +1443,7 @@ static int scan_async_group(struct soc_camera_host *ici,
sasc->notifier.subdevs = asd;
sasc->notifier.num_subdevs = size;
- sasc->notifier.bound = soc_camera_async_bound;
- sasc->notifier.unbind = soc_camera_async_unbind;
- sasc->notifier.complete = soc_camera_async_complete;
+ sasc->notifier.ops = &soc_camera_async_ops;
icd->sasc = sasc;
icd->parent = ici->v4l2_dev.dev;
@@ -1537,9 +1541,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
sasc->notifier.subdevs = &info->subdev;
sasc->notifier.num_subdevs = 1;
- sasc->notifier.bound = soc_camera_async_bound;
- sasc->notifier.unbind = soc_camera_async_unbind;
- sasc->notifier.complete = soc_camera_async_complete;
+ sasc->notifier.ops = &soc_camera_async_ops;
icd->sasc = sasc;
icd->parent = ici->v4l2_dev.dev;
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
index 0116097c0c0f..270ec613c27c 100644
--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -306,16 +306,17 @@ update_cache:
}
/**
- * @icd - soc-camera device
- * @rect - camera cropping window
- * @subrect - part of rect, sent to the user
- * @mf - in- / output camera output window
- * @width - on input: max host input width
- * on output: user width, mapped back to input
- * @height - on input: max host input height
- * on output: user height, mapped back to input
- * @host_can_scale - host can scale this pixel format
- * @shift - shift, used for scaling
+ * soc_camera_client_scale
+ * @icd: soc-camera device
+ * @rect: camera cropping window
+ * @subrect: part of rect, sent to the user
+ * @mf: in- / output camera output window
+ * @width: on input: max host input width;
+ * on output: user width, mapped back to input
+ * @height: on input: max host input height;
+ * on output: user height, mapped back to input
+ * @host_can_scale: host can scale this pixel format
+ * @shift: shift, used for scaling
*/
int soc_camera_client_scale(struct soc_camera_device *icd,
struct v4l2_rect *rect, struct v4l2_rect *subrect,
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index 939da6da7644..7e9ed9c7b3e1 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -723,7 +723,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 v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_pix_format *pix;
struct bdisp_frame *frame = ctx_get_frame(ctx, f->type);
if (IS_ERR(frame)) {
diff --git a/drivers/media/platform/sti/c8sectpfe/Makefile b/drivers/media/platform/sti/c8sectpfe/Makefile
index b578c7cb4c34..b642b4fd5045 100644
--- a/drivers/media/platform/sti/c8sectpfe/Makefile
+++ b/drivers/media/platform/sti/c8sectpfe/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
c8sectpfe-y += c8sectpfe-core.o c8sectpfe-common.o c8sectpfe-dvb.o \
c8sectpfe-debugfs.o
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 59280ac31937..a0acee7671b1 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -61,9 +61,9 @@ static int load_c8sectpfe_fw(struct c8sectpfei *fei);
#define FIFO_LEN 1024
-static void c8sectpfe_timer_interrupt(unsigned long ac8sectpfei)
+static void c8sectpfe_timer_interrupt(struct timer_list *t)
{
- struct c8sectpfei *fei = (struct c8sectpfei *)ac8sectpfei;
+ struct c8sectpfei *fei = from_timer(fei, t, timer);
struct channel_info *channel;
int chan_num;
@@ -865,8 +865,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
}
/* Setup timer interrupt */
- setup_timer(&fei->timer, c8sectpfe_timer_interrupt,
- (unsigned long)fei);
+ timer_setup(&fei->timer, c8sectpfe_timer_interrupt, 0);
mutex_init(&fei->lock);
diff --git a/drivers/media/platform/sti/hva/hva-h264.c b/drivers/media/platform/sti/hva/hva-h264.c
index e6f247a983c7..17f1eb0ba957 100644
--- a/drivers/media/platform/sti/hva/hva-h264.c
+++ b/drivers/media/platform/sti/hva/hva-h264.c
@@ -134,7 +134,7 @@ enum hva_h264_sei_payload_type {
SEI_FRAME_PACKING_ARRANGEMENT = 45
};
-/**
+/*
* stereo Video Info struct
*/
struct hva_h264_stereo_video_sei {
@@ -146,7 +146,9 @@ struct hva_h264_stereo_video_sei {
u8 right_view_self_contained_flag;
};
-/**
+/*
+ * struct hva_h264_td
+ *
* @frame_width: width in pixels of the buffer containing the input frame
* @frame_height: height in pixels of the buffer containing the input frame
* @frame_num: the parameter to be written in the slice header
@@ -352,7 +354,9 @@ struct hva_h264_td {
u32 addr_brc_in_out_parameter;
};
-/**
+/*
+ * struct hva_h264_slice_po
+ *
* @ slice_size: slice size
* @ slice_start_time: start time
* @ slice_stop_time: stop time
@@ -365,7 +369,9 @@ struct hva_h264_slice_po {
u32 slice_num;
};
-/**
+/*
+ * struct hva_h264_po
+ *
* @ bitstream_size: bitstream size
* @ dct_bitstream_size: dtc bitstream size
* @ stuffing_bits: number of stuffing bits inserted by the encoder
@@ -391,7 +397,9 @@ struct hva_h264_task {
struct hva_h264_po po;
};
-/**
+/*
+ * struct hva_h264_ctx
+ *
* @seq_info: sequence information buffer
* @ref_frame: reference frame buffer
* @rec_frame: reconstructed frame buffer
@@ -999,7 +1007,6 @@ static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame,
{
struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
struct hva_h264_task *task = (struct hva_h264_task *)ctx->task->vaddr;
- struct hva_buffer *tmp_frame;
u32 stuffing_bytes = 0;
int ret = 0;
@@ -1023,9 +1030,7 @@ static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame,
&stream->bytesused);
/* switch reference & reconstructed frame */
- tmp_frame = ctx->ref_frame;
- ctx->ref_frame = ctx->rec_frame;
- ctx->rec_frame = tmp_frame;
+ swap(ctx->ref_frame, ctx->rec_frame);
return 0;
err:
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index 35ba6f211b79..ac4c450a6c7d 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -1495,6 +1495,12 @@ static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier,
return 0;
}
+static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = {
+ .bound = dcmi_graph_notify_bound,
+ .unbind = dcmi_graph_notify_unbind,
+ .complete = dcmi_graph_notify_complete,
+};
+
static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
{
struct device_node *ep = NULL;
@@ -1542,9 +1548,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
dcmi->notifier.subdevs = subdevs;
dcmi->notifier.num_subdevs = 1;
- dcmi->notifier.bound = dcmi_graph_notify_bound;
- dcmi->notifier.unbind = dcmi_graph_notify_unbind;
- dcmi->notifier.complete = dcmi_graph_notify_complete;
+ dcmi->notifier.ops = &dcmi_graph_notify_ops;
ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier);
if (ret < 0) {
diff --git a/drivers/media/platform/tegra-cec/Makefile b/drivers/media/platform/tegra-cec/Makefile
new file mode 100644
index 000000000000..f3d81127589f
--- /dev/null
+++ b/drivers/media/platform/tegra-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC) += tegra_cec.o
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c
new file mode 100644
index 000000000000..807c94c70049
--- /dev/null
+++ b/drivers/media/platform/tegra-cec/tegra_cec.c
@@ -0,0 +1,495 @@
+/*
+ * Tegra CEC implementation
+ *
+ * The original 3.10 CEC driver using a custom API:
+ *
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Conversion to the CEC framework and to the mainline kernel:
+ *
+ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/clk/tegra.h>
+
+#include <media/cec-notifier.h>
+
+#include "tegra_cec.h"
+
+#define TEGRA_CEC_NAME "tegra-cec"
+
+struct tegra_cec {
+ struct cec_adapter *adap;
+ struct device *dev;
+ struct clk *clk;
+ void __iomem *cec_base;
+ struct cec_notifier *notifier;
+ int tegra_cec_irq;
+ bool rx_done;
+ bool tx_done;
+ int tx_status;
+ u8 rx_buf[CEC_MAX_MSG_SIZE];
+ u8 rx_buf_cnt;
+ u32 tx_buf[CEC_MAX_MSG_SIZE];
+ u8 tx_buf_cur;
+ u8 tx_buf_cnt;
+};
+
+static inline u32 cec_read(struct tegra_cec *cec, u32 reg)
+{
+ return readl(cec->cec_base + reg);
+}
+
+static inline void cec_write(struct tegra_cec *cec, u32 reg, u32 val)
+{
+ writel(val, cec->cec_base + reg);
+}
+
+static void tegra_cec_error_recovery(struct tegra_cec *cec)
+{
+ u32 hw_ctrl;
+
+ hw_ctrl = cec_read(cec, TEGRA_CEC_HW_CONTROL);
+ cec_write(cec, TEGRA_CEC_HW_CONTROL, 0);
+ cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff);
+ cec_write(cec, TEGRA_CEC_HW_CONTROL, hw_ctrl);
+}
+
+static irqreturn_t tegra_cec_irq_thread_handler(int irq, void *data)
+{
+ struct device *dev = data;
+ struct tegra_cec *cec = dev_get_drvdata(dev);
+
+ if (cec->tx_done) {
+ cec_transmit_attempt_done(cec->adap, cec->tx_status);
+ cec->tx_done = false;
+ }
+ if (cec->rx_done) {
+ struct cec_msg msg = {};
+
+ msg.len = cec->rx_buf_cnt;
+ memcpy(msg.msg, cec->rx_buf, msg.len);
+ cec_received_msg(cec->adap, &msg);
+ cec->rx_done = false;
+ cec->rx_buf_cnt = 0;
+ }
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
+{
+ struct device *dev = data;
+ struct tegra_cec *cec = dev_get_drvdata(dev);
+ u32 status, mask;
+
+ status = cec_read(cec, TEGRA_CEC_INT_STAT);
+ mask = cec_read(cec, TEGRA_CEC_INT_MASK);
+
+ status &= mask;
+
+ if (!status)
+ return IRQ_HANDLED;
+
+ if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN) {
+ dev_err(dev, "TX underrun, interrupt timing issue!\n");
+
+ tegra_cec_error_recovery(cec);
+ cec_write(cec, TEGRA_CEC_INT_MASK,
+ mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+
+ cec->tx_done = true;
+ cec->tx_status = CEC_TX_STATUS_ERROR;
+ return IRQ_WAKE_THREAD;
+ }
+
+ if ((status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) ||
+ (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) {
+ tegra_cec_error_recovery(cec);
+ cec_write(cec, TEGRA_CEC_INT_MASK,
+ mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+
+ cec->tx_done = true;
+ if (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)
+ cec->tx_status = CEC_TX_STATUS_LOW_DRIVE;
+ else
+ cec->tx_status = CEC_TX_STATUS_ARB_LOST;
+ return IRQ_WAKE_THREAD;
+ }
+
+ if (status & TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED) {
+ cec_write(cec, TEGRA_CEC_INT_STAT,
+ TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED);
+
+ if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) {
+ tegra_cec_error_recovery(cec);
+
+ cec->tx_done = true;
+ cec->tx_status = CEC_TX_STATUS_NACK;
+ } else {
+ cec->tx_done = true;
+ cec->tx_status = CEC_TX_STATUS_OK;
+ }
+ return IRQ_WAKE_THREAD;
+ }
+
+ if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD)
+ dev_warn(dev, "TX NAKed on the fly!\n");
+
+ if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY) {
+ if (cec->tx_buf_cur == cec->tx_buf_cnt) {
+ cec_write(cec, TEGRA_CEC_INT_MASK,
+ mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+ } else {
+ cec_write(cec, TEGRA_CEC_TX_REGISTER,
+ cec->tx_buf[cec->tx_buf_cur++]);
+ cec_write(cec, TEGRA_CEC_INT_STAT,
+ TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY);
+ }
+ }
+
+ if (status & (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
+ TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
+ TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
+ TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)) {
+ cec_write(cec, TEGRA_CEC_INT_STAT,
+ (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
+ TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
+ TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
+ TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED));
+ } else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
+ u32 v;
+
+ cec_write(cec, TEGRA_CEC_INT_STAT,
+ TEGRA_CEC_INT_STAT_RX_REGISTER_FULL);
+ v = cec_read(cec, TEGRA_CEC_RX_REGISTER);
+ if (cec->rx_buf_cnt < CEC_MAX_MSG_SIZE)
+ cec->rx_buf[cec->rx_buf_cnt++] = v & 0xff;
+ if (v & TEGRA_CEC_RX_REGISTER_EOM) {
+ cec->rx_done = true;
+ return IRQ_WAKE_THREAD;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct tegra_cec *cec = adap->priv;
+
+ cec->rx_buf_cnt = 0;
+ cec->tx_buf_cnt = 0;
+ cec->tx_buf_cur = 0;
+
+ cec_write(cec, TEGRA_CEC_HW_CONTROL, 0);
+ cec_write(cec, TEGRA_CEC_INT_MASK, 0);
+ cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff);
+ cec_write(cec, TEGRA_CEC_SW_CONTROL, 0);
+
+ if (!enable)
+ return 0;
+
+ cec_write(cec, TEGRA_CEC_INPUT_FILTER, (1U << 31) | 0x20);
+
+ cec_write(cec, TEGRA_CEC_RX_TIMING_0,
+ (0x7a << TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT) |
+ (0x6d << TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT) |
+ (0x93 << TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT) |
+ (0x86 << TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT));
+
+ cec_write(cec, TEGRA_CEC_RX_TIMING_1,
+ (0x35 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT) |
+ (0x21 << TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT) |
+ (0x56 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT) |
+ (0x40 << TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT));
+
+ cec_write(cec, TEGRA_CEC_RX_TIMING_2,
+ (0x50 << TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT));
+
+ cec_write(cec, TEGRA_CEC_TX_TIMING_0,
+ (0x74 << TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT) |
+ (0x8d << TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT) |
+ (0x08 << TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT) |
+ (0x71 << TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT));
+
+ cec_write(cec, TEGRA_CEC_TX_TIMING_1,
+ (0x2f << TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT) |
+ (0x13 << TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT) |
+ (0x4b << TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT) |
+ (0x21 << TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT));
+
+ cec_write(cec, TEGRA_CEC_TX_TIMING_2,
+ (0x07 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT) |
+ (0x05 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT) |
+ (0x03 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT));
+
+ cec_write(cec, TEGRA_CEC_INT_MASK,
+ TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
+ TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
+ TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
+ TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
+ TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
+ TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
+ TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN);
+
+ cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE);
+ return 0;
+}
+
+static int tegra_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+ struct tegra_cec *cec = adap->priv;
+ u32 state = cec_read(cec, TEGRA_CEC_HW_CONTROL);
+
+ if (logical_addr == CEC_LOG_ADDR_INVALID)
+ state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK;
+ else
+ state |= TEGRA_CEC_HWCTRL_RX_LADDR((1 << logical_addr));
+
+ cec_write(cec, TEGRA_CEC_HW_CONTROL, state);
+ return 0;
+}
+
+static int tegra_cec_adap_monitor_all_enable(struct cec_adapter *adap,
+ bool enable)
+{
+ struct tegra_cec *cec = adap->priv;
+ u32 reg = cec_read(cec, TEGRA_CEC_HW_CONTROL);
+
+ if (enable)
+ reg |= TEGRA_CEC_HWCTRL_RX_SNOOP;
+ else
+ reg &= ~TEGRA_CEC_HWCTRL_RX_SNOOP;
+ cec_write(cec, TEGRA_CEC_HW_CONTROL, reg);
+ return 0;
+}
+
+static int tegra_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time_ms, struct cec_msg *msg)
+{
+ bool retry_xfer = signal_free_time_ms == CEC_SIGNAL_FREE_TIME_RETRY;
+ struct tegra_cec *cec = adap->priv;
+ unsigned int i;
+ u32 mode = 0;
+ u32 mask;
+
+ if (cec_msg_is_broadcast(msg))
+ mode = TEGRA_CEC_TX_REG_BCAST;
+
+ cec->tx_buf_cur = 0;
+ cec->tx_buf_cnt = msg->len;
+
+ for (i = 0; i < msg->len; i++) {
+ cec->tx_buf[i] = mode | msg->msg[i];
+ if (i == 0)
+ cec->tx_buf[i] |= TEGRA_CEC_TX_REG_START_BIT;
+ if (i == msg->len - 1)
+ cec->tx_buf[i] |= TEGRA_CEC_TX_REG_EOM;
+ if (i == 0 && retry_xfer)
+ cec->tx_buf[i] |= TEGRA_CEC_TX_REG_RETRY;
+ }
+
+ mask = cec_read(cec, TEGRA_CEC_INT_MASK);
+ cec_write(cec, TEGRA_CEC_INT_MASK,
+ mask | TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY);
+
+ return 0;
+}
+
+static const struct cec_adap_ops tegra_cec_ops = {
+ .adap_enable = tegra_cec_adap_enable,
+ .adap_log_addr = tegra_cec_adap_log_addr,
+ .adap_transmit = tegra_cec_adap_transmit,
+ .adap_monitor_all_enable = tegra_cec_adap_monitor_all_enable,
+};
+
+static int tegra_cec_probe(struct platform_device *pdev)
+{
+ struct platform_device *hdmi_dev;
+ struct device_node *np;
+ struct tegra_cec *cec;
+ struct resource *res;
+ int ret = 0;
+
+ np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0);
+
+ if (!np) {
+ dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n");
+ return -ENODEV;
+ }
+ hdmi_dev = of_find_device_by_node(np);
+ if (hdmi_dev == NULL)
+ return -EPROBE_DEFER;
+
+ cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
+
+ if (!cec)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res) {
+ dev_err(&pdev->dev,
+ "Unable to allocate resources for device\n");
+ return -EBUSY;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+ pdev->name)) {
+ dev_err(&pdev->dev,
+ "Unable to request mem region for device\n");
+ return -EBUSY;
+ }
+
+ cec->tegra_cec_irq = platform_get_irq(pdev, 0);
+
+ if (cec->tegra_cec_irq <= 0)
+ return -EBUSY;
+
+ cec->cec_base = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
+
+ if (!cec->cec_base) {
+ dev_err(&pdev->dev, "Unable to grab IOs for device\n");
+ return -EBUSY;
+ }
+
+ cec->clk = devm_clk_get(&pdev->dev, "cec");
+
+ if (IS_ERR_OR_NULL(cec->clk)) {
+ dev_err(&pdev->dev, "Can't get clock for CEC\n");
+ return -ENOENT;
+ }
+
+ clk_prepare_enable(cec->clk);
+
+ /* set context info. */
+ cec->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, cec);
+
+ ret = devm_request_threaded_irq(&pdev->dev, cec->tegra_cec_irq,
+ tegra_cec_irq_handler, tegra_cec_irq_thread_handler,
+ 0, "cec_irq", &pdev->dev);
+
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Unable to request interrupt for device\n");
+ goto clk_error;
+ }
+
+ cec->notifier = cec_notifier_get(&hdmi_dev->dev);
+ if (!cec->notifier) {
+ ret = -ENOMEM;
+ goto clk_error;
+ }
+
+ cec->adap = cec_allocate_adapter(&tegra_cec_ops, cec, TEGRA_CEC_NAME,
+ CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL,
+ CEC_MAX_LOG_ADDRS);
+ if (IS_ERR(cec->adap)) {
+ ret = -ENOMEM;
+ dev_err(&pdev->dev, "Couldn't create cec adapter\n");
+ goto cec_error;
+ }
+ ret = cec_register_adapter(cec->adap, &pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Couldn't register device\n");
+ goto cec_error;
+ }
+
+ cec_register_cec_notifier(cec->adap, cec->notifier);
+
+ return 0;
+
+cec_error:
+ if (cec->notifier)
+ cec_notifier_put(cec->notifier);
+ cec_delete_adapter(cec->adap);
+clk_error:
+ clk_disable_unprepare(cec->clk);
+ return ret;
+}
+
+static int tegra_cec_remove(struct platform_device *pdev)
+{
+ struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(cec->clk);
+
+ cec_unregister_adapter(cec->adap);
+ cec_notifier_put(cec->notifier);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(cec->clk);
+
+ dev_notice(&pdev->dev, "suspended\n");
+ return 0;
+}
+
+static int tegra_cec_resume(struct platform_device *pdev)
+{
+ struct tegra_cec *cec = platform_get_drvdata(pdev);
+
+ dev_notice(&pdev->dev, "Resuming\n");
+
+ clk_prepare_enable(cec->clk);
+
+ return 0;
+}
+#endif
+
+static const struct of_device_id tegra_cec_of_match[] = {
+ { .compatible = "nvidia,tegra114-cec", },
+ { .compatible = "nvidia,tegra124-cec", },
+ { .compatible = "nvidia,tegra210-cec", },
+ {},
+};
+
+static struct platform_driver tegra_cec_driver = {
+ .driver = {
+ .name = TEGRA_CEC_NAME,
+ .of_match_table = of_match_ptr(tegra_cec_of_match),
+ },
+ .probe = tegra_cec_probe,
+ .remove = tegra_cec_remove,
+
+#ifdef CONFIG_PM
+ .suspend = tegra_cec_suspend,
+ .resume = tegra_cec_resume,
+#endif
+};
+
+module_platform_driver(tegra_cec_driver);
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.h b/drivers/media/platform/tegra-cec/tegra_cec.h
new file mode 100644
index 000000000000..e301513daa87
--- /dev/null
+++ b/drivers/media/platform/tegra-cec/tegra_cec.h
@@ -0,0 +1,127 @@
+/*
+ * Tegra CEC register definitions
+ *
+ * The original 3.10 CEC driver using a custom API:
+ *
+ * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Conversion to the CEC framework and to the mainline kernel:
+ *
+ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TEGRA_CEC_H
+#define TEGRA_CEC_H
+
+/* CEC registers */
+#define TEGRA_CEC_SW_CONTROL 0x000
+#define TEGRA_CEC_HW_CONTROL 0x004
+#define TEGRA_CEC_INPUT_FILTER 0x008
+#define TEGRA_CEC_TX_REGISTER 0x010
+#define TEGRA_CEC_RX_REGISTER 0x014
+#define TEGRA_CEC_RX_TIMING_0 0x018
+#define TEGRA_CEC_RX_TIMING_1 0x01c
+#define TEGRA_CEC_RX_TIMING_2 0x020
+#define TEGRA_CEC_TX_TIMING_0 0x024
+#define TEGRA_CEC_TX_TIMING_1 0x028
+#define TEGRA_CEC_TX_TIMING_2 0x02c
+#define TEGRA_CEC_INT_STAT 0x030
+#define TEGRA_CEC_INT_MASK 0x034
+#define TEGRA_CEC_HW_DEBUG_RX 0x038
+#define TEGRA_CEC_HW_DEBUG_TX 0x03c
+
+#define TEGRA_CEC_HWCTRL_RX_LADDR_MASK 0x7fff
+#define TEGRA_CEC_HWCTRL_RX_LADDR(x) \
+ ((x) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK)
+#define TEGRA_CEC_HWCTRL_RX_SNOOP (1 << 15)
+#define TEGRA_CEC_HWCTRL_RX_NAK_MODE (1 << 16)
+#define TEGRA_CEC_HWCTRL_TX_NAK_MODE (1 << 24)
+#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE (1 << 30)
+#define TEGRA_CEC_HWCTRL_TX_RX_MODE (1 << 31)
+
+#define TEGRA_CEC_INPUT_FILTER_MODE (1 << 31)
+#define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_SHIFT 0
+
+#define TEGRA_CEC_TX_REG_DATA_SHIFT 0
+#define TEGRA_CEC_TX_REG_EOM (1 << 8)
+#define TEGRA_CEC_TX_REG_BCAST (1 << 12)
+#define TEGRA_CEC_TX_REG_START_BIT (1 << 16)
+#define TEGRA_CEC_TX_REG_RETRY (1 << 17)
+
+#define TEGRA_CEC_RX_REGISTER_SHIFT 0
+#define TEGRA_CEC_RX_REGISTER_EOM (1 << 8)
+#define TEGRA_CEC_RX_REGISTER_ACK (1 << 9)
+
+#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT 0
+#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT 8
+#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT 16
+#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT 24
+
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT 0
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT 8
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT 16
+#define TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT 24
+
+#define TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT 0
+
+#define TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT 0
+#define TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT 8
+#define TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT 16
+#define TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT 24
+
+#define TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT 0
+#define TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT 8
+#define TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT 16
+#define TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT 24
+
+#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT 0
+#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT 4
+#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT 8
+
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY (1 << 0)
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN (1 << 1)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD (1 << 2)
+#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED (1 << 3)
+#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED (1 << 4)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED (1 << 5)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL (1 << 8)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN (1 << 9)
+#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED (1 << 10)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED (1 << 11)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED (1 << 12)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1 << 13)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1 << 14)
+
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY (1 << 0)
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN (1 << 1)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD (1 << 2)
+#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED (1 << 3)
+#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED (1 << 4)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED (1 << 5)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL (1 << 8)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN (1 << 9)
+#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED (1 << 10)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED (1 << 11)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED (1 << 12)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1 << 13)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1 << 14)
+
+#define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_SHIFT 0
+#define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_SHIFT 17
+#define TEGRA_CEC_HW_DEBUG_TX_STATE_SHIFT 21
+#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT (1 << 25)
+#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER (1 << 26)
+
+#endif /* TEGRA_CEC_H */
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile
index 32504b724b5d..886ac5ec073f 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti-vpe/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 42e383a48ffe..8b586c864524 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -1522,6 +1522,11 @@ static int cal_async_complete(struct v4l2_async_notifier *notifier)
return 0;
}
+static const struct v4l2_async_notifier_operations cal_async_ops = {
+ .bound = cal_async_bound,
+ .complete = cal_async_complete,
+};
+
static int cal_complete_ctx(struct cal_ctx *ctx)
{
struct video_device *vfd;
@@ -1736,8 +1741,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
ctx->asd_list[0] = asd;
ctx->notifier.subdevs = ctx->asd_list;
ctx->notifier.num_subdevs = 1;
- ctx->notifier.bound = cal_async_bound;
- ctx->notifier.complete = cal_async_complete;
+ ctx->notifier.ops = &cal_async_ops;
ret = v4l2_async_notifier_register(&ctx->v4l2_dev,
&ctx->notifier);
if (ret) {
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 45bd10544189..e395aa85c8ad 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -926,7 +926,7 @@ static struct vpe_ctx *file2ctx(struct file *file)
* mem2mem callbacks
*/
-/**
+/*
* job_ready() - check whether an instance is ready to be scheduled to run
*/
static int job_ready(void *priv)
diff --git a/drivers/media/platform/via-camera.h b/drivers/media/platform/via-camera.h
index b12a4b3d616f..2d67f8ce258d 100644
--- a/drivers/media/platform/via-camera.h
+++ b/drivers/media/platform/via-camera.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* VIA Camera register definitions.
*/
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index b01fba020d5f..065483e62db4 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -343,7 +343,7 @@ static void schedule_irq(struct vim2m_dev *dev, int msec_timeout)
* mem2mem callbacks
*/
-/**
+/*
* job_ready() - check whether an instance is ready to be scheduled to run
*/
static int job_ready(void *priv)
@@ -388,9 +388,9 @@ static void device_run(void *priv)
schedule_irq(dev, ctx->transtime);
}
-static void device_isr(unsigned long priv)
+static void device_isr(struct timer_list *t)
{
- struct vim2m_dev *vim2m_dev = (struct vim2m_dev *)priv;
+ struct vim2m_dev *vim2m_dev = from_timer(vim2m_dev, t, timer);
struct vim2m_ctx *curr_ctx;
struct vb2_v4l2_buffer *src_vb, *dst_vb;
unsigned long flags;
@@ -1024,7 +1024,7 @@ static int vim2m_probe(struct platform_device *pdev)
v4l2_info(&dev->v4l2_dev,
"Device registered as /dev/video%d\n", vfd->num);
- setup_timer(&dev->timer, device_isr, (long)dev);
+ timer_setup(&dev->timer, device_isr, 0);
platform_set_drvdata(pdev, dev);
dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
diff --git a/drivers/media/platform/vimc/Makefile b/drivers/media/platform/vimc/Makefile
index 68c5d9804c11..4b2e3de7856e 100644
--- a/drivers/media/platform/vimc/Makefile
+++ b/drivers/media/platform/vimc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
vimc-objs := vimc-core.o
vimc_capture-objs := vimc-capture.o
vimc_common-objs := vimc-common.o
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
index 51c0eee61ca6..fe088a953860 100644
--- a/drivers/media/platform/vimc/vimc-core.c
+++ b/drivers/media/platform/vimc/vimc-core.c
@@ -267,11 +267,12 @@ static struct component_match *vimc_add_subdevs(struct vimc_device *vimc)
PLATFORM_DEVID_AUTO,
&pdata,
sizeof(pdata));
- if (!vimc->subdevs[i]) {
+ if (IS_ERR(vimc->subdevs[i])) {
+ match = ERR_CAST(vimc->subdevs[i]);
while (--i >= 0)
platform_device_unregister(vimc->subdevs[i]);
- return ERR_PTR(-ENOMEM);
+ return match;
}
component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare,
diff --git a/drivers/media/platform/vivid/Makefile b/drivers/media/platform/vivid/Makefile
index 29738810e3ee..2f5762e3309a 100644
--- a/drivers/media/platform/vivid/Makefile
+++ b/drivers/media/platform/vivid/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index f0f423c7ca41..a651527d80db 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -189,6 +189,22 @@ struct vivid_fmt vivid_formats[] = {
.buffers = 1,
},
{
+ .fourcc = V4L2_PIX_FMT_Y10,
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .color_enc = TGP_COLOR_ENC_LUMA,
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_Y12,
+ .vdownsampling = { 1 },
+ .bit_depth = { 16 },
+ .color_enc = TGP_COLOR_ENC_LUMA,
+ .planes = 1,
+ .buffers = 1,
+ },
+ {
.fourcc = V4L2_PIX_FMT_Y16,
.vdownsampling = { 1 },
.bit_depth = { 16 },
diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index a33afc385a48..f5cd6f0491cb 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_pipe.o
vsp1-y += vsp1_dl.o vsp1_drm.o vsp1_video.o
vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 8b5cbb6b7a70..4257451f1bd8 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -70,6 +70,7 @@ struct vsp1_dl_body {
* @dma: DMA address for the header
* @body0: first display list body
* @fragments: list of extra display list bodies
+ * @has_chain: if true, indicates that there's a partition chain
* @chain: entry in the display list partition chain
*/
struct vsp1_dl_list {
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index ebfdf334d99c..d881cf09876d 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -351,6 +351,11 @@ static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier,
return -EINVAL;
}
+static const struct v4l2_async_notifier_operations xvip_graph_notify_ops = {
+ .bound = xvip_graph_notify_bound,
+ .complete = xvip_graph_notify_complete,
+};
+
static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
struct device_node *node)
{
@@ -548,8 +553,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev)
xdev->notifier.subdevs = subdevs;
xdev->notifier.num_subdevs = num_subdevs;
- xdev->notifier.bound = xvip_graph_notify_bound;
- xdev->notifier.complete = xvip_graph_notify_complete;
+ xdev->notifier.ops = &xvip_graph_notify_ops;
ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier);
if (ret < 0) {
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 120e791199b2..37e6e8255b57 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel character device drivers.
#
diff --git a/drivers/media/radio/lm7000.h b/drivers/media/radio/lm7000.h
index 139cd6b68824..adb217965620 100644
--- a/drivers/media/radio/lm7000.h
+++ b/drivers/media/radio/lm7000.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LM7000_H
#define __LM7000_H
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 6888b7db449d..7575e5370a49 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -281,9 +281,9 @@ static bool cadet_has_rds_data(struct cadet *dev)
}
-static void cadet_handler(unsigned long data)
+static void cadet_handler(struct timer_list *t)
{
- struct cadet *dev = (void *)data;
+ struct cadet *dev = from_timer(dev, t, readtimer);
/* Service the RDS fifo */
if (mutex_trylock(&dev->lock)) {
@@ -309,7 +309,6 @@ static void cadet_handler(unsigned long data)
/*
* Clean up and exit
*/
- setup_timer(&dev->readtimer, cadet_handler, data);
dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
add_timer(&dev->readtimer);
}
@@ -318,7 +317,7 @@ static void cadet_start_rds(struct cadet *dev)
{
dev->rdsstat = 1;
outb(0x80, dev->io); /* Select RDS fifo */
- setup_timer(&dev->readtimer, cadet_handler, (unsigned long)dev);
+ timer_setup(&dev->readtimer, cadet_handler, 0);
dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
add_timer(&dev->readtimer);
}
diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c
index 3c0a22a54113..70a2c86774ce 100644
--- a/drivers/media/radio/radio-raremono.c
+++ b/drivers/media/radio/radio-raremono.c
@@ -254,7 +254,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct raremono_device *radio = video_drvdata(file);
- u32 freq = f->frequency;
+ u32 freq;
unsigned band;
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 271f725b17e8..540ac887a63c 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -158,7 +158,7 @@ enum si476x_ctrl_idx {
};
static struct v4l2_ctrl_config si476x_ctrls[] = {
- /**
+ /*
* SI476X during its station seeking(or tuning) process uses several
* parameters to detrmine if "the station" is valid:
*
@@ -197,7 +197,7 @@ static struct v4l2_ctrl_config si476x_ctrls[] = {
.step = 2,
},
- /**
+ /*
* #V4L2_CID_SI476X_HARMONICS_COUNT -- number of harmonics
* built-in power-line noise supression filter is to reject
* during AM-mode operation.
@@ -213,7 +213,7 @@ static struct v4l2_ctrl_config si476x_ctrls[] = {
.step = 1,
},
- /**
+ /*
* #V4L2_CID_SI476X_DIVERSITY_MODE -- configuration which
* two tuners working in diversity mode are to work in.
*
@@ -237,7 +237,7 @@ static struct v4l2_ctrl_config si476x_ctrls[] = {
.max = ARRAY_SIZE(phase_diversity_modes) - 1,
},
- /**
+ /*
* #V4L2_CID_SI476X_INTERCHIP_LINK -- inter-chip link in
* diversity mode indicator. Allows user to determine if two
* chips working in diversity mode have established a link
@@ -296,11 +296,15 @@ struct si476x_radio_ops {
/**
* struct si476x_radio - radio device
*
- * @core: Pointer to underlying core device
+ * @v4l2dev: Pointer to V4L2 device created by V4L2 subsystem
* @videodev: Pointer to video device created by V4L2 subsystem
+ * @ctrl_handler: V4L2 controls handler
+ * @core: Pointer to underlying core device
* @ops: Vtable of functions. See struct si476x_radio_ops for details
- * @kref: Reference counter
- * @core_lock: An r/w semaphore to brebvent the deletion of underlying
+ * @debugfs: pointer to &strucd dentry for debugfs
+ * @audmode: audio mode, as defined for the rxsubchans field
+ * at videodev2.h
+ *
* core structure is the radio device is being used
*/
struct si476x_radio {
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 903fcd5e99c0..3cbdc085c65d 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -1330,7 +1330,7 @@ static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
/**
* wl1273_fm_set_tx_power() - Set the transmission power value.
- * @core: A pointer to the device struct.
+ * @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)
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index cd76facc22f5..c89a7d5b8c55 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -749,7 +749,7 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
/*
* si470x_viddev_template - video device interface
*/
-struct video_device si470x_viddev_template = {
+const struct video_device si470x_viddev_template = {
.fops = &si470x_fops,
.name = DRIVER_NAME,
.release = video_device_release_empty,
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index 7d2defd9d399..eb7b834a0ae5 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -209,7 +209,7 @@ struct si470x_device {
/**************************************************************************
* Common Functions
**************************************************************************/
-extern struct video_device si470x_viddev_template;
+extern const struct video_device si470x_viddev_template;
extern const struct v4l2_ctrl_ops si470x_ctrl_ops;
int si470x_get_register(struct si470x_device *radio, int regnr);
int si470x_set_register(struct si470x_device *radio, int regnr);
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
index c9e349b169c4..2add222ea346 100644
--- a/drivers/media/radio/wl128x/Kconfig
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -7,11 +7,11 @@ config RADIO_WL128X
depends on VIDEO_V4L2 && RFKILL && TTY && TI_ST
depends on GPIOLIB || COMPILE_TEST
help
- Choose Y here if you have this FM radio chip.
+ 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/video4linux/API.html>.
+ 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/video4linux/API.html>.
endmenu
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index ab3428bf63fe..800d69c3f80b 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -543,13 +543,13 @@ static inline void fm_irq_common_cmd_resp_helper(struct fmdev *fmdev, u8 stage)
* interrupt process. Therefore reset stage index to re-enable default
* interrupts. So that next interrupt will be processed as usual.
*/
-static void int_timeout_handler(unsigned long data)
+static void int_timeout_handler(struct timer_list *t)
{
struct fmdev *fmdev;
struct fm_irq *fmirq;
fmdbg("irq: timeout,trying to re-enable fm interrupts\n");
- fmdev = (struct fmdev *)data;
+ fmdev = from_timer(fmdev, t, irq_info.timer);
fmirq = &fmdev->irq_info;
fmirq->retry++;
@@ -1550,8 +1550,7 @@ int fmc_prepare(struct fmdev *fmdev)
atomic_set(&fmdev->tx_cnt, 1);
fmdev->resp_comp = NULL;
- setup_timer(&fmdev->irq_info.timer, &int_timeout_handler,
- (unsigned long)fmdev);
+ timer_setup(&fmdev->irq_info.timer, int_timeout_handler, 0);
/*TODO: add FM_STIC_EVENT later */
fmdev->irq_info.mask = FM_MAL_EVENT;
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index d9ce8ff55d0c..afb3456d4e20 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -2,7 +2,6 @@
menuconfig RC_CORE
tristate "Remote Controller support"
depends on INPUT
- default y
---help---
Enable support for Remote Controllers on Linux. This is
needed in order to support several video capture adapters,
@@ -179,6 +178,7 @@ config IR_ENE
config IR_HIX5HD2
tristate "Hisilicon hix5hd2 IR remote control"
depends on RC_CORE
+ depends on OF || COMPILE_TEST
help
Say Y here if you want to use hisilicon hix5hd2 remote control.
To compile this driver as a module, choose M here: the module will be
@@ -286,6 +286,7 @@ config IR_REDRAT3
config IR_SPI
tristate "SPI connected IR LED"
depends on SPI && LIRC
+ depends on OF || COMPILE_TEST
---help---
Say Y if you want to use an IR LED connected through SPI bus.
@@ -393,6 +394,7 @@ config RC_LOOPBACK
config IR_GPIO_CIR
tristate "GPIO IR remote control"
depends on RC_CORE
+ depends on (OF && GPIOLIB) || COMPILE_TEST
---help---
Say Y if you want to use GPIO based IR Receiver.
@@ -403,6 +405,7 @@ config IR_GPIO_TX
tristate "GPIO IR Bit Banging Transmitter"
depends on RC_CORE
depends on LIRC
+ depends on (OF && GPIOLIB) || COMPILE_TEST
---help---
Say Y if you want to a GPIO based IR transmitter. This is a
bit banging driver.
@@ -415,6 +418,7 @@ config IR_PWM_TX
depends on RC_CORE
depends on LIRC
depends on PWM
+ depends on OF || COMPILE_TEST
---help---
Say Y if you want to use a PWM based IR transmitter. This is
more power efficient than the bit banging gpio driver.
@@ -469,6 +473,16 @@ config IR_SIR
To compile this driver as a module, choose M here: the module will
be called sir-ir.
+config IR_TANGO
+ tristate "Sigma Designs SMP86xx IR decoder"
+ depends on RC_CORE
+ depends on ARCH_TANGO || COMPILE_TEST
+ ---help---
+ Adds support for the HW IR decoder embedded on Sigma Designs
+ Tango-based systems (SMP86xx, SMP87xx).
+ The HW decoder supports NEC, RC-5, RC-6 IR protocols.
+ When compiled as a module, look for tango-ir.
+
config IR_ZX
tristate "ZTE ZX IR remote control"
depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 9bc6a3980ed0..10026477a677 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
rc-core-objs := rc-main.o rc-ir-raw.o
obj-y += keymaps/
@@ -44,3 +45,4 @@ obj-$(CONFIG_IR_SERIAL) += serial_ir.o
obj-$(CONFIG_IR_SIR) += sir_ir.o
obj-$(CONFIG_IR_MTK) += mtk-cir.o
obj-$(CONFIG_IR_ZX) += zx-irdec.o
+obj-$(CONFIG_IR_TANGO) += tango-ir.o
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index d0871d60a723..8e82610ffaad 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -198,7 +198,7 @@ static const struct ati_receiver_type type_firefly = {
.default_keymap = RC_MAP_SNAPSTREAM_FIREFLY
};
-static struct usb_device_id ati_remote_table[] = {
+static const struct usb_device_id ati_remote_table[] = {
{
USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID),
.driver_info = (unsigned long)&type_ati
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index af7ba23e16e1..71b8c9bbf6c4 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -670,9 +670,9 @@ exit:
}
/* timer to simulate tx done interrupt */
-static void ene_tx_irqsim(unsigned long data)
+static void ene_tx_irqsim(struct timer_list *t)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = from_timer(dev, t, tx_sim_timer);
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
@@ -1045,8 +1045,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
if (!dev->hw_learning_and_tx_capable && txsim) {
dev->hw_learning_and_tx_capable = true;
- setup_timer(&dev->tx_sim_timer, ene_tx_irqsim,
- (long unsigned int)dev);
+ timer_setup(&dev->tx_sim_timer, ene_tx_irqsim, 0);
pr_warn("Simulation of TX activated\n");
}
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 7248b3662285..3d99b51384ac 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -14,119 +14,64 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <media/rc-core.h>
-#include <linux/platform_data/media/gpio-ir-recv.h>
-#define GPIO_IR_DRIVER_NAME "gpio-rc-recv"
#define GPIO_IR_DEVICE_NAME "gpio_ir_recv"
struct gpio_rc_dev {
struct rc_dev *rcdev;
- int gpio_nr;
- bool active_low;
+ struct gpio_desc *gpiod;
+ int irq;
};
-#ifdef CONFIG_OF
-/*
- * Translate OpenFirmware node properties into platform_data
- */
-static int gpio_ir_recv_get_devtree_pdata(struct device *dev,
- struct gpio_ir_recv_platform_data *pdata)
-{
- struct device_node *np = dev->of_node;
- enum of_gpio_flags flags;
- int gpio;
-
- gpio = of_get_gpio_flags(np, 0, &flags);
- if (gpio < 0) {
- if (gpio != -EPROBE_DEFER)
- dev_err(dev, "Failed to get gpio flags (%d)\n", gpio);
- return gpio;
- }
-
- pdata->gpio_nr = gpio;
- pdata->active_low = (flags & OF_GPIO_ACTIVE_LOW);
- /* probe() takes care of map_name == NULL or allowed_protos == 0 */
- pdata->map_name = of_get_property(np, "linux,rc-map-name", NULL);
- pdata->allowed_protos = 0;
-
- return 0;
-}
-
-static const struct of_device_id gpio_ir_recv_of_match[] = {
- { .compatible = "gpio-ir-receiver", },
- { },
-};
-MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match);
-
-#else /* !CONFIG_OF */
-
-#define gpio_ir_recv_get_devtree_pdata(dev, pdata) (-ENOSYS)
-
-#endif
-
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
{
+ int val;
struct gpio_rc_dev *gpio_dev = dev_id;
- int gval;
- int rc = 0;
-
- gval = gpio_get_value(gpio_dev->gpio_nr);
-
- if (gval < 0)
- goto err_get_value;
-
- if (gpio_dev->active_low)
- gval = !gval;
- rc = ir_raw_event_store_edge(gpio_dev->rcdev, gval == 1);
- if (rc < 0)
- goto err_get_value;
+ val = gpiod_get_value(gpio_dev->gpiod);
+ if (val >= 0)
+ ir_raw_event_store_edge(gpio_dev->rcdev, val == 1);
-err_get_value:
return IRQ_HANDLED;
}
static int gpio_ir_recv_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
struct gpio_rc_dev *gpio_dev;
struct rc_dev *rcdev;
- const struct gpio_ir_recv_platform_data *pdata =
- pdev->dev.platform_data;
int rc;
- if (pdev->dev.of_node) {
- struct gpio_ir_recv_platform_data *dtpdata =
- devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL);
- if (!dtpdata)
- return -ENOMEM;
- rc = gpio_ir_recv_get_devtree_pdata(&pdev->dev, dtpdata);
- if (rc)
- return rc;
- pdata = dtpdata;
- }
-
- if (!pdata)
- return -EINVAL;
+ if (!np)
+ return -ENODEV;
- if (pdata->gpio_nr < 0)
- return -EINVAL;
-
- gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL);
+ gpio_dev = devm_kzalloc(dev, sizeof(*gpio_dev), GFP_KERNEL);
if (!gpio_dev)
return -ENOMEM;
- rcdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rcdev) {
- rc = -ENOMEM;
- goto err_allocate_device;
+ gpio_dev->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN);
+ if (IS_ERR(gpio_dev->gpiod)) {
+ rc = PTR_ERR(gpio_dev->gpiod);
+ /* Just try again if this happens */
+ if (rc != -EPROBE_DEFER)
+ dev_err(dev, "error getting gpio (%d)\n", rc);
+ return rc;
}
+ gpio_dev->irq = gpiod_to_irq(gpio_dev->gpiod);
+ if (gpio_dev->irq < 0)
+ return gpio_dev->irq;
+
+ rcdev = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
+ if (!rcdev)
+ return -ENOMEM;
rcdev->priv = gpio_dev;
rcdev->device_name = GPIO_IR_DEVICE_NAME;
@@ -135,92 +80,52 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
rcdev->input_id.vendor = 0x0001;
rcdev->input_id.product = 0x0001;
rcdev->input_id.version = 0x0100;
- rcdev->dev.parent = &pdev->dev;
- rcdev->driver_name = GPIO_IR_DRIVER_NAME;
+ rcdev->dev.parent = dev;
+ rcdev->driver_name = KBUILD_MODNAME;
rcdev->min_timeout = 1;
rcdev->timeout = IR_DEFAULT_TIMEOUT;
rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
- if (pdata->allowed_protos)
- rcdev->allowed_protocols = pdata->allowed_protos;
- else
- rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
- rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
+ rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
+ rcdev->map_name = of_get_property(np, "linux,rc-map-name", NULL);
+ if (!rcdev->map_name)
+ rcdev->map_name = RC_MAP_EMPTY;
gpio_dev->rcdev = rcdev;
- gpio_dev->gpio_nr = pdata->gpio_nr;
- gpio_dev->active_low = pdata->active_low;
-
- rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
- if (rc < 0)
- goto err_gpio_request;
- rc = gpio_direction_input(pdata->gpio_nr);
- if (rc < 0)
- goto err_gpio_direction_input;
- rc = rc_register_device(rcdev);
+ rc = devm_rc_register_device(dev, rcdev);
if (rc < 0) {
- dev_err(&pdev->dev, "failed to register rc device\n");
- goto err_register_rc_device;
+ dev_err(dev, "failed to register rc device (%d)\n", rc);
+ return rc;
}
platform_set_drvdata(pdev, gpio_dev);
- rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
- gpio_ir_recv_irq,
- IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
- "gpio-ir-recv-irq", gpio_dev);
- if (rc < 0)
- goto err_request_irq;
-
- return 0;
-
-err_request_irq:
- rc_unregister_device(rcdev);
- rcdev = NULL;
-err_register_rc_device:
-err_gpio_direction_input:
- gpio_free(pdata->gpio_nr);
-err_gpio_request:
- rc_free_device(rcdev);
-err_allocate_device:
- kfree(gpio_dev);
- return rc;
-}
-
-static int gpio_ir_recv_remove(struct platform_device *pdev)
-{
- struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
-
- free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
- rc_unregister_device(gpio_dev->rcdev);
- gpio_free(gpio_dev->gpio_nr);
- kfree(gpio_dev);
- return 0;
+ return devm_request_irq(dev, gpio_dev->irq, gpio_ir_recv_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "gpio-ir-recv-irq", gpio_dev);
}
#ifdef CONFIG_PM
static int gpio_ir_recv_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
+ struct gpio_rc_dev *gpio_dev = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
- enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
+ enable_irq_wake(gpio_dev->irq);
else
- disable_irq(gpio_to_irq(gpio_dev->gpio_nr));
+ disable_irq(gpio_dev->irq);
return 0;
}
static int gpio_ir_recv_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
+ struct gpio_rc_dev *gpio_dev = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
- disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
+ disable_irq_wake(gpio_dev->irq);
else
- enable_irq(gpio_to_irq(gpio_dev->gpio_nr));
+ enable_irq(gpio_dev->irq);
return 0;
}
@@ -231,11 +136,16 @@ static const struct dev_pm_ops gpio_ir_recv_pm_ops = {
};
#endif
+static const struct of_device_id gpio_ir_recv_of_match[] = {
+ { .compatible = "gpio-ir-receiver", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match);
+
static struct platform_driver gpio_ir_recv_driver = {
.probe = gpio_ir_recv_probe,
- .remove = gpio_ir_recv_remove,
.driver = {
- .name = GPIO_IR_DRIVER_NAME,
+ .name = KBUILD_MODNAME,
.of_match_table = of_match_ptr(gpio_ir_recv_of_match),
#ifdef CONFIG_PM
.pm = &gpio_ir_recv_pm_ops,
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index a5ea86be8f44..f563ddd7f739 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -137,9 +137,9 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd)
dev_err(ir->dev, "submit urb failed: %d", ret);
}
-static void igorplugusb_timer(unsigned long data)
+static void igorplugusb_timer(struct timer_list *t)
{
- struct igorplugusb *ir = (struct igorplugusb *)data;
+ struct igorplugusb *ir = from_timer(ir, t, timer);
igorplugusb_cmd(ir, GET_INFRACODE);
}
@@ -174,7 +174,7 @@ static int igorplugusb_probe(struct usb_interface *intf,
ir->dev = &intf->dev;
- setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir);
+ timer_setup(&ir->timer, igorplugusb_timer, 0);
ir->request.bRequest = GET_INFRACODE;
ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN;
@@ -245,7 +245,7 @@ static void igorplugusb_disconnect(struct usb_interface *intf)
usb_free_urb(ir->urb);
}
-static struct usb_device_id igorplugusb_table[] = {
+static const struct usb_device_id igorplugusb_table[] = {
/* Igor Plug USB (Atmel's Manufact. ID) */
{ USB_DEVICE(0x03eb, 0x0002) },
/* Fit PC2 Infrared Adapter */
diff --git a/drivers/media/rc/img-ir/Makefile b/drivers/media/rc/img-ir/Makefile
index 8e6d458e66ad..741fedc5dceb 100644
--- a/drivers/media/rc/img-ir/Makefile
+++ b/drivers/media/rc/img-ir/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
img-ir-y := img-ir-core.o
img-ir-$(CONFIG_IR_IMG_RAW) += img-ir-raw.o
img-ir-$(CONFIG_IR_IMG_HW) += img-ir-hw.o
diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c
index 03fe080278df..bcbabeeab12a 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -92,10 +92,9 @@ static int img_ir_probe(struct platform_device *pdev)
/* Private driver data */
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&pdev->dev, "cannot allocate device data\n");
+ if (!priv)
return -ENOMEM;
- }
+
platform_set_drvdata(pdev, priv);
priv->dev = &pdev->dev;
spin_lock_init(&priv->lock);
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
index 82fdf4cc0824..ec4ded84cd17 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -339,7 +339,7 @@ static void img_ir_decoder_preprocess(struct img_ir_decoder *decoder)
/**
* img_ir_decoder_convert() - Generate internal timings in decoder.
* @decoder: Decoder to be converted to internal timings.
- * @timings: Timing register values.
+ * @reg_timings: Timing register values.
* @clock_hz: IR clock rate in Hz.
*
* Fills out the repeat timings and timing register values for a specific clock
@@ -867,9 +867,9 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
}
/* timer function to end waiting for repeat. */
-static void img_ir_end_timer(unsigned long arg)
+static void img_ir_end_timer(struct timer_list *t)
{
- struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+ struct img_ir_priv *priv = from_timer(priv, t, hw.end_timer);
spin_lock_irq(&priv->lock);
img_ir_end_repeat(priv);
@@ -881,9 +881,9 @@ static void img_ir_end_timer(unsigned long arg)
* cleared when invalid interrupts were generated due to a quirk in the
* img-ir decoder.
*/
-static void img_ir_suspend_timer(unsigned long arg)
+static void img_ir_suspend_timer(struct timer_list *t)
{
- struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+ struct img_ir_priv *priv = from_timer(priv, t, hw.suspend_timer);
spin_lock_irq(&priv->lock);
/*
@@ -1055,9 +1055,8 @@ int img_ir_probe_hw(struct img_ir_priv *priv)
img_ir_probe_hw_caps(priv);
/* Set up the end timer */
- setup_timer(&hw->end_timer, img_ir_end_timer, (unsigned long)priv);
- setup_timer(&hw->suspend_timer, img_ir_suspend_timer,
- (unsigned long)priv);
+ timer_setup(&hw->end_timer, img_ir_end_timer, 0);
+ timer_setup(&hw->suspend_timer, img_ir_suspend_timer, 0);
/* Register a clock notifier */
if (!IS_ERR(priv->clk)) {
diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
index 64714efc1145..6e545680d3b6 100644
--- a/drivers/media/rc/img-ir/img-ir-raw.c
+++ b/drivers/media/rc/img-ir/img-ir-raw.c
@@ -67,9 +67,9 @@ void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status)
* order to be assured of the final space. If there are no edges for a certain
* time we use this timer to emit a final sample to satisfy them.
*/
-static void img_ir_echo_timer(unsigned long arg)
+static void img_ir_echo_timer(struct timer_list *t)
{
- struct img_ir_priv *priv = (struct img_ir_priv *)arg;
+ struct img_ir_priv *priv = from_timer(priv, t, raw.timer);
spin_lock_irq(&priv->lock);
@@ -107,7 +107,7 @@ int img_ir_probe_raw(struct img_ir_priv *priv)
int error;
/* Set up the echo timer */
- setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv);
+ timer_setup(&raw->timer, img_ir_echo_timer, 0);
/* Allocate raw decoder */
raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 7b3f31cc63d2..eb943e862515 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -346,7 +346,7 @@ static const struct imon_usb_dev_descr imon_ir_raw = {
* devices use the SoundGraph vendor ID (0x15c2). This driver only supports
* the ffdc and later devices, which do onboard decoding.
*/
-static struct usb_device_id imon_usb_id_table[] = {
+static const struct usb_device_id imon_usb_id_table[] = {
/*
* Several devices with this same device ID, all use iMON_PAD.inf
* SoundGraph iMON PAD (IR & VFD)
@@ -492,7 +492,7 @@ static void free_imon_context(struct imon_context *ictx)
dev_dbg(dev, "%s: iMON context freed\n", __func__);
}
-/**
+/*
* Called when the Display device (e.g. /dev/lcd0)
* is opened by the application.
*/
@@ -542,7 +542,7 @@ exit:
return retval;
}
-/**
+/*
* Called when the display device (e.g. /dev/lcd0)
* is closed by the application.
*/
@@ -575,7 +575,7 @@ static int display_close(struct inode *inode, struct file *file)
return retval;
}
-/**
+/*
* Sends a packet to the device -- this function must be called with
* ictx->lock held, or its unlock/lock sequence while waiting for tx
* to complete can/will lead to a deadlock.
@@ -602,8 +602,7 @@ static int send_packet(struct imon_context *ictx)
ictx->tx_urb->actual_length = 0;
} else {
/* fill request into kmalloc'ed space: */
- control_req = kmalloc(sizeof(struct usb_ctrlrequest),
- GFP_KERNEL);
+ control_req = kmalloc(sizeof(*control_req), GFP_KERNEL);
if (control_req == NULL)
return -ENOMEM;
@@ -665,7 +664,7 @@ static int send_packet(struct imon_context *ictx)
return retval;
}
-/**
+/*
* Sends an associate packet to the iMON 2.4G.
*
* This might not be such a good idea, since it has an id collision with
@@ -695,7 +694,7 @@ static int send_associate_24g(struct imon_context *ictx)
return retval;
}
-/**
+/*
* Sends packets to setup and show clock on iMON display
*
* Arguments: year - last 2 digits of year, month - 1..12,
@@ -782,7 +781,7 @@ static int send_set_imon_clock(struct imon_context *ictx,
return retval;
}
-/**
+/*
* These are the sysfs functions to handle the association on the iMON 2.4G LT.
*/
static ssize_t show_associate_remote(struct device *d,
@@ -824,7 +823,7 @@ static ssize_t store_associate_remote(struct device *d,
return count;
}
-/**
+/*
* sysfs functions to control internal imon clock
*/
static ssize_t show_imon_clock(struct device *d,
@@ -924,7 +923,7 @@ static const struct attribute_group imon_rf_attr_group = {
.attrs = imon_rf_sysfs_entries
};
-/**
+/*
* Writes data to the VFD. The iMON VFD is 2x16 characters
* and requires data in 5 consecutive USB interrupt packets,
* each packet but the last carrying 7 bytes.
@@ -943,7 +942,7 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
int seq;
int retval = 0;
struct imon_context *ictx;
- const unsigned char vfd_packet6[] = {
+ static const unsigned char vfd_packet6[] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
ictx = file->private_data;
@@ -1009,7 +1008,7 @@ exit:
return (!retval) ? n_bytes : retval;
}
-/**
+/*
* Writes data to the LCD. The iMON OEM LCD screen expects 8-byte
* packets. We accept data as 16 hexadecimal digits, followed by a
* newline (to make it easy to drive the device from a command-line
@@ -1067,7 +1066,7 @@ exit:
return (!retval) ? n_bytes : retval;
}
-/**
+/*
* Callback function for USB core API: transmit data
*/
static void usb_tx_callback(struct urb *urb)
@@ -1088,12 +1087,12 @@ static void usb_tx_callback(struct urb *urb)
complete(&ictx->tx.finished);
}
-/**
+/*
* report touchscreen input
*/
-static void imon_touch_display_timeout(unsigned long data)
+static void imon_touch_display_timeout(struct timer_list *t)
{
- struct imon_context *ictx = (struct imon_context *)data;
+ struct imon_context *ictx = from_timer(ictx, t, ttimer);
if (ictx->display_type != IMON_DISPLAY_TYPE_VGA)
return;
@@ -1104,7 +1103,7 @@ static void imon_touch_display_timeout(unsigned long data)
input_sync(ictx->touch);
}
-/**
+/*
* iMON IR receivers support two different signal sets -- those used by
* the iMON remotes, and those used by the Windows MCE remotes (which is
* really just RC-6), but only one or the other at a time, as the signals
@@ -1192,7 +1191,7 @@ static inline int tv2int(const struct timeval *a, const struct timeval *b)
return sec;
}
-/**
+/*
* The directional pad behaves a bit differently, depending on whether this is
* one of the older ffdc devices or a newer device. Newer devices appear to
* have a higher resolution matrix for more precise mouse movement, but it
@@ -1544,7 +1543,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
}
}
-/**
+/*
* figure out if these is a press or a release. We don't actually
* care about repeats, as those will be auto-generated within the IR
* subsystem for repeating scancodes.
@@ -1593,10 +1592,10 @@ static int imon_parse_press_type(struct imon_context *ictx,
return press_type;
}
-/**
+/*
* Process the incoming packet
*/
-/**
+/*
* Convert bit count to time duration (in us) and submit
* the value to lirc_dev.
*/
@@ -1609,7 +1608,7 @@ static void submit_data(struct imon_context *context)
ir_raw_event_store_with_filter(context->rdev, &ev);
}
-/**
+/*
* Process the incoming packet
*/
static void imon_incoming_ir_raw(struct imon_context *context,
@@ -1832,7 +1831,7 @@ not_input_data:
}
}
-/**
+/*
* Callback function for USB core API: receive data
*/
static void usb_rx_callback_intf0(struct urb *urb)
@@ -2047,8 +2046,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
{
struct rc_dev *rdev;
int ret;
- const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x88 };
+ static const unsigned char fp_packet[] = {
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 };
rdev = rc_allocate_device(ictx->dev_descr->flags & IMON_IR_RAW ?
RC_DRIVER_IR_RAW : RC_DRIVER_SCANCODE);
@@ -2310,11 +2309,10 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf,
struct usb_host_interface *iface_desc;
int ret = -ENOMEM;
- ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
- if (!ictx) {
- dev_err(dev, "%s: kzalloc failed for context", __func__);
+ ictx = kzalloc(sizeof(*ictx), GFP_KERNEL);
+ if (!ictx)
goto exit;
- }
+
rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!rx_urb)
goto rx_urb_alloc_failed;
@@ -2413,8 +2411,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf,
mutex_lock(&ictx->lock);
if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
- setup_timer(&ictx->ttimer, imon_touch_display_timeout,
- (unsigned long)ictx);
+ timer_setup(&ictx->ttimer, imon_touch_display_timeout, 0);
}
ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
@@ -2488,7 +2485,7 @@ static void imon_init_display(struct imon_context *ictx,
}
-/**
+/*
* Callback function for USB core API: Probe
*/
static int imon_probe(struct usb_interface *interface,
@@ -2517,6 +2514,11 @@ static int imon_probe(struct usb_interface *interface,
mutex_lock(&driver_lock);
first_if = usb_ifnum_to_if(usbdev, 0);
+ if (!first_if) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
first_if_ctx = usb_get_intfdata(first_if);
if (ifnum == 0) {
@@ -2581,7 +2583,7 @@ fail:
return ret;
}
-/**
+/*
* Callback function for USB core API: disconnect
*/
static void imon_disconnect(struct usb_interface *interface)
diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index e2bd68c42edf..22c8aee3df4f 100644
--- a/drivers/media/rc/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -39,7 +39,7 @@ enum jvc_state {
/**
* ir_jvc_decode() - Decode one JVC pulse or space
* @dev: the struct rc_dev descriptor of the device
- * @duration: the struct ir_raw_event descriptor of the pulse/space
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index d2223c04e9ad..4fd4521693d9 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -25,8 +25,8 @@
/**
* ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
* lircd userspace daemon for decoding.
- * @input_dev: the struct rc_dev descriptor of the device
- * @duration: the struct ir_raw_event descriptor of the pulse/space
+ * @dev: the struct rc_dev descriptor of the device
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the lirc interfaces aren't wired up.
*/
@@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
struct lirc_codec *lirc = &dev->raw->lirc;
int sample;
- if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
+ if (!dev->raw->lirc.ldev || !dev->raw->lirc.ldev->buf)
return -EINVAL;
/* Packet start */
@@ -84,8 +84,8 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
(u64)LIRC_VALUE_MASK);
gap_sample = LIRC_SPACE(lirc->gap_duration);
- lirc_buffer_write(dev->raw->lirc.drv->rbuf,
- (unsigned char *) &gap_sample);
+ lirc_buffer_write(dev->raw->lirc.ldev->buf,
+ (unsigned char *)&gap_sample);
lirc->gap = false;
}
@@ -95,9 +95,9 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
TO_US(ev.duration), TO_STR(ev.pulse));
}
- lirc_buffer_write(dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.ldev->buf,
(unsigned char *) &sample);
- wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
+ wake_up(&dev->raw->lirc.ldev->buf->wait_poll);
return 0;
}
@@ -298,11 +298,14 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
if (!dev->max_timeout)
return -ENOTTY;
+ /* Check for multiply overflow */
+ if (val > U32_MAX / 1000)
+ return -EINVAL;
+
tmp = val * 1000;
- if (tmp < dev->min_timeout ||
- tmp > dev->max_timeout)
- return -EINVAL;
+ if (tmp < dev->min_timeout || tmp > dev->max_timeout)
+ return -EINVAL;
if (dev->s_timeout)
ret = dev->s_timeout(dev, tmp);
@@ -343,12 +346,12 @@ static const struct file_operations lirc_fops = {
static int ir_lirc_register(struct rc_dev *dev)
{
- struct lirc_driver *drv;
+ struct lirc_dev *ldev;
int rc = -ENOMEM;
unsigned long features = 0;
- drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
- if (!drv)
+ ldev = lirc_allocate_device();
+ if (!ldev)
return rc;
if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
@@ -380,32 +383,29 @@ static int ir_lirc_register(struct rc_dev *dev)
if (dev->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT;
- snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
+ snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)",
dev->driver_name);
- drv->minor = -1;
- drv->features = features;
- drv->data = &dev->raw->lirc;
- drv->rbuf = NULL;
- drv->code_length = sizeof(struct ir_raw_event) * 8;
- drv->chunk_size = sizeof(int);
- drv->buffer_size = LIRCBUF_SIZE;
- drv->fops = &lirc_fops;
- drv->dev = &dev->dev;
- drv->rdev = dev;
- drv->owner = THIS_MODULE;
-
- drv->minor = lirc_register_driver(drv);
- if (drv->minor < 0) {
- rc = -ENODEV;
+ ldev->features = features;
+ ldev->data = &dev->raw->lirc;
+ ldev->buf = NULL;
+ ldev->code_length = sizeof(struct ir_raw_event) * 8;
+ ldev->chunk_size = sizeof(int);
+ ldev->buffer_size = LIRCBUF_SIZE;
+ ldev->fops = &lirc_fops;
+ ldev->dev.parent = &dev->dev;
+ ldev->rdev = dev;
+ ldev->owner = THIS_MODULE;
+
+ rc = lirc_register_device(ldev);
+ if (rc < 0)
goto out;
- }
- dev->raw->lirc.drv = drv;
+ dev->raw->lirc.ldev = ldev;
dev->raw->lirc.dev = dev;
return 0;
out:
- kfree(drv);
+ lirc_free_device(ldev);
return rc;
}
@@ -413,9 +413,8 @@ static int ir_lirc_unregister(struct rc_dev *dev)
{
struct lirc_codec *lirc = &dev->raw->lirc;
- lirc_unregister_driver(lirc->drv->minor);
- kfree(lirc->drv);
- lirc->drv = NULL;
+ lirc_unregister_device(lirc->ldev);
+ lirc->ldev = NULL;
return 0;
}
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index 7c572a643656..69d6264d54e6 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -115,9 +115,9 @@ static unsigned char kbd_keycodes[256] = {
KEY_RESERVED
};
-static void mce_kbd_rx_timeout(unsigned long data)
+static void mce_kbd_rx_timeout(struct timer_list *t)
{
- struct mce_kbd_dec *mce_kbd = (struct mce_kbd_dec *)data;
+ struct mce_kbd_dec *mce_kbd = from_timer(mce_kbd, t, rx_timeout);
int i;
unsigned char maskcode;
@@ -389,8 +389,7 @@ static int ir_mce_kbd_register(struct rc_dev *dev)
set_bit(EV_MSC, idev->evbit);
set_bit(MSC_SCAN, idev->mscbit);
- setup_timer(&mce_kbd->rx_timeout, mce_kbd_rx_timeout,
- (unsigned long)mce_kbd);
+ timer_setup(&mce_kbd->rx_timeout, mce_kbd_rx_timeout, 0);
input_set_drvdata(idev, mce_kbd);
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 817c18f2ddd1..6880c190dcd2 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -41,7 +41,7 @@ enum nec_state {
/**
* ir_nec_decode() - Decode one NEC pulse or space
* @dev: the struct rc_dev descriptor of the device
- * @duration: the struct ir_raw_event descriptor of the pulse/space
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
@@ -87,8 +87,6 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
data->state = STATE_BIT_PULSE;
return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
- rc_repeat(dev);
- IR_dprintk(1, "Repeat last key\n");
data->state = STATE_TRAILER_PULSE;
return 0;
}
@@ -151,19 +149,26 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
break;
- address = bitrev8((data->bits >> 24) & 0xff);
- not_address = bitrev8((data->bits >> 16) & 0xff);
- command = bitrev8((data->bits >> 8) & 0xff);
- not_command = bitrev8((data->bits >> 0) & 0xff);
+ if (data->count == NEC_NBITS) {
+ address = bitrev8((data->bits >> 24) & 0xff);
+ not_address = bitrev8((data->bits >> 16) & 0xff);
+ command = bitrev8((data->bits >> 8) & 0xff);
+ not_command = bitrev8((data->bits >> 0) & 0xff);
+
+ scancode = ir_nec_bytes_to_scancode(address,
+ not_address,
+ command,
+ not_command,
+ &rc_proto);
- scancode = ir_nec_bytes_to_scancode(address, not_address,
- command, not_command,
- &rc_proto);
+ if (data->is_nec_x)
+ data->necx_repeat = true;
- if (data->is_nec_x)
- data->necx_repeat = true;
+ rc_keydown(dev, rc_proto, scancode, 0);
+ } else {
+ rc_repeat(dev);
+ }
- rc_keydown(dev, rc_proto, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
@@ -178,7 +183,6 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
* ir_nec_scancode_to_raw() - encode an NEC scancode ready for modulation.
* @protocol: specific protocol to use
* @scancode: a single NEC scancode.
- * @raw: raw data to be modulated.
*/
static u32 ir_nec_scancode_to_raw(enum rc_proto protocol, u32 scancode)
{
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
index 758c60956850..d94e07b02f3b 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -48,7 +48,7 @@ enum sanyo_state {
/**
* ir_sanyo_decode() - Decode one SANYO pulse or space
* @dev: the struct rc_dev descriptor of the device
- * @duration: the struct ir_raw_event descriptor of the pulse/space
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c
index 129b558acc92..7140dd6160ee 100644
--- a/drivers/media/rc/ir-sharp-decoder.c
+++ b/drivers/media/rc/ir-sharp-decoder.c
@@ -39,7 +39,7 @@ enum sharp_state {
/**
* ir_sharp_decode() - Decode one Sharp pulse or space
* @dev: the struct rc_dev descriptor of the device
- * @duration: the struct ir_raw_event descriptor of the pulse/space
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c
index 6f464be1c8d7..712bc6d76e92 100644
--- a/drivers/media/rc/ir-xmp-decoder.c
+++ b/drivers/media/rc/ir-xmp-decoder.c
@@ -35,7 +35,7 @@ enum xmp_state {
/**
* ir_xmp_decode() - Decode one XMP pulse or space
* @dev: the struct rc_dev descriptor of the device
- * @duration: the struct ir_raw_event descriptor of the pulse/space
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index af6496d709fb..50b319355edf 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -1,7 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-alink-dtu-m.o \
rc-anysee.o \
rc-apac-viewcomp.o \
+ rc-astrometa-t2hybrid.o \
rc-asus-pc39.o \
rc-asus-ps3-100.o \
rc-ati-tv-wonder-hd-600.o \
@@ -47,6 +49,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-geekbox.o \
rc-genius-tvgo-a11mce.o \
rc-gotview7135.o \
+ rc-hisi-poplar.o \
+ rc-hisi-tv-demo.o \
rc-imon-mce.o \
rc-imon-pad.o \
rc-iodata-bctv7e.o \
@@ -88,6 +92,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-reddo.o \
rc-snapstream-firefly.o \
rc-streamzap.o \
+ rc-tango.o \
rc-tbs-nec.o \
rc-technisat-ts35.o \
rc-technisat-usb2.o \
diff --git a/drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c b/drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c
new file mode 100644
index 000000000000..51690960fec4
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c
@@ -0,0 +1,70 @@
+/*
+ * Keytable for the Astrometa T2hybrid remote controller
+ *
+ * Copyright (C) 2017 Oleh Kravchenko <oleg@kaa.org.ua>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table t2hybrid[] = {
+ { 0x4d, KEY_POWER2 },
+ { 0x54, KEY_VIDEO }, /* Source */
+ { 0x16, KEY_MUTE },
+
+ { 0x4c, KEY_RECORD },
+ { 0x05, KEY_CHANNELUP },
+ { 0x0c, KEY_TIME}, /* Timeshift */
+
+ { 0x0a, KEY_VOLUMEDOWN },
+ { 0x40, KEY_ZOOM }, /* Fullscreen */
+ { 0x1e, KEY_VOLUMEUP },
+
+ { 0x12, KEY_0 },
+ { 0x02, KEY_CHANNELDOWN },
+ { 0x1c, KEY_AGAIN }, /* Recall */
+
+ { 0x09, KEY_1 },
+ { 0x1d, KEY_2 },
+ { 0x1f, KEY_3 },
+
+ { 0x0d, KEY_4 },
+ { 0x19, KEY_5 },
+ { 0x1b, KEY_6 },
+
+ { 0x11, KEY_7 },
+ { 0x15, KEY_8 },
+ { 0x17, KEY_9 },
+};
+
+static struct rc_map_list t2hybrid_map = {
+ .map = {
+ .scan = t2hybrid,
+ .size = ARRAY_SIZE(t2hybrid),
+ .rc_proto = RC_PROTO_NEC,
+ .name = RC_MAP_ASTROMETA_T2HYBRID,
+ }
+};
+
+static int __init init_rc_map_t2hybrid(void)
+{
+ return rc_map_register(&t2hybrid_map);
+}
+
+static void __exit exit_rc_map_t2hybrid(void)
+{
+ rc_map_unregister(&t2hybrid_map);
+}
+
+module_init(init_rc_map_t2hybrid)
+module_exit(exit_rc_map_t2hybrid)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>");
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index 9882e2cde975..6d5a73b7ccec 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -43,7 +43,8 @@ static struct rc_map_table avermedia_m135a[] = {
{ 0x0213, KEY_RIGHT }, /* -> or L */
{ 0x0212, KEY_LEFT }, /* <- or R */
- { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
+ { 0x0215, KEY_MENU },
+ { 0x0217, KEY_CAMERA }, /* Capturar Imagem or Snapshot */
{ 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
{ 0x0303, KEY_CHANNELUP },
diff --git a/drivers/media/rc/keymaps/rc-hisi-poplar.c b/drivers/media/rc/keymaps/rc-hisi-poplar.c
new file mode 100644
index 000000000000..78728bc7f63a
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-hisi-poplar.c
@@ -0,0 +1,69 @@
+/*
+ * Keytable for remote controller of HiSilicon poplar board.
+ *
+ * Copyright (c) 2017 HiSilicon Technologies Co., Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <media/rc-map.h>
+
+static struct rc_map_table hisi_poplar_keymap[] = {
+ { 0x0000b292, KEY_1},
+ { 0x0000b293, KEY_2},
+ { 0x0000b2cc, KEY_3},
+ { 0x0000b28e, KEY_4},
+ { 0x0000b28f, KEY_5},
+ { 0x0000b2c8, KEY_6},
+ { 0x0000b28a, KEY_7},
+ { 0x0000b28b, KEY_8},
+ { 0x0000b2c4, KEY_9},
+ { 0x0000b287, KEY_0},
+ { 0x0000b282, KEY_HOMEPAGE},
+ { 0x0000b2ca, KEY_UP},
+ { 0x0000b299, KEY_LEFT},
+ { 0x0000b2c1, KEY_RIGHT},
+ { 0x0000b2d2, KEY_DOWN},
+ { 0x0000b2c5, KEY_DELETE},
+ { 0x0000b29c, KEY_MUTE},
+ { 0x0000b281, KEY_VOLUMEDOWN},
+ { 0x0000b280, KEY_VOLUMEUP},
+ { 0x0000b2dc, KEY_POWER},
+ { 0x0000b29a, KEY_MENU},
+ { 0x0000b28d, KEY_SETUP},
+ { 0x0000b2c5, KEY_BACK},
+ { 0x0000b295, KEY_PLAYPAUSE},
+ { 0x0000b2ce, KEY_ENTER},
+ { 0x0000b285, KEY_CHANNELUP},
+ { 0x0000b286, KEY_CHANNELDOWN},
+ { 0x0000b2da, KEY_NUMERIC_STAR},
+ { 0x0000b2d0, KEY_NUMERIC_POUND},
+};
+
+static struct rc_map_list hisi_poplar_map = {
+ .map = {
+ .scan = hisi_poplar_keymap,
+ .size = ARRAY_SIZE(hisi_poplar_keymap),
+ .rc_proto = RC_PROTO_NEC,
+ .name = RC_MAP_HISI_POPLAR,
+ }
+};
+
+static int __init init_rc_map_hisi_poplar(void)
+{
+ return rc_map_register(&hisi_poplar_map);
+}
+
+static void __exit exit_rc_map_hisi_poplar(void)
+{
+ rc_map_unregister(&hisi_poplar_map);
+}
+
+module_init(init_rc_map_hisi_poplar)
+module_exit(exit_rc_map_hisi_poplar)
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/rc/keymaps/rc-hisi-tv-demo.c b/drivers/media/rc/keymaps/rc-hisi-tv-demo.c
new file mode 100644
index 000000000000..4816e3a4a18d
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-hisi-tv-demo.c
@@ -0,0 +1,81 @@
+/*
+ * Keytable for remote controller of HiSilicon tv demo board.
+ *
+ * Copyright (c) 2017 HiSilicon Technologies Co., Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <media/rc-map.h>
+
+static struct rc_map_table hisi_tv_demo_keymap[] = {
+ { 0x00000092, KEY_1},
+ { 0x00000093, KEY_2},
+ { 0x000000cc, KEY_3},
+ { 0x0000009f, KEY_4},
+ { 0x0000008e, KEY_5},
+ { 0x0000008f, KEY_6},
+ { 0x000000c8, KEY_7},
+ { 0x00000094, KEY_8},
+ { 0x0000008a, KEY_9},
+ { 0x0000008b, KEY_0},
+ { 0x000000ce, KEY_ENTER},
+ { 0x000000ca, KEY_UP},
+ { 0x00000099, KEY_LEFT},
+ { 0x00000084, KEY_PAGEUP},
+ { 0x000000c1, KEY_RIGHT},
+ { 0x000000d2, KEY_DOWN},
+ { 0x00000089, KEY_PAGEDOWN},
+ { 0x000000d1, KEY_MUTE},
+ { 0x00000098, KEY_VOLUMEDOWN},
+ { 0x00000090, KEY_VOLUMEUP},
+ { 0x0000009c, KEY_POWER},
+ { 0x000000d6, KEY_STOP},
+ { 0x00000097, KEY_MENU},
+ { 0x000000cb, KEY_BACK},
+ { 0x000000da, KEY_PLAYPAUSE},
+ { 0x00000080, KEY_INFO},
+ { 0x000000c3, KEY_REWIND},
+ { 0x00000087, KEY_HOMEPAGE},
+ { 0x000000d0, KEY_FASTFORWARD},
+ { 0x000000c4, KEY_SOUND},
+ { 0x00000082, BTN_1},
+ { 0x000000c7, BTN_2},
+ { 0x00000086, KEY_PROGRAM},
+ { 0x000000d9, KEY_SUBTITLE},
+ { 0x00000085, KEY_ZOOM},
+ { 0x0000009b, KEY_RED},
+ { 0x0000009a, KEY_GREEN},
+ { 0x000000c0, KEY_YELLOW},
+ { 0x000000c2, KEY_BLUE},
+ { 0x0000009d, KEY_CHANNELDOWN},
+ { 0x000000cf, KEY_CHANNELUP},
+};
+
+static struct rc_map_list hisi_tv_demo_map = {
+ .map = {
+ .scan = hisi_tv_demo_keymap,
+ .size = ARRAY_SIZE(hisi_tv_demo_keymap),
+ .rc_proto = RC_PROTO_NEC,
+ .name = RC_MAP_HISI_TV_DEMO,
+ }
+};
+
+static int __init init_rc_map_hisi_tv_demo(void)
+{
+ return rc_map_register(&hisi_tv_demo_map);
+}
+
+static void __exit exit_rc_map_hisi_tv_demo(void)
+{
+ rc_map_unregister(&hisi_tv_demo_map);
+}
+
+module_init(init_rc_map_hisi_tv_demo)
+module_exit(exit_rc_map_hisi_tv_demo)
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/rc/keymaps/rc-tango.c b/drivers/media/rc/keymaps/rc-tango.c
new file mode 100644
index 000000000000..1c6e8875d46f
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tango.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 Sigma Designs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <media/rc-map.h>
+
+static struct rc_map_table tango_table[] = {
+ { 0x4cb4a, KEY_POWER },
+ { 0x4cb48, KEY_FILE },
+ { 0x4cb0f, KEY_SETUP },
+ { 0x4cb4d, KEY_SUSPEND },
+ { 0x4cb4e, KEY_VOLUMEUP },
+ { 0x4cb44, KEY_EJECTCD },
+ { 0x4cb13, KEY_TV },
+ { 0x4cb51, KEY_MUTE },
+ { 0x4cb52, KEY_VOLUMEDOWN },
+
+ { 0x4cb41, KEY_1 },
+ { 0x4cb03, KEY_2 },
+ { 0x4cb42, KEY_3 },
+ { 0x4cb45, KEY_4 },
+ { 0x4cb07, KEY_5 },
+ { 0x4cb46, KEY_6 },
+ { 0x4cb55, KEY_7 },
+ { 0x4cb17, KEY_8 },
+ { 0x4cb56, KEY_9 },
+ { 0x4cb1b, KEY_0 },
+ { 0x4cb59, KEY_DELETE },
+ { 0x4cb5a, KEY_CAPSLOCK },
+
+ { 0x4cb47, KEY_BACK },
+ { 0x4cb05, KEY_SWITCHVIDEOMODE },
+ { 0x4cb06, KEY_UP },
+ { 0x4cb43, KEY_LEFT },
+ { 0x4cb01, KEY_RIGHT },
+ { 0x4cb0a, KEY_DOWN },
+ { 0x4cb02, KEY_ENTER },
+ { 0x4cb4b, KEY_INFO },
+ { 0x4cb09, KEY_HOME },
+
+ { 0x4cb53, KEY_MENU },
+ { 0x4cb12, KEY_PREVIOUS },
+ { 0x4cb50, KEY_PLAY },
+ { 0x4cb11, KEY_NEXT },
+ { 0x4cb4f, KEY_TITLE },
+ { 0x4cb0e, KEY_REWIND },
+ { 0x4cb4c, KEY_STOP },
+ { 0x4cb0d, KEY_FORWARD },
+ { 0x4cb57, KEY_MEDIA_REPEAT },
+ { 0x4cb16, KEY_ANGLE },
+ { 0x4cb54, KEY_PAUSE },
+ { 0x4cb15, KEY_SLOW },
+ { 0x4cb5b, KEY_TIME },
+ { 0x4cb1a, KEY_AUDIO },
+ { 0x4cb58, KEY_SUBTITLE },
+ { 0x4cb19, KEY_ZOOM },
+
+ { 0x4cb5f, KEY_RED },
+ { 0x4cb1e, KEY_GREEN },
+ { 0x4cb5c, KEY_YELLOW },
+ { 0x4cb1d, KEY_BLUE },
+};
+
+static struct rc_map_list tango_map = {
+ .map = {
+ .scan = tango_table,
+ .size = ARRAY_SIZE(tango_table),
+ .rc_proto = RC_PROTO_NECX,
+ .name = RC_MAP_TANGO,
+ }
+};
+
+static int __init init_rc_map_tango(void)
+{
+ return rc_map_register(&tango_map);
+}
+
+static void __exit exit_rc_map_tango(void)
+{
+ rc_map_unregister(&tango_map);
+}
+
+module_init(init_rc_map_tango)
+module_exit(exit_rc_map_tango)
+
+MODULE_AUTHOR("Sigma Designs");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c
index 2275b37c61d2..78bb3143a1a8 100644
--- a/drivers/media/rc/keymaps/rc-twinhan1027.c
+++ b/drivers/media/rc/keymaps/rc-twinhan1027.c
@@ -66,7 +66,7 @@ static struct rc_map_list twinhan_vp1027_map = {
.map = {
.scan = twinhan_vp1027,
.size = ARRAY_SIZE(twinhan_vp1027),
- .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */
+ .rc_proto = RC_PROTO_NEC,
.name = RC_MAP_TWINHAN_VP1027_DVBS,
}
};
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 9080e39ea391..e16d1138ca48 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -24,96 +24,91 @@
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/cdev.h>
+#include <linux/idr.h>
#include <media/rc-core.h>
#include <media/lirc.h>
#include <media/lirc_dev.h>
-#define NOPLUG -1
#define LOGHEAD "lirc_dev (%s[%d]): "
static dev_t lirc_base_dev;
-struct irctl {
- struct lirc_driver d;
- int attached;
- int open;
+/* Used to keep track of allocated lirc devices */
+#define LIRC_MAX_DEVICES 256
+static DEFINE_IDA(lirc_ida);
- struct mutex irctl_lock;
- struct lirc_buffer *buf;
- bool buf_internal;
- unsigned int chunk_size;
-
- struct device dev;
- struct cdev cdev;
-};
+/* Only used for sysfs but defined to void otherwise */
+static struct class *lirc_class;
-static DEFINE_MUTEX(lirc_dev_lock);
+static void lirc_release_device(struct device *ld)
+{
+ struct lirc_dev *d = container_of(ld, struct lirc_dev, dev);
-static struct irctl *irctls[MAX_IRCTL_DEVICES];
+ put_device(d->dev.parent);
-/* Only used for sysfs but defined to void otherwise */
-static struct class *lirc_class;
+ if (d->buf_internal) {
+ lirc_buffer_free(d->buf);
+ kfree(d->buf);
+ d->buf = NULL;
+ }
+ kfree(d);
+ module_put(THIS_MODULE);
+}
-static void lirc_release(struct device *ld)
+static int lirc_allocate_buffer(struct lirc_dev *d)
{
- struct irctl *ir = container_of(ld, struct irctl, dev);
+ int err;
- put_device(ir->dev.parent);
+ if (d->buf) {
+ d->buf_internal = false;
+ return 0;
+ }
- if (ir->buf_internal) {
- lirc_buffer_free(ir->buf);
- kfree(ir->buf);
+ d->buf = kmalloc(sizeof(*d->buf), GFP_KERNEL);
+ if (!d->buf)
+ return -ENOMEM;
+
+ err = lirc_buffer_init(d->buf, d->chunk_size, d->buffer_size);
+ if (err) {
+ kfree(d->buf);
+ d->buf = NULL;
+ return err;
}
- mutex_lock(&lirc_dev_lock);
- irctls[ir->d.minor] = NULL;
- mutex_unlock(&lirc_dev_lock);
- kfree(ir);
+ d->buf_internal = true;
+ return 0;
}
-static int lirc_allocate_buffer(struct irctl *ir)
+struct lirc_dev *
+lirc_allocate_device(void)
{
- int err = 0;
- int bytes_in_key;
- unsigned int chunk_size;
- unsigned int buffer_size;
- struct lirc_driver *d = &ir->d;
-
- bytes_in_key = BITS_TO_LONGS(d->code_length) +
- (d->code_length % 8 ? 1 : 0);
- buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key;
- chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key;
-
- if (d->rbuf) {
- ir->buf = d->rbuf;
- ir->buf_internal = false;
- } else {
- ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
- if (!ir->buf) {
- err = -ENOMEM;
- goto out;
- }
+ struct lirc_dev *d;
- err = lirc_buffer_init(ir->buf, chunk_size, buffer_size);
- if (err) {
- kfree(ir->buf);
- ir->buf = NULL;
- goto out;
- }
-
- ir->buf_internal = true;
- d->rbuf = ir->buf;
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
+ if (d) {
+ mutex_init(&d->mutex);
+ device_initialize(&d->dev);
+ d->dev.class = lirc_class;
+ d->dev.release = lirc_release_device;
+ __module_get(THIS_MODULE);
}
- ir->chunk_size = ir->buf->chunk_size;
-out:
- return err;
+ return d;
}
+EXPORT_SYMBOL(lirc_allocate_device);
-int lirc_register_driver(struct lirc_driver *d)
+void lirc_free_device(struct lirc_dev *d)
+{
+ if (!d)
+ return;
+
+ put_device(&d->dev);
+}
+EXPORT_SYMBOL(lirc_free_device);
+
+int lirc_register_device(struct lirc_dev *d)
{
- struct irctl *ir;
int minor;
int err;
@@ -122,8 +117,8 @@ int lirc_register_driver(struct lirc_driver *d)
return -EBADRQC;
}
- if (!d->dev) {
- pr_err("dev pointer not filled in!\n");
+ if (!d->dev.parent) {
+ pr_err("dev parent pointer not filled in!\n");
return -EINVAL;
}
@@ -132,226 +127,146 @@ int lirc_register_driver(struct lirc_driver *d)
return -EINVAL;
}
- if (d->minor >= MAX_IRCTL_DEVICES) {
- dev_err(d->dev, "minor must be between 0 and %d!\n",
- MAX_IRCTL_DEVICES - 1);
- return -EBADRQC;
+ if (!d->buf && d->chunk_size < 1) {
+ pr_err("chunk_size must be set!\n");
+ return -EINVAL;
}
- if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) {
- dev_err(d->dev, "code length must be less than %d bits\n",
- BUFLEN * 8);
- return -EBADRQC;
+ if (!d->buf && d->buffer_size < 1) {
+ pr_err("buffer_size must be set!\n");
+ return -EINVAL;
}
- if (!d->rbuf && !(d->fops && d->fops->read &&
- d->fops->poll && d->fops->unlocked_ioctl)) {
- dev_err(d->dev, "undefined read, poll, ioctl\n");
+ if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) {
+ dev_err(&d->dev, "code length must be less than %d bits\n",
+ BUFLEN * 8);
return -EBADRQC;
}
- mutex_lock(&lirc_dev_lock);
-
- minor = d->minor;
-
- if (minor < 0) {
- /* find first free slot for driver */
- for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
- if (!irctls[minor])
- break;
- if (minor == MAX_IRCTL_DEVICES) {
- dev_err(d->dev, "no free slots for drivers!\n");
- err = -ENOMEM;
- goto out_lock;
- }
- } else if (irctls[minor]) {
- dev_err(d->dev, "minor (%d) just registered!\n", minor);
- err = -EBUSY;
- goto out_lock;
- }
-
- ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
- if (!ir) {
- err = -ENOMEM;
- goto out_lock;
+ if (!d->buf && !(d->fops && d->fops->read &&
+ d->fops->poll && d->fops->unlocked_ioctl)) {
+ dev_err(&d->dev, "undefined read, poll, ioctl\n");
+ return -EBADRQC;
}
- mutex_init(&ir->irctl_lock);
- irctls[minor] = ir;
- d->minor = minor;
-
/* some safety check 8-) */
- d->name[sizeof(d->name)-1] = '\0';
+ d->name[sizeof(d->name) - 1] = '\0';
if (d->features == 0)
d->features = LIRC_CAN_REC_LIRCCODE;
- ir->d = *d;
-
if (LIRC_CAN_REC(d->features)) {
- err = lirc_allocate_buffer(irctls[minor]);
- if (err) {
- kfree(ir);
- goto out_lock;
- }
- d->rbuf = ir->buf;
+ err = lirc_allocate_buffer(d);
+ if (err)
+ return err;
}
- device_initialize(&ir->dev);
- ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor);
- ir->dev.class = lirc_class;
- ir->dev.parent = d->dev;
- ir->dev.release = lirc_release;
- dev_set_name(&ir->dev, "lirc%d", ir->d.minor);
+ minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
+ if (minor < 0)
+ return minor;
- cdev_init(&ir->cdev, d->fops);
- ir->cdev.owner = ir->d.owner;
- ir->cdev.kobj.parent = &ir->dev.kobj;
-
- err = cdev_add(&ir->cdev, ir->dev.devt, 1);
- if (err)
- goto out_free_dev;
-
- ir->attached = 1;
-
- err = device_add(&ir->dev);
- if (err)
- goto out_cdev;
-
- mutex_unlock(&lirc_dev_lock);
+ d->minor = minor;
+ d->dev.devt = MKDEV(MAJOR(lirc_base_dev), d->minor);
+ dev_set_name(&d->dev, "lirc%d", d->minor);
- get_device(ir->dev.parent);
+ cdev_init(&d->cdev, d->fops);
+ d->cdev.owner = d->owner;
+ d->attached = true;
- dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
- ir->d.name, ir->d.minor);
+ err = cdev_device_add(&d->cdev, &d->dev);
+ if (err) {
+ ida_simple_remove(&lirc_ida, minor);
+ return err;
+ }
- return minor;
+ get_device(d->dev.parent);
-out_cdev:
- cdev_del(&ir->cdev);
-out_free_dev:
- put_device(&ir->dev);
-out_lock:
- mutex_unlock(&lirc_dev_lock);
+ dev_info(&d->dev, "lirc_dev: driver %s registered at minor = %d\n",
+ d->name, d->minor);
- return err;
+ return 0;
}
-EXPORT_SYMBOL(lirc_register_driver);
+EXPORT_SYMBOL(lirc_register_device);
-int lirc_unregister_driver(int minor)
+void lirc_unregister_device(struct lirc_dev *d)
{
- struct irctl *ir;
+ if (!d)
+ return;
- if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
- pr_err("minor (%d) must be between 0 and %d!\n",
- minor, MAX_IRCTL_DEVICES - 1);
- return -EBADRQC;
- }
-
- ir = irctls[minor];
- if (!ir) {
- pr_err("failed to get irctl\n");
- return -ENOENT;
- }
+ dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
+ d->name, d->minor);
- mutex_lock(&lirc_dev_lock);
+ mutex_lock(&d->mutex);
- if (ir->d.minor != minor) {
- dev_err(ir->d.dev, "lirc_dev: minor %d device not registered\n",
- minor);
- mutex_unlock(&lirc_dev_lock);
- return -ENOENT;
+ d->attached = false;
+ if (d->open) {
+ dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
+ d->name, d->minor);
+ wake_up_interruptible(&d->buf->wait_poll);
}
- dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n",
- ir->d.name, ir->d.minor);
-
- ir->attached = 0;
- if (ir->open) {
- dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n",
- ir->d.name, ir->d.minor);
- wake_up_interruptible(&ir->buf->wait_poll);
- }
+ mutex_unlock(&d->mutex);
- mutex_unlock(&lirc_dev_lock);
-
- device_del(&ir->dev);
- cdev_del(&ir->cdev);
- put_device(&ir->dev);
-
- return 0;
+ cdev_device_del(&d->cdev, &d->dev);
+ ida_simple_remove(&lirc_ida, d->minor);
+ put_device(&d->dev);
}
-EXPORT_SYMBOL(lirc_unregister_driver);
+EXPORT_SYMBOL(lirc_unregister_device);
int lirc_dev_fop_open(struct inode *inode, struct file *file)
{
- struct irctl *ir;
- int retval = 0;
-
- if (iminor(inode) >= MAX_IRCTL_DEVICES) {
- pr_err("open result for %d is -ENODEV\n", iminor(inode));
- return -ENODEV;
- }
-
- if (mutex_lock_interruptible(&lirc_dev_lock))
- return -ERESTARTSYS;
-
- ir = irctls[iminor(inode)];
- mutex_unlock(&lirc_dev_lock);
+ struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+ int retval;
- if (!ir) {
- retval = -ENODEV;
- goto error;
- }
+ dev_dbg(&d->dev, LOGHEAD "open called\n", d->name, d->minor);
- dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
+ retval = mutex_lock_interruptible(&d->mutex);
+ if (retval)
+ return retval;
- if (ir->d.minor == NOPLUG) {
+ if (!d->attached) {
retval = -ENODEV;
- goto error;
+ goto out;
}
- if (ir->open) {
+ if (d->open) {
retval = -EBUSY;
- goto error;
+ goto out;
}
- if (ir->d.rdev) {
- retval = rc_open(ir->d.rdev);
+ if (d->rdev) {
+ retval = rc_open(d->rdev);
if (retval)
- goto error;
+ goto out;
}
- if (ir->buf)
- lirc_buffer_clear(ir->buf);
+ if (d->buf)
+ lirc_buffer_clear(d->buf);
- ir->open++;
+ d->open++;
-error:
+ lirc_init_pdata(inode, file);
nonseekable_open(inode, file);
+ mutex_unlock(&d->mutex);
+
+ return 0;
+out:
+ mutex_unlock(&d->mutex);
return retval;
}
EXPORT_SYMBOL(lirc_dev_fop_open);
int lirc_dev_fop_close(struct inode *inode, struct file *file)
{
- struct irctl *ir = irctls[iminor(inode)];
- int ret;
-
- if (!ir) {
- pr_err("called with invalid irctl\n");
- return -EINVAL;
- }
+ struct lirc_dev *d = file->private_data;
- ret = mutex_lock_killable(&lirc_dev_lock);
- WARN_ON(ret);
+ mutex_lock(&d->mutex);
- rc_close(ir->d.rdev);
+ rc_close(d->rdev);
+ d->open--;
- ir->open--;
- if (!ret)
- mutex_unlock(&lirc_dev_lock);
+ mutex_unlock(&d->mutex);
return 0;
}
@@ -359,29 +274,24 @@ EXPORT_SYMBOL(lirc_dev_fop_close);
unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
{
- struct irctl *ir = irctls[iminor(file_inode(file))];
+ struct lirc_dev *d = file->private_data;
unsigned int ret;
- if (!ir) {
- pr_err("called with invalid irctl\n");
- return POLLERR;
- }
-
- if (!ir->attached)
+ if (!d->attached)
return POLLHUP | POLLERR;
- if (ir->buf) {
- poll_wait(file, &ir->buf->wait_poll, wait);
+ if (d->buf) {
+ poll_wait(file, &d->buf->wait_poll, wait);
- if (lirc_buffer_empty(ir->buf))
+ if (lirc_buffer_empty(d->buf))
ret = 0;
else
ret = POLLIN | POLLRDNORM;
- } else
+ } else {
ret = POLLERR;
+ }
- dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n",
- ir->d.name, ir->d.minor, ret);
+ dev_dbg(&d->dev, LOGHEAD "poll result = %d\n", d->name, d->minor, ret);
return ret;
}
@@ -389,48 +299,44 @@ EXPORT_SYMBOL(lirc_dev_fop_poll);
long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
+ struct lirc_dev *d = file->private_data;
__u32 mode;
- int result = 0;
- struct irctl *ir = irctls[iminor(file_inode(file))];
+ int result;
- if (!ir) {
- pr_err("no irctl found!\n");
- return -ENODEV;
- }
+ dev_dbg(&d->dev, LOGHEAD "ioctl called (0x%x)\n",
+ d->name, d->minor, cmd);
- dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
- ir->d.name, ir->d.minor, cmd);
+ result = mutex_lock_interruptible(&d->mutex);
+ if (result)
+ return result;
- if (ir->d.minor == NOPLUG || !ir->attached) {
- dev_err(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n",
- ir->d.name, ir->d.minor);
- return -ENODEV;
+ if (!d->attached) {
+ result = -ENODEV;
+ goto out;
}
- mutex_lock(&ir->irctl_lock);
-
switch (cmd) {
case LIRC_GET_FEATURES:
- result = put_user(ir->d.features, (__u32 __user *)arg);
+ result = put_user(d->features, (__u32 __user *)arg);
break;
case LIRC_GET_REC_MODE:
- if (!LIRC_CAN_REC(ir->d.features)) {
+ if (!LIRC_CAN_REC(d->features)) {
result = -ENOTTY;
break;
}
result = put_user(LIRC_REC2MODE
- (ir->d.features & LIRC_CAN_REC_MASK),
+ (d->features & LIRC_CAN_REC_MASK),
(__u32 __user *)arg);
break;
case LIRC_SET_REC_MODE:
- if (!LIRC_CAN_REC(ir->d.features)) {
+ if (!LIRC_CAN_REC(d->features)) {
result = -ENOTTY;
break;
}
result = get_user(mode, (__u32 __user *)arg);
- if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
+ if (!result && !(LIRC_MODE2REC(mode) & d->features))
result = -EINVAL;
/*
* FIXME: We should actually set the mode somehow but
@@ -438,32 +344,14 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/
break;
case LIRC_GET_LENGTH:
- result = put_user(ir->d.code_length, (__u32 __user *)arg);
- break;
- case LIRC_GET_MIN_TIMEOUT:
- if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
- ir->d.min_timeout == 0) {
- result = -ENOTTY;
- break;
- }
-
- result = put_user(ir->d.min_timeout, (__u32 __user *)arg);
- break;
- case LIRC_GET_MAX_TIMEOUT:
- if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
- ir->d.max_timeout == 0) {
- result = -ENOTTY;
- break;
- }
-
- result = put_user(ir->d.max_timeout, (__u32 __user *)arg);
+ result = put_user(d->code_length, (__u32 __user *)arg);
break;
default:
result = -ENOTTY;
}
- mutex_unlock(&ir->irctl_lock);
-
+out:
+ mutex_unlock(&d->mutex);
return result;
}
EXPORT_SYMBOL(lirc_dev_fop_ioctl);
@@ -473,35 +361,34 @@ ssize_t lirc_dev_fop_read(struct file *file,
size_t length,
loff_t *ppos)
{
- struct irctl *ir = irctls[iminor(file_inode(file))];
+ struct lirc_dev *d = file->private_data;
unsigned char *buf;
- int ret = 0, written = 0;
+ int ret, written = 0;
DECLARE_WAITQUEUE(wait, current);
- if (!ir) {
- pr_err("called with invalid irctl\n");
- return -ENODEV;
- }
-
- if (!LIRC_CAN_REC(ir->d.features))
- return -EINVAL;
-
- dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
-
- buf = kzalloc(ir->chunk_size, GFP_KERNEL);
+ buf = kzalloc(d->buf->chunk_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- if (mutex_lock_interruptible(&ir->irctl_lock)) {
- ret = -ERESTARTSYS;
- goto out_unlocked;
+ dev_dbg(&d->dev, LOGHEAD "read called\n", d->name, d->minor);
+
+ ret = mutex_lock_interruptible(&d->mutex);
+ if (ret) {
+ kfree(buf);
+ return ret;
}
- if (!ir->attached) {
+
+ if (!d->attached) {
ret = -ENODEV;
goto out_locked;
}
- if (length % ir->chunk_size) {
+ if (!LIRC_CAN_REC(d->features)) {
+ ret = -EINVAL;
+ goto out_locked;
+ }
+
+ if (length % d->buf->chunk_size) {
ret = -EINVAL;
goto out_locked;
}
@@ -511,14 +398,14 @@ ssize_t lirc_dev_fop_read(struct file *file,
* to avoid losing scan code (in case when queue is awaken somewhere
* between while condition checking and scheduling)
*/
- add_wait_queue(&ir->buf->wait_poll, &wait);
+ add_wait_queue(&d->buf->wait_poll, &wait);
/*
* while we didn't provide 'length' bytes, device is opened in blocking
* mode and 'copy_to_user' is happy, wait for data.
*/
while (written < length && ret == 0) {
- if (lirc_buffer_empty(ir->buf)) {
+ if (lirc_buffer_empty(d->buf)) {
/* According to the read(2) man page, 'written' can be
* returned as less than 'length', instead of blocking
* again, returning -EWOULDBLOCK, or returning
@@ -535,36 +422,36 @@ ssize_t lirc_dev_fop_read(struct file *file,
break;
}
- mutex_unlock(&ir->irctl_lock);
+ mutex_unlock(&d->mutex);
set_current_state(TASK_INTERRUPTIBLE);
schedule();
set_current_state(TASK_RUNNING);
- if (mutex_lock_interruptible(&ir->irctl_lock)) {
- ret = -ERESTARTSYS;
- remove_wait_queue(&ir->buf->wait_poll, &wait);
+ ret = mutex_lock_interruptible(&d->mutex);
+ if (ret) {
+ remove_wait_queue(&d->buf->wait_poll, &wait);
goto out_unlocked;
}
- if (!ir->attached) {
+ if (!d->attached) {
ret = -ENODEV;
goto out_locked;
}
} else {
- lirc_buffer_read(ir->buf, buf);
+ lirc_buffer_read(d->buf, buf);
ret = copy_to_user((void __user *)buffer+written, buf,
- ir->buf->chunk_size);
+ d->buf->chunk_size);
if (!ret)
- written += ir->buf->chunk_size;
+ written += d->buf->chunk_size;
else
ret = -EFAULT;
}
}
- remove_wait_queue(&ir->buf->wait_poll, &wait);
+ remove_wait_queue(&d->buf->wait_poll, &wait);
out_locked:
- mutex_unlock(&ir->irctl_lock);
+ mutex_unlock(&d->mutex);
out_unlocked:
kfree(buf);
@@ -573,9 +460,19 @@ out_unlocked:
}
EXPORT_SYMBOL(lirc_dev_fop_read);
+void lirc_init_pdata(struct inode *inode, struct file *file)
+{
+ struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+
+ file->private_data = d;
+}
+EXPORT_SYMBOL(lirc_init_pdata);
+
void *lirc_get_pdata(struct file *file)
{
- return irctls[iminor(file_inode(file))]->d.data;
+ struct lirc_dev *d = file->private_data;
+
+ return d->data;
}
EXPORT_SYMBOL(lirc_get_pdata);
@@ -590,7 +487,7 @@ static int __init lirc_dev_init(void)
return PTR_ERR(lirc_class);
}
- retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES,
+ retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
"BaseRemoteCtl");
if (retval) {
class_destroy(lirc_class);
@@ -607,7 +504,7 @@ static int __init lirc_dev_init(void)
static void __exit lirc_dev_exit(void)
{
class_destroy(lirc_class);
- unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES);
+ unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);
pr_info("module unloaded\n");
}
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index bf7aaff3aa37..a9187b0b46a1 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -188,6 +188,8 @@ enum mceusb_model_type {
TIVO_KIT,
MCE_GEN2_NO_TX,
HAUPPAUGE_CX_HYBRID_TV,
+ EVROMEDIA_FULL_HYBRID_FULLHD,
+ ASTROMETA_T2HYBRID,
};
struct mceusb_model {
@@ -247,9 +249,19 @@ static const struct mceusb_model mceusb_model[] = {
.mce_gen2 = 1,
.rc_map = RC_MAP_TIVO,
},
+ [EVROMEDIA_FULL_HYBRID_FULLHD] = {
+ .name = "Evromedia USB Full Hybrid Full HD",
+ .no_tx = 1,
+ .rc_map = RC_MAP_MSI_DIGIVOX_III,
+ },
+ [ASTROMETA_T2HYBRID] = {
+ .name = "Astrometa T2Hybrid",
+ .no_tx = 1,
+ .rc_map = RC_MAP_ASTROMETA_T2HYBRID,
+ }
};
-static struct usb_device_id mceusb_dev_table[] = {
+static const struct usb_device_id mceusb_dev_table[] = {
/* Original Microsoft MCE IR Transceiver (often HP-branded) */
{ USB_DEVICE(VENDOR_MICROSOFT, 0x006d),
.driver_info = MCE_GEN1 },
@@ -398,6 +410,12 @@ static struct usb_device_id mceusb_dev_table[] = {
.driver_info = HAUPPAUGE_CX_HYBRID_TV },
/* Adaptec / HP eHome Receiver */
{ USB_DEVICE(VENDOR_ADAPTEC, 0x0094) },
+ /* Evromedia USB Full Hybrid Full HD */
+ { USB_DEVICE(0x1b80, 0xd3b2),
+ .driver_info = EVROMEDIA_FULL_HYBRID_FULLHD },
+ /* Astrometa T2hybrid */
+ { USB_DEVICE(0x15f4, 0x0135),
+ .driver_info = ASTROMETA_T2HYBRID },
/* Terminating entry */
{ }
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 7da9c96cb058..ae4dd0c27731 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -106,7 +106,7 @@ struct ir_raw_event_ctrl {
} mce_kbd;
struct lirc_codec {
struct rc_dev *dev;
- struct lirc_driver *drv;
+ struct lirc_dev *ldev;
int carrier_low;
ktime_t gap_start;
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 503bc425a187..d78483a504c9 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
/**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing
* @dev: the struct rc_dev device descriptor
- * @type: the type of the event that has occurred
+ * @ev: the event that has occurred
*
* This routine (which may be called from an interrupt context) works
* in similar manner to ir_raw_event_store_edge.
@@ -471,9 +471,10 @@ int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
}
EXPORT_SYMBOL(ir_raw_encode_scancode);
-static void edge_handle(unsigned long arg)
+static void edge_handle(struct timer_list *t)
{
- struct rc_dev *dev = (struct rc_dev *)arg;
+ struct ir_raw_event_ctrl *raw = from_timer(raw, t, edge_handle);
+ struct rc_dev *dev = raw->dev;
ktime_t interval = ktime_sub(ktime_get(), dev->raw->last_event);
if (ktime_to_ns(interval) >= dev->timeout) {
@@ -513,8 +514,7 @@ int ir_raw_event_prepare(struct rc_dev *dev)
dev->raw->dev = dev;
dev->change_protocol = change_protocol;
- setup_timer(&dev->raw->edge_handle, edge_handle,
- (unsigned long)dev);
+ timer_setup(&dev->raw->edge_handle, edge_handle, 0);
INIT_KFIFO(dev->raw->kfifo);
return 0;
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 981cccd6b988..c144b77eac98 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -15,6 +15,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/rc-core.h>
+#include <linux/bsearch.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/input.h>
@@ -38,41 +39,41 @@ static const struct {
[RC_PROTO_UNKNOWN] = { .name = "unknown", .repeat_period = 250 },
[RC_PROTO_OTHER] = { .name = "other", .repeat_period = 250 },
[RC_PROTO_RC5] = { .name = "rc-5",
- .scancode_bits = 0x1f7f, .repeat_period = 164 },
+ .scancode_bits = 0x1f7f, .repeat_period = 250 },
[RC_PROTO_RC5X_20] = { .name = "rc-5x-20",
- .scancode_bits = 0x1f7f3f, .repeat_period = 164 },
+ .scancode_bits = 0x1f7f3f, .repeat_period = 250 },
[RC_PROTO_RC5_SZ] = { .name = "rc-5-sz",
- .scancode_bits = 0x2fff, .repeat_period = 164 },
+ .scancode_bits = 0x2fff, .repeat_period = 250 },
[RC_PROTO_JVC] = { .name = "jvc",
.scancode_bits = 0xffff, .repeat_period = 250 },
[RC_PROTO_SONY12] = { .name = "sony-12",
- .scancode_bits = 0x1f007f, .repeat_period = 100 },
+ .scancode_bits = 0x1f007f, .repeat_period = 250 },
[RC_PROTO_SONY15] = { .name = "sony-15",
- .scancode_bits = 0xff007f, .repeat_period = 100 },
+ .scancode_bits = 0xff007f, .repeat_period = 250 },
[RC_PROTO_SONY20] = { .name = "sony-20",
- .scancode_bits = 0x1fff7f, .repeat_period = 100 },
+ .scancode_bits = 0x1fff7f, .repeat_period = 250 },
[RC_PROTO_NEC] = { .name = "nec",
- .scancode_bits = 0xffff, .repeat_period = 160 },
+ .scancode_bits = 0xffff, .repeat_period = 250 },
[RC_PROTO_NECX] = { .name = "nec-x",
- .scancode_bits = 0xffffff, .repeat_period = 160 },
+ .scancode_bits = 0xffffff, .repeat_period = 250 },
[RC_PROTO_NEC32] = { .name = "nec-32",
- .scancode_bits = 0xffffffff, .repeat_period = 160 },
+ .scancode_bits = 0xffffffff, .repeat_period = 250 },
[RC_PROTO_SANYO] = { .name = "sanyo",
.scancode_bits = 0x1fffff, .repeat_period = 250 },
[RC_PROTO_MCIR2_KBD] = { .name = "mcir2-kbd",
- .scancode_bits = 0xffff, .repeat_period = 150 },
+ .scancode_bits = 0xffff, .repeat_period = 250 },
[RC_PROTO_MCIR2_MSE] = { .name = "mcir2-mse",
- .scancode_bits = 0x1fffff, .repeat_period = 150 },
+ .scancode_bits = 0x1fffff, .repeat_period = 250 },
[RC_PROTO_RC6_0] = { .name = "rc-6-0",
- .scancode_bits = 0xffff, .repeat_period = 164 },
+ .scancode_bits = 0xffff, .repeat_period = 250 },
[RC_PROTO_RC6_6A_20] = { .name = "rc-6-6a-20",
- .scancode_bits = 0xfffff, .repeat_period = 164 },
+ .scancode_bits = 0xfffff, .repeat_period = 250 },
[RC_PROTO_RC6_6A_24] = { .name = "rc-6-6a-24",
- .scancode_bits = 0xffffff, .repeat_period = 164 },
+ .scancode_bits = 0xffffff, .repeat_period = 250 },
[RC_PROTO_RC6_6A_32] = { .name = "rc-6-6a-32",
- .scancode_bits = 0xffffffff, .repeat_period = 164 },
+ .scancode_bits = 0xffffffff, .repeat_period = 250 },
[RC_PROTO_RC6_MCE] = { .name = "rc-6-mce",
- .scancode_bits = 0xffff7fff, .repeat_period = 164 },
+ .scancode_bits = 0xffff7fff, .repeat_period = 250 },
[RC_PROTO_SHARP] = { .name = "sharp",
.scancode_bits = 0x1fff, .repeat_period = 250 },
[RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 250 },
@@ -169,10 +170,11 @@ static struct rc_map_list empty_map = {
* @name: name to assign to the table
* @rc_proto: ir type to assign to the new table
* @size: initial size of the table
- * @return: zero on success or a negative error code
*
* This routine will initialize the rc_map and will allocate
* memory to hold at least the specified number of elements.
+ *
+ * return: zero on success or a negative error code
*/
static int ir_create_table(struct rc_map *rc_map,
const char *name, u64 rc_proto, size_t size)
@@ -215,10 +217,11 @@ static void ir_free_table(struct rc_map *rc_map)
* ir_resize_table() - resizes a scancode table if necessary
* @rc_map: the rc_map to resize
* @gfp_flags: gfp flags to use when allocating memory
- * @return: zero on success or a negative error code
*
* This routine will shrink the rc_map if it has lots of
* unused entries and grow it if it is full.
+ *
+ * return: zero on success or a negative error code
*/
static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags)
{
@@ -264,11 +267,13 @@ static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags)
* @dev: the struct rc_dev device descriptor
* @rc_map: scancode table to be adjusted
* @index: index of the mapping that needs to be updated
- * @keycode: the desired keycode
- * @return: previous keycode assigned to the mapping
+ * @new_keycode: the desired keycode
*
* This routine is used to update scancode->keycode mapping at given
* position.
+ *
+ * return: previous keycode assigned to the mapping
+ *
*/
static unsigned int ir_update_mapping(struct rc_dev *dev,
struct rc_map *rc_map,
@@ -319,12 +324,13 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,
* @scancode: the desired scancode
* @resize: controls whether we allowed to resize the table to
* accommodate not yet present scancodes
- * @return: index of the mapping containing scancode in question
- * or -1U in case of failure.
*
* This routine is used to locate given scancode in rc_map.
* If scancode is not yet present the routine will allocate a new slot
* for it.
+ *
+ * return: index of the mapping containing scancode in question
+ * or -1U in case of failure.
*/
static unsigned int ir_establish_scancode(struct rc_dev *dev,
struct rc_map *rc_map,
@@ -374,11 +380,12 @@ static unsigned int ir_establish_scancode(struct rc_dev *dev,
/**
* ir_setkeycode() - set a keycode in the scancode->keycode table
* @idev: the struct input_dev device descriptor
- * @scancode: the desired scancode
- * @keycode: result
- * @return: -EINVAL if the keycode could not be inserted, otherwise zero.
+ * @ke: Input keymap entry
+ * @old_keycode: result
*
* This routine is used to handle evdev EVIOCSKEY ioctl.
+ *
+ * return: -EINVAL if the keycode could not be inserted, otherwise zero.
*/
static int ir_setkeycode(struct input_dev *idev,
const struct input_keymap_entry *ke,
@@ -421,11 +428,11 @@ out:
/**
* ir_setkeytable() - sets several entries in the scancode->keycode table
* @dev: the struct rc_dev device descriptor
- * @to: the struct rc_map to copy entries to
* @from: the struct rc_map to copy entries from
- * @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*
* This routine is used to handle table initialization.
+ *
+ * return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*/
static int ir_setkeytable(struct rc_dev *dev,
const struct rc_map *from)
@@ -439,9 +446,6 @@ static int ir_setkeytable(struct rc_dev *dev,
if (rc)
return rc;
- IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n",
- rc_map->size, rc_map->alloc);
-
for (i = 0; i < from->size; i++) {
index = ir_establish_scancode(dev, rc_map,
from->scan[i].scancode, false);
@@ -460,43 +464,49 @@ static int ir_setkeytable(struct rc_dev *dev,
return rc;
}
+static int rc_map_cmp(const void *key, const void *elt)
+{
+ const unsigned int *scancode = key;
+ const struct rc_map_table *e = elt;
+
+ if (*scancode < e->scancode)
+ return -1;
+ else if (*scancode > e->scancode)
+ return 1;
+ return 0;
+}
+
/**
* ir_lookup_by_scancode() - locate mapping by scancode
* @rc_map: the struct rc_map to search
* @scancode: scancode to look for in the table
- * @return: index in the table, -1U if not found
*
* This routine performs binary search in RC keykeymap table for
* given scancode.
+ *
+ * return: index in the table, -1U if not found
*/
static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
unsigned int scancode)
{
- int start = 0;
- int end = rc_map->len - 1;
- int mid;
-
- while (start <= end) {
- mid = (start + end) / 2;
- if (rc_map->scan[mid].scancode < scancode)
- start = mid + 1;
- else if (rc_map->scan[mid].scancode > scancode)
- end = mid - 1;
- else
- return mid;
- }
+ struct rc_map_table *res;
- return -1U;
+ res = bsearch(&scancode, rc_map->scan, rc_map->len,
+ sizeof(struct rc_map_table), rc_map_cmp);
+ if (!res)
+ return -1U;
+ else
+ return res - rc_map->scan;
}
/**
* ir_getkeycode() - get a keycode from the scancode->keycode table
* @idev: the struct input_dev device descriptor
- * @scancode: the desired scancode
- * @keycode: used to return the keycode, if found, or KEY_RESERVED
- * @return: always returns zero.
+ * @ke: Input keymap entry
*
* This routine is used to handle evdev EVIOCGKEY ioctl.
+ *
+ * return: always returns zero.
*/
static int ir_getkeycode(struct input_dev *idev,
struct input_keymap_entry *ke)
@@ -553,11 +563,12 @@ out:
* rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode
* @dev: the struct rc_dev descriptor of the device
* @scancode: the scancode to look for
- * @return: the corresponding keycode, or KEY_RESERVED
*
* This routine is used by drivers which need to convert a scancode to a
* keycode. Normally it should not be used since drivers should have no
* interest in keycodes.
+ *
+ * return: the corresponding keycode, or KEY_RESERVED
*/
u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
{
@@ -622,14 +633,15 @@ EXPORT_SYMBOL_GPL(rc_keyup);
/**
* ir_timer_keyup() - generates a keyup event after a timeout
- * @cookie: a pointer to the struct rc_dev for the device
+ *
+ * @t: a pointer to the struct timer_list
*
* This routine will generate a keyup event some time after a keydown event
* is generated when no further activity has been detected.
*/
-static void ir_timer_keyup(unsigned long cookie)
+static void ir_timer_keyup(struct timer_list *t)
{
- struct rc_dev *dev = (struct rc_dev *)cookie;
+ struct rc_dev *dev = from_timer(dev, t, timer_keyup);
unsigned long flags;
/*
@@ -777,7 +789,8 @@ EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
* provides sensible defaults
* @dev: the struct rc_dev descriptor of the device
* @filter: the scancode and mask
- * @return: 0 or -EINVAL if the filter is not valid
+ *
+ * return: 0 or -EINVAL if the filter is not valid
*/
static int rc_validate_filter(struct rc_dev *dev,
struct rc_scancode_filter *filter)
@@ -1480,6 +1493,8 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
if (dev->driver_name)
ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
+ if (dev->device_name)
+ ADD_HOTPLUG_VAR("DEV_NAME=%s", dev->device_name);
return 0;
}
@@ -1487,7 +1502,10 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
/*
* Static device attribute struct with the sysfs attributes for IR's
*/
-static DEVICE_ATTR(protocols, 0644, show_protocols, store_protocols);
+static struct device_attribute dev_attr_ro_protocols =
+__ATTR(protocols, 0444, show_protocols, NULL);
+static struct device_attribute dev_attr_rw_protocols =
+__ATTR(protocols, 0644, show_protocols, store_protocols);
static DEVICE_ATTR(wakeup_protocols, 0644, show_wakeup_protocols,
store_wakeup_protocols);
static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR,
@@ -1499,13 +1517,22 @@ static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR,
static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR,
show_filter, store_filter, RC_FILTER_WAKEUP, true);
-static struct attribute *rc_dev_protocol_attrs[] = {
- &dev_attr_protocols.attr,
+static struct attribute *rc_dev_rw_protocol_attrs[] = {
+ &dev_attr_rw_protocols.attr,
NULL,
};
-static const struct attribute_group rc_dev_protocol_attr_grp = {
- .attrs = rc_dev_protocol_attrs,
+static const struct attribute_group rc_dev_rw_protocol_attr_grp = {
+ .attrs = rc_dev_rw_protocol_attrs,
+};
+
+static struct attribute *rc_dev_ro_protocol_attrs[] = {
+ &dev_attr_ro_protocols.attr,
+ NULL,
+};
+
+static const struct attribute_group rc_dev_ro_protocol_attr_grp = {
+ .attrs = rc_dev_ro_protocol_attrs,
};
static struct attribute *rc_dev_filter_attrs[] = {
@@ -1529,7 +1556,7 @@ static const struct attribute_group rc_dev_wakeup_filter_attr_grp = {
.attrs = rc_dev_wakeup_filter_attrs,
};
-static struct device_type rc_dev_type = {
+static const struct device_type rc_dev_type = {
.release = rc_dev_release,
.uevent = rc_dev_uevent,
};
@@ -1553,8 +1580,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type)
dev->input_dev->setkeycode = ir_setkeycode;
input_set_drvdata(dev->input_dev, dev);
- setup_timer(&dev->timer_keyup, ir_timer_keyup,
- (unsigned long)dev);
+ timer_setup(&dev->timer_keyup, ir_timer_keyup, 0);
spin_lock_init(&dev->rc_map.lock);
spin_lock_init(&dev->keylock);
@@ -1638,6 +1664,9 @@ static int rc_prepare_rx_device(struct rc_dev *dev)
rc_proto = BIT_ULL(rc_map->rc_proto);
+ if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol)
+ dev->enabled_protocols = dev->allowed_protocols;
+
if (dev->change_protocol) {
rc = dev->change_protocol(dev, &rc_proto);
if (rc < 0)
@@ -1729,8 +1758,10 @@ int rc_register_device(struct rc_dev *dev)
dev_set_drvdata(&dev->dev, dev);
dev->dev.groups = dev->sysfs_groups;
- if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
- dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
+ if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol)
+ dev->sysfs_groups[attr++] = &rc_dev_ro_protocol_attr_grp;
+ else if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+ dev->sysfs_groups[attr++] = &rc_dev_rw_protocol_attr_grp;
if (dev->s_filter)
dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;
if (dev->s_wakeup_filter)
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 6784cb9fc4e7..6bfc24885b5c 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -186,7 +186,7 @@ struct redrat3_error {
} __packed;
/* table of devices that work with this driver */
-static struct usb_device_id redrat3_dev_table[] = {
+static const struct usb_device_id redrat3_dev_table[] = {
/* Original version of the RedRat3 */
{USB_DEVICE(USB_RR3USB_VENDOR_ID, USB_RR3USB_PRODUCT_ID)},
/* Second Version/release of the RedRat3 - RetRat3-II */
diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c
index 8b66926bc16a..8bf5637b3a69 100644
--- a/drivers/media/rc/serial_ir.c
+++ b/drivers/media/rc/serial_ir.c
@@ -470,7 +470,7 @@ static int hardware_init_port(void)
return 0;
}
-static void serial_ir_timeout(unsigned long arg)
+static void serial_ir_timeout(struct timer_list *unused)
{
DEFINE_IR_RAW_EVENT(ev);
@@ -540,8 +540,7 @@ static int serial_ir_probe(struct platform_device *dev)
serial_ir.rcdev = rcdev;
- setup_timer(&serial_ir.timeout_timer, serial_ir_timeout,
- (unsigned long)&serial_ir);
+ timer_setup(&serial_ir.timeout_timer, serial_ir_timeout, 0);
result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler,
share_irq ? IRQF_SHARED : 0,
diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c
index bc906fb128d5..9ee2c9196b4d 100644
--- a/drivers/media/rc/sir_ir.c
+++ b/drivers/media/rc/sir_ir.c
@@ -57,7 +57,7 @@ static void add_read_queue(int flag, unsigned long val);
static irqreturn_t sir_interrupt(int irq, void *dev_id);
static void send_space(unsigned long len);
static void send_pulse(unsigned long len);
-static void init_hardware(void);
+static int init_hardware(void);
static void drop_hardware(void);
/* Initialisation */
@@ -120,7 +120,7 @@ static void add_read_queue(int flag, unsigned long val)
}
/* SECTION: Hardware */
-static void sir_timeout(unsigned long data)
+static void sir_timeout(struct timer_list *unused)
{
/*
* if last received signal was a pulse, but receiving stopped
@@ -263,11 +263,36 @@ static void send_pulse(unsigned long len)
}
}
-static void init_hardware(void)
+static int init_hardware(void)
{
+ u8 scratch, scratch2, scratch3;
unsigned long flags;
spin_lock_irqsave(&hardware_lock, flags);
+
+ /*
+ * This is a simple port existence test, borrowed from the autoconfig
+ * function in drivers/tty/serial/8250/8250_port.c
+ */
+ scratch = sinp(UART_IER);
+ soutp(UART_IER, 0);
+#ifdef __i386__
+ outb(0xff, 0x080);
+#endif
+ scratch2 = sinp(UART_IER) & 0x0f;
+ soutp(UART_IER, 0x0f);
+#ifdef __i386__
+ outb(0x00, 0x080);
+#endif
+ scratch3 = sinp(UART_IER) & 0x0f;
+ soutp(UART_IER, scratch);
+ if (scratch2 != 0 || scratch3 != 0x0f) {
+ /* we fail, there's nothing here */
+ spin_unlock_irqrestore(&hardware_lock, flags);
+ pr_err("port existence test failed, cannot continue\n");
+ return -ENODEV;
+ }
+
/* reset UART */
outb(0, io + UART_MCR);
outb(0, io + UART_IER);
@@ -285,6 +310,8 @@ static void init_hardware(void)
/* turn on UART */
outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, io + UART_MCR);
spin_unlock_irqrestore(&hardware_lock, flags);
+
+ return 0;
}
static void drop_hardware(void)
@@ -321,7 +348,7 @@ static int sir_ir_probe(struct platform_device *dev)
rcdev->timeout = IR_DEFAULT_TIMEOUT;
rcdev->dev.parent = &sir_ir_dev->dev;
- setup_timer(&timerlist, sir_timeout, 0);
+ timer_setup(&timerlist, sir_timeout, 0);
/* get I/O port access and IRQ line */
if (!devm_request_region(&sir_ir_dev->dev, io, 8, KBUILD_MODNAME)) {
@@ -334,14 +361,19 @@ static int sir_ir_probe(struct platform_device *dev)
pr_err("IRQ %d already in use.\n", irq);
return retval;
}
+
+ retval = init_hardware();
+ if (retval) {
+ del_timer_sync(&timerlist);
+ return retval;
+ }
+
pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq);
retval = devm_rc_register_device(&sir_ir_dev->dev, rcdev);
if (retval < 0)
return retval;
- init_hardware();
-
return 0;
}
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index a8e39c635f34..d2efd7b2c3bc 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -49,7 +49,7 @@ struct st_rc_device {
#define IRB_RX_NOISE_SUPPR 0x5c /* noise suppression */
#define IRB_RX_POLARITY_INV 0x68 /* polarity inverter */
-/**
+/*
* IRQ set: Enable full FIFO 1 -> bit 3;
* Enable overrun IRQ 1 -> bit 2;
* Enable last symbol IRQ 1 -> bit 1:
@@ -72,7 +72,7 @@ static void st_rc_send_lirc_timeout(struct rc_dev *rdev)
ir_raw_event_store(rdev, &ev);
}
-/**
+/*
* RX graphical example to better understand the difference between ST IR block
* output and standard definition used by LIRC (and most of the world!)
*
@@ -317,7 +317,7 @@ static int st_rc_probe(struct platform_device *pdev)
device_init_wakeup(dev, true);
dev_pm_set_wake_irq(dev, rc_dev->irq);
- /**
+ /*
* for LIRC_MODE_MODE2 or LIRC_MODE_PULSE or LIRC_MODE_RAW
* lircd expects a long space first before a signal train to sync.
*/
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index f03a174ddf9d..c9a70fda88a8 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -43,7 +43,7 @@
#define USB_STREAMZAP_PRODUCT_ID 0x0000
/* table of devices that work with this driver */
-static struct usb_device_id streamzap_table[] = {
+static const struct usb_device_id streamzap_table[] = {
/* Streamzap Remote Control */
{ USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
/* Terminating entry */
@@ -191,7 +191,7 @@ static void sz_push_half_space(struct streamzap_ir *sz,
sz_push_full_space(sz, value & SZ_SPACE_MASK);
}
-/**
+/*
* streamzap_callback - usb IRQ handler callback
*
* This procedure is invoked on reception of data from
@@ -321,7 +321,7 @@ out:
return NULL;
}
-/**
+/*
* streamzap_probe
*
* Called by usb-core to associated with a candidate device
@@ -450,7 +450,7 @@ free_sz:
return retval;
}
-/**
+/*
* streamzap_disconnect
*
* Called by the usb core when the device is removed from the system.
diff --git a/drivers/media/rc/tango-ir.c b/drivers/media/rc/tango-ir.c
new file mode 100644
index 000000000000..9d4c17230c3a
--- /dev/null
+++ b/drivers/media/rc/tango-ir.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 Mans Rullgard <mans@mansr.com>
+ *
+ * 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.
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <media/rc-core.h>
+
+#define DRIVER_NAME "tango-ir"
+
+#define IR_NEC_CTRL 0x00
+#define IR_NEC_DATA 0x04
+#define IR_CTRL 0x08
+#define IR_RC5_CLK_DIV 0x0c
+#define IR_RC5_DATA 0x10
+#define IR_INT 0x14
+
+#define NEC_TIME_BASE 560
+#define RC5_TIME_BASE 1778
+
+#define RC6_CTRL 0x00
+#define RC6_CLKDIV 0x04
+#define RC6_DATA0 0x08
+#define RC6_DATA1 0x0c
+#define RC6_DATA2 0x10
+#define RC6_DATA3 0x14
+#define RC6_DATA4 0x18
+
+#define RC6_CARRIER 36000
+#define RC6_TIME_BASE 16
+
+#define NEC_CAP(n) ((n) << 24)
+#define GPIO_SEL(n) ((n) << 16)
+#define DISABLE_NEC (BIT(4) | BIT(8))
+#define ENABLE_RC5 (BIT(0) | BIT(9))
+#define ENABLE_RC6 (BIT(0) | BIT(7))
+#define ACK_IR_INT (BIT(0) | BIT(1))
+#define ACK_RC6_INT (BIT(31))
+
+#define NEC_ANY (RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32)
+
+struct tango_ir {
+ void __iomem *rc5_base;
+ void __iomem *rc6_base;
+ struct rc_dev *rc;
+ struct clk *clk;
+};
+
+static void tango_ir_handle_nec(struct tango_ir *ir)
+{
+ u32 v, code;
+ enum rc_proto proto;
+
+ v = readl_relaxed(ir->rc5_base + IR_NEC_DATA);
+ if (!v) {
+ rc_repeat(ir->rc);
+ return;
+ }
+
+ code = ir_nec_bytes_to_scancode(v, v >> 8, v >> 16, v >> 24, &proto);
+ rc_keydown(ir->rc, proto, code, 0);
+}
+
+static void tango_ir_handle_rc5(struct tango_ir *ir)
+{
+ u32 data, field, toggle, addr, cmd, code;
+
+ data = readl_relaxed(ir->rc5_base + IR_RC5_DATA);
+ if (data & BIT(31))
+ return;
+
+ field = data >> 12 & 1;
+ toggle = data >> 11 & 1;
+ addr = data >> 6 & 0x1f;
+ cmd = (data & 0x3f) | (field ^ 1) << 6;
+
+ code = RC_SCANCODE_RC5(addr, cmd);
+ rc_keydown(ir->rc, RC_PROTO_RC5, code, toggle);
+}
+
+static void tango_ir_handle_rc6(struct tango_ir *ir)
+{
+ u32 data0, data1, toggle, mode, addr, cmd, code;
+
+ data0 = readl_relaxed(ir->rc6_base + RC6_DATA0);
+ data1 = readl_relaxed(ir->rc6_base + RC6_DATA1);
+
+ mode = data0 >> 1 & 7;
+ if (mode != 0)
+ return;
+
+ toggle = data0 & 1;
+ addr = data0 >> 16;
+ cmd = data1;
+
+ code = RC_SCANCODE_RC6_0(addr, cmd);
+ rc_keydown(ir->rc, RC_PROTO_RC6_0, code, toggle);
+}
+
+static irqreturn_t tango_ir_irq(int irq, void *dev_id)
+{
+ struct tango_ir *ir = dev_id;
+ unsigned int rc5_stat;
+ unsigned int rc6_stat;
+
+ rc5_stat = readl_relaxed(ir->rc5_base + IR_INT);
+ writel_relaxed(rc5_stat, ir->rc5_base + IR_INT);
+
+ rc6_stat = readl_relaxed(ir->rc6_base + RC6_CTRL);
+ writel_relaxed(rc6_stat, ir->rc6_base + RC6_CTRL);
+
+ if (!(rc5_stat & 3) && !(rc6_stat & BIT(31)))
+ return IRQ_NONE;
+
+ if (rc5_stat & BIT(0))
+ tango_ir_handle_rc5(ir);
+
+ if (rc5_stat & BIT(1))
+ tango_ir_handle_nec(ir);
+
+ if (rc6_stat & BIT(31))
+ tango_ir_handle_rc6(ir);
+
+ return IRQ_HANDLED;
+}
+
+static int tango_change_protocol(struct rc_dev *dev, u64 *rc_type)
+{
+ struct tango_ir *ir = dev->priv;
+ u32 rc5_ctrl = DISABLE_NEC;
+ u32 rc6_ctrl = 0;
+
+ if (*rc_type & NEC_ANY)
+ rc5_ctrl = 0;
+
+ if (*rc_type & RC_PROTO_BIT_RC5)
+ rc5_ctrl |= ENABLE_RC5;
+
+ if (*rc_type & RC_PROTO_BIT_RC6_0)
+ rc6_ctrl = ENABLE_RC6;
+
+ writel_relaxed(rc5_ctrl, ir->rc5_base + IR_CTRL);
+ writel_relaxed(rc6_ctrl, ir->rc6_base + RC6_CTRL);
+
+ return 0;
+}
+
+static int tango_ir_probe(struct platform_device *pdev)
+{
+ const char *map_name = RC_MAP_TANGO;
+ struct device *dev = &pdev->dev;
+ struct rc_dev *rc;
+ struct tango_ir *ir;
+ struct resource *rc5_res;
+ struct resource *rc6_res;
+ u64 clkrate, clkdiv;
+ int irq, err;
+ u32 val;
+
+ rc5_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!rc5_res)
+ return -EINVAL;
+
+ rc6_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!rc6_res)
+ return -EINVAL;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0)
+ return -EINVAL;
+
+ ir = devm_kzalloc(dev, sizeof(*ir), GFP_KERNEL);
+ if (!ir)
+ return -ENOMEM;
+
+ ir->rc5_base = devm_ioremap_resource(dev, rc5_res);
+ if (IS_ERR(ir->rc5_base))
+ return PTR_ERR(ir->rc5_base);
+
+ ir->rc6_base = devm_ioremap_resource(dev, rc6_res);
+ if (IS_ERR(ir->rc6_base))
+ return PTR_ERR(ir->rc6_base);
+
+ ir->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(ir->clk))
+ return PTR_ERR(ir->clk);
+
+ rc = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE);
+ if (!rc)
+ return -ENOMEM;
+
+ of_property_read_string(dev->of_node, "linux,rc-map-name", &map_name);
+
+ rc->device_name = DRIVER_NAME;
+ rc->driver_name = DRIVER_NAME;
+ rc->input_phys = DRIVER_NAME "/input0";
+ rc->map_name = map_name;
+ rc->allowed_protocols = NEC_ANY | RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_0;
+ rc->change_protocol = tango_change_protocol;
+ rc->priv = ir;
+ ir->rc = rc;
+
+ err = clk_prepare_enable(ir->clk);
+ if (err)
+ return err;
+
+ clkrate = clk_get_rate(ir->clk);
+
+ clkdiv = clkrate * NEC_TIME_BASE;
+ do_div(clkdiv, 1000000);
+
+ val = NEC_CAP(31) | GPIO_SEL(12) | clkdiv;
+ writel_relaxed(val, ir->rc5_base + IR_NEC_CTRL);
+
+ clkdiv = clkrate * RC5_TIME_BASE;
+ do_div(clkdiv, 1000000);
+
+ writel_relaxed(DISABLE_NEC, ir->rc5_base + IR_CTRL);
+ writel_relaxed(clkdiv, ir->rc5_base + IR_RC5_CLK_DIV);
+ writel_relaxed(ACK_IR_INT, ir->rc5_base + IR_INT);
+
+ clkdiv = clkrate * RC6_TIME_BASE;
+ do_div(clkdiv, RC6_CARRIER);
+
+ writel_relaxed(ACK_RC6_INT, ir->rc6_base + RC6_CTRL);
+ writel_relaxed((clkdiv >> 2) << 18 | clkdiv, ir->rc6_base + RC6_CLKDIV);
+
+ err = devm_request_irq(dev, irq, tango_ir_irq, IRQF_SHARED,
+ dev_name(dev), ir);
+ if (err)
+ goto err_clk;
+
+ err = devm_rc_register_device(dev, rc);
+ if (err)
+ goto err_clk;
+
+ platform_set_drvdata(pdev, ir);
+ return 0;
+
+err_clk:
+ clk_disable_unprepare(ir->clk);
+ return err;
+}
+
+static int tango_ir_remove(struct platform_device *pdev)
+{
+ struct tango_ir *ir = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(ir->clk);
+ return 0;
+}
+
+static const struct of_device_id tango_ir_dt_ids[] = {
+ { .compatible = "sigma,smp8642-ir" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tango_ir_dt_ids);
+
+static struct platform_driver tango_ir_driver = {
+ .probe = tango_ir_probe,
+ .remove = tango_ir_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = tango_ir_dt_ids,
+ },
+};
+module_platform_driver(tango_ir_driver);
+
+MODULE_DESCRIPTION("SMP86xx IR decoder driver");
+MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
index 06a9ab65e5fa..7be96511532d 100644
--- a/drivers/media/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for common V4L/DVB tuners
#
diff --git a/drivers/media/tuners/fc0011.h b/drivers/media/tuners/fc0011.h
index 438cf897acd1..a36871c44c8c 100644
--- a/drivers/media/tuners/fc0011.h
+++ b/drivers/media/tuners/fc0011.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LINUX_FC0011_H_
#define LINUX_FC0011_H_
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index 8b39d8dc97a0..5c87c5c6a455 100644
--- a/drivers/media/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -1397,9 +1397,9 @@ static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
* risk of overflow. It accurately calculates
* f_ref * num / denom to within 1 HZ with fixed math.
*
- * @num : Fractional portion of the multiplier
+ * @f_ref: SRO frequency.
+ * @num: Fractional portion of the multiplier
* @denom: denominator portion of the ratio
- * @f_Ref: SRO frequency.
*
* This calculation handles f_ref as two separate 14-bit fields.
* Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
@@ -1464,8 +1464,6 @@ static u32 MT2063_CalcLO1Mult(u32 *Div,
* @f_LO: desired LO frequency.
* @f_LO_Step: Minimum step size for the LO (in Hz).
* @f_Ref: SRO frequency.
- * @f_Avoid: Range of PLL frequencies to avoid near
- * integer multiples of f_Ref (in Hz).
*
* Returns: Recalculated LO frequency.
*/
diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h
index e55e0a6dd1be..0e3e3b0525bb 100644
--- a/drivers/media/tuners/mt2063.h
+++ b/drivers/media/tuners/mt2063.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __MT2063_H__
#define __MT2063_H__
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 738b993ec8b0..21e46b10caa5 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the USB media device drivers
#
diff --git a/drivers/media/usb/as102/Makefile b/drivers/media/usb/as102/Makefile
index 22f43eee4a3b..56bd2d00b920 100644
--- a/drivers/media/usb/as102/Makefile
+++ b/drivers/media/usb/as102/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
as102_usb_drv.o as10x_cmd_cfg.o
diff --git a/drivers/media/usb/as102/as102_fw.c b/drivers/media/usb/as102/as102_fw.c
index 5a28ce3a1d49..38dbc128340d 100644
--- a/drivers/media/usb/as102/as102_fw.c
+++ b/drivers/media/usb/as102/as102_fw.c
@@ -101,18 +101,23 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
unsigned char *cmd,
const struct firmware *firmware) {
- struct as10x_fw_pkt_t fw_pkt;
+ struct as10x_fw_pkt_t *fw_pkt;
int total_read_bytes = 0, errno = 0;
unsigned char addr_has_changed = 0;
+ fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL);
+ if (!fw_pkt)
+ return -ENOMEM;
+
+
for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
int read_bytes = 0, data_len = 0;
/* parse intel hex line */
read_bytes = parse_hex_line(
(u8 *) (firmware->data + total_read_bytes),
- fw_pkt.raw.address,
- fw_pkt.raw.data,
+ fw_pkt->raw.address,
+ fw_pkt->raw.data,
&data_len,
&addr_has_changed);
@@ -122,28 +127,28 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
/* detect the end of file */
total_read_bytes += read_bytes;
if (total_read_bytes == firmware->size) {
- fw_pkt.u.request[0] = 0x00;
- fw_pkt.u.request[1] = 0x03;
+ fw_pkt->u.request[0] = 0x00;
+ fw_pkt->u.request[1] = 0x03;
/* send EOF command */
errno = bus_adap->ops->upload_fw_pkt(bus_adap,
(uint8_t *)
- &fw_pkt, 2, 0);
+ fw_pkt, 2, 0);
if (errno < 0)
goto error;
} else {
if (!addr_has_changed) {
/* prepare command to send */
- fw_pkt.u.request[0] = 0x00;
- fw_pkt.u.request[1] = 0x01;
+ fw_pkt->u.request[0] = 0x00;
+ fw_pkt->u.request[1] = 0x01;
- data_len += sizeof(fw_pkt.u.request);
- data_len += sizeof(fw_pkt.raw.address);
+ data_len += sizeof(fw_pkt->u.request);
+ data_len += sizeof(fw_pkt->raw.address);
/* send cmd to device */
errno = bus_adap->ops->upload_fw_pkt(bus_adap,
(uint8_t *)
- &fw_pkt,
+ fw_pkt,
data_len,
0);
if (errno < 0)
@@ -152,6 +157,7 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
}
}
error:
+ kfree(fw_pkt);
return (errno == 0) ? total_read_bytes : errno;
}
diff --git a/drivers/media/usb/au0828/Makefile b/drivers/media/usb/au0828/Makefile
index 3dc7539a5c4e..c06ef6601f2d 100644
--- a/drivers/media/usb/au0828/Makefile
+++ b/drivers/media/usb/au0828/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o
ifeq ($(CONFIG_VIDEO_AU0828_V4L2),y)
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 34dc7e062471..d9093a3c57c5 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -105,9 +105,9 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
static void au0828_restart_dvb_streaming(struct work_struct *work);
-static void au0828_bulk_timeout(unsigned long data)
+static void au0828_bulk_timeout(struct timer_list *t)
{
- struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dev *dev = from_timer(dev, t, bulk_timeout);
dprintk(1, "%s called\n", __func__);
dev->bulk_timeout_running = 0;
@@ -648,9 +648,7 @@ int au0828_dvb_register(struct au0828_dev *dev)
return ret;
}
- dev->bulk_timeout.function = au0828_bulk_timeout;
- dev->bulk_timeout.data = (unsigned long) dev;
- init_timer(&dev->bulk_timeout);
+ timer_setup(&dev->bulk_timeout, au0828_bulk_timeout, 0);
return 0;
}
diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c
index ef7d1b830ca3..1b8ec5d9e7ab 100644
--- a/drivers/media/usb/au0828/au0828-i2c.c
+++ b/drivers/media/usb/au0828/au0828-i2c.c
@@ -342,7 +342,7 @@ static const struct i2c_adapter au0828_i2c_adap_template = {
.algo = &au0828_i2c_algo_template,
};
-static struct i2c_client au0828_i2c_client_template = {
+static const struct i2c_client au0828_i2c_client_template = {
.name = "au0828 internal",
};
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 7996eb83a54e..af68afe085b5 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -269,7 +269,7 @@ static void au0828_rc_stop(struct rc_dev *rc)
static int au0828_probe_i2c_ir(struct au0828_dev *dev)
{
int i = 0;
- const unsigned short addr_list[] = {
+ static const unsigned short addr_list[] = {
0x47, I2C_CLIENT_END
};
diff --git a/drivers/media/usb/au0828/au0828-vbi.c b/drivers/media/usb/au0828/au0828-vbi.c
index e0930ce59b8d..9dd6bdb7304f 100644
--- a/drivers/media/usb/au0828/au0828-vbi.c
+++ b/drivers/media/usb/au0828/au0828-vbi.c
@@ -79,7 +79,7 @@ vbi_buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&dev->slock, flags);
}
-struct vb2_ops au0828_vbi_qops = {
+const struct vb2_ops au0828_vbi_qops = {
.queue_setup = vbi_queue_setup,
.buf_prepare = vbi_buffer_prepare,
.buf_queue = vbi_buffer_queue,
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 9342402b92f7..a240153821e0 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -67,10 +67,10 @@ static inline void print_err_status(struct au0828_dev *dev,
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
@@ -954,9 +954,9 @@ int au0828_analog_unregister(struct au0828_dev *dev)
/* This function ensures that video frames continue to be delivered even if
the ITU-656 input isn't receiving any data (thereby preventing applications
such as tvtime from hanging) */
-static void au0828_vid_buffer_timeout(unsigned long data)
+static void au0828_vid_buffer_timeout(struct timer_list *t)
{
- struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dev *dev = from_timer(dev, t, vid_timeout);
struct au0828_dmaqueue *dma_q = &dev->vidq;
struct au0828_buffer *buf;
unsigned char *vid_data;
@@ -978,9 +978,9 @@ static void au0828_vid_buffer_timeout(unsigned long data)
spin_unlock_irqrestore(&dev->slock, flags);
}
-static void au0828_vbi_buffer_timeout(unsigned long data)
+static void au0828_vbi_buffer_timeout(struct timer_list *t)
{
- struct au0828_dev *dev = (struct au0828_dev *) data;
+ struct au0828_dev *dev = from_timer(dev, t, vbi_timeout);
struct au0828_dmaqueue *dma_q = &dev->vbiq;
struct au0828_buffer *buf;
unsigned char *vbi_data;
@@ -1953,10 +1953,8 @@ int au0828_analog_register(struct au0828_dev *dev,
INIT_LIST_HEAD(&dev->vidq.active);
INIT_LIST_HEAD(&dev->vbiq.active);
- setup_timer(&dev->vid_timeout, au0828_vid_buffer_timeout,
- (unsigned long)dev);
- setup_timer(&dev->vbi_timeout, au0828_vbi_buffer_timeout,
- (unsigned long)dev);
+ timer_setup(&dev->vid_timeout, au0828_vid_buffer_timeout, 0);
+ timer_setup(&dev->vbi_timeout, au0828_vbi_buffer_timeout, 0);
dev->width = NTSC_STD_W;
dev->height = NTSC_STD_H;
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 05e445fe0b77..f6f37e8ef51d 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -358,7 +358,7 @@ void au0828_dvb_suspend(struct au0828_dev *dev);
void au0828_dvb_resume(struct au0828_dev *dev);
/* au0828-vbi.c */
-extern struct vb2_ops au0828_vbi_qops;
+extern const struct vb2_ops au0828_vbi_qops;
#define dprintk(level, fmt, arg...)\
do { if (au0828_debug & level)\
diff --git a/drivers/media/usb/b2c2/Kconfig b/drivers/media/usb/b2c2/Kconfig
index 17d35833980c..a620ae42dfc8 100644
--- a/drivers/media/usb/b2c2/Kconfig
+++ b/drivers/media/usb/b2c2/Kconfig
@@ -10,6 +10,6 @@ config DVB_B2C2_FLEXCOP_USB_DEBUG
bool "Enable debug for the B2C2 FlexCop drivers"
depends on DVB_B2C2_FLEXCOP_USB
select DVB_B2C2_FLEXCOP_DEBUG
- help
- Say Y if you want to enable the module option to control debug messages
- of all B2C2 FlexCop drivers.
+ help
+ Say Y if you want to enable the module option to control debug messages
+ of all B2C2 FlexCop drivers.
diff --git a/drivers/media/usb/b2c2/flexcop-usb.h b/drivers/media/usb/b2c2/flexcop-usb.h
index 25ad43166e78..e86faa0e06ca 100644
--- a/drivers/media/usb/b2c2/flexcop-usb.h
+++ b/drivers/media/usb/b2c2/flexcop-usb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-usb.h - header file for the USB part
diff --git a/drivers/media/usb/cx231xx/Makefile b/drivers/media/usb/cx231xx/Makefile
index 52cf76935e69..19e8c35d6a77 100644
--- a/drivers/media/usb/cx231xx/Makefile
+++ b/drivers/media/usb/cx231xx/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
cx231xx-y += cx231xx-video.o cx231xx-i2c.o cx231xx-cards.o cx231xx-core.o
cx231xx-y += cx231xx-avcore.o cx231xx-417.o cx231xx-pcb-cfg.o cx231xx-vbi.o
cx231xx-$(CONFIG_VIDEO_CX231XX_RC) += cx231xx-input.o
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index e0daa9b6c2a0..54d9d0cb326f 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -847,7 +847,7 @@ struct cx231xx_board cx231xx_boards[] = {
.demod_addr = 0x64, /* 0xc8 >> 1 */
.demod_i2c_master = I2C_1_MUX_3,
.has_dvb = 1,
- .ir_i2c_master = I2C_0,
+ .decoder = CX231XX_AVDECODER,
.norm = V4L2_STD_PAL,
.output_mode = OUT_MODE_VIP11,
.tuner_addr = 0x60, /* 0xc0 >> 1 */
@@ -872,6 +872,7 @@ struct cx231xx_board cx231xx_boards[] = {
.name = "Astrometa T2hybrid",
.tuner_type = TUNER_ABSENT,
.has_dvb = 1,
+ .decoder = CX231XX_AVDECODER,
.output_mode = OUT_MODE_VIP11,
.agc_analog_digital_select_gpio = 0x01,
.ctl_pin_status_mask = 0xffffffc4,
@@ -1684,7 +1685,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
nr = dev->devno;
assoc_desc = udev->actconfig->intf_assoc[0];
- if (assoc_desc->bFirstInterface != ifnum) {
+ if (!assoc_desc || assoc_desc->bFirstInterface != ifnum) {
dev_err(d, "Not found matching IAD interface\n");
retval = -ENODEV;
goto err_if;
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index c18bb33e060e..54abc1a7c8e1 100644
--- a/drivers/media/usb/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
@@ -179,10 +179,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status)
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c
index 76e901920f6f..d3bfe8e23b1f 100644
--- a/drivers/media/usb/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c
@@ -43,10 +43,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status)
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
@@ -285,7 +285,7 @@ static void vbi_buffer_release(struct videobuf_queue *vq,
free_buffer(vq, buf);
}
-struct videobuf_queue_ops cx231xx_vbi_qops = {
+const struct videobuf_queue_ops cx231xx_vbi_qops = {
.buf_setup = vbi_buffer_setup,
.buf_prepare = vbi_buffer_prepare,
.buf_queue = vbi_buffer_queue,
diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.h b/drivers/media/usb/cx231xx/cx231xx-vbi.h
index 16c7d20a22a4..b33d2bdb621c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-vbi.h
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.h
@@ -22,7 +22,7 @@
#ifndef _CX231XX_VBI_H
#define _CX231XX_VBI_H
-extern struct videobuf_queue_ops cx231xx_vbi_qops;
+extern const struct videobuf_queue_ops cx231xx_vbi_qops;
#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */
#define NTSC_VBI_END_LINE 21
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 179b8481a870..226059fc672b 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -199,10 +199,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status)
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
index 969f68e55265..bed44601f324 100644
--- a/drivers/media/usb/dvb-usb-v2/Makefile
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
dvb_usb_v2-objs := dvb_usb_core.o dvb_usb_urb.o usb_urb.o
obj-$(CONFIG_DVB_USB_V2) += dvb_usb_v2.o
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index 096bb75a24e5..2bf3bd81280a 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -628,8 +628,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
}
ret = dvb_usbv2_device_power_ctrl(d, 0);
- if (ret < 0)
- goto err;
+
err:
if (!adap->suspend_resume_active) {
adap->active_fe = -1;
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.h b/drivers/media/usb/dvb-usb-v2/gl861.h
index b0b80d87bb7e..b651b857e034 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.h
+++ b/drivers/media/usb/dvb-usb-v2/gl861.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DVB_USB_GL861_H_
#define _DVB_USB_GL861_H_
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
index 0eb33e043079..a221bb8a12b4 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
@@ -516,7 +516,6 @@ static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
data required to program */
block_len = (msg->len / 8);
left_over_len = (msg->len % 8);
- index = 0;
mxl_i2c("block_len %d, left_over_len %d",
block_len, left_over_len);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 95a7b9123f8e..c76e78f9638a 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1598,7 +1598,7 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d)
struct rtl28xxu_dev *dev = d->priv;
u8 buf[5];
u32 rc_code;
- struct rtl28xxu_reg_val rc_nec_tab[] = {
+ static const struct rtl28xxu_reg_val rc_nec_tab[] = {
{ 0x3033, 0x80 },
{ 0x3020, 0x43 },
{ 0x3021, 0x16 },
diff --git a/drivers/media/usb/dvb-usb-v2/usb_urb.c b/drivers/media/usb/dvb-usb-v2/usb_urb.c
index 55136cde38f5..dce2b97efce4 100644
--- a/drivers/media/usb/dvb-usb-v2/usb_urb.c
+++ b/drivers/media/usb/dvb-usb-v2/usb_urb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* usb-urb.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
index 3b3f32b426d1..16de1e4f36a4 100644
--- a/drivers/media/usb/dvb-usb/Makefile
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
dvb-usb-objs += dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o
dvb-usb-objs += dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
obj-$(CONFIG_DVB_USB) += dvb-usb.o
diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
index 7ba975bea96a..540886b3bb29 100644
--- a/drivers/media/usb/dvb-usb/a800.c
+++ b/drivers/media/usb/dvb-usb/a800.c
@@ -37,48 +37,9 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
return 0;
}
-static struct rc_map_table rc_map_a800_table[] = {
- { 0x0201, KEY_MODE }, /* SOURCE */
- { 0x0200, KEY_POWER2 }, /* POWER */
- { 0x0205, KEY_1 }, /* 1 */
- { 0x0206, KEY_2 }, /* 2 */
- { 0x0207, KEY_3 }, /* 3 */
- { 0x0209, KEY_4 }, /* 4 */
- { 0x020a, KEY_5 }, /* 5 */
- { 0x020b, KEY_6 }, /* 6 */
- { 0x020d, KEY_7 }, /* 7 */
- { 0x020e, KEY_8 }, /* 8 */
- { 0x020f, KEY_9 }, /* 9 */
- { 0x0212, KEY_LEFT }, /* L / DISPLAY */
- { 0x0211, KEY_0 }, /* 0 */
- { 0x0213, KEY_RIGHT }, /* R / CH RTN */
- { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
- { 0x0210, KEY_LAST }, /* 16-CH PREV */
- { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
- { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
- { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
- { 0x0214, KEY_MUTE }, /* MUTE */
- { 0x0208, KEY_AUDIO }, /* AUDIO */
- { 0x0219, KEY_RECORD }, /* RECORD */
- { 0x0218, KEY_PLAY }, /* PLAY */
- { 0x021b, KEY_STOP }, /* STOP */
- { 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
- { 0x021d, KEY_BACK }, /* << / RED */
- { 0x021c, KEY_FORWARD }, /* >> / YELLOW */
- { 0x0203, KEY_TEXT }, /* TELETEXT */
- { 0x0204, KEY_EPG }, /* EPG */
- { 0x0215, KEY_MENU }, /* MENU */
-
- { 0x0303, KEY_CHANNELUP }, /* CH UP */
- { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
- { 0x0301, KEY_FIRST }, /* |<< / GREEN */
- { 0x0300, KEY_LAST }, /* >>| / BLUE */
-
-};
-
-static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int a800_rc_query(struct dvb_usb_device *d)
{
- int ret;
+ int ret = 0;
u8 *key = kmalloc(5, GFP_KERNEL);
if (!key)
return -ENOMEM;
@@ -90,11 +51,12 @@ static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
goto out;
}
- /* call the universal NEC remote processor, to find out the key's state and event */
- dvb_usb_nec_rc_key_to_event(d,key,event,state);
- if (key[0] != 0)
- deb_rc("key: %*ph\n", 5, key);
- ret = 0;
+ /* Note that extended nec and nec32 are dropped */
+ if (key[0] == 1)
+ rc_keydown(d->rc_dev, RC_PROTO_NEC,
+ RC_SCANCODE_NEC(key[1], key[3]), 0);
+ else if (key[0] == 2)
+ rc_repeat(d->rc_dev);
out:
kfree(key);
return ret;
@@ -157,11 +119,12 @@ static struct dvb_usb_device_properties a800_properties = {
.power_ctrl = a800_power_ctrl,
.identify_state = a800_identify_state,
- .rc.legacy = {
- .rc_interval = DEFAULT_RC_INTERVAL,
- .rc_map_table = rc_map_a800_table,
- .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
- .rc_query = a800_rc_query,
+ .rc.core = {
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_codes = RC_MAP_AVERMEDIA_M135A,
+ .module_name = KBUILD_MODNAME,
+ .rc_query = a800_rc_query,
+ .allowed_protos = RC_PROTO_BIT_NEC,
},
.i2c_algo = &dibusb_i2c_algo,
diff --git a/drivers/media/usb/dvb-usb/af9005-script.h b/drivers/media/usb/dvb-usb/af9005-script.h
index 4d69045426dd..870cb59cd904 100644
--- a/drivers/media/usb/dvb-usb/af9005-script.h
+++ b/drivers/media/usb/dvb-usb/af9005-script.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
File automatically generated by createinit.py using data
extracted from AF05BDA.sys (windows driver):
diff --git a/drivers/media/usb/dvb-usb/az6027.h b/drivers/media/usb/dvb-usb/az6027.h
index f3afe17f3f3d..95b056b36030 100644
--- a/drivers/media/usb/dvb-usb/az6027.h
+++ b/drivers/media/usb/dvb-usb/az6027.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DVB_USB_VP6027_H_
#define _DVB_USB_VP6027_H_
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
index f9772ad0a2a5..5a2f81311fb7 100644
--- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
@@ -26,7 +26,7 @@
#include "cinergyT2.h"
-/**
+/*
* convert linux-dvb frontend parameter set into TPS.
* See ETSI ETS-300744, section 4.6.2, table 9 for details.
*
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 66429d7f69b5..88f9b9804b25 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DVB_USB_CXUSB_H_
#define _DVB_USB_CXUSB_H_
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 6020170fe99a..366b05529915 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -291,7 +291,7 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
stk7700d_dib7000p_mt2266_config)
!= 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
}
@@ -325,7 +325,7 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
stk7700d_dib7000p_mt2266_config)
!= 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
}
@@ -478,7 +478,7 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
&stk7700ph_dib7700_xc3028_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -1010,7 +1010,7 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
&dib7070p_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -1068,7 +1068,7 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
&dib7770p_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -1677,10 +1677,10 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
return -EINVAL;
}
- /** Update PLL if needed ratio **/
+ /* Update PLL if needed ratio */
state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
- /** Get optimize PLL ratio to remove spurious **/
+ /* Get optimize PLL ratio to remove spurious */
pll_ratio = dib8090_compute_pll_parameters(fe);
if (pll_ratio == 17)
timf = 21387946;
@@ -1691,7 +1691,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
else
timf = 18179756;
- /** Update ratio **/
+ /* Update ratio */
state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio);
state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, timf);
@@ -3056,7 +3056,7 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
@@ -3109,7 +3109,7 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
/* initialize IC 0 */
if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3139,7 +3139,7 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3214,7 +3214,7 @@ static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap)
1, 0x10, &tfe7790p_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
@@ -3309,7 +3309,7 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
stk7070pd_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
@@ -3357,7 +3357,7 @@ static int novatd_sleep_override(struct dvb_frontend* fe)
return state->sleep(fe);
}
-/**
+/*
* novatd_frontend_attach - Nova-TD specific attach
*
* Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
@@ -3384,7 +3384,7 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
stk7070pd_dib7000p_config) != 0) {
err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
}
@@ -3620,7 +3620,7 @@ static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
/* Demodulator not found for some reason? */
- dvb_detach(&state->dib7000p_ops);
+ dvb_detach(state->dib7000p_ops.set_wbd_ref);
return -ENODEV;
}
diff --git a/drivers/media/usb/dvb-usb/dib07x0.h b/drivers/media/usb/dvb-usb/dib07x0.h
index 7e62c1018520..2e67f794fe37 100644
--- a/drivers/media/usb/dvb-usb/dib07x0.h
+++ b/drivers/media/usb/dvb-usb/dib07x0.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DIB07X0_H_
#define _DIB07X0_H_
diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
index 8207e6900656..bcacb0f22028 100644
--- a/drivers/media/usb/dvb-usb/dibusb-common.c
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c
@@ -223,8 +223,20 @@ EXPORT_SYMBOL(dibusb_i2c_algo);
int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
{
- u8 wbuf[1] = { offs };
- return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
+ u8 *buf;
+ int rc;
+
+ buf = kmalloc(2, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ buf[0] = offs;
+
+ rc = dibusb_i2c_msg(d, 0x50, &buf[0], 1, &buf[1], 1);
+ *val = buf[1];
+ kfree(buf);
+
+ return rc;
}
EXPORT_SYMBOL(dibusb_read_eeprom_byte);
diff --git a/drivers/media/usb/dvb-usb/digitv.h b/drivers/media/usb/dvb-usb/digitv.h
index 581e09c25491..2af9fedfad70 100644
--- a/drivers/media/usb/dvb-usb/digitv.h
+++ b/drivers/media/usb/dvb-usb/digitv.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DVB_USB_DIGITV_H_
#define _DVB_USB_DIGITV_H_
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-common.h b/drivers/media/usb/dvb-usb/dvb-usb-common.h
index 7e619d638809..8c51ac4493dd 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* dvb-usb-common.h is part of the DVB USB library.
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
index e5675da286cb..3a66e732e0d8 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* dvb-usb-dvb.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
index 04033efe7ad5..15c153e49382 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* dvb-usb-firmware.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-i2c.c b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
index 4f0b0adce7f5..ca0b734e009b 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* dvb-usb-i2c.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
index 0b03f9bd9c26..65e2c9e2cdc9 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* dvb-usb-remote.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
@@ -279,10 +280,11 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
dev->change_protocol = d->props.rc.core.change_protocol;
dev->allowed_protocols = d->props.rc.core.allowed_protos;
usb_to_input_id(d->udev, &dev->input_id);
- dev->device_name = "IR-receiver inside an USB DVB receiver";
+ dev->device_name = d->desc->name;
dev->input_phys = d->rc_phys;
dev->dev.parent = &d->udev->dev;
dev->priv = d;
+ dev->scancode_mask = d->props.rc.core.scancode_mask;
err = rc_register_device(dev);
if (err < 0) {
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-urb.c b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
index 95f9097498cb..c1b4e94a37f8 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* dvb-usb-urb.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index 72468fdffa18..e71fc86b4fb2 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* dvb-usb.h is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
@@ -207,6 +208,7 @@ struct dvb_rc {
int (*rc_query) (struct dvb_usb_device *d);
int rc_interval;
bool bulk_mode; /* uses bulk mode */
+ u32 scancode_mask;
};
/**
diff --git a/drivers/media/usb/dvb-usb/dw2102.h b/drivers/media/usb/dvb-usb/dw2102.h
index 5cd0b0eb6ce1..f64cf79b7934 100644
--- a/drivers/media/usb/dvb-usb/dw2102.h
+++ b/drivers/media/usb/dvb-usb/dw2102.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DW2102_H_
#define _DW2102_H_
diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
index 0251a4e91d47..b6046e0e07f6 100644
--- a/drivers/media/usb/dvb-usb/friio-fe.c
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
@@ -261,28 +261,6 @@ static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
return 0;
}
-
-/* filter out un-supported properties to notify users */
-static int jdvbt90502_set_property(struct dvb_frontend *fe,
- struct dtv_property *tvp)
-{
- int r = 0;
-
- switch (tvp->cmd) {
- case DTV_DELIVERY_SYSTEM:
- if (tvp->u.data != SYS_ISDBT)
- r = -EINVAL;
- break;
- case DTV_CLEAR:
- case DTV_TUNE:
- case DTV_FREQUENCY:
- break;
- default:
- r = -EINVAL;
- }
- return r;
-}
-
static int jdvbt90502_set_frontend(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
@@ -319,7 +297,7 @@ static int jdvbt90502_set_frontend(struct dvb_frontend *fe)
}
-/**
+/*
* (reg, val) commad list to initialize this module.
* captured on a Windows box.
*/
@@ -457,8 +435,6 @@ static const struct dvb_frontend_ops jdvbt90502_ops = {
.init = jdvbt90502_init,
.write = _jdvbt90502_write,
- .set_property = jdvbt90502_set_property,
-
.set_frontend = jdvbt90502_set_frontend,
.read_status = jdvbt90502_read_status,
diff --git a/drivers/media/usb/dvb-usb/friio.c b/drivers/media/usb/dvb-usb/friio.c
index 62abe6c43a32..16875945e662 100644
--- a/drivers/media/usb/dvb-usb/friio.c
+++ b/drivers/media/usb/dvb-usb/friio.c
@@ -21,7 +21,7 @@ MODULE_PARM_DESC(debug,
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-/**
+/*
* Indirect I2C access to the PLL via FE.
* whole I2C protocol data to the PLL is sent via the FE's I2C register.
* This is done by a control msg to the FE with the I2C data accompanied, and
diff --git a/drivers/media/usb/dvb-usb/m920x.h b/drivers/media/usb/dvb-usb/m920x.h
index 3c061518ffc1..bab3c6ac7084 100644
--- a/drivers/media/usb/dvb-usb/m920x.h
+++ b/drivers/media/usb/dvb-usb/m920x.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DVB_USB_M920X_H_
#define _DVB_USB_M920X_H_
diff --git a/drivers/media/usb/dvb-usb/usb-urb.c b/drivers/media/usb/dvb-usb/usb-urb.c
index 89173603be67..2804d2d0e83a 100644
--- a/drivers/media/usb/dvb-usb/usb-urb.c
+++ b/drivers/media/usb/dvb-usb/usb-urb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* usb-urb.c is part of the DVB USB library.
*
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
diff --git a/drivers/media/usb/dvb-usb/vp702x.h b/drivers/media/usb/dvb-usb/vp702x.h
index 20b90055e7ac..18ad7ced2045 100644
--- a/drivers/media/usb/dvb-usb/vp702x.h
+++ b/drivers/media/usb/dvb-usb/vp702x.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DVB_USB_VP7021_H_
#define _DVB_USB_VP7021_H_
diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
index 13340af0d39c..2527b88beb87 100644
--- a/drivers/media/usb/dvb-usb/vp7045.c
+++ b/drivers/media/usb/dvb-usb/vp7045.c
@@ -97,82 +97,22 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
}
-/* remote control stuff */
-
-/* The keymapping struct. Somehow this should be loaded to the driver, but
- * currently it is hardcoded. */
-static struct rc_map_table rc_map_vp7045_table[] = {
- { 0x0016, KEY_POWER },
- { 0x0010, KEY_MUTE },
- { 0x0003, KEY_1 },
- { 0x0001, KEY_2 },
- { 0x0006, KEY_3 },
- { 0x0009, KEY_4 },
- { 0x001d, KEY_5 },
- { 0x001f, KEY_6 },
- { 0x000d, KEY_7 },
- { 0x0019, KEY_8 },
- { 0x001b, KEY_9 },
- { 0x0015, KEY_0 },
- { 0x0005, KEY_CHANNELUP },
- { 0x0002, KEY_CHANNELDOWN },
- { 0x001e, KEY_VOLUMEUP },
- { 0x000a, KEY_VOLUMEDOWN },
- { 0x0011, KEY_RECORD },
- { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
- { 0x0014, KEY_PLAY },
- { 0x001a, KEY_STOP },
- { 0x0040, KEY_REWIND },
- { 0x0012, KEY_FASTFORWARD },
- { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
- { 0x004c, KEY_PAUSE },
- { 0x004d, KEY_SCREEN }, /* Full screen mode. */
- { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
- { 0x000c, KEY_CANCEL }, /* Cancel */
- { 0x001c, KEY_EPG }, /* EPG */
- { 0x0000, KEY_TAB }, /* Tab */
- { 0x0048, KEY_INFO }, /* Preview */
- { 0x0004, KEY_LIST }, /* RecordList */
- { 0x000f, KEY_TEXT }, /* Teletext */
- { 0x0041, KEY_PREVIOUSSONG },
- { 0x0042, KEY_NEXTSONG },
- { 0x004b, KEY_UP },
- { 0x0051, KEY_DOWN },
- { 0x004e, KEY_LEFT },
- { 0x0052, KEY_RIGHT },
- { 0x004f, KEY_ENTER },
- { 0x0013, KEY_CANCEL },
- { 0x004a, KEY_CLEAR },
- { 0x0054, KEY_PRINT }, /* Capture */
- { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
- { 0x0008, KEY_VIDEO }, /* A/V */
- { 0x0007, KEY_SLEEP }, /* Hibernate */
- { 0x0045, KEY_ZOOM }, /* Zoom+ */
- { 0x0018, KEY_RED},
- { 0x0053, KEY_GREEN},
- { 0x005e, KEY_YELLOW},
- { 0x005f, KEY_BLUE}
-};
-
-static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int vp7045_rc_query(struct dvb_usb_device *d)
{
u8 key;
- int i;
vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
deb_rc("remote query key: %x %d\n",key,key);
- if (key == 0x44) {
- *state = REMOTE_NO_KEY_PRESSED;
- return 0;
+ if (key != 0x44) {
+ /*
+ * The 8 bit address isn't available, but since the remote uses
+ * address 0 we'll use that. nec repeats are ignored too, even
+ * though the remote sends them.
+ */
+ rc_keydown(d->rc_dev, RC_PROTO_NEC, RC_SCANCODE_NEC(0, key), 0);
}
- for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
- if (rc5_data(&rc_map_vp7045_table[i]) == key) {
- *state = REMOTE_KEY_PRESSED;
- *event = rc_map_vp7045_table[i].keycode;
- break;
- }
return 0;
}
@@ -265,11 +205,13 @@ static struct dvb_usb_device_properties vp7045_properties = {
.power_ctrl = vp7045_power_ctrl,
.read_mac_address = vp7045_read_mac_addr,
- .rc.legacy = {
- .rc_interval = 400,
- .rc_map_table = rc_map_vp7045_table,
- .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
- .rc_query = vp7045_rc_query,
+ .rc.core = {
+ .rc_interval = 400,
+ .rc_codes = RC_MAP_TWINHAN_VP1027_DVBS,
+ .module_name = KBUILD_MODNAME,
+ .rc_query = vp7045_rc_query,
+ .allowed_protos = RC_PROTO_BIT_NEC,
+ .scancode_mask = 0xff,
},
.num_device_descs = 2,
diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
index 3f850d5063d0..86bfc35e2ed4 100644
--- a/drivers/media/usb/em28xx/Makefile
+++ b/drivers/media/usb/em28xx/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
em28xx-y += em28xx-core.o em28xx-i2c.o em28xx-cards.o em28xx-camera.o
em28xx-v4l-objs := em28xx-video.o em28xx-vbi.o
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 4a7db623fe29..9950a740e04e 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -112,10 +112,10 @@ static inline void print_err_status(struct em28xx *dev,
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index 66c5012a628a..9bf49d666e5a 100644
--- a/drivers/media/usb/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -882,7 +882,7 @@ static const struct i2c_adapter em28xx_adap_template = {
.algo = &em28xx_algo,
};
-static struct i2c_client em28xx_client_template = {
+static const struct i2c_client em28xx_client_template = {
.name = "em28xx internal",
};
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 747525ca7ed5..9e5cdfb25a73 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define EM_GPIO_0 (1 << 0)
#define EM_GPIO_1 (1 << 1)
#define EM_GPIO_2 (1 << 2)
diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h
index 8dfcb56bf4b3..9c411aac3878 100644
--- a/drivers/media/usb/em28xx/em28xx-v4l.h
+++ b/drivers/media/usb/em28xx/em28xx-v4l.h
@@ -16,4 +16,4 @@
int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count);
void em28xx_stop_vbi_streaming(struct vb2_queue *vq);
-extern struct vb2_ops em28xx_vbi_qops;
+extern const struct vb2_ops em28xx_vbi_qops;
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c
index 0bac552bbe87..f5123651ef30 100644
--- a/drivers/media/usb/em28xx/em28xx-vbi.c
+++ b/drivers/media/usb/em28xx/em28xx-vbi.c
@@ -93,7 +93,7 @@ vbi_buffer_queue(struct vb2_buffer *vb)
spin_unlock_irqrestore(&dev->slock, flags);
}
-struct vb2_ops em28xx_vbi_qops = {
+const struct vb2_ops em28xx_vbi_qops = {
.queue_setup = vbi_queue_setup,
.buf_prepare = vbi_buffer_prepare,
.buf_queue = vbi_buffer_queue,
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 8d253a5df0a9..a2ba2d905952 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -557,10 +557,10 @@ static inline void print_err_status(struct em28xx *dev,
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
diff --git a/drivers/media/usb/go7007/Makefile b/drivers/media/usb/go7007/Makefile
index e99287c3b828..3d95bbc4192c 100644
--- a/drivers/media/usb/go7007/Makefile
+++ b/drivers/media/usb/go7007/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_GO7007) += go7007.o
obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
obj-$(CONFIG_VIDEO_GO7007_LOADER) += go7007-loader.o
diff --git a/drivers/media/usb/gspca/Kconfig b/drivers/media/usb/gspca/Kconfig
index 3fd94fe7e1eb..d214a21acff7 100644
--- a/drivers/media/usb/gspca/Kconfig
+++ b/drivers/media/usb/gspca/Kconfig
@@ -204,11 +204,11 @@ config USB_GSPCA_SE401
tristate "SE401 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the
- Endpoints (formerly known as AOX) se401 chip.
+ Say Y here if you want support for cameras based on the
+ Endpoints (formerly known as AOX) se401 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_se401.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_se401.
config USB_GSPCA_SN9C2028
tristate "SONIX Dual-Mode USB Camera Driver"
@@ -224,11 +224,11 @@ config USB_GSPCA_SN9C20X
tristate "SN9C20X USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the
- sn9c20x chips (SN9C201 and SN9C202).
+ Say Y here if you want support for cameras based on the
+ sn9c20x chips (SN9C201 and SN9C202).
- To compile this driver as a module, choose M here: the
- module will be called gspca_sn9c20x.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sn9c20x.
config USB_GSPCA_SONIXB
tristate "SONIX Bayer USB Camera Driver"
diff --git a/drivers/media/usb/gspca/Makefile b/drivers/media/usb/gspca/Makefile
index 9f5ccecb9c8a..3e3ecbffdf9f 100644
--- a/drivers/media/usb/gspca/Makefile
+++ b/drivers/media/usb/gspca/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB_GSPCA) += gspca_main.o
obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o
obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
diff --git a/drivers/media/usb/gspca/gl860/Makefile b/drivers/media/usb/gspca/gl860/Makefile
index cf6397415aad..7bcfa36f12ac 100644
--- a/drivers/media/usb/gspca/gl860/Makefile
+++ b/drivers/media/usb/gspca/gl860/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB_GL860) += gspca_gl860.o
gspca_gl860-objs := gl860.o \
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index 0f141762abf1..961343873fd0 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1075,7 +1075,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
/* give an index to each format */
index = 0;
- j = 0;
for (i = gspca_dev->cam.nmodes; --i >= 0; ) {
fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat;
j = 0;
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index d39adf90303b..9e0cf711642b 100644
--- a/drivers/media/usb/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GSPCAV2_H
#define GSPCAV2_H
diff --git a/drivers/media/usb/gspca/m5602/Makefile b/drivers/media/usb/gspca/m5602/Makefile
index 8e1fb5a1d2a1..95c9db6dc59c 100644
--- a/drivers/media/usb/gspca/m5602/Makefile
+++ b/drivers/media/usb/gspca/m5602/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB_M5602) += gspca_m5602.o
gspca_m5602-objs := m5602_core.o \
diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index cdb79c5f0c38..1b30434b72ef 100644
--- a/drivers/media/usb/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -1,4 +1,4 @@
-/**
+/*
* OV519 driver
*
* Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
@@ -2865,7 +2865,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
static void ov51x_upload_quan_tables(struct sd *sd)
{
- const unsigned char yQuanTable511[] = {
+ static const unsigned char yQuanTable511[] = {
0, 1, 1, 2, 2, 3, 3, 4,
1, 1, 1, 2, 2, 3, 4, 4,
1, 1, 2, 2, 3, 4, 4, 4,
@@ -2876,7 +2876,7 @@ static void ov51x_upload_quan_tables(struct sd *sd)
4, 4, 4, 4, 5, 5, 5, 5
};
- const unsigned char uvQuanTable511[] = {
+ static const unsigned char uvQuanTable511[] = {
0, 2, 2, 3, 4, 4, 4, 4,
2, 2, 2, 4, 4, 4, 4, 4,
2, 2, 3, 4, 4, 4, 4, 4,
@@ -2888,13 +2888,13 @@ static void ov51x_upload_quan_tables(struct sd *sd)
};
/* OV518 quantization tables are 8x4 (instead of 8x8) */
- const unsigned char yQuanTable518[] = {
+ static const unsigned char yQuanTable518[] = {
5, 4, 5, 6, 6, 7, 7, 7,
5, 5, 5, 5, 6, 7, 7, 7,
6, 6, 6, 6, 7, 7, 7, 8,
7, 7, 6, 7, 7, 7, 8, 8
};
- const unsigned char uvQuanTable518[] = {
+ static const unsigned char uvQuanTable518[] = {
6, 6, 6, 7, 7, 7, 7, 7,
6, 6, 6, 7, 7, 7, 7, 7,
6, 6, 6, 7, 7, 7, 7, 8,
@@ -2943,7 +2943,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
/* For 511 and 511+ */
- const struct ov_regvals init_511[] = {
+ static const struct ov_regvals init_511[] = {
{ R51x_SYS_RESET, 0x7f },
{ R51x_SYS_INIT, 0x01 },
{ R51x_SYS_RESET, 0x7f },
@@ -2953,7 +2953,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ R51x_SYS_RESET, 0x3d },
};
- const struct ov_regvals norm_511[] = {
+ static const struct ov_regvals norm_511[] = {
{ R511_DRAM_FLOW_CTL, 0x01 },
{ R51x_SYS_SNAP, 0x00 },
{ R51x_SYS_SNAP, 0x02 },
@@ -2963,7 +2963,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ R511_COMP_LUT_EN, 0x03 },
};
- const struct ov_regvals norm_511_p[] = {
+ static const struct ov_regvals norm_511_p[] = {
{ R511_DRAM_FLOW_CTL, 0xff },
{ R51x_SYS_SNAP, 0x00 },
{ R51x_SYS_SNAP, 0x02 },
@@ -2973,7 +2973,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ R511_COMP_LUT_EN, 0x03 },
};
- const struct ov_regvals compress_511[] = {
+ static const struct ov_regvals compress_511[] = {
{ 0x70, 0x1f },
{ 0x71, 0x05 },
{ 0x72, 0x06 },
@@ -3009,7 +3009,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
/* For 518 and 518+ */
- const struct ov_regvals init_518[] = {
+ static const struct ov_regvals init_518[] = {
{ R51x_SYS_RESET, 0x40 },
{ R51x_SYS_INIT, 0xe1 },
{ R51x_SYS_RESET, 0x3e },
@@ -3020,7 +3020,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
{ 0x5d, 0x03 },
};
- const struct ov_regvals norm_518[] = {
+ static const struct ov_regvals norm_518[] = {
{ R51x_SYS_SNAP, 0x02 }, /* Reset */
{ R51x_SYS_SNAP, 0x01 }, /* Enable */
{ 0x31, 0x0f },
@@ -3033,7 +3033,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
{ 0x2f, 0x80 },
};
- const struct ov_regvals norm_518_p[] = {
+ static const struct ov_regvals norm_518_p[] = {
{ R51x_SYS_SNAP, 0x02 }, /* Reset */
{ R51x_SYS_SNAP, 0x01 }, /* Enable */
{ 0x31, 0x0f },
diff --git a/drivers/media/usb/gspca/stv06xx/Makefile b/drivers/media/usb/gspca/stv06xx/Makefile
index 3a4b2f899049..c4d7206e0c92 100644
--- a/drivers/media/usb/gspca/stv06xx/Makefile
+++ b/drivers/media/usb/gspca/stv06xx/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o
gspca_stv06xx-objs := stv06xx.o \
diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c
index a097d3dbc141..65ef755adfdc 100644
--- a/drivers/media/usb/msi2500/msi2500.c
+++ b/drivers/media/usb/msi2500/msi2500.c
@@ -386,7 +386,7 @@ static void msi2500_isoc_handler(struct urb *urb)
if (unlikely(urb->status == -ENOENT ||
urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN)) {
- dev_dbg(dev->dev, "URB (%p) unlinked %ssynchronuously\n",
+ dev_dbg(dev->dev, "URB (%p) unlinked %ssynchronously\n",
urb, urb->status == -ENOENT ? "" : "a");
return;
}
diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig
index 60a2604e4cb3..1ad913fc30bf 100644
--- a/drivers/media/usb/pvrusb2/Kconfig
+++ b/drivers/media/usb/pvrusb2/Kconfig
@@ -44,7 +44,6 @@ config VIDEO_PVRUSB2_DVB
select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
---help---
-
This option enables a DVB interface for the pvrusb2 driver.
If your device does not support digital television, this
feature will have no affect on the driver's operation.
diff --git a/drivers/media/usb/pvrusb2/Makefile b/drivers/media/usb/pvrusb2/Makefile
index ad705547bdce..0d84064036b2 100644
--- a/drivers/media/usb/pvrusb2/Makefile
+++ b/drivers/media/usb/pvrusb2/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index 884ff916a352..b500c86d4178 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PVRUSB2_DVB_H__
#define __PVRUSB2_DVB_H__
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index ad5b25b89699..8289ee482f49 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -330,10 +330,10 @@ static void pvr2_hdw_state_log_state(struct pvr2_hdw *);
static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw);
static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
-static void pvr2_hdw_quiescent_timeout(unsigned long);
-static void pvr2_hdw_decoder_stabilization_timeout(unsigned long);
-static void pvr2_hdw_encoder_wait_timeout(unsigned long);
-static void pvr2_hdw_encoder_run_timeout(unsigned long);
+static void pvr2_hdw_quiescent_timeout(struct timer_list *);
+static void pvr2_hdw_decoder_stabilization_timeout(struct timer_list *);
+static void pvr2_hdw_encoder_wait_timeout(struct timer_list *);
+static void pvr2_hdw_encoder_run_timeout(struct timer_list *);
static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
unsigned int timeout,int probe_fl,
@@ -2373,18 +2373,15 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
}
if (!hdw) goto fail;
- setup_timer(&hdw->quiescent_timer, pvr2_hdw_quiescent_timeout,
- (unsigned long)hdw);
+ timer_setup(&hdw->quiescent_timer, pvr2_hdw_quiescent_timeout, 0);
- setup_timer(&hdw->decoder_stabilization_timer,
- pvr2_hdw_decoder_stabilization_timeout,
- (unsigned long)hdw);
+ timer_setup(&hdw->decoder_stabilization_timer,
+ pvr2_hdw_decoder_stabilization_timeout, 0);
- setup_timer(&hdw->encoder_wait_timer, pvr2_hdw_encoder_wait_timeout,
- (unsigned long)hdw);
+ timer_setup(&hdw->encoder_wait_timer, pvr2_hdw_encoder_wait_timeout,
+ 0);
- setup_timer(&hdw->encoder_run_timer, pvr2_hdw_encoder_run_timeout,
- (unsigned long)hdw);
+ timer_setup(&hdw->encoder_run_timer, pvr2_hdw_encoder_run_timeout, 0);
hdw->master_state = PVR2_STATE_DEAD;
@@ -3539,10 +3536,16 @@ static void pvr2_ctl_read_complete(struct urb *urb)
complete(&hdw->ctl_done);
}
+struct hdw_timer {
+ struct timer_list timer;
+ struct pvr2_hdw *hdw;
+};
-static void pvr2_ctl_timeout(unsigned long data)
+static void pvr2_ctl_timeout(struct timer_list *t)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+ struct hdw_timer *timer = from_timer(timer, t, timer);
+ struct pvr2_hdw *hdw = timer->hdw;
+
if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
hdw->ctl_timeout_flag = !0;
if (hdw->ctl_write_pend_flag)
@@ -3564,7 +3567,10 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
{
unsigned int idx;
int status = 0;
- struct timer_list timer;
+ struct hdw_timer timer = {
+ .hdw = hdw,
+ };
+
if (!hdw->ctl_lock_held) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"Attempted to execute control transfer without lock!!");
@@ -3621,8 +3627,8 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
hdw->ctl_timeout_flag = 0;
hdw->ctl_write_pend_flag = 0;
hdw->ctl_read_pend_flag = 0;
- setup_timer(&timer, pvr2_ctl_timeout, (unsigned long)hdw);
- timer.expires = jiffies + timeout;
+ timer_setup_on_stack(&timer.timer, pvr2_ctl_timeout, 0);
+ timer.timer.expires = jiffies + timeout;
if (write_len && write_data) {
hdw->cmd_debug_state = 2;
@@ -3677,7 +3683,7 @@ status);
}
/* Start timer */
- add_timer(&timer);
+ add_timer(&timer.timer);
/* Now wait for all I/O to complete */
hdw->cmd_debug_state = 4;
@@ -3687,7 +3693,7 @@ status);
hdw->cmd_debug_state = 5;
/* Stop timer */
- del_timer_sync(&timer);
+ del_timer_sync(&timer.timer);
hdw->cmd_debug_state = 6;
status = 0;
@@ -3769,6 +3775,8 @@ status);
if ((status < 0) && (!probe_fl)) {
pvr2_hdw_render_useless(hdw);
}
+ destroy_timer_on_stack(&timer.timer);
+
return status;
}
@@ -4366,9 +4374,9 @@ static int state_eval_encoder_run(struct pvr2_hdw *hdw)
/* Timeout function for quiescent timer. */
-static void pvr2_hdw_quiescent_timeout(unsigned long data)
+static void pvr2_hdw_quiescent_timeout(struct timer_list *t)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+ struct pvr2_hdw *hdw = from_timer(hdw, t, quiescent_timer);
hdw->state_decoder_quiescent = !0;
trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
hdw->state_stale = !0;
@@ -4377,9 +4385,9 @@ static void pvr2_hdw_quiescent_timeout(unsigned long data)
/* Timeout function for decoder stabilization timer. */
-static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
+static void pvr2_hdw_decoder_stabilization_timeout(struct timer_list *t)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+ struct pvr2_hdw *hdw = from_timer(hdw, t, decoder_stabilization_timer);
hdw->state_decoder_ready = !0;
trace_stbit("state_decoder_ready", hdw->state_decoder_ready);
hdw->state_stale = !0;
@@ -4388,9 +4396,9 @@ static void pvr2_hdw_decoder_stabilization_timeout(unsigned long data)
/* Timeout function for encoder wait timer. */
-static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
+static void pvr2_hdw_encoder_wait_timeout(struct timer_list *t)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+ struct pvr2_hdw *hdw = from_timer(hdw, t, encoder_wait_timer);
hdw->state_encoder_waitok = !0;
trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
hdw->state_stale = !0;
@@ -4399,9 +4407,9 @@ static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
/* Timeout function for encoder run timer. */
-static void pvr2_hdw_encoder_run_timeout(unsigned long data)
+static void pvr2_hdw_encoder_run_timeout(struct timer_list *t)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
+ struct pvr2_hdw *hdw = from_timer(hdw, t, encoder_run_timer);
if (!hdw->state_encoder_runok) {
hdw->state_encoder_runok = !0;
trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
diff --git a/drivers/media/usb/pwc/pwc-dec23.c b/drivers/media/usb/pwc/pwc-dec23.c
index 3792fedff951..1283b3bd9800 100644
--- a/drivers/media/usb/pwc/pwc-dec23.c
+++ b/drivers/media/usb/pwc/pwc-dec23.c
@@ -649,11 +649,10 @@ static void DecompressBand23(struct pwc_dec23_private *pdec,
}
/**
- *
* Uncompress a pwc23 buffer.
- *
- * src: raw data
- * dst: image output
+ * @pdev: pointer to pwc device's internal struct
+ * @src: raw data
+ * @dst: image output
*/
void pwc_dec23_decompress(struct pwc_device *pdev,
const void *src,
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index eb6921d2743e..54b036d39c5b 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -262,7 +262,8 @@ static void pwc_isoc_handler(struct urb *urb)
if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN) {
- PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
+ PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronously.\n",
+ urb, urb->status == -ENOENT ? "" : "a");
return;
}
diff --git a/drivers/media/usb/pwc/pwc-nala.h b/drivers/media/usb/pwc/pwc-nala.h
index 168c73ef75d8..0fe9d473f4e9 100644
--- a/drivers/media/usb/pwc/pwc-nala.h
+++ b/drivers/media/usb/pwc/pwc-nala.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* SQCIF */
{
{0, 0, {0x04, 0x01, 0x03}},
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index b2f239c4ba42..7fee5766587a 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -485,9 +485,10 @@ static void s2255_reset_dsppower(struct s2255_dev *dev)
/* kickstarts the firmware loading. from probe
*/
-static void s2255_timer(unsigned long user_data)
+static void s2255_timer(struct timer_list *t)
{
- struct s2255_fw *data = (struct s2255_fw *)user_data;
+ struct s2255_dev *dev = from_timer(dev, t, timer);
+ struct s2255_fw *data = dev->fw_data;
if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
pr_err("s2255: can't submit urb\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
@@ -2283,7 +2284,7 @@ static int s2255_probe(struct usb_interface *interface,
dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
goto errorEP;
}
- setup_timer(&dev->timer, s2255_timer, (unsigned long)dev->fw_data);
+ timer_setup(&dev->timer, s2255_timer, 0);
init_waitqueue_head(&dev->fw_data->wait_fw);
for (i = 0; i < MAX_CHANNELS; i++) {
struct s2255_vc *vc = &dev->vc[i];
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index 8c1f926567ec..d07349cf9489 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -74,7 +74,7 @@ struct smsusb_device_t {
static int smsusb_submit_urb(struct smsusb_device_t *dev,
struct smsusb_urb_t *surb);
-/**
+/*
* Completing URB's callback handler - bottom half (proccess context)
* submits the URB prepared on smsusb_onresponse()
*/
@@ -86,7 +86,7 @@ static void do_submit_urb(struct work_struct *work)
smsusb_submit_urb(dev, surb);
}
-/**
+/*
* Completing URB's callback handler - top half (interrupt context)
* adds completing sms urb to the global surbs list and activtes the worker
* thread the surb
diff --git a/drivers/media/usb/stk1160/Makefile b/drivers/media/usb/stk1160/Makefile
index 42d05463b353..613471528749 100644
--- a/drivers/media/usb/stk1160/Makefile
+++ b/drivers/media/usb/stk1160/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
stk1160-y := stk1160-core.o \
stk1160-v4l.o \
stk1160-video.o \
diff --git a/drivers/media/usb/stk1160/stk1160-i2c.c b/drivers/media/usb/stk1160/stk1160-i2c.c
index 2c70173e3c82..62a12d5356ad 100644
--- a/drivers/media/usb/stk1160/stk1160-i2c.c
+++ b/drivers/media/usb/stk1160/stk1160-i2c.c
@@ -246,7 +246,7 @@ static const struct i2c_adapter adap_template = {
.algo = &algo,
};
-static struct i2c_client client_template = {
+static const struct i2c_client client_template = {
.name = "stk1160 internal",
};
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index ce8ebbe395a6..423c03a0638d 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -38,10 +38,10 @@ static inline void print_err_status(struct stk1160 *dev,
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
diff --git a/drivers/media/usb/tm6000/Makefile b/drivers/media/usb/tm6000/Makefile
index f2644933b8d1..05322a72e862 100644
--- a/drivers/media/usb/tm6000/Makefile
+++ b/drivers/media/usb/tm6000/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
tm6000-y := tm6000-cards.o \
tm6000-core.o \
tm6000-i2c.o \
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 2537643a1808..77347541904d 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
@@ -1184,7 +1184,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
struct usb_device *usbdev;
- struct tm6000_core *dev = NULL;
+ struct tm6000_core *dev;
int i, rc = 0;
int nr = 0;
char *speed;
@@ -1194,22 +1194,21 @@ static int tm6000_usb_probe(struct usb_interface *interface,
/* Selects the proper interface */
rc = usb_set_interface(usbdev, 0, 1);
if (rc < 0)
- goto err;
+ goto report_failure;
/* Check to see next free device and mark as used */
nr = find_first_zero_bit(&tm6000_devused, TM6000_MAXBOARDS);
if (nr >= TM6000_MAXBOARDS) {
printk(KERN_ERR "tm6000: Supports only %i tm60xx boards.\n", TM6000_MAXBOARDS);
- usb_put_dev(usbdev);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto put_device;
}
/* Create and initialize dev struct */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- printk(KERN_ERR "tm6000" ": out of memory!\n");
- usb_put_dev(usbdev);
- return -ENOMEM;
+ if (!dev) {
+ rc = -ENOMEM;
+ goto put_device;
}
spin_lock_init(&dev->slock);
mutex_init(&dev->usb_lock);
@@ -1313,8 +1312,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
if (!dev->isoc_in.endp) {
printk(KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n");
rc = -ENODEV;
-
- goto err;
+ goto free_device;
}
/* save our data pointer in this interface device */
@@ -1324,17 +1322,18 @@ static int tm6000_usb_probe(struct usb_interface *interface,
rc = tm6000_init_dev(dev);
if (rc < 0)
- goto err;
+ goto free_device;
return 0;
-err:
+free_device:
+ kfree(dev);
+report_failure:
printk(KERN_ERR "tm6000: Error %d while registering\n", rc);
clear_bit(nr, &tm6000_devused);
+put_device:
usb_put_dev(usbdev);
-
- kfree(dev);
return rc;
}
diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c
index 097ac321b7e1..c811fc6cf48a 100644
--- a/drivers/media/usb/tm6000/tm6000-dvb.c
+++ b/drivers/media/usb/tm6000/tm6000-dvb.c
@@ -45,10 +45,10 @@ static inline void print_err_status(struct tm6000_core *dev,
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
@@ -123,7 +123,7 @@ static int tm6000_start_stream(struct tm6000_core *dev)
}
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (dvb->bulk_urb == NULL)
+ if (!dvb->bulk_urb)
return -ENOMEM;
pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress
@@ -133,9 +133,8 @@ static int tm6000_start_stream(struct tm6000_core *dev)
size = size * 15; /* 512 x 8 or 12 or 15 */
dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
- if (dvb->bulk_urb->transfer_buffer == NULL) {
+ if (!dvb->bulk_urb->transfer_buffer) {
usb_free_urb(dvb->bulk_urb);
- printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
}
@@ -361,7 +360,7 @@ static void unregister_dvb(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if (dvb->bulk_urb != NULL) {
+ if (dvb->bulk_urb) {
struct urb *bulk_urb = dvb->bulk_urb;
kfree(bulk_urb->transfer_buffer);
@@ -400,10 +399,8 @@ static int dvb_init(struct tm6000_core *dev)
}
dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
- if (!dvb) {
- printk(KERN_INFO "Cannot allocate memory\n");
+ if (!dvb)
return -ENOMEM;
- }
dev->dvb = dvb;
diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c
index 91889ad9cdd7..397990afe00b 100644
--- a/drivers/media/usb/tm6000/tm6000-input.c
+++ b/drivers/media/usb/tm6000/tm6000-input.c
@@ -352,7 +352,7 @@ static int __tm6000_ir_int_start(struct rc_dev *rc)
dprintk(1, "IR max size: %d\n", size);
ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC);
- if (ir->int_urb->transfer_buffer == NULL) {
+ if (!ir->int_urb->transfer_buffer) {
usb_free_urb(ir->int_urb);
return err;
}
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index ec8c4d2534dc..9fa25de6b5a9 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -342,10 +342,10 @@ static inline void print_err_status(struct tm6000_core *dev,
switch (status) {
case -ENOENT:
- errmsg = "unlinked synchronuously";
+ errmsg = "unlinked synchronously";
break;
case -ECONNRESET:
- errmsg = "unlinked asynchronuously";
+ errmsg = "unlinked asynchronously";
break;
case -ENOSR:
errmsg = "Buffer error (overrun)";
@@ -470,20 +470,16 @@ static int tm6000_alloc_urb_buffers(struct tm6000_core *dev)
int num_bufs = TM6000_NUM_URB_BUF;
int i;
- if (dev->urb_buffer != NULL)
+ if (dev->urb_buffer)
return 0;
dev->urb_buffer = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
- if (!dev->urb_buffer) {
- tm6000_err("cannot allocate memory for urb buffers\n");
+ if (!dev->urb_buffer)
return -ENOMEM;
- }
dev->urb_dma = kmalloc(sizeof(dma_addr_t *)*num_bufs, GFP_KERNEL);
- if (!dev->urb_dma) {
- tm6000_err("cannot allocate memory for urb dma pointers\n");
+ if (!dev->urb_dma)
return -ENOMEM;
- }
for (i = 0; i < num_bufs; i++) {
dev->urb_buffer[i] = usb_alloc_coherent(
@@ -507,7 +503,7 @@ static int tm6000_free_urb_buffers(struct tm6000_core *dev)
{
int i;
- if (dev->urb_buffer == NULL)
+ if (!dev->urb_buffer)
return 0;
for (i = 0; i < TM6000_NUM_URB_BUF; i++) {
@@ -598,15 +594,12 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
dev->isoc_ctl.num_bufs = num_bufs;
dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
- if (!dev->isoc_ctl.urb) {
- tm6000_err("cannot alloc memory for usb buffers\n");
+ if (!dev->isoc_ctl.urb)
return -ENOMEM;
- }
dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs,
GFP_KERNEL);
if (!dev->isoc_ctl.transfer_buffer) {
- tm6000_err("cannot allocate memory for usbtransfer\n");
kfree(dev->isoc_ctl.urb);
return -ENOMEM;
}
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index b842f367249f..a142b9dc0feb 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -76,7 +76,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define TTUSB_REV_2_2 0x22
#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
-/**
+/*
* since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
* the dvb_demux field must be the first in struct!!
*/
@@ -713,7 +713,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
}
}
- /**
+ /*
* if length is valid and we reached the end:
* goto next muxpack
*/
@@ -729,7 +729,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
/* maximum bytes, until we know the length */
ttusb->muxpack_len = 2;
- /**
+ /*
* no muxpacks left?
* return to search-sync state
*/
diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c
index f06f09a0876e..127f8a0c098b 100644
--- a/drivers/media/usb/usbtv/usbtv-core.c
+++ b/drivers/media/usb/usbtv/usbtv-core.c
@@ -84,7 +84,7 @@ static int usbtv_probe(struct usb_interface *intf,
/* Packet size is split into 11 bits of base size and count of
* extra multiplies of it.*/
size = usb_endpoint_maxp(&ep->desc);
- size = (size & 0x07ff) * usb_endpoint_maxp_mult(&ep->desc);
+ size = size * usb_endpoint_maxp_mult(&ep->desc);
/* Device structure */
usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
@@ -144,6 +144,7 @@ static void usbtv_disconnect(struct usb_interface *intf)
static const struct usb_device_id usbtv_id_table[] = {
{ USB_DEVICE(0x1b71, 0x3002) },
+ { USB_DEVICE(0x1f71, 0x3301) },
{}
};
MODULE_DEVICE_TABLE(usb, usbtv_id_table);
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index 95b5f4319ec2..3668a04359e8 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -718,8 +718,8 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl)
*/
if (ctrl->id == V4L2_CID_BRIGHTNESS || ctrl->id == V4L2_CID_CONTRAST) {
ret = usb_control_msg(usbtv->udev,
- usb_sndctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, USBTV_BASE + 0x0244, (void *)data, 3, 0);
if (ret < 0)
goto error;
diff --git a/drivers/media/usb/usbvision/usbvision-cards.h b/drivers/media/usb/usbvision/usbvision-cards.h
index a51cc1185cce..07ec83512743 100644
--- a/drivers/media/usb/usbvision/usbvision-cards.h
+++ b/drivers/media/usb/usbvision/usbvision-cards.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define XANBOO 0
#define BELKIN_VIDEOBUS_II 1
#define BELKIN_VIDEOBUS 2
diff --git a/drivers/media/usb/uvc/Makefile b/drivers/media/usb/uvc/Makefile
index c26d12fdb8f4..a4fe5b5d533f 100644
--- a/drivers/media/usb/uvc/Makefile
+++ b/drivers/media/usb/uvc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
uvc_status.o uvc_isight.o uvc_debugfs.o
ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 6d22b22cb35b..28b91b7d756f 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2230,7 +2230,7 @@ static int uvc_reset_resume(struct usb_interface *intf)
* Module parameters
*/
-static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
+static int uvc_clock_param_get(char *buffer, const struct kernel_param *kp)
{
if (uvc_clock_param == CLOCK_MONOTONIC)
return sprintf(buffer, "CLOCK_MONOTONIC");
@@ -2238,7 +2238,7 @@ static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
return sprintf(buffer, "CLOCK_REALTIME");
}
-static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
+static int uvc_clock_param_set(const char *val, const struct kernel_param *kp)
{
if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
val += strlen("clock_");
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 34c7ee6cc9e5..05398784d1c8 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _USB_VIDEO_H_
#define _USB_VIDEO_H_
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
index 4ff8d0aed015..1d888661fd03 100644
--- a/drivers/media/usb/zr364xx/zr364xx.c
+++ b/drivers/media/usb/zr364xx/zr364xx.c
@@ -209,10 +209,8 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
int status;
unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);
- if (!transfer_buffer) {
- dev_err(&udev->dev, "kmalloc(%d) failed\n", size);
+ if (!transfer_buffer)
return -ENOMEM;
- }
memcpy(transfer_buffer, cp, size);
@@ -387,9 +385,9 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
vb);
int rc;
- DBG("%s, field=%d, fmt name = %s\n", __func__, field, cam->fmt != NULL ?
- cam->fmt->name : "");
- if (cam->fmt == NULL)
+ DBG("%s, field=%d, fmt name = %s\n", __func__, field,
+ cam->fmt ? cam->fmt->name : "");
+ if (!cam->fmt)
return -EINVAL;
buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3);
@@ -789,7 +787,7 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct zr364xx_camera *cam = video_drvdata(file);
char pixelformat_name[5];
- if (cam == NULL)
+ if (!cam)
return -ENODEV;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
@@ -819,7 +817,7 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
{
struct zr364xx_camera *cam;
- if (file == NULL)
+ if (!file)
return -ENODEV;
cam = video_drvdata(file);
@@ -981,13 +979,13 @@ static void read_pipe_completion(struct urb *purb)
pipe_info = purb->context;
_DBG("%s %p, status %d\n", __func__, purb, purb->status);
- if (pipe_info == NULL) {
+ if (!pipe_info) {
printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
return;
}
cam = pipe_info->cam;
- if (cam == NULL) {
+ if (!cam) {
printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
return;
}
@@ -1071,7 +1069,7 @@ static void zr364xx_stop_readpipe(struct zr364xx_camera *cam)
{
struct zr364xx_pipeinfo *pipe_info;
- if (cam == NULL) {
+ if (!cam) {
printk(KERN_ERR KBUILD_MODNAME ": invalid device\n");
return;
}
@@ -1275,7 +1273,7 @@ static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
struct zr364xx_camera *cam = video_drvdata(file);
int ret;
- if (cam == NULL) {
+ if (!cam) {
DBG("%s: cam == NULL\n", __func__);
return -ENODEV;
}
@@ -1359,7 +1357,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
pipe->transfer_buffer = kzalloc(pipe->transfer_size,
GFP_KERNEL);
- if (pipe->transfer_buffer == NULL) {
+ if (!pipe->transfer_buffer) {
DBG("out of memory!\n");
return -ENOMEM;
}
@@ -1375,7 +1373,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
DBG("valloc %p, idx %lu, pdata %p\n",
&cam->buffer.frame[i], i,
cam->buffer.frame[i].lpvbits);
- if (cam->buffer.frame[i].lpvbits == NULL) {
+ if (!cam->buffer.frame[i].lpvbits) {
printk(KERN_INFO KBUILD_MODNAME ": out of memory. Using less frames\n");
break;
}
@@ -1423,11 +1421,9 @@ static int zr364xx_probe(struct usb_interface *intf,
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
- cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL);
- if (cam == NULL) {
- dev_err(&udev->dev, "cam: out of memory !\n");
+ cam = kzalloc(sizeof(*cam), GFP_KERNEL);
+ if (!cam)
return -ENOMEM;
- }
cam->v4l2_dev.release = zr364xx_release;
err = v4l2_device_register(&intf->dev, &cam->v4l2_dev);
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 098ad5fd5231..77303286aef7 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the V4L2 core
#
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index 8db45dfc271b..82852f23a3b6 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -239,7 +239,7 @@ static const struct analog_demod_ops tuner_analog_ops = {
* @type: type of the tuner (e. g. tuner number)
* @new_mode_mask: Indicates if tuner supports TV and/or Radio
* @new_config: an optional parameter used by a few tuners to adjust
- internal parameters, like LNA mode
+ * internal parameters, like LNA mode
* @tuner_callback: an optional function to be called when switching
* to analog mode
*
@@ -750,6 +750,7 @@ static int tuner_remove(struct i2c_client *client)
/**
* check_mode - Verify if tuner supports the requested mode
* @t: a pointer to the module's internal struct_tuner
+ * @mode: mode of the tuner, as defined by &enum v4l2_tuner_type.
*
* This function checks if the tuner is capable of tuning analog TV,
* digital TV or radio, depending on what the caller wants. If the
@@ -757,6 +758,7 @@ static int tuner_remove(struct i2c_client *client)
* returns 0.
* This function is needed for boards that have a separate tuner for
* radio (like devices with tea5767).
+ *
* NOTE: mt20xx uses V4L2_TUNER_DIGITAL_TV and calls set_tv_freq to
* select a TV frequency. So, t_mode = T_ANALOG_TV could actually
* be used to represent a Digital TV too.
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index d741a8e0fdac..e5acfab470a5 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -22,8 +22,37 @@
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
+static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ if (!n->ops || !n->ops->bound)
+ return 0;
+
+ return n->ops->bound(n, subdev, asd);
+}
+
+static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ if (!n->ops || !n->ops->unbind)
+ return;
+
+ n->ops->unbind(n, subdev, asd);
+}
+
+static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
+{
+ if (!n->ops || !n->ops->complete)
+ return 0;
+
+ return n->ops->complete(n);
+}
+
static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
#if IS_ENABLED(CONFIG_I2C)
@@ -60,8 +89,8 @@ static LIST_HEAD(subdev_list);
static LIST_HEAD(notifier_list);
static DEFINE_MUTEX(list_lock);
-static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd)
+static struct v4l2_async_subdev *v4l2_async_find_match(
+ struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd)
{
bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *);
struct v4l2_async_subdev *asd;
@@ -95,22 +124,96 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
return NULL;
}
-static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
+/* Find the sub-device notifier registered by a sub-device driver. */
+static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier(
+ struct v4l2_subdev *sd)
{
- int ret;
+ struct v4l2_async_notifier *n;
- if (notifier->bound) {
- ret = notifier->bound(notifier, sd, asd);
- if (ret < 0)
- return ret;
+ list_for_each_entry(n, &notifier_list, list)
+ if (n->sd == sd)
+ return n;
+
+ return NULL;
+}
+
+/* Get v4l2_device related to the notifier if one can be found. */
+static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev(
+ struct v4l2_async_notifier *notifier)
+{
+ while (notifier->parent)
+ notifier = notifier->parent;
+
+ return notifier->v4l2_dev;
+}
+
+/*
+ * Return true if all child sub-device notifiers are complete, false otherwise.
+ */
+static bool v4l2_async_notifier_can_complete(
+ struct v4l2_async_notifier *notifier)
+{
+ struct v4l2_subdev *sd;
+
+ if (!list_empty(&notifier->waiting))
+ return false;
+
+ list_for_each_entry(sd, &notifier->done, async_list) {
+ struct v4l2_async_notifier *subdev_notifier =
+ v4l2_async_find_subdev_notifier(sd);
+
+ if (subdev_notifier &&
+ !v4l2_async_notifier_can_complete(subdev_notifier))
+ return false;
}
- ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+ return true;
+}
+
+/*
+ * Complete the master notifier if possible. This is done when all async
+ * sub-devices have been bound; v4l2_device is also available then.
+ */
+static int v4l2_async_notifier_try_complete(
+ struct v4l2_async_notifier *notifier)
+{
+ /* Quick check whether there are still more sub-devices here. */
+ if (!list_empty(&notifier->waiting))
+ return 0;
+
+ /* Check the entire notifier tree; find the root notifier first. */
+ while (notifier->parent)
+ notifier = notifier->parent;
+
+ /* This is root if it has v4l2_dev. */
+ if (!notifier->v4l2_dev)
+ return 0;
+
+ /* Is everything ready? */
+ if (!v4l2_async_notifier_can_complete(notifier))
+ return 0;
+
+ return v4l2_async_notifier_call_complete(notifier);
+}
+
+static int v4l2_async_notifier_try_all_subdevs(
+ struct v4l2_async_notifier *notifier);
+
+static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+ struct v4l2_device *v4l2_dev,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct v4l2_async_notifier *subdev_notifier;
+ int ret;
+
+ ret = v4l2_device_register_subdev(v4l2_dev, sd);
+ if (ret < 0)
+ return ret;
+
+ ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
if (ret < 0) {
- if (notifier->unbind)
- notifier->unbind(notifier, sd, asd);
+ v4l2_device_unregister_subdev(sd);
return ret;
}
@@ -122,8 +225,55 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
/* Move from the global subdevice list to notifier's done */
list_move(&sd->async_list, &notifier->done);
- if (list_empty(&notifier->waiting) && notifier->complete)
- return notifier->complete(notifier);
+ /*
+ * See if the sub-device has a notifier. If not, return here.
+ */
+ subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+ if (!subdev_notifier || subdev_notifier->parent)
+ return 0;
+
+ /*
+ * Proceed with checking for the sub-device notifier's async
+ * sub-devices, and return the result. The error will be handled by the
+ * caller.
+ */
+ subdev_notifier->parent = notifier;
+
+ return v4l2_async_notifier_try_all_subdevs(subdev_notifier);
+}
+
+/* Test all async sub-devices in a notifier for a match. */
+static int v4l2_async_notifier_try_all_subdevs(
+ struct v4l2_async_notifier *notifier)
+{
+ struct v4l2_device *v4l2_dev =
+ v4l2_async_notifier_find_v4l2_dev(notifier);
+ struct v4l2_subdev *sd;
+
+ if (!v4l2_dev)
+ return 0;
+
+again:
+ list_for_each_entry(sd, &subdev_list, async_list) {
+ struct v4l2_async_subdev *asd;
+ int ret;
+
+ asd = v4l2_async_find_match(notifier, sd);
+ if (!asd)
+ continue;
+
+ ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * v4l2_async_match_notify() may lead to registering a
+ * new notifier and thus changing the async subdevs
+ * list. In order to proceed safely from here, restart
+ * parsing the list from the beginning.
+ */
+ goto again;
+ }
return 0;
}
@@ -134,24 +284,107 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
/* Subdevice driver will reprobe and put the subdev back onto the list */
list_del_init(&sd->async_list);
sd->asd = NULL;
- sd->dev = NULL;
}
-int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
- struct v4l2_async_notifier *notifier)
+/* Unbind all sub-devices in the notifier tree. */
+static void v4l2_async_notifier_unbind_all_subdevs(
+ struct v4l2_async_notifier *notifier)
{
struct v4l2_subdev *sd, *tmp;
+
+ list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
+ struct v4l2_async_notifier *subdev_notifier =
+ v4l2_async_find_subdev_notifier(sd);
+
+ if (subdev_notifier)
+ v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
+
+ v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
+ v4l2_async_cleanup(sd);
+
+ list_move(&sd->async_list, &subdev_list);
+ }
+
+ notifier->parent = NULL;
+}
+
+/* See if an fwnode can be found in a notifier's lists. */
+static bool __v4l2_async_notifier_fwnode_has_async_subdev(
+ struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode)
+{
struct v4l2_async_subdev *asd;
+ struct v4l2_subdev *sd;
+
+ list_for_each_entry(asd, &notifier->waiting, list) {
+ if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
+ continue;
+
+ if (asd->match.fwnode.fwnode == fwnode)
+ return true;
+ }
+
+ list_for_each_entry(sd, &notifier->done, async_list) {
+ if (WARN_ON(!sd->asd))
+ continue;
+
+ if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
+ continue;
+
+ if (sd->asd->match.fwnode.fwnode == fwnode)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Find out whether an async sub-device was set up for an fwnode already or
+ * whether it exists in a given notifier before @this_index.
+ */
+static bool v4l2_async_notifier_fwnode_has_async_subdev(
+ struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode,
+ unsigned int this_index)
+{
+ unsigned int j;
+
+ lockdep_assert_held(&list_lock);
+
+ /* Check that an fwnode is not being added more than once. */
+ for (j = 0; j < this_index; j++) {
+ struct v4l2_async_subdev *asd = notifier->subdevs[this_index];
+ struct v4l2_async_subdev *other_asd = notifier->subdevs[j];
+
+ if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&
+ asd->match.fwnode.fwnode ==
+ other_asd->match.fwnode.fwnode)
+ return true;
+ }
+
+ /* Check than an fwnode did not exist in other notifiers. */
+ list_for_each_entry(notifier, &notifier_list, list)
+ if (__v4l2_async_notifier_fwnode_has_async_subdev(
+ notifier, fwnode))
+ return true;
+
+ return false;
+}
+
+static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+{
+ struct device *dev =
+ notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
+ struct v4l2_async_subdev *asd;
+ int ret;
int i;
- if (!v4l2_dev || !notifier->num_subdevs ||
- notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+ if (notifier->num_subdevs > V4L2_MAX_SUBDEVS)
return -EINVAL;
- notifier->v4l2_dev = v4l2_dev;
INIT_LIST_HEAD(&notifier->waiting);
INIT_LIST_HEAD(&notifier->done);
+ mutex_lock(&list_lock);
+
for (i = 0; i < notifier->num_subdevs; i++) {
asd = notifier->subdevs[i];
@@ -159,32 +392,32 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
case V4L2_ASYNC_MATCH_CUSTOM:
case V4L2_ASYNC_MATCH_DEVNAME:
case V4L2_ASYNC_MATCH_I2C:
+ break;
case V4L2_ASYNC_MATCH_FWNODE:
+ if (v4l2_async_notifier_fwnode_has_async_subdev(
+ notifier, asd->match.fwnode.fwnode, i)) {
+ dev_err(dev,
+ "fwnode has already been registered or in notifier's subdev list\n");
+ ret = -EEXIST;
+ goto err_unlock;
+ }
break;
default:
- dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
- "Invalid match type %u on %p\n",
+ dev_err(dev, "Invalid match type %u on %p\n",
asd->match_type, asd);
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_unlock;
}
list_add_tail(&asd->list, &notifier->waiting);
}
- mutex_lock(&list_lock);
+ ret = v4l2_async_notifier_try_all_subdevs(notifier);
+ if (ret < 0)
+ goto err_unbind;
- list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) {
- int ret;
-
- asd = v4l2_async_belongs(notifier, sd);
- if (!asd)
- continue;
-
- ret = v4l2_async_test_notify(notifier, sd, asd);
- if (ret < 0) {
- mutex_unlock(&list_lock);
- return ret;
- }
- }
+ ret = v4l2_async_notifier_try_complete(notifier);
+ if (ret < 0)
+ goto err_unbind;
/* Keep also completed notifiers on the list */
list_add(&notifier->list, &notifier_list);
@@ -192,90 +425,114 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
mutex_unlock(&list_lock);
return 0;
+
+err_unbind:
+ /*
+ * On failure, unbind all sub-devices registered through this notifier.
+ */
+ v4l2_async_notifier_unbind_all_subdevs(notifier);
+
+err_unlock:
+ mutex_unlock(&list_lock);
+
+ return ret;
+}
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+ struct v4l2_async_notifier *notifier)
+{
+ int ret;
+
+ if (WARN_ON(!v4l2_dev || notifier->sd))
+ return -EINVAL;
+
+ notifier->v4l2_dev = v4l2_dev;
+
+ ret = __v4l2_async_notifier_register(notifier);
+ if (ret)
+ notifier->v4l2_dev = NULL;
+
+ return ret;
}
EXPORT_SYMBOL(v4l2_async_notifier_register);
-void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
+ struct v4l2_async_notifier *notifier)
{
- struct v4l2_subdev *sd, *tmp;
- unsigned int notif_n_subdev = notifier->num_subdevs;
- unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
- struct device **dev;
- int i = 0;
+ int ret;
- if (!notifier->v4l2_dev)
- return;
+ if (WARN_ON(!sd || notifier->v4l2_dev))
+ return -EINVAL;
- dev = kvmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- dev_err(notifier->v4l2_dev->dev,
- "Failed to allocate device cache!\n");
- }
+ notifier->sd = sd;
- mutex_lock(&list_lock);
+ ret = __v4l2_async_notifier_register(notifier);
+ if (ret)
+ notifier->sd = NULL;
- list_del(&notifier->list);
+ return ret;
+}
+EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
- list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
- struct device *d;
+static void __v4l2_async_notifier_unregister(
+ struct v4l2_async_notifier *notifier)
+{
+ if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
+ return;
- d = get_device(sd->dev);
+ v4l2_async_notifier_unbind_all_subdevs(notifier);
- v4l2_async_cleanup(sd);
+ notifier->sd = NULL;
+ notifier->v4l2_dev = NULL;
- /* If we handled USB devices, we'd have to lock the parent too */
- device_release_driver(d);
+ list_del(&notifier->list);
+}
- if (notifier->unbind)
- notifier->unbind(notifier, sd, sd->asd);
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+ mutex_lock(&list_lock);
- /*
- * Store device at the device cache, in order to call
- * put_device() on the final step
- */
- if (dev)
- dev[i++] = d;
- else
- put_device(d);
- }
+ __v4l2_async_notifier_unregister(notifier);
mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_notifier_unregister);
- /*
- * Call device_attach() to reprobe devices
- *
- * NOTE: If dev allocation fails, i is 0, and the whole loop won't be
- * executed.
- */
- while (i--) {
- struct device *d = dev[i];
-
- if (d && device_attach(d) < 0) {
- const char *name = "(none)";
- int lock = device_trylock(d);
-
- if (lock && d->driver)
- name = d->driver->name;
- dev_err(d, "Failed to re-probe to %s\n", name);
- if (lock)
- device_unlock(d);
+void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
+{
+ unsigned int i;
+
+ if (!notifier || !notifier->max_subdevs)
+ return;
+
+ for (i = 0; i < notifier->num_subdevs; i++) {
+ struct v4l2_async_subdev *asd = notifier->subdevs[i];
+
+ switch (asd->match_type) {
+ case V4L2_ASYNC_MATCH_FWNODE:
+ fwnode_handle_put(asd->match.fwnode.fwnode);
+ break;
+ default:
+ WARN_ON_ONCE(true);
+ break;
}
- put_device(d);
+
+ kfree(asd);
}
- kvfree(dev);
- notifier->v4l2_dev = NULL;
+ notifier->max_subdevs = 0;
+ notifier->num_subdevs = 0;
- /*
- * Don't care about the waiting list, it is initialised and populated
- * upon notifier registration.
- */
+ kvfree(notifier->subdevs);
+ notifier->subdevs = NULL;
}
-EXPORT_SYMBOL(v4l2_async_notifier_unregister);
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
int v4l2_async_register_subdev(struct v4l2_subdev *sd)
{
+ struct v4l2_async_notifier *subdev_notifier;
struct v4l2_async_notifier *notifier;
+ int ret;
/*
* No reference taken. The reference is held by the device
@@ -290,41 +547,73 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
INIT_LIST_HEAD(&sd->async_list);
list_for_each_entry(notifier, &notifier_list, list) {
- struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd);
- if (asd) {
- int ret = v4l2_async_test_notify(notifier, sd, asd);
- mutex_unlock(&list_lock);
- return ret;
- }
+ struct v4l2_device *v4l2_dev =
+ v4l2_async_notifier_find_v4l2_dev(notifier);
+ struct v4l2_async_subdev *asd;
+
+ if (!v4l2_dev)
+ continue;
+
+ asd = v4l2_async_find_match(notifier, sd);
+ if (!asd)
+ continue;
+
+ ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd);
+ if (ret)
+ goto err_unbind;
+
+ ret = v4l2_async_notifier_try_complete(notifier);
+ if (ret)
+ goto err_unbind;
+
+ goto out_unlock;
}
/* None matched, wait for hot-plugging */
list_add(&sd->async_list, &subdev_list);
+out_unlock:
mutex_unlock(&list_lock);
return 0;
+
+err_unbind:
+ /*
+ * Complete failed. Unbind the sub-devices bound through registering
+ * this async sub-device.
+ */
+ subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+ if (subdev_notifier)
+ v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
+
+ if (sd->asd)
+ v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
+ v4l2_async_cleanup(sd);
+
+ mutex_unlock(&list_lock);
+
+ return ret;
}
EXPORT_SYMBOL(v4l2_async_register_subdev);
void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
{
- struct v4l2_async_notifier *notifier = sd->notifier;
+ mutex_lock(&list_lock);
- if (!sd->asd) {
- if (!list_empty(&sd->async_list))
- v4l2_async_cleanup(sd);
- return;
- }
+ __v4l2_async_notifier_unregister(sd->subdev_notifier);
+ v4l2_async_notifier_cleanup(sd->subdev_notifier);
+ kfree(sd->subdev_notifier);
+ sd->subdev_notifier = NULL;
- mutex_lock(&list_lock);
+ if (sd->asd) {
+ struct v4l2_async_notifier *notifier = sd->notifier;
- list_add(&sd->asd->list, &notifier->waiting);
+ list_add(&sd->asd->list, &notifier->waiting);
- v4l2_async_cleanup(sd);
+ v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
+ }
- if (notifier->unbind)
- notifier->unbind(notifier, sd, sd->asd);
+ v4l2_async_cleanup(sd);
mutex_unlock(&list_lock);
}
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index dd1db678718c..cbb2ef43945f 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1227,6 +1227,16 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
}
EXPORT_SYMBOL(v4l2_ctrl_fill);
+static u32 user_flags(const struct v4l2_ctrl *ctrl)
+{
+ u32 flags = ctrl->flags;
+
+ if (ctrl->is_ptr)
+ flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
+
+ return flags;
+}
+
static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes)
{
memset(ev->reserved, 0, sizeof(ev->reserved));
@@ -1234,7 +1244,7 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change
ev->id = ctrl->id;
ev->u.ctrl.changes = changes;
ev->u.ctrl.type = ctrl->type;
- ev->u.ctrl.flags = ctrl->flags;
+ ev->u.ctrl.flags = user_flags(ctrl);
if (ctrl->is_ptr)
ev->u.ctrl.value64 = 0;
else
@@ -2003,10 +2013,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
handler_set_err(hdl, err);
return NULL;
}
- if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) {
- handler_set_err(hdl, -ERANGE);
- return NULL;
- }
if (is_array &&
(type == V4L2_CTRL_TYPE_BUTTON ||
type == V4L2_CTRL_TYPE_CTRL_CLASS)) {
@@ -2577,10 +2583,8 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr
else
qc->id = ctrl->id;
strlcpy(qc->name, ctrl->name, sizeof(qc->name));
- qc->flags = ctrl->flags;
+ qc->flags = user_flags(ctrl);
qc->type = ctrl->type;
- if (ctrl->is_ptr)
- qc->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
qc->elem_size = ctrl->elem_size;
qc->elems = ctrl->elems;
qc->nr_of_dims = ctrl->nr_of_dims;
@@ -2818,7 +2822,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
{
if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL)
- return list_empty(&hdl->ctrl_refs) ? -EINVAL : 0;
+ return 0;
return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
}
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 5c8c49d240d1..930f9c53a64e 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -245,11 +245,11 @@ EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cea861_vic);
/**
* v4l2_match_dv_timings - check if two timings match
- * @t1 - compare this v4l2_dv_timings struct...
- * @t2 - with this struct.
- * @pclock_delta - the allowed pixelclock deviation.
- * @match_reduced_fps - if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
- * match.
+ * @t1: compare this v4l2_dv_timings struct...
+ * @t2: with this struct.
+ * @pclock_delta: the allowed pixelclock deviation.
+ * @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
+ * match.
*
* Compare t1 with t2 with a given margin of error for the pixelclock.
*/
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 40b2fbfe8865..fb72c7ac04d4 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -19,6 +19,7 @@
*/
#include <linux/acpi.h>
#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
@@ -26,7 +27,9 @@
#include <linux/string.h>
#include <linux/types.h>
+#include <media/v4l2-async.h>
#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
enum v4l2_fwnode_bus_type {
V4L2_FWNODE_BUS_TYPE_GUESS = 0,
@@ -181,25 +184,6 @@ v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode,
vep->bus_type = V4L2_MBUS_CSI1;
}
-/**
- * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- * @vep: pointer to the V4L2 fwnode data structure
- *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
- *
- * NOTE: This function does not parse properties the size of which is variable
- * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in
- * new drivers instead.
- *
- * Return: 0 on success or a negative error code on failure.
- */
int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
struct v4l2_fwnode_endpoint *vep)
{
@@ -239,14 +223,6 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse);
-/*
- * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by
- * v4l2_fwnode_endpoint_alloc_parse()
- * @vep - the V4L2 fwnode the resources of which are to be released
- *
- * It is safe to call this function with NULL argument or on a V4L2 fwnode the
- * parsing of which failed.
- */
void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
{
if (IS_ERR_OR_NULL(vep))
@@ -257,29 +233,6 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);
-/**
- * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
- * @fwnode: pointer to the endpoint's fwnode handle
- *
- * All properties are optional. If none are found, we don't set any flags. This
- * means the port has a static configuration and no properties have to be
- * specified explicitly. If any properties that identify the bus as parallel
- * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
- * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
- * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
- * reference to @fwnode.
- *
- * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
- * v4l2_fwnode_endpoint_parse():
- *
- * 1. It also parses variable size data.
- *
- * 2. The memory it has allocated to store the variable size data must be freed
- * using v4l2_fwnode_endpoint_free() when no longer needed.
- *
- * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer
- * on error.
- */
struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
struct fwnode_handle *fwnode)
{
@@ -322,24 +275,6 @@ out_err:
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
-/**
- * v4l2_fwnode_endpoint_parse_link() - parse a link between two endpoints
- * @__fwnode: pointer to the endpoint's fwnode at the local end of the link
- * @link: pointer to the V4L2 fwnode link data structure
- *
- * Fill the link structure with the local and remote nodes and port numbers.
- * The local_node and remote_node fields are set to point to the local and
- * remote port's parent nodes respectively (the port parent node being the
- * parent node of the port node if that node isn't a 'ports' node, or the
- * grand-parent node of the port node otherwise).
- *
- * A reference is taken to both the local and remote nodes, the caller must use
- * v4l2_fwnode_endpoint_put_link() to drop the references when done with the
- * link.
- *
- * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be
- * found.
- */
int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,
struct v4l2_fwnode_link *link)
{
@@ -374,13 +309,6 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link);
-/**
- * v4l2_fwnode_put_link() - drop references to nodes in a link
- * @link: pointer to the V4L2 fwnode link data structure
- *
- * Drop references to the local and remote nodes in the link. This function
- * must be called on every link parsed with v4l2_fwnode_parse_link().
- */
void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
{
fwnode_handle_put(link->local_node);
@@ -388,6 +316,630 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
+static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier,
+ unsigned int max_subdevs)
+{
+ struct v4l2_async_subdev **subdevs;
+
+ if (max_subdevs <= notifier->max_subdevs)
+ return 0;
+
+ subdevs = kvmalloc_array(
+ max_subdevs, sizeof(*notifier->subdevs),
+ GFP_KERNEL | __GFP_ZERO);
+ if (!subdevs)
+ return -ENOMEM;
+
+ if (notifier->subdevs) {
+ memcpy(subdevs, notifier->subdevs,
+ sizeof(*subdevs) * notifier->num_subdevs);
+
+ kvfree(notifier->subdevs);
+ }
+
+ notifier->subdevs = subdevs;
+ notifier->max_subdevs = max_subdevs;
+
+ return 0;
+}
+
+static int v4l2_async_notifier_fwnode_parse_endpoint(
+ struct device *dev, struct v4l2_async_notifier *notifier,
+ struct fwnode_handle *endpoint, unsigned int asd_struct_size,
+ int (*parse_endpoint)(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd))
+{
+ struct v4l2_async_subdev *asd;
+ struct v4l2_fwnode_endpoint *vep;
+ int ret = 0;
+
+ asd = kzalloc(asd_struct_size, GFP_KERNEL);
+ if (!asd)
+ return -ENOMEM;
+
+ asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+ asd->match.fwnode.fwnode =
+ fwnode_graph_get_remote_port_parent(endpoint);
+ if (!asd->match.fwnode.fwnode) {
+ dev_warn(dev, "bad remote port parent\n");
+ ret = -EINVAL;
+ goto out_err;
+ }
+
+ vep = v4l2_fwnode_endpoint_alloc_parse(endpoint);
+ if (IS_ERR(vep)) {
+ ret = PTR_ERR(vep);
+ dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n",
+ ret);
+ goto out_err;
+ }
+
+ ret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0;
+ if (ret == -ENOTCONN)
+ dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep->base.port,
+ vep->base.id);
+ else if (ret < 0)
+ dev_warn(dev,
+ "driver could not parse port@%u/endpoint@%u (%d)\n",
+ vep->base.port, vep->base.id, ret);
+ v4l2_fwnode_endpoint_free(vep);
+ if (ret < 0)
+ goto out_err;
+
+ notifier->subdevs[notifier->num_subdevs] = asd;
+ notifier->num_subdevs++;
+
+ return 0;
+
+out_err:
+ fwnode_handle_put(asd->match.fwnode.fwnode);
+ kfree(asd);
+
+ return ret == -ENOTCONN ? 0 : ret;
+}
+
+static int __v4l2_async_notifier_parse_fwnode_endpoints(
+ struct device *dev, struct v4l2_async_notifier *notifier,
+ size_t asd_struct_size, unsigned int port, bool has_port,
+ int (*parse_endpoint)(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd))
+{
+ struct fwnode_handle *fwnode;
+ unsigned int max_subdevs = notifier->max_subdevs;
+ int ret;
+
+ if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))
+ return -EINVAL;
+
+ for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(
+ dev_fwnode(dev), fwnode)); ) {
+ struct fwnode_handle *dev_fwnode;
+ bool is_available;
+
+ dev_fwnode = fwnode_graph_get_port_parent(fwnode);
+ is_available = fwnode_device_is_available(dev_fwnode);
+ fwnode_handle_put(dev_fwnode);
+ if (!is_available)
+ continue;
+
+ if (has_port) {
+ struct fwnode_endpoint ep;
+
+ ret = fwnode_graph_parse_endpoint(fwnode, &ep);
+ if (ret) {
+ fwnode_handle_put(fwnode);
+ return ret;
+ }
+
+ if (ep.port != port)
+ continue;
+ }
+ max_subdevs++;
+ }
+
+ /* No subdevs to add? Return here. */
+ if (max_subdevs == notifier->max_subdevs)
+ return 0;
+
+ ret = v4l2_async_notifier_realloc(notifier, max_subdevs);
+ if (ret)
+ return ret;
+
+ for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint(
+ dev_fwnode(dev), fwnode)); ) {
+ struct fwnode_handle *dev_fwnode;
+ bool is_available;
+
+ dev_fwnode = fwnode_graph_get_port_parent(fwnode);
+ is_available = fwnode_device_is_available(dev_fwnode);
+ fwnode_handle_put(dev_fwnode);
+ if (!is_available)
+ continue;
+
+ if (has_port) {
+ struct fwnode_endpoint ep;
+
+ ret = fwnode_graph_parse_endpoint(fwnode, &ep);
+ if (ret)
+ break;
+
+ if (ep.port != port)
+ continue;
+ }
+
+ if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
+ ret = -EINVAL;
+ break;
+ }
+
+ ret = v4l2_async_notifier_fwnode_parse_endpoint(
+ dev, notifier, fwnode, asd_struct_size, parse_endpoint);
+ if (ret < 0)
+ break;
+ }
+
+ fwnode_handle_put(fwnode);
+
+ return ret;
+}
+
+int v4l2_async_notifier_parse_fwnode_endpoints(
+ struct device *dev, struct v4l2_async_notifier *notifier,
+ size_t asd_struct_size,
+ int (*parse_endpoint)(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd))
+{
+ return __v4l2_async_notifier_parse_fwnode_endpoints(
+ dev, notifier, asd_struct_size, 0, false, parse_endpoint);
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
+
+int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
+ struct device *dev, struct v4l2_async_notifier *notifier,
+ size_t asd_struct_size, unsigned int port,
+ int (*parse_endpoint)(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd))
+{
+ return __v4l2_async_notifier_parse_fwnode_endpoints(
+ dev, notifier, asd_struct_size, port, true, parse_endpoint);
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
+
+/*
+ * v4l2_fwnode_reference_parse - parse references for async sub-devices
+ * @dev: the device node the properties of which are parsed for references
+ * @notifier: the async notifier where the async subdevs will be added
+ * @prop: the name of the property
+ *
+ * Return: 0 on success
+ * -ENOENT if no entries were found
+ * -ENOMEM if memory allocation failed
+ * -EINVAL if property parsing failed
+ */
+static int v4l2_fwnode_reference_parse(
+ struct device *dev, struct v4l2_async_notifier *notifier,
+ const char *prop)
+{
+ struct fwnode_reference_args args;
+ unsigned int index;
+ int ret;
+
+ for (index = 0;
+ !(ret = fwnode_property_get_reference_args(
+ dev_fwnode(dev), prop, NULL, 0, index, &args));
+ index++)
+ fwnode_handle_put(args.fwnode);
+
+ if (!index)
+ return -ENOENT;
+
+ /*
+ * Note that right now both -ENODATA and -ENOENT may signal
+ * out-of-bounds access. Return the error in cases other than that.
+ */
+ if (ret != -ENOENT && ret != -ENODATA)
+ return ret;
+
+ ret = v4l2_async_notifier_realloc(notifier,
+ notifier->num_subdevs + index);
+ if (ret)
+ return ret;
+
+ for (index = 0; !fwnode_property_get_reference_args(
+ dev_fwnode(dev), prop, NULL, 0, index, &args);
+ index++) {
+ struct v4l2_async_subdev *asd;
+
+ if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ asd = kzalloc(sizeof(*asd), GFP_KERNEL);
+ if (!asd) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ notifier->subdevs[notifier->num_subdevs] = asd;
+ asd->match.fwnode.fwnode = args.fwnode;
+ asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+ notifier->num_subdevs++;
+ }
+
+ return 0;
+
+error:
+ fwnode_handle_put(args.fwnode);
+ return ret;
+}
+
+/*
+ * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
+ * arguments
+ * @fwnode: fwnode to read @prop from
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @index: the index of the reference to get
+ * @props: the array of integer property names
+ * @nprops: the number of integer property names in @nprops
+ *
+ * First find an fwnode referred to by the reference at @index in @prop.
+ *
+ * Then under that fwnode, @nprops times, for each property in @props,
+ * iteratively follow child nodes starting from fwnode such that they have the
+ * property in @props array at the index of the child node distance from the
+ * root node and the value of that property matching with the integer argument
+ * of the reference, at the same index.
+ *
+ * The child fwnode reched at the end of the iteration is then returned to the
+ * caller.
+ *
+ * The core reason for this is that you cannot refer to just any node in ACPI.
+ * So to refer to an endpoint (easy in DT) you need to refer to a device, then
+ * provide a list of (property name, property value) tuples where each tuple
+ * uniquely identifies a child node. The first tuple identifies a child directly
+ * underneath the device fwnode, the next tuple identifies a child node
+ * underneath the fwnode identified by the previous tuple, etc. until you
+ * reached the fwnode you need.
+ *
+ * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt:
+ *
+ * Scope (\_SB.PCI0.I2C2)
+ * {
+ * Device (CAM0)
+ * {
+ * Name (_DSD, Package () {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () {
+ * "compatible",
+ * Package () { "nokia,smia" }
+ * },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "port0", "PRT0" },
+ * }
+ * })
+ * Name (PRT0, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "port", 0 },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "endpoint0", "EP00" },
+ * }
+ * })
+ * Name (EP00, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "endpoint", 0 },
+ * Package () {
+ * "remote-endpoint",
+ * Package() {
+ * \_SB.PCI0.ISP, 4, 0
+ * }
+ * },
+ * }
+ * })
+ * }
+ * }
+ *
+ * Scope (\_SB.PCI0)
+ * {
+ * Device (ISP)
+ * {
+ * Name (_DSD, Package () {
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "port4", "PRT4" },
+ * }
+ * })
+ *
+ * Name (PRT4, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "port", 4 },
+ * },
+ * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
+ * Package () {
+ * Package () { "endpoint0", "EP40" },
+ * }
+ * })
+ *
+ * Name (EP40, Package() {
+ * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ * Package () {
+ * Package () { "endpoint", 0 },
+ * Package () {
+ * "remote-endpoint",
+ * Package () {
+ * \_SB.PCI0.I2C2.CAM0,
+ * 0, 0
+ * }
+ * },
+ * }
+ * })
+ * }
+ * }
+ *
+ * From the EP40 node under ISP device, you could parse the graph remote
+ * endpoint using v4l2_fwnode_reference_get_int_prop with these arguments:
+ *
+ * @fwnode: fwnode referring to EP40 under ISP.
+ * @prop: "remote-endpoint"
+ * @index: 0
+ * @props: "port", "endpoint"
+ * @nprops: 2
+ *
+ * And you'd get back fwnode referring to EP00 under CAM0.
+ *
+ * The same works the other way around: if you use EP00 under CAM0 as the
+ * fwnode, you'll get fwnode referring to EP40 under ISP.
+ *
+ * The same example in DT syntax would look like this:
+ *
+ * cam: cam0 {
+ * compatible = "nokia,smia";
+ *
+ * port {
+ * port = <0>;
+ * endpoint {
+ * endpoint = <0>;
+ * remote-endpoint = <&isp 4 0>;
+ * };
+ * };
+ * };
+ *
+ * isp: isp {
+ * ports {
+ * port@4 {
+ * port = <4>;
+ * endpoint {
+ * endpoint = <0>;
+ * remote-endpoint = <&cam 0 0>;
+ * };
+ * };
+ * };
+ * };
+ *
+ * Return: 0 on success
+ * -ENOENT if no entries (or the property itself) were found
+ * -EINVAL if property parsing otherwise failed
+ * -ENOMEM if memory allocation failed
+ */
+static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
+ struct fwnode_handle *fwnode, const char *prop, unsigned int index,
+ const char * const *props, unsigned int nprops)
+{
+ struct fwnode_reference_args fwnode_args;
+ unsigned int *args = fwnode_args.args;
+ struct fwnode_handle *child;
+ int ret;
+
+ /*
+ * Obtain remote fwnode as well as the integer arguments.
+ *
+ * Note that right now both -ENODATA and -ENOENT may signal
+ * out-of-bounds access. Return -ENOENT in that case.
+ */
+ ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
+ index, &fwnode_args);
+ if (ret)
+ return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);
+
+ /*
+ * Find a node in the tree under the referred fwnode corresponding to
+ * the integer arguments.
+ */
+ fwnode = fwnode_args.fwnode;
+ while (nprops--) {
+ u32 val;
+
+ /* Loop over all child nodes under fwnode. */
+ fwnode_for_each_child_node(fwnode, child) {
+ if (fwnode_property_read_u32(child, *props, &val))
+ continue;
+
+ /* Found property, see if its value matches. */
+ if (val == *args)
+ break;
+ }
+
+ fwnode_handle_put(fwnode);
+
+ /* No property found; return an error here. */
+ if (!child) {
+ fwnode = ERR_PTR(-ENOENT);
+ break;
+ }
+
+ props++;
+ args++;
+ fwnode = child;
+ }
+
+ return fwnode;
+}
+
+/*
+ * v4l2_fwnode_reference_parse_int_props - parse references for async
+ * sub-devices
+ * @dev: struct device pointer
+ * @notifier: notifier for @dev
+ * @prop: the name of the property
+ * @props: the array of integer property names
+ * @nprops: the number of integer properties
+ *
+ * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in
+ * property @prop with integer arguments with child nodes matching in properties
+ * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
+ * accordingly.
+ *
+ * While it is technically possible to use this function on DT, it is only
+ * meaningful on ACPI. On Device tree you can refer to any node in the tree but
+ * on ACPI the references are limited to devices.
+ *
+ * Return: 0 on success
+ * -ENOENT if no entries (or the property itself) were found
+ * -EINVAL if property parsing otherwisefailed
+ * -ENOMEM if memory allocation failed
+ */
+static int v4l2_fwnode_reference_parse_int_props(
+ struct device *dev, struct v4l2_async_notifier *notifier,
+ const char *prop, const char * const *props, unsigned int nprops)
+{
+ struct fwnode_handle *fwnode;
+ unsigned int index;
+ int ret;
+
+ for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
+ dev_fwnode(dev), prop, index, props,
+ nprops))); index++)
+ fwnode_handle_put(fwnode);
+
+ /*
+ * Note that right now both -ENODATA and -ENOENT may signal
+ * out-of-bounds access. Return the error in cases other than that.
+ */
+ if (PTR_ERR(fwnode) != -ENOENT && PTR_ERR(fwnode) != -ENODATA)
+ return PTR_ERR(fwnode);
+
+ ret = v4l2_async_notifier_realloc(notifier,
+ notifier->num_subdevs + index);
+ if (ret)
+ return -ENOMEM;
+
+ for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
+ dev_fwnode(dev), prop, index, props,
+ nprops))); index++) {
+ struct v4l2_async_subdev *asd;
+
+ if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ asd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL);
+ if (!asd) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ notifier->subdevs[notifier->num_subdevs] = asd;
+ asd->match.fwnode.fwnode = fwnode;
+ asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+ notifier->num_subdevs++;
+ }
+
+ return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
+
+error:
+ fwnode_handle_put(fwnode);
+ return ret;
+}
+
+int v4l2_async_notifier_parse_fwnode_sensor_common(
+ struct device *dev, struct v4l2_async_notifier *notifier)
+{
+ static const char * const led_props[] = { "led" };
+ static const struct {
+ const char *name;
+ const char * const *props;
+ unsigned int nprops;
+ } props[] = {
+ { "flash-leds", led_props, ARRAY_SIZE(led_props) },
+ { "lens-focus", NULL, 0 },
+ };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(props); i++) {
+ int ret;
+
+ if (props[i].props && is_acpi_node(dev_fwnode(dev)))
+ ret = v4l2_fwnode_reference_parse_int_props(
+ dev, notifier, props[i].name,
+ props[i].props, props[i].nprops);
+ else
+ ret = v4l2_fwnode_reference_parse(
+ dev, notifier, props[i].name);
+ if (ret && ret != -ENOENT) {
+ dev_warn(dev, "parsing property \"%s\" failed (%d)\n",
+ props[i].name, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);
+
+int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
+{
+ struct v4l2_async_notifier *notifier;
+ int ret;
+
+ if (WARN_ON(!sd->dev))
+ return -ENODEV;
+
+ notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
+ if (!notifier)
+ return -ENOMEM;
+
+ ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,
+ notifier);
+ if (ret < 0)
+ goto out_cleanup;
+
+ ret = v4l2_async_subdev_notifier_register(sd, notifier);
+ if (ret < 0)
+ goto out_cleanup;
+
+ ret = v4l2_async_register_subdev(sd);
+ if (ret < 0)
+ goto out_unregister;
+
+ sd->subdev_notifier = notifier;
+
+ return 0;
+
+out_unregister:
+ v4l2_async_notifier_unregister(notifier);
+
+out_cleanup:
+ v4l2_async_notifier_cleanup(notifier);
+ kfree(notifier);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index b60a6b0841d1..79614992ee21 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -730,9 +730,12 @@ static void v4l_print_frmsizeenum(const void *arg, bool write_only)
break;
case V4L2_FRMSIZE_TYPE_STEPWISE:
pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n",
- p->stepwise.min_width, p->stepwise.min_height,
- p->stepwise.step_width, p->stepwise.step_height,
- p->stepwise.max_width, p->stepwise.max_height);
+ p->stepwise.min_width,
+ p->stepwise.min_height,
+ p->stepwise.max_width,
+ p->stepwise.max_height,
+ p->stepwise.step_width,
+ p->stepwise.step_height);
break;
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
/* fall through */
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index f62e68aa04c4..bc580fbe18fa 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -183,6 +183,7 @@ EXPORT_SYMBOL(v4l2_m2m_get_curr_priv);
/**
* v4l2_m2m_try_run() - select next job to perform and run it if possible
+ * @m2m_dev: per-device context
*
* Get next transaction (if present) from the waiting jobs list and run it.
*/
@@ -281,6 +282,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_try_schedule);
/**
* v4l2_m2m_cancel_job() - cancel pending jobs for the context
+ * @m2m_ctx: m2m context with jobs to be canceled
*
* In case of streamoff or release called on any context,
* 1] If the context is currently running, then abort job will be called
diff --git a/drivers/media/v4l2-core/v4l2-trace.c b/drivers/media/v4l2-core/v4l2-trace.c
index 7416010542c1..95f3b02e1f84 100644
--- a/drivers/media/v4l2-core/v4l2-trace.c
+++ b/drivers/media/v4l2-core/v4l2-trace.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <media/v4l2-common.h>
#include <media/v4l2-fh.h>
#include <media/videobuf2-v4l2.h>
diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/v4l2-core/vb2-trace.c
index 61e74f5936b3..4c0f39d271f0 100644
--- a/drivers/media/v4l2-core/vb2-trace.c
+++ b/drivers/media/v4l2-core/vb2-trace.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <media/videobuf2-core.h>
#define CREATE_TRACE_POINTS
diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c
index 1dbf6f7785bb..e87fb13b22dc 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -222,7 +222,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
}
EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
-/**
+/*
* __videobuf_free() - free all the buffers and their control structures
*
* This function can only be called if streaming/reading is off, i.e. no buffers
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 0b5c43f7e020..f412429cf5ba 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -185,12 +185,13 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
data, size, dma->nr_pages);
- err = get_user_pages(data & PAGE_MASK, dma->nr_pages,
+ err = get_user_pages_longterm(data & PAGE_MASK, dma->nr_pages,
flags, dma->pages, NULL);
if (err != dma->nr_pages) {
dma->nr_pages = (err >= 0) ? err : 0;
- dprintk(1, "get_user_pages: err=%d [%d]\n", err, dma->nr_pages);
+ dprintk(1, "get_user_pages_longterm: err=%d [%d]\n", err,
+ dma->nr_pages);
return err < 0 ? err : -EINVAL;
}
return 0;
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index cb115ba6a1d2..a8589d96ef72 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -188,7 +188,7 @@ module_param(debug, int, 0644);
static void __vb2_queue_cancel(struct vb2_queue *q);
static void __enqueue_in_driver(struct vb2_buffer *vb);
-/**
+/*
* __vb2_buf_mem_alloc() - allocate video memory for the given buffer
*/
static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
@@ -229,7 +229,7 @@ free:
return ret;
}
-/**
+/*
* __vb2_buf_mem_free() - free memory of the given buffer
*/
static void __vb2_buf_mem_free(struct vb2_buffer *vb)
@@ -243,7 +243,7 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb)
}
}
-/**
+/*
* __vb2_buf_userptr_put() - release userspace memory associated with
* a USERPTR buffer
*/
@@ -258,7 +258,7 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
}
}
-/**
+/*
* __vb2_plane_dmabuf_put() - release memory associated with
* a DMABUF shared plane
*/
@@ -277,7 +277,7 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p)
p->dbuf_mapped = 0;
}
-/**
+/*
* __vb2_buf_dmabuf_put() - release memory associated with
* a DMABUF shared buffer
*/
@@ -289,7 +289,7 @@ static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
__vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
}
-/**
+/*
* __setup_offsets() - setup unique offsets ("cookies") for every plane in
* the buffer.
*/
@@ -317,7 +317,7 @@ static void __setup_offsets(struct vb2_buffer *vb)
}
}
-/**
+/*
* __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type)
* video buffer memory for all buffers/planes on the queue and initializes the
* queue
@@ -386,7 +386,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
return buffer;
}
-/**
+/*
* __vb2_free_mem() - release all video buffer memory for a given queue
*/
static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
@@ -410,7 +410,7 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
}
}
-/**
+/*
* __vb2_queue_free() - free buffers at the end of the queue - video memory and
* related information, if no buffers are left return the queue to an
* uninitialized state. Might be called even if the queue has already been freed.
@@ -544,7 +544,7 @@ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
}
EXPORT_SYMBOL(vb2_buffer_in_use);
-/**
+/*
* __buffers_in_use() - return true if any buffers on the queue are in use and
* the queue cannot be freed (by the means of REQBUFS(0)) call
*/
@@ -564,7 +564,7 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb)
}
EXPORT_SYMBOL_GPL(vb2_core_querybuf);
-/**
+/*
* __verify_userptr_ops() - verify that all memory operations required for
* USERPTR queue type have been provided
*/
@@ -577,7 +577,7 @@ static int __verify_userptr_ops(struct vb2_queue *q)
return 0;
}
-/**
+/*
* __verify_mmap_ops() - verify that all memory operations required for
* MMAP queue type have been provided
*/
@@ -590,7 +590,7 @@ static int __verify_mmap_ops(struct vb2_queue *q)
return 0;
}
-/**
+/*
* __verify_dmabuf_ops() - verify that all memory operations required for
* DMABUF queue type have been provided
*/
@@ -953,7 +953,7 @@ void vb2_discard_done(struct vb2_queue *q)
}
EXPORT_SYMBOL_GPL(vb2_discard_done);
-/**
+/*
* __prepare_mmap() - prepare an MMAP buffer
*/
static int __prepare_mmap(struct vb2_buffer *vb, const void *pb)
@@ -966,7 +966,7 @@ static int __prepare_mmap(struct vb2_buffer *vb, const void *pb)
return ret ? ret : call_vb_qop(vb, buf_prepare, vb);
}
-/**
+/*
* __prepare_userptr() - prepare a USERPTR buffer
*/
static int __prepare_userptr(struct vb2_buffer *vb, const void *pb)
@@ -1082,7 +1082,7 @@ err:
return ret;
}
-/**
+/*
* __prepare_dmabuf() - prepare a DMABUF buffer
*/
static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
@@ -1215,7 +1215,7 @@ err:
return ret;
}
-/**
+/*
* __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing
*/
static void __enqueue_in_driver(struct vb2_buffer *vb)
@@ -1298,7 +1298,7 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
}
EXPORT_SYMBOL_GPL(vb2_core_prepare_buf);
-/**
+/*
* vb2_start_streaming() - Attempt to start streaming.
* @q: videobuf2 queue
*
@@ -1427,7 +1427,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
}
EXPORT_SYMBOL_GPL(vb2_core_qbuf);
-/**
+/*
* __vb2_wait_for_done_vb() - wait for a buffer to become available
* for dequeuing
*
@@ -1502,7 +1502,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
return 0;
}
-/**
+/*
* __vb2_get_done_vb() - get a buffer ready for dequeuing
*
* Will sleep if required for nonblocking == false.
@@ -1553,7 +1553,7 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q)
}
EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
-/**
+/*
* __vb2_dqbuf() - bring back the buffer to the DEQUEUED state
*/
static void __vb2_dqbuf(struct vb2_buffer *vb)
@@ -1625,7 +1625,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
}
EXPORT_SYMBOL_GPL(vb2_core_dqbuf);
-/**
+/*
* __vb2_queue_cancel() - cancel and stop (pause) streaming
*
* Removes all queued buffers from driver's queue and all buffers queued by
@@ -1773,7 +1773,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)
}
EXPORT_SYMBOL_GPL(vb2_core_streamoff);
-/**
+/*
* __find_plane_by_offset() - find plane associated with the given offset off
*/
static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
@@ -2104,7 +2104,7 @@ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file,
}
EXPORT_SYMBOL_GPL(vb2_core_poll);
-/**
+/*
* struct vb2_fileio_buf - buffer context used by file io emulator
*
* vb2 provides a compatibility layer and emulator of file io (read and
@@ -2118,7 +2118,7 @@ struct vb2_fileio_buf {
unsigned int queued:1;
};
-/**
+/*
* struct vb2_fileio_data - queue context used by file io emulator
*
* @cur_index: the index of the buffer currently being read from or
@@ -2155,7 +2155,7 @@ struct vb2_fileio_data {
unsigned write_immediately:1;
};
-/**
+/*
* __vb2_init_fileio() - initialize file io emulator
* @q: videobuf2 queue
* @read: mode selector (1 means read, 0 means write)
@@ -2274,7 +2274,7 @@ err_kfree:
return ret;
}
-/**
+/*
* __vb2_cleanup_fileio() - free resourced used by file io emulator
* @q: videobuf2 queue
*/
@@ -2293,7 +2293,7 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q)
return 0;
}
-/**
+/*
* __vb2_perform_fileio() - perform a single file io (read or write) operation
* @q: videobuf2 queue
* @data: pointed to target userspace buffer
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 9f389f36566d..a9806ba6116d 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -479,7 +479,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
{
struct vb2_dc_buf *buf;
struct frame_vector *vec;
- unsigned long offset;
+ unsigned int offset;
int n_pages, i;
int ret = 0;
struct sg_table *sgt;
@@ -507,7 +507,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
buf->dev = dev;
buf->dma_dir = dma_dir;
- offset = vaddr & ~PAGE_MASK;
+ offset = lower_32_bits(offset_in_page(vaddr));
vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE ||
dma_dir == DMA_BIDIRECTIONAL);
if (IS_ERR(vec)) {
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c
index 4bb8424114ce..89e51989332b 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -120,7 +120,7 @@ static void vb2_common_vm_close(struct vm_area_struct *vma)
h->put(h->arg);
}
-/**
+/*
* vb2_common_vm_ops - common vm_ops used for tracking refcount of mmaped
* video buffers
*/
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 0c0669976bdc..4075314a6989 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -49,7 +49,7 @@ module_param(debug, int, 0644);
#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
-/**
+/*
* __verify_planes_array() - verify that the planes array passed in struct
* v4l2_buffer from userspace can be safely used
*/
@@ -78,7 +78,7 @@ static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb)
return __verify_planes_array(vb, pb);
}
-/**
+/*
* __verify_length() - Verify that the bytesused value for each plane fits in
* the plane length and that the data offset doesn't exceed the bytesused value.
*/
@@ -181,7 +181,7 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b,
return __verify_planes_array(q->bufs[b->index], b);
}
-/**
+/*
* __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
* returned to userspace
*/
@@ -286,7 +286,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
q->last_buffer_dequeued = true;
}
-/**
+/*
* __fill_vb2_buffer() - fill a vb2_buffer with information provided in a
* v4l2_buffer by the userspace. It also verifies that struct
* v4l2_buffer has a valid number of planes.
@@ -446,7 +446,7 @@ static const struct vb2_buf_ops v4l2_buf_ops = {
.copy_timestamp = __copy_timestamp,
};
-/**
+/*
* vb2_querybuf() - query video buffer information
* @q: videobuf queue
* @b: buffer struct passed from userspace to vidioc_querybuf handler