summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-05 20:34:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-05 20:34:57 -0400
commite87d51ac61f88ae44fe14b34abe08566032d726b (patch)
treefc418d2e29fbf8a06f1ed0b6eaff8ba03e0543d7 /drivers/media
parentbdc713bf5674bc6a881bd05c85e2a0f811b409b3 (diff)
parent3622d3e77ecef090b5111e3c5423313f11711dfa (diff)
Merge tag 'media/v4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: "Media updates for v4.12-rc1: - new driver to support mediatek jpeg in hardware codec - rc-lirc, s5p-cec and st-cec staging drivers got promoted - hardware histogram support for vsp1 driver - added Virtual Media Controller driver, to make easier to test the media controller - added a new CEC driver (rainshadow-cec) - removed two staging LIRC drivers for obscure hardware that are too obsolete - added support for Intel SR300 Depth camera - some improvements at CEC and RC core - lots of driver cleanups, improvements all over the tree With this series, we're finally getting rid of the LIRC staging driver. There's just one left (lirc_zilog), with require more care, as part of its functionality (IR RX) is already provided by another driver. Work in progress to convert it on the proper way" * tag 'media/v4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (304 commits) [media] ov2640: print error if devm_*_optional*() fails [media] atmel-isc: Fix the static checker warning [media] ov2640: add support for MEDIA_BUS_FMT_YVYU8_2X8 and MEDIA_BUS_FMT_VYUY8_2X8 [media] ov2640: fix vflip control [media] ov2640: fix duplicate width+height returning from ov2640_select_win() [media] ov2640: add missing write to size change preamble [media] ov2640: add information about DSP register 0xc7 [media] ov2640: improve banding filter register definitions/documentation [media] ov2640: fix init sequence alignment [media] ov2640: make GPIOLIB an optional dependency [media] xc5000: fix spelling mistake: "calibration" [media] vidioc-queryctrl.rst: fix menu/int menu references [media] media-entity: only call dev_dbg_obj if mdev is not NULL [media] pixfmt-meta-vsp1-hgo.rst: remove spurious '-' [media] mtk-vcodec: avoid warnings because of empty macros [media] coda: bump maximum number of internal framebuffers to 17 [media] media: mtk-vcodec: remove informative log [media] subdev-formats.rst: remove spurious '-' [media] dw2102: limit messages to buffer size [media] ttusb2: limit messages to buffer size ...
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Kconfig22
-rw-r--r--drivers/media/Makefile10
-rw-r--r--drivers/media/cec/Kconfig19
-rw-r--r--drivers/media/cec/Makefile8
-rw-r--r--drivers/media/cec/cec-adap.c141
-rw-r--r--drivers/media/cec/cec-api.c21
-rw-r--r--drivers/media/cec/cec-core.c40
-rw-r--r--drivers/media/cec/cec-edid.c (renamed from drivers/media/cec-edid.c)6
-rw-r--r--drivers/media/cec/cec-notifier.c130
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c2
-rw-r--r--drivers/media/common/saa7146/saa7146_vbi.c5
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c5
-rw-r--r--drivers/media/common/tveeprom.c4
-rw-r--r--drivers/media/common/v4l2-tpg/v4l2-tpg-core.c9
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c23
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h2
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c4
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c4
-rw-r--r--drivers/media/dvb-frontends/mn88472.c134
-rw-r--r--drivers/media/dvb-frontends/mn88472_priv.h1
-rw-r--r--drivers/media/dvb-frontends/si2168.c4
-rw-r--r--drivers/media/dvb-frontends/si2168_priv.h2
-rw-r--r--drivers/media/i2c/Kconfig43
-rw-r--r--drivers/media/i2c/Makefile3
-rw-r--r--drivers/media/i2c/ad5820.c4
-rw-r--r--drivers/media/i2c/adv7511.c6
-rw-r--r--drivers/media/i2c/adv7604.c6
-rw-r--r--drivers/media/i2c/adv7842.c6
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_driver.c2
-rw-r--r--drivers/media/i2c/ov2640.c (renamed from drivers/media/i2c/soc_camera/ov2640.c)291
-rw-r--r--drivers/media/i2c/ov5645.c1345
-rw-r--r--drivers/media/i2c/ov5647.c634
-rw-r--r--drivers/media/i2c/ov7670.c75
-rw-r--r--drivers/media/i2c/soc_camera/Kconfig6
-rw-r--r--drivers/media/i2c/soc_camera/Makefile1
-rw-r--r--drivers/media/i2c/soc_camera/imx074.c8
-rw-r--r--drivers/media/i2c/soc_camera/mt9m001.c14
-rw-r--r--drivers/media/i2c/soc_camera/mt9t031.c6
-rw-r--r--drivers/media/i2c/soc_camera/mt9t112.c6
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c14
-rw-r--r--drivers/media/i2c/soc_camera/ov5642.c17
-rw-r--r--drivers/media/i2c/soc_camera/ov6650.c8
-rw-r--r--drivers/media/i2c/soc_camera/ov772x.c47
-rw-r--r--drivers/media/i2c/soc_camera/ov9640.c30
-rw-r--r--drivers/media/i2c/soc_camera/ov9740.c24
-rw-r--r--drivers/media/i2c/soc_camera/rj54n1cb0c.c6
-rw-r--r--drivers/media/i2c/soc_camera/tw9910.c6
-rw-r--r--drivers/media/i2c/tc358743.c59
-rw-r--r--drivers/media/i2c/tvp5150.c4
-rw-r--r--drivers/media/media-entity.c4
-rw-r--r--drivers/media/pci/bt8xx/bttv-cards.c2
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c2
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c4
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c3
-rw-r--r--drivers/media/pci/cx88/cx88-cards.c4
-rw-r--r--drivers/media/pci/cx88/cx88-core.c4
-rw-r--r--drivers/media/pci/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/pci/cx88/cx88.h3
-rw-r--r--drivers/media/pci/dm1105/dm1105.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c7
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c4
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.c2
-rw-r--r--drivers/media/pci/mantis/mantis_vp1034.c2
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c5
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c2
-rw-r--r--drivers/media/pci/saa7134/saa7134-dvb.c4
-rw-r--r--drivers/media/pci/saa7134/saa7134-ts.c5
-rw-r--r--drivers/media/pci/saa7134/saa7134-vbi.c5
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c5
-rw-r--r--drivers/media/pci/saa7164/saa7164-cards.c4
-rw-r--r--drivers/media/pci/saa7164/saa7164-cmd.c5
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c5
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2.c11
-rw-r--r--drivers/media/pci/ttpci/av7110_ir.c5
-rw-r--r--drivers/media/pci/ttpci/budget-av.c8
-rw-r--r--drivers/media/pci/ttpci/budget-ci.c2
-rw-r--r--drivers/media/pci/ttpci/budget.c4
-rw-r--r--drivers/media/pci/tw5864/tw5864-video.c11
-rw-r--r--drivers/media/platform/Kconfig48
-rw-r--r--drivers/media/platform/Makefile6
-rw-r--r--drivers/media/platform/atmel/Kconfig11
-rw-r--r--drivers/media/platform/atmel/Makefile1
-rw-r--r--drivers/media/platform/atmel/atmel-isc-regs.h102
-rw-r--r--drivers/media/platform/atmel/atmel-isc.c628
-rw-r--r--drivers/media/platform/atmel/atmel-isi.c1368
-rw-r--r--drivers/media/platform/atmel/atmel-isi.h (renamed from drivers/media/platform/soc_camera/atmel-isi.h)0
-rw-r--r--drivers/media/platform/coda/coda-bit.c100
-rw-r--r--drivers/media/platform/coda/coda-common.c130
-rw-r--r--drivers/media/platform/coda/coda-h264.c87
-rw-r--r--drivers/media/platform/coda/coda.h10
-rw-r--r--drivers/media/platform/coda/coda_regs.h1
-rw-r--r--drivers/media/platform/davinci/vpif_display.c2
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.c27
-rw-r--r--drivers/media/platform/fsl-viu.c5
-rw-r--r--drivers/media/platform/m2m-deinterlace.c1
-rw-r--r--drivers/media/platform/mtk-jpeg/Makefile2
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c1292
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h139
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c417
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h91
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c160
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h25
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h58
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c33
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h2
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c5
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h17
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c26
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_drv_if.h2
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c4
-rw-r--r--drivers/media/platform/s5p-cec/Makefile2
-rw-r--r--drivers/media/platform/s5p-cec/exynos_hdmi_cec.h37
-rw-r--r--drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c208
-rw-r--r--drivers/media/platform/s5p-cec/regs-cec.h96
-rw-r--r--drivers/media/platform/s5p-cec/s5p_cec.c304
-rw-r--r--drivers/media/platform/s5p-cec/s5p_cec.h79
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c2
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc-v6.h2
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc-v7.h2
-rw-r--r--drivers/media/platform/s5p-mfc/regs-mfc-v8.h2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c245
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h43
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c72
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h1
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c8
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c10
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h51
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.c93
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr.h12
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c48
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c16
-rw-r--r--drivers/media/platform/sh_vou.c4
-rw-r--r--drivers/media/platform/soc_camera/Kconfig12
-rw-r--r--drivers/media/platform/soc_camera/Makefile1
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c1167
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c13
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c103
-rw-r--r--drivers/media/platform/soc_camera/soc_scale_crop.c11
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c5
-rw-r--r--drivers/media/platform/sti/cec/Makefile1
-rw-r--r--drivers/media/platform/sti/cec/stih-cec.c404
-rw-r--r--drivers/media/platform/sti/delta/delta-mjpeg-dec.c2
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.c14
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.h6
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c34
-rw-r--r--drivers/media/platform/vimc/Kconfig14
-rw-r--r--drivers/media/platform/vimc/Makefile3
-rw-r--r--drivers/media/platform/vimc/vimc-capture.c498
-rw-r--r--drivers/media/platform/vimc/vimc-capture.h28
-rw-r--r--drivers/media/platform/vimc/vimc-core.c695
-rw-r--r--drivers/media/platform/vimc/vimc-core.h112
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c276
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.h28
-rw-r--r--drivers/media/platform/vivid/Kconfig5
-rw-r--r--drivers/media/platform/vivid/vivid-cec.c4
-rw-r--r--drivers/media/platform/vivid/vivid-core.c32
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c13
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c4
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.c26
-rw-r--r--drivers/media/platform/vsp1/Makefile1
-rw-r--r--drivers/media/platform/vsp1/vsp1.h6
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c27
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.c27
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.c42
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c82
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c163
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h8
-rw-r--r--drivers/media/platform/vsp1/vsp1_hgo.c230
-rw-r--r--drivers/media/platform/vsp1/vsp1_hgo.h45
-rw-r--r--drivers/media/platform/vsp1/vsp1_hgt.c222
-rw-r--r--drivers/media/platform/vsp1/vsp1_hgt.h42
-rw-r--r--drivers/media/platform/vsp1/vsp1_histo.c646
-rw-r--r--drivers/media/platform/vsp1/vsp1_histo.h84
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c3
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c6
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.c59
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.h9
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h33
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c54
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.c11
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h7
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c3
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c3
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c85
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c224
-rw-r--r--drivers/media/radio/si4713/si4713.c9
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c5
-rw-r--r--drivers/media/rc/Kconfig9
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/gpio-ir-recv.c2
-rw-r--r--drivers/media/rc/igorplugusb.c2
-rw-r--r--drivers/media/rc/imon.c5
-rw-r--r--drivers/media/rc/ir-lirc-codec.c34
-rw-r--r--drivers/media/rc/ir-mce_kbd-decoder.c49
-rw-r--r--drivers/media/rc/keymaps/Makefile1
-rw-r--r--drivers/media/rc/keymaps/rc-dvico-mce.c92
-rw-r--r--drivers/media/rc/keymaps/rc-dvico-portable.c74
-rw-r--r--drivers/media/rc/keymaps/rc-lirc.c42
-rw-r--r--drivers/media/rc/lirc_dev.c122
-rw-r--r--drivers/media/rc/mceusb.c4
-rw-r--r--drivers/media/rc/rc-core-priv.h2
-rw-r--r--drivers/media/rc/rc-ir-raw.c6
-rw-r--r--drivers/media/rc/rc-main.c8
-rw-r--r--drivers/media/rc/serial_ir.c4
-rw-r--r--drivers/media/rc/sir_ir.c438
-rw-r--r--drivers/media/rc/st_rc.c15
-rw-r--r--drivers/media/rc/sunxi-cir.c21
-rw-r--r--drivers/media/rc/winbond-cir.c4
-rw-r--r--drivers/media/tuners/si2157.c23
-rw-r--r--drivers/media/tuners/si2157_priv.h2
-rw-r--r--drivers/media/tuners/xc5000.c3
-rw-r--r--drivers/media/usb/Kconfig1
-rw-r--r--drivers/media/usb/Makefile1
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c2
-rw-r--r--drivers/media/usb/au0828/au0828-video.c7
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-audio.c42
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c48
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-i2c.c16
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c16
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c163
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c3
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mc-common.c2
-rw-r--r--drivers/media/usb/dvb-usb/digitv.c3
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c54
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c19
-rw-r--r--drivers/media/usb/em28xx/Kconfig7
-rw-r--r--drivers/media/usb/em28xx/em28xx-camera.c107
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c15
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h18
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c13
-rw-r--r--drivers/media/usb/em28xx/em28xx.h1
-rw-r--r--drivers/media/usb/go7007/go7007-v4l2.c5
-rw-r--r--drivers/media/usb/gspca/konica.c3
-rw-r--r--drivers/media/usb/pulse8-cec/Kconfig2
-rw-r--r--drivers/media/usb/pulse8-cec/pulse8-cec.c6
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-eeprom.c13
-rw-r--r--drivers/media/usb/rainshadow-cec/Kconfig10
-rw-r--r--drivers/media/usb/rainshadow-cec/Makefile1
-rw-r--r--drivers/media/usb/rainshadow-cec/rainshadow-cec.c388
-rw-r--r--drivers/media/usb/stk1160/Kconfig6
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c2
-rw-r--r--drivers/media/usb/usbvision/usbvision-video.c9
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c15
-rw-r--r--drivers/media/usb/uvc/uvc_video.c12
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h9
-rw-r--r--drivers/media/usb/zr364xx/zr364xx.c8
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c24
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c8
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c16
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c3
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c37
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c14
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c11
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-sg.c11
-rw-r--r--drivers/media/v4l2-core/videobuf2-memops.c6
-rw-r--r--drivers/media/v4l2-core/videobuf2-v4l2.c3
-rw-r--r--drivers/media/v4l2-core/videobuf2-vmalloc.c11
260 files changed, 14372 insertions, 2947 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 3512316e7a46..b72edd27f880 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -81,23 +81,15 @@ config MEDIA_RC_SUPPORT
81 Say Y when you have a TV or an IR device. 81 Say Y when you have a TV or an IR device.
82 82
83config MEDIA_CEC_SUPPORT 83config MEDIA_CEC_SUPPORT
84 bool "HDMI CEC support" 84 bool "HDMI CEC support"
85 select MEDIA_CEC_EDID 85 ---help---
86 ---help--- 86 Enable support for HDMI CEC (Consumer Electronics Control),
87 Enable support for HDMI CEC (Consumer Electronics Control), 87 which is an optional HDMI feature.
88 which is an optional HDMI feature.
89
90 Say Y when you have an HDMI receiver, transmitter or a USB CEC
91 adapter that supports HDMI CEC.
92 88
93config MEDIA_CEC_DEBUG 89 Say Y when you have an HDMI receiver, transmitter or a USB CEC
94 bool "HDMI CEC debugfs interface" 90 adapter that supports HDMI CEC.
95 depends on MEDIA_CEC_SUPPORT && DEBUG_FS
96 ---help---
97 Turns on the DebugFS interface for CEC devices.
98 91
99config MEDIA_CEC_EDID 92source "drivers/media/cec/Kconfig"
100 bool
101 93
102# 94#
103# Media controller 95# Media controller
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index d87ccb8eeabe..523fea3648ad 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,16 +2,10 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5ifeq ($(CONFIG_MEDIA_CEC_EDID),y)
6 obj-$(CONFIG_MEDIA_SUPPORT) += cec-edid.o
7endif
8
9ifeq ($(CONFIG_MEDIA_CEC_SUPPORT),y)
10 obj-$(CONFIG_MEDIA_SUPPORT) += cec/
11endif
12
13media-objs := media-device.o media-devnode.o media-entity.o 5media-objs := media-device.o media-devnode.o media-entity.o
14 6
7obj-$(CONFIG_CEC_CORE) += cec/
8
15# 9#
16# I2C drivers should come before other drivers, otherwise they'll fail 10# I2C drivers should come before other drivers, otherwise they'll fail
17# when compiled as builtin drivers 11# when compiled as builtin drivers
diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig
new file mode 100644
index 000000000000..f944d93e3167
--- /dev/null
+++ b/drivers/media/cec/Kconfig
@@ -0,0 +1,19 @@
1config CEC_CORE
2 tristate
3 depends on MEDIA_CEC_SUPPORT
4 default y
5
6config MEDIA_CEC_NOTIFIER
7 bool
8
9config MEDIA_CEC_RC
10 bool "HDMI CEC RC integration"
11 depends on CEC_CORE && RC_CORE
12 ---help---
13 Pass on CEC remote control messages to the RC framework.
14
15config MEDIA_CEC_DEBUG
16 bool "HDMI CEC debugfs interface"
17 depends on CEC_CORE && DEBUG_FS
18 ---help---
19 Turns on the DebugFS interface for CEC devices.
diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile
index d6686337275f..402a6c62a3e8 100644
--- a/drivers/media/cec/Makefile
+++ b/drivers/media/cec/Makefile
@@ -1,5 +1,7 @@
1cec-objs := cec-core.o cec-adap.o cec-api.o 1cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o
2 2
3ifeq ($(CONFIG_MEDIA_CEC_SUPPORT),y) 3ifeq ($(CONFIG_MEDIA_CEC_NOTIFIER),y)
4 obj-$(CONFIG_MEDIA_SUPPORT) += cec.o 4 cec-objs += cec-notifier.o
5endif 5endif
6
7obj-$(CONFIG_CEC_CORE) += cec.o
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index ccda41c2c9e4..f5fe01c9da8a 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -300,6 +300,40 @@ static void cec_data_cancel(struct cec_data *data)
300} 300}
301 301
302/* 302/*
303 * Flush all pending transmits and cancel any pending timeout work.
304 *
305 * This function is called with adap->lock held.
306 */
307static void cec_flush(struct cec_adapter *adap)
308{
309 struct cec_data *data, *n;
310
311 /*
312 * If the adapter is disabled, or we're asked to stop,
313 * then cancel any pending transmits.
314 */
315 while (!list_empty(&adap->transmit_queue)) {
316 data = list_first_entry(&adap->transmit_queue,
317 struct cec_data, list);
318 cec_data_cancel(data);
319 }
320 if (adap->transmitting)
321 cec_data_cancel(adap->transmitting);
322
323 /* Cancel the pending timeout work. */
324 list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
325 if (cancel_delayed_work(&data->work))
326 cec_data_cancel(data);
327 /*
328 * If cancel_delayed_work returned false, then
329 * the cec_wait_timeout function is running,
330 * which will call cec_data_completed. So no
331 * need to do anything special in that case.
332 */
333 }
334}
335
336/*
303 * Main CEC state machine 337 * Main CEC state machine
304 * 338 *
305 * Wait until the thread should be stopped, or we are not transmitting and 339 * Wait until the thread should be stopped, or we are not transmitting and
@@ -333,7 +367,6 @@ int cec_thread_func(void *_adap)
333 */ 367 */
334 err = wait_event_interruptible_timeout(adap->kthread_waitq, 368 err = wait_event_interruptible_timeout(adap->kthread_waitq,
335 kthread_should_stop() || 369 kthread_should_stop() ||
336 (!adap->is_configured && !adap->is_configuring) ||
337 (!adap->transmitting && 370 (!adap->transmitting &&
338 !list_empty(&adap->transmit_queue)), 371 !list_empty(&adap->transmit_queue)),
339 msecs_to_jiffies(CEC_XFER_TIMEOUT_MS)); 372 msecs_to_jiffies(CEC_XFER_TIMEOUT_MS));
@@ -348,39 +381,8 @@ int cec_thread_func(void *_adap)
348 381
349 mutex_lock(&adap->lock); 382 mutex_lock(&adap->lock);
350 383
351 if ((!adap->is_configured && !adap->is_configuring) || 384 if (kthread_should_stop()) {
352 kthread_should_stop()) { 385 cec_flush(adap);
353 /*
354 * If the adapter is disabled, or we're asked to stop,
355 * then cancel any pending transmits.
356 */
357 while (!list_empty(&adap->transmit_queue)) {
358 data = list_first_entry(&adap->transmit_queue,
359 struct cec_data, list);
360 cec_data_cancel(data);
361 }
362 if (adap->transmitting)
363 cec_data_cancel(adap->transmitting);
364
365 /*
366 * Cancel the pending timeout work. We have to unlock
367 * the mutex when flushing the work since
368 * cec_wait_timeout() will take it. This is OK since
369 * no new entries can be added to wait_queue as long
370 * as adap->transmitting is NULL, which it is due to
371 * the cec_data_cancel() above.
372 */
373 while (!list_empty(&adap->wait_queue)) {
374 data = list_first_entry(&adap->wait_queue,
375 struct cec_data, list);
376
377 if (!cancel_delayed_work(&data->work)) {
378 mutex_unlock(&adap->lock);
379 flush_scheduled_work();
380 mutex_lock(&adap->lock);
381 }
382 cec_data_cancel(data);
383 }
384 goto unlock; 386 goto unlock;
385 } 387 }
386 388
@@ -410,6 +412,7 @@ int cec_thread_func(void *_adap)
410 struct cec_data, list); 412 struct cec_data, list);
411 list_del_init(&data->list); 413 list_del_init(&data->list);
412 adap->transmit_queue_sz--; 414 adap->transmit_queue_sz--;
415
413 /* Make this the current transmitting message */ 416 /* Make this the current transmitting message */
414 adap->transmitting = data; 417 adap->transmitting = data;
415 418
@@ -603,17 +606,17 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
603 606
604 /* Sanity checks */ 607 /* Sanity checks */
605 if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { 608 if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) {
606 dprintk(1, "cec_transmit_msg: invalid length %d\n", msg->len); 609 dprintk(1, "%s: invalid length %d\n", __func__, msg->len);
607 return -EINVAL; 610 return -EINVAL;
608 } 611 }
609 if (msg->timeout && msg->len == 1) { 612 if (msg->timeout && msg->len == 1) {
610 dprintk(1, "cec_transmit_msg: can't reply for poll msg\n"); 613 dprintk(1, "%s: can't reply for poll msg\n", __func__);
611 return -EINVAL; 614 return -EINVAL;
612 } 615 }
613 memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); 616 memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);
614 if (msg->len == 1) { 617 if (msg->len == 1) {
615 if (cec_msg_destination(msg) == 0xf) { 618 if (cec_msg_destination(msg) == 0xf) {
616 dprintk(1, "cec_transmit_msg: invalid poll message\n"); 619 dprintk(1, "%s: invalid poll message\n", __func__);
617 return -EINVAL; 620 return -EINVAL;
618 } 621 }
619 if (cec_has_log_addr(adap, cec_msg_destination(msg))) { 622 if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
@@ -634,20 +637,30 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
634 } 637 }
635 if (msg->len > 1 && !cec_msg_is_broadcast(msg) && 638 if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
636 cec_has_log_addr(adap, cec_msg_destination(msg))) { 639 cec_has_log_addr(adap, cec_msg_destination(msg))) {
637 dprintk(1, "cec_transmit_msg: destination is the adapter itself\n"); 640 dprintk(1, "%s: destination is the adapter itself\n", __func__);
638 return -EINVAL; 641 return -EINVAL;
639 } 642 }
640 if (msg->len > 1 && adap->is_configured && 643 if (msg->len > 1 && adap->is_configured &&
641 !cec_has_log_addr(adap, cec_msg_initiator(msg))) { 644 !cec_has_log_addr(adap, cec_msg_initiator(msg))) {
642 dprintk(1, "cec_transmit_msg: initiator has unknown logical address %d\n", 645 dprintk(1, "%s: initiator has unknown logical address %d\n",
643 cec_msg_initiator(msg)); 646 __func__, cec_msg_initiator(msg));
644 return -EINVAL; 647 return -EINVAL;
645 } 648 }
646 if (!adap->is_configured && !adap->is_configuring) 649 if (!adap->is_configured && !adap->is_configuring) {
647 return -ENONET; 650 if (msg->msg[0] != 0xf0) {
651 dprintk(1, "%s: adapter is unconfigured\n", __func__);
652 return -ENONET;
653 }
654 if (msg->reply) {
655 dprintk(1, "%s: invalid msg->reply\n", __func__);
656 return -EINVAL;
657 }
658 }
648 659
649 if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) 660 if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) {
661 dprintk(1, "%s: transmit queue full\n", __func__);
650 return -EBUSY; 662 return -EBUSY;
663 }
651 664
652 data = kzalloc(sizeof(*data), GFP_KERNEL); 665 data = kzalloc(sizeof(*data), GFP_KERNEL);
653 if (!data) 666 if (!data)
@@ -659,11 +672,11 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
659 } 672 }
660 673
661 if (msg->timeout) 674 if (msg->timeout)
662 dprintk(2, "cec_transmit_msg: %*ph (wait for 0x%02x%s)\n", 675 dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n",
663 msg->len, msg->msg, msg->reply, !block ? ", nb" : ""); 676 __func__, msg->len, msg->msg, msg->reply, !block ? ", nb" : "");
664 else 677 else
665 dprintk(2, "cec_transmit_msg: %*ph%s\n", 678 dprintk(2, "%s: %*ph%s\n",
666 msg->len, msg->msg, !block ? " (nb)" : ""); 679 __func__, msg->len, msg->msg, !block ? " (nb)" : "");
667 680
668 data->msg = *msg; 681 data->msg = *msg;
669 data->fh = fh; 682 data->fh = fh;
@@ -692,6 +705,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
692 705
693 if (fh) 706 if (fh)
694 list_add_tail(&data->xfer_list, &fh->xfer_list); 707 list_add_tail(&data->xfer_list, &fh->xfer_list);
708
695 list_add_tail(&data->list, &adap->transmit_queue); 709 list_add_tail(&data->list, &adap->transmit_queue);
696 adap->transmit_queue_sz++; 710 adap->transmit_queue_sz++;
697 if (!adap->transmitting) 711 if (!adap->transmitting)
@@ -1117,6 +1131,7 @@ static void cec_adap_unconfigure(struct cec_adapter *adap)
1117 adap->is_configuring = false; 1131 adap->is_configuring = false;
1118 adap->is_configured = false; 1132 adap->is_configured = false;
1119 memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); 1133 memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
1134 cec_flush(adap);
1120 wake_up_interruptible(&adap->kthread_waitq); 1135 wake_up_interruptible(&adap->kthread_waitq);
1121 cec_post_state_event(adap); 1136 cec_post_state_event(adap);
1122} 1137}
@@ -1348,19 +1363,30 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
1348 /* Disabling monitor all mode should always succeed */ 1363 /* Disabling monitor all mode should always succeed */
1349 if (adap->monitor_all_cnt) 1364 if (adap->monitor_all_cnt)
1350 WARN_ON(call_op(adap, adap_monitor_all_enable, false)); 1365 WARN_ON(call_op(adap, adap_monitor_all_enable, false));
1351 WARN_ON(adap->ops->adap_enable(adap, false)); 1366 mutex_lock(&adap->devnode.lock);
1367 if (list_empty(&adap->devnode.fhs))
1368 WARN_ON(adap->ops->adap_enable(adap, false));
1369 mutex_unlock(&adap->devnode.lock);
1352 if (phys_addr == CEC_PHYS_ADDR_INVALID) 1370 if (phys_addr == CEC_PHYS_ADDR_INVALID)
1353 return; 1371 return;
1354 } 1372 }
1355 1373
1356 if (adap->ops->adap_enable(adap, true)) 1374 mutex_lock(&adap->devnode.lock);
1375 if (list_empty(&adap->devnode.fhs) &&
1376 adap->ops->adap_enable(adap, true)) {
1377 mutex_unlock(&adap->devnode.lock);
1357 return; 1378 return;
1379 }
1358 1380
1359 if (adap->monitor_all_cnt && 1381 if (adap->monitor_all_cnt &&
1360 call_op(adap, adap_monitor_all_enable, true)) { 1382 call_op(adap, adap_monitor_all_enable, true)) {
1361 WARN_ON(adap->ops->adap_enable(adap, false)); 1383 if (list_empty(&adap->devnode.fhs))
1384 WARN_ON(adap->ops->adap_enable(adap, false));
1385 mutex_unlock(&adap->devnode.lock);
1362 return; 1386 return;
1363 } 1387 }
1388 mutex_unlock(&adap->devnode.lock);
1389
1364 adap->phys_addr = phys_addr; 1390 adap->phys_addr = phys_addr;
1365 cec_post_state_event(adap); 1391 cec_post_state_event(adap);
1366 if (adap->log_addrs.num_log_addrs) 1392 if (adap->log_addrs.num_log_addrs)
@@ -1435,12 +1461,16 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
1435 * within the correct range. 1461 * within the correct range.
1436 */ 1462 */
1437 if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE && 1463 if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE &&
1438 (log_addrs->vendor_id & 0xff000000) != 0) 1464 (log_addrs->vendor_id & 0xff000000) != 0) {
1465 dprintk(1, "invalid vendor ID\n");
1439 return -EINVAL; 1466 return -EINVAL;
1467 }
1440 1468
1441 if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 && 1469 if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 &&
1442 log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) 1470 log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) {
1471 dprintk(1, "invalid CEC version\n");
1443 return -EINVAL; 1472 return -EINVAL;
1473 }
1444 1474
1445 if (log_addrs->num_log_addrs > 1) 1475 if (log_addrs->num_log_addrs > 1)
1446 for (i = 0; i < log_addrs->num_log_addrs; i++) 1476 for (i = 0; i < log_addrs->num_log_addrs; i++)
@@ -1585,6 +1615,9 @@ static int cec_feature_abort_reason(struct cec_adapter *adap,
1585 */ 1615 */
1586 if (msg->msg[1] == CEC_MSG_FEATURE_ABORT) 1616 if (msg->msg[1] == CEC_MSG_FEATURE_ABORT)
1587 return 0; 1617 return 0;
1618 /* Don't Feature Abort messages from 'Unregistered' */
1619 if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED)
1620 return 0;
1588 cec_msg_set_reply_to(&tx_msg, msg); 1621 cec_msg_set_reply_to(&tx_msg, msg);
1589 cec_msg_feature_abort(&tx_msg, msg->msg[1], reason); 1622 cec_msg_feature_abort(&tx_msg, msg->msg[1], reason);
1590 return cec_transmit_msg(adap, &tx_msg, false); 1623 return cec_transmit_msg(adap, &tx_msg, false);
@@ -1699,7 +1732,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
1699 !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) 1732 !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
1700 break; 1733 break;
1701 1734
1702#if IS_REACHABLE(CONFIG_RC_CORE) 1735#ifdef CONFIG_MEDIA_CEC_RC
1703 switch (msg->msg[2]) { 1736 switch (msg->msg[2]) {
1704 /* 1737 /*
1705 * Play function, this message can have variable length 1738 * Play function, this message can have variable length
@@ -1736,7 +1769,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
1736 if (!(adap->capabilities & CEC_CAP_RC) || 1769 if (!(adap->capabilities & CEC_CAP_RC) ||
1737 !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) 1770 !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU))
1738 break; 1771 break;
1739#if IS_REACHABLE(CONFIG_RC_CORE) 1772#ifdef CONFIG_MEDIA_CEC_RC
1740 rc_keyup(adap->rc); 1773 rc_keyup(adap->rc);
1741#endif 1774#endif
1742 break; 1775 break;
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 8950b6c9d6a9..0860fb458757 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -198,7 +198,11 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
198 return -EINVAL; 198 return -EINVAL;
199 199
200 mutex_lock(&adap->lock); 200 mutex_lock(&adap->lock);
201 if (!adap->is_configured) 201 if (adap->log_addrs.num_log_addrs == 0)
202 err = -EPERM;
203 else if (adap->is_configuring)
204 err = -ENONET;
205 else if (!adap->is_configured && msg.msg[0] != 0xf0)
202 err = -ENONET; 206 err = -ENONET;
203 else if (cec_is_busy(adap, fh)) 207 else if (cec_is_busy(adap, fh))
204 err = -EBUSY; 208 err = -EBUSY;
@@ -515,9 +519,18 @@ static int cec_open(struct inode *inode, struct file *filp)
515 return err; 519 return err;
516 } 520 }
517 521
522 mutex_lock(&devnode->lock);
523 if (list_empty(&devnode->fhs) &&
524 adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
525 err = adap->ops->adap_enable(adap, true);
526 if (err) {
527 mutex_unlock(&devnode->lock);
528 kfree(fh);
529 return err;
530 }
531 }
518 filp->private_data = fh; 532 filp->private_data = fh;
519 533
520 mutex_lock(&devnode->lock);
521 /* Queue up initial state events */ 534 /* Queue up initial state events */
522 ev_state.state_change.phys_addr = adap->phys_addr; 535 ev_state.state_change.phys_addr = adap->phys_addr;
523 ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; 536 ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
@@ -551,6 +564,10 @@ static int cec_release(struct inode *inode, struct file *filp)
551 564
552 mutex_lock(&devnode->lock); 565 mutex_lock(&devnode->lock);
553 list_del(&fh->list); 566 list_del(&fh->list);
567 if (list_empty(&devnode->fhs) &&
568 adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
569 WARN_ON(adap->ops->adap_enable(adap, false));
570 }
554 mutex_unlock(&devnode->lock); 571 mutex_unlock(&devnode->lock);
555 572
556 /* Unhook pending transmits from this filehandle. */ 573 /* Unhook pending transmits from this filehandle. */
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index 3163e038a364..f9ebff90f8eb 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -187,6 +187,24 @@ static void cec_devnode_unregister(struct cec_devnode *devnode)
187 put_device(&devnode->dev); 187 put_device(&devnode->dev);
188} 188}
189 189
190#ifdef CONFIG_MEDIA_CEC_NOTIFIER
191static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
192{
193 cec_s_phys_addr(adap, pa, false);
194}
195
196void cec_register_cec_notifier(struct cec_adapter *adap,
197 struct cec_notifier *notifier)
198{
199 if (WARN_ON(!adap->devnode.registered))
200 return;
201
202 adap->notifier = notifier;
203 cec_notifier_register(adap->notifier, adap, cec_cec_notify);
204}
205EXPORT_SYMBOL_GPL(cec_register_cec_notifier);
206#endif
207
190struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, 208struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
191 void *priv, const char *name, u32 caps, 209 void *priv, const char *name, u32 caps,
192 u8 available_las) 210 u8 available_las)
@@ -194,6 +212,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
194 struct cec_adapter *adap; 212 struct cec_adapter *adap;
195 int res; 213 int res;
196 214
215#ifndef CONFIG_MEDIA_CEC_RC
216 caps &= ~CEC_CAP_RC;
217#endif
218
197 if (WARN_ON(!caps)) 219 if (WARN_ON(!caps))
198 return ERR_PTR(-EINVAL); 220 return ERR_PTR(-EINVAL);
199 if (WARN_ON(!ops)) 221 if (WARN_ON(!ops))
@@ -226,10 +248,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
226 return ERR_PTR(res); 248 return ERR_PTR(res);
227 } 249 }
228 250
251#ifdef CONFIG_MEDIA_CEC_RC
229 if (!(caps & CEC_CAP_RC)) 252 if (!(caps & CEC_CAP_RC))
230 return adap; 253 return adap;
231 254
232#if IS_REACHABLE(CONFIG_RC_CORE)
233 /* Prepare the RC input device */ 255 /* Prepare the RC input device */
234 adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE); 256 adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
235 if (!adap->rc) { 257 if (!adap->rc) {
@@ -256,8 +278,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
256 adap->rc->priv = adap; 278 adap->rc->priv = adap;
257 adap->rc->map_name = RC_MAP_CEC; 279 adap->rc->map_name = RC_MAP_CEC;
258 adap->rc->timeout = MS_TO_NS(100); 280 adap->rc->timeout = MS_TO_NS(100);
259#else
260 adap->capabilities &= ~CEC_CAP_RC;
261#endif 281#endif
262 return adap; 282 return adap;
263} 283}
@@ -277,9 +297,9 @@ int cec_register_adapter(struct cec_adapter *adap,
277 adap->owner = parent->driver->owner; 297 adap->owner = parent->driver->owner;
278 adap->devnode.dev.parent = parent; 298 adap->devnode.dev.parent = parent;
279 299
280#if IS_REACHABLE(CONFIG_RC_CORE) 300#ifdef CONFIG_MEDIA_CEC_RC
281 adap->rc->dev.parent = parent;
282 if (adap->capabilities & CEC_CAP_RC) { 301 if (adap->capabilities & CEC_CAP_RC) {
302 adap->rc->dev.parent = parent;
283 res = rc_register_device(adap->rc); 303 res = rc_register_device(adap->rc);
284 304
285 if (res) { 305 if (res) {
@@ -294,7 +314,7 @@ int cec_register_adapter(struct cec_adapter *adap,
294 314
295 res = cec_devnode_register(&adap->devnode, adap->owner); 315 res = cec_devnode_register(&adap->devnode, adap->owner);
296 if (res) { 316 if (res) {
297#if IS_REACHABLE(CONFIG_RC_CORE) 317#ifdef CONFIG_MEDIA_CEC_RC
298 /* Note: rc_unregister also calls rc_free */ 318 /* Note: rc_unregister also calls rc_free */
299 rc_unregister_device(adap->rc); 319 rc_unregister_device(adap->rc);
300 adap->rc = NULL; 320 adap->rc = NULL;
@@ -329,12 +349,16 @@ void cec_unregister_adapter(struct cec_adapter *adap)
329 if (IS_ERR_OR_NULL(adap)) 349 if (IS_ERR_OR_NULL(adap))
330 return; 350 return;
331 351
332#if IS_REACHABLE(CONFIG_RC_CORE) 352#ifdef CONFIG_MEDIA_CEC_RC
333 /* Note: rc_unregister also calls rc_free */ 353 /* Note: rc_unregister also calls rc_free */
334 rc_unregister_device(adap->rc); 354 rc_unregister_device(adap->rc);
335 adap->rc = NULL; 355 adap->rc = NULL;
336#endif 356#endif
337 debugfs_remove_recursive(adap->cec_dir); 357 debugfs_remove_recursive(adap->cec_dir);
358#ifdef CONFIG_MEDIA_CEC_NOTIFIER
359 if (adap->notifier)
360 cec_notifier_unregister(adap->notifier);
361#endif
338 cec_devnode_unregister(&adap->devnode); 362 cec_devnode_unregister(&adap->devnode);
339} 363}
340EXPORT_SYMBOL_GPL(cec_unregister_adapter); 364EXPORT_SYMBOL_GPL(cec_unregister_adapter);
@@ -349,7 +373,7 @@ void cec_delete_adapter(struct cec_adapter *adap)
349 kthread_stop(adap->kthread); 373 kthread_stop(adap->kthread);
350 if (adap->kthread_config) 374 if (adap->kthread_config)
351 kthread_stop(adap->kthread_config); 375 kthread_stop(adap->kthread_config);
352#if IS_REACHABLE(CONFIG_RC_CORE) 376#ifdef CONFIG_MEDIA_CEC_RC
353 rc_free_device(adap->rc); 377 rc_free_device(adap->rc);
354#endif 378#endif
355 kfree(adap); 379 kfree(adap);
diff --git a/drivers/media/cec-edid.c b/drivers/media/cec/cec-edid.c
index 5719b991e340..38e3fec6152b 100644
--- a/drivers/media/cec-edid.c
+++ b/drivers/media/cec/cec-edid.c
@@ -20,7 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <media/cec-edid.h> 23#include <media/cec.h>
24 24
25/* 25/*
26 * This EDID is expected to be a CEA-861 compliant, which means that there are 26 * This EDID is expected to be a CEA-861 compliant, which means that there are
@@ -165,7 +165,3 @@ int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
165 return 0; 165 return 0;
166} 166}
167EXPORT_SYMBOL_GPL(cec_phys_addr_validate); 167EXPORT_SYMBOL_GPL(cec_phys_addr_validate);
168
169MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
170MODULE_DESCRIPTION("CEC EDID helper functions");
171MODULE_LICENSE("GPL");
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
new file mode 100644
index 000000000000..74dc1c32080e
--- /dev/null
+++ b/drivers/media/cec/cec-notifier.c
@@ -0,0 +1,130 @@
1/*
2 * cec-notifier.c - notify CEC drivers of physical address changes
3 *
4 * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk>
5 * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 *
7 * This program is free software; you may redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
12 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
13 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
15 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
16 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
17 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 */
20
21#include <linux/export.h>
22#include <linux/string.h>
23#include <linux/slab.h>
24#include <linux/list.h>
25#include <linux/kref.h>
26
27#include <media/cec.h>
28#include <media/cec-notifier.h>
29#include <drm/drm_edid.h>
30
31struct cec_notifier {
32 struct mutex lock;
33 struct list_head head;
34 struct kref kref;
35 struct device *dev;
36 struct cec_adapter *cec_adap;
37 void (*callback)(struct cec_adapter *adap, u16 pa);
38
39 u16 phys_addr;
40};
41
42static LIST_HEAD(cec_notifiers);
43static DEFINE_MUTEX(cec_notifiers_lock);
44
45struct cec_notifier *cec_notifier_get(struct device *dev)
46{
47 struct cec_notifier *n;
48
49 mutex_lock(&cec_notifiers_lock);
50 list_for_each_entry(n, &cec_notifiers, head) {
51 if (n->dev == dev) {
52 kref_get(&n->kref);
53 mutex_unlock(&cec_notifiers_lock);
54 return n;
55 }
56 }
57 n = kzalloc(sizeof(*n), GFP_KERNEL);
58 if (!n)
59 goto unlock;
60 n->dev = dev;
61 n->phys_addr = CEC_PHYS_ADDR_INVALID;
62 mutex_init(&n->lock);
63 kref_init(&n->kref);
64 list_add_tail(&n->head, &cec_notifiers);
65unlock:
66 mutex_unlock(&cec_notifiers_lock);
67 return n;
68}
69EXPORT_SYMBOL_GPL(cec_notifier_get);
70
71static void cec_notifier_release(struct kref *kref)
72{
73 struct cec_notifier *n =
74 container_of(kref, struct cec_notifier, kref);
75
76 list_del(&n->head);
77 kfree(n);
78}
79
80void cec_notifier_put(struct cec_notifier *n)
81{
82 mutex_lock(&cec_notifiers_lock);
83 kref_put(&n->kref, cec_notifier_release);
84 mutex_unlock(&cec_notifiers_lock);
85}
86EXPORT_SYMBOL_GPL(cec_notifier_put);
87
88void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
89{
90 mutex_lock(&n->lock);
91 n->phys_addr = pa;
92 if (n->callback)
93 n->callback(n->cec_adap, n->phys_addr);
94 mutex_unlock(&n->lock);
95}
96EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
97
98void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
99 const struct edid *edid)
100{
101 u16 pa = CEC_PHYS_ADDR_INVALID;
102
103 if (edid && edid->extensions)
104 pa = cec_get_edid_phys_addr((const u8 *)edid,
105 EDID_LENGTH * (edid->extensions + 1), NULL);
106 cec_notifier_set_phys_addr(n, pa);
107}
108EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr_from_edid);
109
110void cec_notifier_register(struct cec_notifier *n,
111 struct cec_adapter *adap,
112 void (*callback)(struct cec_adapter *adap, u16 pa))
113{
114 kref_get(&n->kref);
115 mutex_lock(&n->lock);
116 n->cec_adap = adap;
117 n->callback = callback;
118 n->callback(adap, n->phys_addr);
119 mutex_unlock(&n->lock);
120}
121EXPORT_SYMBOL_GPL(cec_notifier_register);
122
123void cec_notifier_unregister(struct cec_notifier *n)
124{
125 mutex_lock(&n->lock);
126 n->callback = NULL;
127 mutex_unlock(&n->lock);
128 cec_notifier_put(n);
129}
130EXPORT_SYMBOL_GPL(cec_notifier_unregister);
diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
index 5f10151ecec9..7636606f0be5 100644
--- a/drivers/media/common/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
@@ -473,7 +473,7 @@ static int airstar_atsc1_attach(struct flexcop_device *fc,
473 473
474/* AirStar ATSC 2nd generation */ 474/* AirStar ATSC 2nd generation */
475#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL) 475#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
476static struct nxt200x_config samsung_tbmv_config = { 476static const struct nxt200x_config samsung_tbmv_config = {
477 .demod_address = 0x0a, 477 .demod_address = 0x0a,
478}; 478};
479 479
diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c
index 49237518d65f..3553ac4cba5c 100644
--- a/drivers/media/common/saa7146/saa7146_vbi.c
+++ b/drivers/media/common/saa7146/saa7146_vbi.c
@@ -365,9 +365,8 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
365 365
366 INIT_LIST_HEAD(&vv->vbi_dmaq.queue); 366 INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
367 367
368 init_timer(&vv->vbi_dmaq.timeout); 368 setup_timer(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout,
369 vv->vbi_dmaq.timeout.function = saa7146_buffer_timeout; 369 (unsigned long)(&vv->vbi_dmaq));
370 vv->vbi_dmaq.timeout.data = (unsigned long)(&vv->vbi_dmaq);
371 vv->vbi_dmaq.dev = dev; 370 vv->vbi_dmaq.dev = dev;
372 371
373 init_waitqueue_head(&vv->vbi_wq); 372 init_waitqueue_head(&vv->vbi_wq);
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index e034bcfcf757..b3b29d4f36ed 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -1201,9 +1201,8 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1201{ 1201{
1202 INIT_LIST_HEAD(&vv->video_dmaq.queue); 1202 INIT_LIST_HEAD(&vv->video_dmaq.queue);
1203 1203
1204 init_timer(&vv->video_dmaq.timeout); 1204 setup_timer(&vv->video_dmaq.timeout, saa7146_buffer_timeout,
1205 vv->video_dmaq.timeout.function = saa7146_buffer_timeout; 1205 (unsigned long)(&vv->video_dmaq));
1206 vv->video_dmaq.timeout.data = (unsigned long)(&vv->video_dmaq);
1207 vv->video_dmaq.dev = dev; 1206 vv->video_dmaq.dev = dev;
1208 1207
1209 /* set some default values */ 1208 /* set some default values */
diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c
index 6e1020227f9f..ccf2d3b12aec 100644
--- a/drivers/media/common/tveeprom.c
+++ b/drivers/media/common/tveeprom.c
@@ -420,8 +420,8 @@ static int hasRadioTuner(int tunerType)
420 return 0; 420 return 0;
421} 421}
422 422
423void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, 423void tveeprom_hauppauge_analog(struct tveeprom *tvee,
424 unsigned char *eeprom_data) 424 unsigned char *eeprom_data)
425{ 425{
426 /* ---------------------------------------------- 426 /* ----------------------------------------------
427 ** The hauppauge eeprom format is tagged 427 ** The hauppauge eeprom format is tagged
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index e47b46e2d26c..3dd22da7e17d 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -927,7 +927,14 @@ static void precalculate_color(struct tpg_data *tpg, int k)
927 y >>= 4; 927 y >>= 4;
928 cb >>= 4; 928 cb >>= 4;
929 cr >>= 4; 929 cr >>= 4;
930 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { 930 /*
931 * XV601/709 use the header/footer margins to encode R', G'
932 * and B' values outside the range [0-1]. So do not clamp
933 * XV601/709 values.
934 */
935 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE &&
936 tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV601 &&
937 tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV709) {
931 y = clamp(y, 16, 235); 938 y = clamp(y, 16, 235);
932 cb = clamp(cb, 16, 240); 939 cb = clamp(cb, 16, 240);
933 cr = clamp(cr, 16, 240); 940 cr = clamp(cr, 16, 240);
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 8d65028c7a74..d38bf9bce480 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -785,6 +785,29 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
785 goto exit; 785 goto exit;
786 } 786 }
787 787
788 /*
789 * It may need some time for the CAM to settle down, or there might
790 * be a race condition between the CAM, writing HC and our last
791 * check for DA. This happens, if the CAM asserts DA, just after
792 * checking DA before we are setting HC. In this case it might be
793 * a bug in the CAM to keep the FR bit, the lower layer/HW
794 * communication requires a longer timeout or the CAM needs more
795 * time internally. But this happens in reality!
796 * We need to read the status from the HW again and do the same
797 * we did for the previous check for DA
798 */
799 status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
800 if (status < 0)
801 goto exit;
802
803 if (status & (STATUSREG_DA | STATUSREG_RE)) {
804 if (status & STATUSREG_DA)
805 dvb_ca_en50221_thread_wakeup(ca);
806
807 status = -EAGAIN;
808 goto exit;
809 }
810
788 /* send the amount of data */ 811 /* send the amount of data */
789 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0) 812 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
790 goto exit; 813 goto exit;
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 482912d3b77a..907a05bde162 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -643,6 +643,8 @@ struct dtv_frontend_properties {
643/** 643/**
644 * struct dvb_frontend - Frontend structure to be used on drivers. 644 * struct dvb_frontend - Frontend structure to be used on drivers.
645 * 645 *
646 * @refcount: refcount to keep track of struct dvb_frontend
647 * references
646 * @ops: embedded struct dvb_frontend_ops 648 * @ops: embedded struct dvb_frontend_ops
647 * @dvb: pointer to struct dvb_adapter 649 * @dvb: pointer to struct dvb_adapter
648 * @demodulator_priv: demod private data 650 * @demodulator_priv: demod private data
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 614bfb3740f1..ce37dc2e89c7 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -3852,7 +3852,9 @@ static struct dvb_frontend_ops cxd2841er_t_c_ops = {
3852 FE_CAN_MUTE_TS | 3852 FE_CAN_MUTE_TS |
3853 FE_CAN_2G_MODULATION, 3853 FE_CAN_2G_MODULATION,
3854 .frequency_min = 42000000, 3854 .frequency_min = 42000000,
3855 .frequency_max = 1002000000 3855 .frequency_max = 1002000000,
3856 .symbol_rate_min = 870000,
3857 .symbol_rate_max = 11700000
3856 }, 3858 },
3857 .init = cxd2841er_init_tc, 3859 .init = cxd2841er_init_tc,
3858 .sleep = cxd2841er_sleep_tc, 3860 .sleep = cxd2841er_sleep_tc,
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index 7e1bbbaad625..b5ea9192a341 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -1904,7 +1904,9 @@ static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
1904 status = get_dvbt_lock_status(state, p_lock_status); 1904 status = get_dvbt_lock_status(state, p_lock_status);
1905 break; 1905 break;
1906 default: 1906 default:
1907 break; 1907 pr_debug("Unsupported operation mode %d in %s\n",
1908 state->m_operation_mode, __func__);
1909 return 0;
1908 } 1910 }
1909error: 1911error:
1910 if (status < 0) 1912 if (status < 0)
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index 29dd13b36c28..f6938f9607ac 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -28,8 +28,9 @@ static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
28 struct i2c_client *client = fe->demodulator_priv; 28 struct i2c_client *client = fe->demodulator_priv;
29 struct mn88472_dev *dev = i2c_get_clientdata(client); 29 struct mn88472_dev *dev = i2c_get_clientdata(client);
30 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 30 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
31 int ret; 31 int ret, i, stmp;
32 unsigned int utmp; 32 unsigned int utmp, utmp1, utmp2;
33 u8 buf[5];
33 34
34 if (!dev->active) { 35 if (!dev->active) {
35 ret = -EAGAIN; 36 ret = -EAGAIN;
@@ -77,6 +78,127 @@ static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
77 goto err; 78 goto err;
78 } 79 }
79 80
81 /* Signal strength */
82 if (*status & FE_HAS_SIGNAL) {
83 for (i = 0; i < 2; i++) {
84 ret = regmap_bulk_read(dev->regmap[2], 0x8e + i,
85 &buf[i], 1);
86 if (ret)
87 goto err;
88 }
89
90 utmp1 = buf[0] << 8 | buf[1] << 0 | buf[0] >> 2;
91 dev_dbg(&client->dev, "strength=%u\n", utmp1);
92
93 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
94 c->strength.stat[0].uvalue = utmp1;
95 } else {
96 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
97 }
98
99 /* CNR */
100 if (*status & FE_HAS_VITERBI && c->delivery_system == SYS_DVBT) {
101 /* DVB-T CNR */
102 ret = regmap_bulk_read(dev->regmap[0], 0x9c, buf, 2);
103 if (ret)
104 goto err;
105
106 utmp = buf[0] << 8 | buf[1] << 0;
107 if (utmp) {
108 /* CNR[dB]: 10 * log10(65536 / value) + 2 */
109 /* log10(65536) = 80807124, 0.2 = 3355443 */
110 stmp = ((u64)80807124 - intlog10(utmp) + 3355443)
111 * 10000 >> 24;
112
113 dev_dbg(&client->dev, "cnr=%d value=%u\n", stmp, utmp);
114 } else {
115 stmp = 0;
116 }
117
118 c->cnr.stat[0].svalue = stmp;
119 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
120 } else if (*status & FE_HAS_VITERBI &&
121 c->delivery_system == SYS_DVBT2) {
122 /* DVB-T2 CNR */
123 for (i = 0; i < 3; i++) {
124 ret = regmap_bulk_read(dev->regmap[2], 0xbc + i,
125 &buf[i], 1);
126 if (ret)
127 goto err;
128 }
129
130 utmp = buf[1] << 8 | buf[2] << 0;
131 utmp1 = (buf[0] >> 2) & 0x01; /* 0=SISO, 1=MISO */
132 if (utmp) {
133 if (utmp1) {
134 /* CNR[dB]: 10 * log10(16384 / value) - 6 */
135 /* log10(16384) = 70706234, 0.6 = 10066330 */
136 stmp = ((u64)70706234 - intlog10(utmp)
137 - 10066330) * 10000 >> 24;
138 dev_dbg(&client->dev, "cnr=%d value=%u MISO\n",
139 stmp, utmp);
140 } else {
141 /* CNR[dB]: 10 * log10(65536 / value) + 2 */
142 /* log10(65536) = 80807124, 0.2 = 3355443 */
143 stmp = ((u64)80807124 - intlog10(utmp)
144 + 3355443) * 10000 >> 24;
145
146 dev_dbg(&client->dev, "cnr=%d value=%u SISO\n",
147 stmp, utmp);
148 }
149 } else {
150 stmp = 0;
151 }
152
153 c->cnr.stat[0].svalue = stmp;
154 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
155 } else if (*status & FE_HAS_VITERBI &&
156 c->delivery_system == SYS_DVBC_ANNEX_A) {
157 /* DVB-C CNR */
158 ret = regmap_bulk_read(dev->regmap[1], 0xa1, buf, 4);
159 if (ret)
160 goto err;
161
162 utmp1 = buf[0] << 8 | buf[1] << 0; /* signal */
163 utmp2 = buf[2] << 8 | buf[3] << 0; /* noise */
164 if (utmp1 && utmp2) {
165 /* CNR[dB]: 10 * log10(8 * (signal / noise)) */
166 /* log10(8) = 15151336 */
167 stmp = ((u64)15151336 + intlog10(utmp1)
168 - intlog10(utmp2)) * 10000 >> 24;
169
170 dev_dbg(&client->dev, "cnr=%d signal=%u noise=%u\n",
171 stmp, utmp1, utmp2);
172 } else {
173 stmp = 0;
174 }
175
176 c->cnr.stat[0].svalue = stmp;
177 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
178 } else {
179 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
180 }
181
182 /* PER */
183 if (*status & FE_HAS_SYNC) {
184 ret = regmap_bulk_read(dev->regmap[0], 0xe1, buf, 4);
185 if (ret)
186 goto err;
187
188 utmp1 = buf[0] << 8 | buf[1] << 0;
189 utmp2 = buf[2] << 8 | buf[3] << 0;
190 dev_dbg(&client->dev, "block_error=%u block_count=%u\n",
191 utmp1, utmp2);
192
193 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
194 c->block_error.stat[0].uvalue += utmp1;
195 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
196 c->block_count.stat[0].uvalue += utmp2;
197 } else {
198 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
199 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
200 }
201
80 return 0; 202 return 0;
81err: 203err:
82 dev_dbg(&client->dev, "failed=%d\n", ret); 204 dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -462,6 +584,7 @@ static int mn88472_probe(struct i2c_client *client,
462{ 584{
463 struct mn88472_config *pdata = client->dev.platform_data; 585 struct mn88472_config *pdata = client->dev.platform_data;
464 struct mn88472_dev *dev; 586 struct mn88472_dev *dev;
587 struct dtv_frontend_properties *c;
465 int ret; 588 int ret;
466 unsigned int utmp; 589 unsigned int utmp;
467 static const struct regmap_config regmap_config = { 590 static const struct regmap_config regmap_config = {
@@ -547,6 +670,13 @@ static int mn88472_probe(struct i2c_client *client,
547 *pdata->fe = &dev->fe; 670 *pdata->fe = &dev->fe;
548 i2c_set_clientdata(client, dev); 671 i2c_set_clientdata(client, dev);
549 672
673 /* Init stats to indicate which stats are supported */
674 c = &dev->fe.dtv_property_cache;
675 c->strength.len = 1;
676 c->cnr.len = 1;
677 c->block_error.len = 1;
678 c->block_count.len = 1;
679
550 /* Setup callbacks */ 680 /* Setup callbacks */
551 pdata->get_dvb_frontend = mn88472_get_dvb_frontend; 681 pdata->get_dvb_frontend = mn88472_get_dvb_frontend;
552 682
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index cdf2597a25d1..fb50f56ba30b 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -18,6 +18,7 @@
18#define MN88472_PRIV_H 18#define MN88472_PRIV_H
19 19
20#include "dvb_frontend.h" 20#include "dvb_frontend.h"
21#include "dvb_math.h"
21#include "mn88472.h" 22#include "mn88472.h"
22#include <linux/firmware.h> 23#include <linux/firmware.h>
23#include <linux/regmap.h> 24#include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 680ba06c29fb..172fc367ccaa 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -740,6 +740,9 @@ static int si2168_probe(struct i2c_client *client,
740 case SI2168_CHIP_ID_B40: 740 case SI2168_CHIP_ID_B40:
741 dev->firmware_name = SI2168_B40_FIRMWARE; 741 dev->firmware_name = SI2168_B40_FIRMWARE;
742 break; 742 break;
743 case SI2168_CHIP_ID_D60:
744 dev->firmware_name = SI2168_D60_FIRMWARE;
745 break;
743 default: 746 default:
744 dev_dbg(&client->dev, "unknown chip version Si21%d-%c%c%c\n", 747 dev_dbg(&client->dev, "unknown chip version Si21%d-%c%c%c\n",
745 cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]); 748 cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
@@ -827,3 +830,4 @@ MODULE_LICENSE("GPL");
827MODULE_FIRMWARE(SI2168_A20_FIRMWARE); 830MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
828MODULE_FIRMWARE(SI2168_A30_FIRMWARE); 831MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
829MODULE_FIRMWARE(SI2168_B40_FIRMWARE); 832MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
833MODULE_FIRMWARE(SI2168_D60_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 2fecac6231ff..737cf416fbb2 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -26,6 +26,7 @@
26#define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw" 26#define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
27#define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw" 27#define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
28#define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw" 28#define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
29#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw"
29#define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw" 30#define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
30 31
31/* state struct */ 32/* state struct */
@@ -38,6 +39,7 @@ struct si2168_dev {
38 #define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0) 39 #define SI2168_CHIP_ID_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
39 #define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0) 40 #define SI2168_CHIP_ID_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
40 #define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0) 41 #define SI2168_CHIP_ID_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
42 #define SI2168_CHIP_ID_D60 ('D' << 24 | 68 << 16 | '6' << 8 | '0' << 0)
41 unsigned int chip_id; 43 unsigned int chip_id;
42 unsigned int version; 44 unsigned int version;
43 const char *firmware_name; 45 const char *firmware_name;
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cee1dae6e014..fd181c99ce11 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -209,7 +209,6 @@ config VIDEO_ADV7604
209 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API 209 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
210 depends on GPIOLIB || COMPILE_TEST 210 depends on GPIOLIB || COMPILE_TEST
211 select HDMI 211 select HDMI
212 select MEDIA_CEC_EDID
213 ---help--- 212 ---help---
214 Support for the Analog Devices ADV7604 video decoder. 213 Support for the Analog Devices ADV7604 video decoder.
215 214
@@ -221,7 +220,7 @@ config VIDEO_ADV7604
221 220
222config VIDEO_ADV7604_CEC 221config VIDEO_ADV7604_CEC
223 bool "Enable Analog Devices ADV7604 CEC support" 222 bool "Enable Analog Devices ADV7604 CEC support"
224 depends on VIDEO_ADV7604 && MEDIA_CEC_SUPPORT 223 depends on VIDEO_ADV7604 && CEC_CORE
225 ---help--- 224 ---help---
226 When selected the adv7604 will support the optional 225 When selected the adv7604 will support the optional
227 HDMI CEC feature. 226 HDMI CEC feature.
@@ -230,7 +229,6 @@ config VIDEO_ADV7842
230 tristate "Analog Devices ADV7842 decoder" 229 tristate "Analog Devices ADV7842 decoder"
231 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API 230 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
232 select HDMI 231 select HDMI
233 select MEDIA_CEC_EDID
234 ---help--- 232 ---help---
235 Support for the Analog Devices ADV7842 video decoder. 233 Support for the Analog Devices ADV7842 video decoder.
236 234
@@ -242,7 +240,7 @@ config VIDEO_ADV7842
242 240
243config VIDEO_ADV7842_CEC 241config VIDEO_ADV7842_CEC
244 bool "Enable Analog Devices ADV7842 CEC support" 242 bool "Enable Analog Devices ADV7842 CEC support"
245 depends on VIDEO_ADV7842 && MEDIA_CEC_SUPPORT 243 depends on VIDEO_ADV7842 && CEC_CORE
246 ---help--- 244 ---help---
247 When selected the adv7842 will support the optional 245 When selected the adv7842 will support the optional
248 HDMI CEC feature. 246 HDMI CEC feature.
@@ -470,7 +468,6 @@ config VIDEO_ADV7511
470 tristate "Analog Devices ADV7511 encoder" 468 tristate "Analog Devices ADV7511 encoder"
471 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API 469 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
472 select HDMI 470 select HDMI
473 select MEDIA_CEC_EDID
474 ---help--- 471 ---help---
475 Support for the Analog Devices ADV7511 video encoder. 472 Support for the Analog Devices ADV7511 video encoder.
476 473
@@ -481,7 +478,7 @@ config VIDEO_ADV7511
481 478
482config VIDEO_ADV7511_CEC 479config VIDEO_ADV7511_CEC
483 bool "Enable Analog Devices ADV7511 CEC support" 480 bool "Enable Analog Devices ADV7511 CEC support"
484 depends on VIDEO_ADV7511 && MEDIA_CEC_SUPPORT 481 depends on VIDEO_ADV7511 && CEC_CORE
485 ---help--- 482 ---help---
486 When selected the adv7511 will support the optional 483 When selected the adv7511 will support the optional
487 HDMI CEC feature. 484 HDMI CEC feature.
@@ -520,6 +517,17 @@ config VIDEO_APTINA_PLL
520config VIDEO_SMIAPP_PLL 517config VIDEO_SMIAPP_PLL
521 tristate 518 tristate
522 519
520config VIDEO_OV2640
521 tristate "OmniVision OV2640 sensor support"
522 depends on VIDEO_V4L2 && I2C
523 depends on MEDIA_CAMERA_SUPPORT
524 help
525 This is a Video4Linux2 sensor-level driver for the OmniVision
526 OV2640 camera.
527
528 To compile this driver as a module, choose M here: the
529 module will be called ov2640.
530
523config VIDEO_OV2659 531config VIDEO_OV2659
524 tristate "OmniVision OV2659 sensor support" 532 tristate "OmniVision OV2659 sensor support"
525 depends on VIDEO_V4L2 && I2C 533 depends on VIDEO_V4L2 && I2C
@@ -531,6 +539,29 @@ config VIDEO_OV2659
531 To compile this driver as a module, choose M here: the 539 To compile this driver as a module, choose M here: the
532 module will be called ov2659. 540 module will be called ov2659.
533 541
542config VIDEO_OV5645
543 tristate "OmniVision OV5645 sensor support"
544 depends on OF
545 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
546 depends on MEDIA_CAMERA_SUPPORT
547 ---help---
548 This is a Video4Linux2 sensor-level driver for the OmniVision
549 OV5645 camera.
550
551 To compile this driver as a module, choose M here: the
552 module will be called ov5645.
553
554config VIDEO_OV5647
555 tristate "OmniVision OV5647 sensor support"
556 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
557 depends on MEDIA_CAMERA_SUPPORT
558 ---help---
559 This is a Video4Linux2 sensor-level driver for the OmniVision
560 OV5647 camera.
561
562 To compile this driver as a module, choose M here: the
563 module will be called ov5647.
564
534config VIDEO_OV7640 565config VIDEO_OV7640
535 tristate "OmniVision OV7640 sensor support" 566 tristate "OmniVision OV7640 sensor support"
536 depends on I2C && VIDEO_V4L2 567 depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 5bc7bbeb5499..62323ec66be8 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -57,6 +57,9 @@ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
57obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o 57obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
58obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o 58obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
59obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o 59obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
60obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
61obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
62obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
60obj-$(CONFIG_VIDEO_OV7640) += ov7640.o 63obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
61obj-$(CONFIG_VIDEO_OV7670) += ov7670.o 64obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
62obj-$(CONFIG_VIDEO_OV9650) += ov9650.o 65obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
index a9026a91855e..3d2a3c6b67d8 100644
--- a/drivers/media/i2c/ad5820.c
+++ b/drivers/media/i2c/ad5820.c
@@ -336,7 +336,7 @@ cleanup:
336 return ret; 336 return ret;
337} 337}
338 338
339static int __exit ad5820_remove(struct i2c_client *client) 339static int ad5820_remove(struct i2c_client *client)
340{ 340{
341 struct v4l2_subdev *subdev = i2c_get_clientdata(client); 341 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
342 struct ad5820_device *coil = to_ad5820_device(subdev); 342 struct ad5820_device *coil = to_ad5820_device(subdev);
@@ -362,7 +362,7 @@ static struct i2c_driver ad5820_i2c_driver = {
362 .pm = &ad5820_pm, 362 .pm = &ad5820_pm,
363 }, 363 },
364 .probe = ad5820_probe, 364 .probe = ad5820_probe,
365 .remove = __exit_p(ad5820_remove), 365 .remove = ad5820_remove,
366 .id_table = ad5820_id_table, 366 .id_table = ad5820_id_table,
367}; 367};
368 368
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index 8c9e28949ab1..ccc478605643 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -734,7 +734,7 @@ static int adv7511_s_power(struct v4l2_subdev *sd, int on)
734#if IS_ENABLED(CONFIG_VIDEO_ADV7511_CEC) 734#if IS_ENABLED(CONFIG_VIDEO_ADV7511_CEC)
735static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) 735static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
736{ 736{
737 struct adv7511_state *state = adap->priv; 737 struct adv7511_state *state = cec_get_drvdata(adap);
738 struct v4l2_subdev *sd = &state->sd; 738 struct v4l2_subdev *sd = &state->sd;
739 739
740 if (state->i2c_cec == NULL) 740 if (state->i2c_cec == NULL)
@@ -769,7 +769,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
769 769
770static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) 770static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
771{ 771{
772 struct adv7511_state *state = adap->priv; 772 struct adv7511_state *state = cec_get_drvdata(adap);
773 struct v4l2_subdev *sd = &state->sd; 773 struct v4l2_subdev *sd = &state->sd;
774 unsigned int i, free_idx = ADV7511_MAX_ADDRS; 774 unsigned int i, free_idx = ADV7511_MAX_ADDRS;
775 775
@@ -824,7 +824,7 @@ static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
824static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 824static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
825 u32 signal_free_time, struct cec_msg *msg) 825 u32 signal_free_time, struct cec_msg *msg)
826{ 826{
827 struct adv7511_state *state = adap->priv; 827 struct adv7511_state *state = cec_get_drvdata(adap);
828 struct v4l2_subdev *sd = &state->sd; 828 struct v4l2_subdev *sd = &state->sd;
829 u8 len = msg->len; 829 u8 len = msg->len;
830 unsigned int i; 830 unsigned int i;
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index d8bf435db86d..f1fa9cec489f 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -2050,7 +2050,7 @@ static void adv76xx_cec_isr(struct v4l2_subdev *sd, bool *handled)
2050 2050
2051static int adv76xx_cec_adap_enable(struct cec_adapter *adap, bool enable) 2051static int adv76xx_cec_adap_enable(struct cec_adapter *adap, bool enable)
2052{ 2052{
2053 struct adv76xx_state *state = adap->priv; 2053 struct adv76xx_state *state = cec_get_drvdata(adap);
2054 struct v4l2_subdev *sd = &state->sd; 2054 struct v4l2_subdev *sd = &state->sd;
2055 2055
2056 if (!state->cec_enabled_adap && enable) { 2056 if (!state->cec_enabled_adap && enable) {
@@ -2080,7 +2080,7 @@ static int adv76xx_cec_adap_enable(struct cec_adapter *adap, bool enable)
2080 2080
2081static int adv76xx_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) 2081static int adv76xx_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
2082{ 2082{
2083 struct adv76xx_state *state = adap->priv; 2083 struct adv76xx_state *state = cec_get_drvdata(adap);
2084 struct v4l2_subdev *sd = &state->sd; 2084 struct v4l2_subdev *sd = &state->sd;
2085 unsigned int i, free_idx = ADV76XX_MAX_ADDRS; 2085 unsigned int i, free_idx = ADV76XX_MAX_ADDRS;
2086 2086
@@ -2135,7 +2135,7 @@ static int adv76xx_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
2135static int adv76xx_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 2135static int adv76xx_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
2136 u32 signal_free_time, struct cec_msg *msg) 2136 u32 signal_free_time, struct cec_msg *msg)
2137{ 2137{
2138 struct adv76xx_state *state = adap->priv; 2138 struct adv76xx_state *state = cec_get_drvdata(adap);
2139 struct v4l2_subdev *sd = &state->sd; 2139 struct v4l2_subdev *sd = &state->sd;
2140 u8 len = msg->len; 2140 u8 len = msg->len;
2141 unsigned int i; 2141 unsigned int i;
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 2d61f0cc2b5b..303effda1a2e 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -2250,7 +2250,7 @@ static void adv7842_cec_isr(struct v4l2_subdev *sd, bool *handled)
2250 2250
2251static int adv7842_cec_adap_enable(struct cec_adapter *adap, bool enable) 2251static int adv7842_cec_adap_enable(struct cec_adapter *adap, bool enable)
2252{ 2252{
2253 struct adv7842_state *state = adap->priv; 2253 struct adv7842_state *state = cec_get_drvdata(adap);
2254 struct v4l2_subdev *sd = &state->sd; 2254 struct v4l2_subdev *sd = &state->sd;
2255 2255
2256 if (!state->cec_enabled_adap && enable) { 2256 if (!state->cec_enabled_adap && enable) {
@@ -2279,7 +2279,7 @@ static int adv7842_cec_adap_enable(struct cec_adapter *adap, bool enable)
2279 2279
2280static int adv7842_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) 2280static int adv7842_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
2281{ 2281{
2282 struct adv7842_state *state = adap->priv; 2282 struct adv7842_state *state = cec_get_drvdata(adap);
2283 struct v4l2_subdev *sd = &state->sd; 2283 struct v4l2_subdev *sd = &state->sd;
2284 unsigned int i, free_idx = ADV7842_MAX_ADDRS; 2284 unsigned int i, free_idx = ADV7842_MAX_ADDRS;
2285 2285
@@ -2334,7 +2334,7 @@ static int adv7842_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
2334static int adv7842_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 2334static int adv7842_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
2335 u32 signal_free_time, struct cec_msg *msg) 2335 u32 signal_free_time, struct cec_msg *msg)
2336{ 2336{
2337 struct adv7842_state *state = adap->priv; 2337 struct adv7842_state *state = cec_get_drvdata(adap);
2338 struct v4l2_subdev *sd = &state->sd; 2338 struct v4l2_subdev *sd = &state->sd;
2339 u8 len = msg->len; 2339 u8 len = msg->len;
2340 unsigned int i; 2340 unsigned int i;
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index bec4a563a09c..6e313d5243a0 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1485,6 +1485,7 @@ static const struct of_device_id et8ek8_of_table[] = {
1485 { .compatible = "toshiba,et8ek8" }, 1485 { .compatible = "toshiba,et8ek8" },
1486 { }, 1486 { },
1487}; 1487};
1488MODULE_DEVICE_TABLE(of, et8ek8_of_table);
1488 1489
1489static const struct i2c_device_id et8ek8_id_table[] = { 1490static const struct i2c_device_id et8ek8_id_table[] = {
1490 { ET8EK8_NAME, 0 }, 1491 { ET8EK8_NAME, 0 },
@@ -1495,6 +1496,7 @@ MODULE_DEVICE_TABLE(i2c, et8ek8_id_table);
1495static const struct dev_pm_ops et8ek8_pm_ops = { 1496static const struct dev_pm_ops et8ek8_pm_ops = {
1496 SET_SYSTEM_SLEEP_PM_OPS(et8ek8_suspend, et8ek8_resume) 1497 SET_SYSTEM_SLEEP_PM_OPS(et8ek8_suspend, et8ek8_resume)
1497}; 1498};
1499MODULE_DEVICE_TABLE(of, et8ek8_of_table);
1498 1500
1499static struct i2c_driver et8ek8_i2c_driver = { 1501static struct i2c_driver et8ek8_i2c_driver = {
1500 .driver = { 1502 .driver = {
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/ov2640.c
index 56de18263359..e6d0c1f64f0b 100644
--- a/drivers/media/i2c/soc_camera/ov2640.c
+++ b/drivers/media/i2c/ov2640.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/clk.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
21#include <linux/gpio.h> 22#include <linux/gpio.h>
@@ -24,8 +25,7 @@
24#include <linux/v4l2-mediabus.h> 25#include <linux/v4l2-mediabus.h>
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26 27
27#include <media/soc_camera.h> 28#include <media/v4l2-device.h>
28#include <media/v4l2-clk.h>
29#include <media/v4l2-subdev.h> 29#include <media/v4l2-subdev.h>
30#include <media/v4l2-ctrls.h> 30#include <media/v4l2-ctrls.h>
31#include <media/v4l2-image-sizes.h> 31#include <media/v4l2-image-sizes.h>
@@ -106,6 +106,10 @@
106#define CTRL1_AWB_GAIN 0x04 106#define CTRL1_AWB_GAIN 0x04
107#define CTRL1_LENC 0x02 107#define CTRL1_LENC 0x02
108#define CTRL1_PRE 0x01 108#define CTRL1_PRE 0x01
109/* REG 0xC7 (unknown name): affects Auto White Balance (AWB)
110 * AWB_OFF 0x40
111 * AWB_SIMPLE 0x10
112 * AWB_ON 0x00 (Advanced AWB ?) */
109#define R_DVP_SP 0xD3 /* DVP output speed control */ 113#define R_DVP_SP 0xD3 /* DVP output speed control */
110#define R_DVP_SP_AUTO_MODE 0x80 114#define R_DVP_SP_AUTO_MODE 0x80
111#define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0); 115#define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0);
@@ -199,7 +203,7 @@
199#define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */ 203#define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */
200#define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */ 204#define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */
201#define COM8 0x13 /* Common control 8 */ 205#define COM8 0x13 /* Common control 8 */
202#define COM8_DEF 0xC0 /* Banding filter ON/OFF */ 206#define COM8_DEF 0xC0
203#define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */ 207#define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */
204#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ 208#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */
205#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ 209#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */
@@ -248,8 +252,19 @@
248#define ZOOMS 0x49 /* Zoom: Vertical start point */ 252#define ZOOMS 0x49 /* Zoom: Vertical start point */
249#define COM22 0x4B /* Flash light control */ 253#define COM22 0x4B /* Flash light control */
250#define COM25 0x4E /* For Banding operations */ 254#define COM25 0x4E /* For Banding operations */
255#define COM25_50HZ_BANDING_AEC_MSBS_MASK 0xC0 /* 50Hz Bd. AEC 2 MSBs */
256#define COM25_60HZ_BANDING_AEC_MSBS_MASK 0x30 /* 60Hz Bd. AEC 2 MSBs */
257#define COM25_50HZ_BANDING_AEC_MSBS_SET(x) VAL_SET(x, 0x3, 8, 6)
258#define COM25_60HZ_BANDING_AEC_MSBS_SET(x) VAL_SET(x, 0x3, 8, 4)
251#define BD50 0x4F /* 50Hz Banding AEC 8 LSBs */ 259#define BD50 0x4F /* 50Hz Banding AEC 8 LSBs */
260#define BD50_50HZ_BANDING_AEC_LSBS_SET(x) VAL_SET(x, 0xFF, 0, 0)
252#define BD60 0x50 /* 60Hz Banding AEC 8 LSBs */ 261#define BD60 0x50 /* 60Hz Banding AEC 8 LSBs */
262#define BD60_60HZ_BANDING_AEC_LSBS_SET(x) VAL_SET(x, 0xFF, 0, 0)
263#define REG5A 0x5A /* 50/60Hz Banding Maximum AEC Step */
264#define BD50_MAX_AEC_STEP_MASK 0xF0 /* 50Hz Banding Max. AEC Step */
265#define BD60_MAX_AEC_STEP_MASK 0x0F /* 60Hz Banding Max. AEC Step */
266#define BD50_MAX_AEC_STEP_SET(x) VAL_SET((x - 1), 0x0F, 0, 4)
267#define BD60_MAX_AEC_STEP_SET(x) VAL_SET((x - 1), 0x0F, 0, 0)
253#define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */ 268#define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */
254#define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */ 269#define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */
255#define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */ 270#define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */
@@ -282,12 +297,14 @@ struct ov2640_win_size {
282 297
283struct ov2640_priv { 298struct ov2640_priv {
284 struct v4l2_subdev subdev; 299 struct v4l2_subdev subdev;
300#if defined(CONFIG_MEDIA_CONTROLLER)
301 struct media_pad pad;
302#endif
285 struct v4l2_ctrl_handler hdl; 303 struct v4l2_ctrl_handler hdl;
286 u32 cfmt_code; 304 u32 cfmt_code;
287 struct v4l2_clk *clk; 305 struct clk *clk;
288 const struct ov2640_win_size *win; 306 const struct ov2640_win_size *win;
289 307
290 struct soc_camera_subdev_desc ssdd_dt;
291 struct gpio_desc *resetb_gpio; 308 struct gpio_desc *resetb_gpio;
292 struct gpio_desc *pwdn_gpio; 309 struct gpio_desc *pwdn_gpio;
293}; 310};
@@ -304,11 +321,11 @@ static const struct regval_list ov2640_init_regs[] = {
304 { 0x2e, 0xdf }, 321 { 0x2e, 0xdf },
305 { BANK_SEL, BANK_SEL_SENS }, 322 { BANK_SEL, BANK_SEL_SENS },
306 { 0x3c, 0x32 }, 323 { 0x3c, 0x32 },
307 { CLKRC, CLKRC_DIV_SET(1) }, 324 { CLKRC, CLKRC_DIV_SET(1) },
308 { COM2, COM2_OCAP_Nx_SET(3) }, 325 { COM2, COM2_OCAP_Nx_SET(3) },
309 { REG04, REG04_DEF | REG04_HREF_EN }, 326 { REG04, REG04_DEF | REG04_HREF_EN },
310 { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN }, 327 { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN },
311 { COM9, COM9_AGC_GAIN_8x | 0x08}, 328 { COM9, COM9_AGC_GAIN_8x | 0x08},
312 { 0x2c, 0x0c }, 329 { 0x2c, 0x0c },
313 { 0x33, 0x78 }, 330 { 0x33, 0x78 },
314 { 0x3a, 0x33 }, 331 { 0x3a, 0x33 },
@@ -353,25 +370,28 @@ static const struct regval_list ov2640_init_regs[] = {
353 { 0x71, 0x94 }, 370 { 0x71, 0x94 },
354 { 0x73, 0xc1 }, 371 { 0x73, 0xc1 },
355 { 0x3d, 0x34 }, 372 { 0x3d, 0x34 },
356 { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, 373 { COM7, COM7_RES_UXGA | COM7_ZOOM_EN },
357 { 0x5a, 0x57 }, 374 { REG5A, BD50_MAX_AEC_STEP_SET(6)
358 { BD50, 0xbb }, 375 | BD60_MAX_AEC_STEP_SET(8) }, /* 0x57 */
359 { BD60, 0x9c }, 376 { COM25, COM25_50HZ_BANDING_AEC_MSBS_SET(0x0bb)
360 { BANK_SEL, BANK_SEL_DSP }, 377 | COM25_60HZ_BANDING_AEC_MSBS_SET(0x09c) }, /* 0x00 */
378 { BD50, BD50_50HZ_BANDING_AEC_LSBS_SET(0x0bb) }, /* 0xbb */
379 { BD60, BD60_60HZ_BANDING_AEC_LSBS_SET(0x09c) }, /* 0x9c */
380 { BANK_SEL, BANK_SEL_DSP },
361 { 0xe5, 0x7f }, 381 { 0xe5, 0x7f },
362 { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, 382 { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL },
363 { 0x41, 0x24 }, 383 { 0x41, 0x24 },
364 { RESET, RESET_JPEG | RESET_DVP }, 384 { RESET, RESET_JPEG | RESET_DVP },
365 { 0x76, 0xff }, 385 { 0x76, 0xff },
366 { 0x33, 0xa0 }, 386 { 0x33, 0xa0 },
367 { 0x42, 0x20 }, 387 { 0x42, 0x20 },
368 { 0x43, 0x18 }, 388 { 0x43, 0x18 },
369 { 0x4c, 0x00 }, 389 { 0x4c, 0x00 },
370 { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 }, 390 { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 },
371 { 0x88, 0x3f }, 391 { 0x88, 0x3f },
372 { 0xd7, 0x03 }, 392 { 0xd7, 0x03 },
373 { 0xd9, 0x10 }, 393 { 0xd9, 0x10 },
374 { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 }, 394 { R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x2 },
375 { 0xc8, 0x08 }, 395 { 0xc8, 0x08 },
376 { 0xc9, 0x80 }, 396 { 0xc9, 0x80 },
377 { BPADDR, 0x00 }, 397 { BPADDR, 0x00 },
@@ -433,7 +453,7 @@ static const struct regval_list ov2640_init_regs[] = {
433 { 0xc5, 0x11 }, 453 { 0xc5, 0x11 },
434 { 0xc6, 0x51 }, 454 { 0xc6, 0x51 },
435 { 0xbf, 0x80 }, 455 { 0xbf, 0x80 },
436 { 0xc7, 0x10 }, 456 { 0xc7, 0x10 }, /* simple AWB */
437 { 0xb6, 0x66 }, 457 { 0xb6, 0x66 },
438 { 0xb8, 0xA5 }, 458 { 0xb8, 0xA5 },
439 { 0xb7, 0x64 }, 459 { 0xb7, 0x64 },
@@ -480,6 +500,9 @@ static const struct regval_list ov2640_init_regs[] = {
480static const struct regval_list ov2640_size_change_preamble_regs[] = { 500static const struct regval_list ov2640_size_change_preamble_regs[] = {
481 { BANK_SEL, BANK_SEL_DSP }, 501 { BANK_SEL, BANK_SEL_DSP },
482 { RESET, RESET_DVP }, 502 { RESET, RESET_DVP },
503 { SIZEL, SIZEL_HSIZE8_11_SET(UXGA_WIDTH) |
504 SIZEL_HSIZE8_SET(UXGA_WIDTH) |
505 SIZEL_VSIZE8_SET(UXGA_HEIGHT) },
483 { HSIZE8, HSIZE8_SET(UXGA_WIDTH) }, 506 { HSIZE8, HSIZE8_SET(UXGA_WIDTH) },
484 { VSIZE8, VSIZE8_SET(UXGA_HEIGHT) }, 507 { VSIZE8, VSIZE8_SET(UXGA_HEIGHT) },
485 { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | 508 { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN |
@@ -611,6 +634,8 @@ static const struct regval_list ov2640_rgb565_le_regs[] = {
611static u32 ov2640_codes[] = { 634static u32 ov2640_codes[] = {
612 MEDIA_BUS_FMT_YUYV8_2X8, 635 MEDIA_BUS_FMT_YUYV8_2X8,
613 MEDIA_BUS_FMT_UYVY8_2X8, 636 MEDIA_BUS_FMT_UYVY8_2X8,
637 MEDIA_BUS_FMT_YVYU8_2X8,
638 MEDIA_BUS_FMT_VYUY8_2X8,
614 MEDIA_BUS_FMT_RGB565_2X8_BE, 639 MEDIA_BUS_FMT_RGB565_2X8_BE,
615 MEDIA_BUS_FMT_RGB565_2X8_LE, 640 MEDIA_BUS_FMT_RGB565_2X8_LE,
616}; 641};
@@ -677,13 +702,8 @@ err:
677} 702}
678 703
679/* 704/*
680 * soc_camera_ops functions 705 * functions
681 */ 706 */
682static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
683{
684 return 0;
685}
686
687static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl) 707static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
688{ 708{
689 struct v4l2_subdev *sd = 709 struct v4l2_subdev *sd =
@@ -698,8 +718,10 @@ static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
698 718
699 switch (ctrl->id) { 719 switch (ctrl->id) {
700 case V4L2_CID_VFLIP: 720 case V4L2_CID_VFLIP:
701 val = ctrl->val ? REG04_VFLIP_IMG : 0x00; 721 val = ctrl->val ? REG04_VFLIP_IMG | REG04_VREF_EN : 0x00;
702 return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val); 722 return ov2640_mask_set(client, REG04,
723 REG04_VFLIP_IMG | REG04_VREF_EN, val);
724 /* NOTE: REG04_VREF_EN: 1 line shift / even/odd line swap */
703 case V4L2_CID_HFLIP: 725 case V4L2_CID_HFLIP:
704 val = ctrl->val ? REG04_HFLIP_IMG : 0x00; 726 val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
705 return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val); 727 return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
@@ -743,41 +765,46 @@ static int ov2640_s_register(struct v4l2_subdev *sd,
743 765
744static int ov2640_s_power(struct v4l2_subdev *sd, int on) 766static int ov2640_s_power(struct v4l2_subdev *sd, int on)
745{ 767{
768#ifdef CONFIG_GPIOLIB
746 struct i2c_client *client = v4l2_get_subdevdata(sd); 769 struct i2c_client *client = v4l2_get_subdevdata(sd);
747 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
748 struct ov2640_priv *priv = to_ov2640(client); 770 struct ov2640_priv *priv = to_ov2640(client);
749 771
750 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); 772 if (priv->pwdn_gpio)
773 gpiod_direction_output(priv->pwdn_gpio, !on);
774 if (on && priv->resetb_gpio) {
775 /* Active the resetb pin to perform a reset pulse */
776 gpiod_direction_output(priv->resetb_gpio, 1);
777 usleep_range(3000, 5000);
778 gpiod_set_value(priv->resetb_gpio, 0);
779 }
780#endif
781 return 0;
751} 782}
752 783
753/* Select the nearest higher resolution for capture */ 784/* Select the nearest higher resolution for capture */
754static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height) 785static const struct ov2640_win_size *ov2640_select_win(u32 width, u32 height)
755{ 786{
756 int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1; 787 int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1;
757 788
758 for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) { 789 for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) {
759 if (ov2640_supported_win_sizes[i].width >= *width && 790 if (ov2640_supported_win_sizes[i].width >= width &&
760 ov2640_supported_win_sizes[i].height >= *height) { 791 ov2640_supported_win_sizes[i].height >= height)
761 *width = ov2640_supported_win_sizes[i].width;
762 *height = ov2640_supported_win_sizes[i].height;
763 return &ov2640_supported_win_sizes[i]; 792 return &ov2640_supported_win_sizes[i];
764 }
765 } 793 }
766 794
767 *width = ov2640_supported_win_sizes[default_size].width;
768 *height = ov2640_supported_win_sizes[default_size].height;
769 return &ov2640_supported_win_sizes[default_size]; 795 return &ov2640_supported_win_sizes[default_size];
770} 796}
771 797
772static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height, 798static int ov2640_set_params(struct i2c_client *client,
773 u32 code) 799 const struct ov2640_win_size *win, u32 code)
774{ 800{
775 struct ov2640_priv *priv = to_ov2640(client); 801 struct ov2640_priv *priv = to_ov2640(client);
776 const struct regval_list *selected_cfmt_regs; 802 const struct regval_list *selected_cfmt_regs;
803 u8 val;
777 int ret; 804 int ret;
778 805
779 /* select win */ 806 /* select win */
780 priv->win = ov2640_select_win(width, height); 807 priv->win = win;
781 808
782 /* select format */ 809 /* select format */
783 priv->cfmt_code = 0; 810 priv->cfmt_code = 0;
@@ -794,10 +821,19 @@ static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
794 dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__); 821 dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__);
795 selected_cfmt_regs = ov2640_yuyv_regs; 822 selected_cfmt_regs = ov2640_yuyv_regs;
796 break; 823 break;
797 default:
798 case MEDIA_BUS_FMT_UYVY8_2X8: 824 case MEDIA_BUS_FMT_UYVY8_2X8:
825 default:
799 dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__); 826 dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__);
800 selected_cfmt_regs = ov2640_uyvy_regs; 827 selected_cfmt_regs = ov2640_uyvy_regs;
828 break;
829 case MEDIA_BUS_FMT_YVYU8_2X8:
830 dev_dbg(&client->dev, "%s: Selected cfmt YVYU", __func__);
831 selected_cfmt_regs = ov2640_yuyv_regs;
832 break;
833 case MEDIA_BUS_FMT_VYUY8_2X8:
834 dev_dbg(&client->dev, "%s: Selected cfmt VYUY", __func__);
835 selected_cfmt_regs = ov2640_uyvy_regs;
836 break;
801 } 837 }
802 838
803 /* reset hardware */ 839 /* reset hardware */
@@ -830,10 +866,13 @@ static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
830 ret = ov2640_write_array(client, selected_cfmt_regs); 866 ret = ov2640_write_array(client, selected_cfmt_regs);
831 if (ret < 0) 867 if (ret < 0)
832 goto err; 868 goto err;
869 val = (code == MEDIA_BUS_FMT_YVYU8_2X8)
870 || (code == MEDIA_BUS_FMT_VYUY8_2X8) ? CTRL0_VFIRST : 0x00;
871 ret = ov2640_mask_set(client, CTRL0, CTRL0_VFIRST, val);
872 if (ret < 0)
873 goto err;
833 874
834 priv->cfmt_code = code; 875 priv->cfmt_code = code;
835 *width = priv->win->width;
836 *height = priv->win->height;
837 876
838 return 0; 877 return 0;
839 878
@@ -857,25 +896,14 @@ static int ov2640_get_fmt(struct v4l2_subdev *sd,
857 return -EINVAL; 896 return -EINVAL;
858 897
859 if (!priv->win) { 898 if (!priv->win) {
860 u32 width = SVGA_WIDTH, height = SVGA_HEIGHT; 899 priv->win = ov2640_select_win(SVGA_WIDTH, SVGA_HEIGHT);
861 priv->win = ov2640_select_win(&width, &height);
862 priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8; 900 priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8;
863 } 901 }
864 902
865 mf->width = priv->win->width; 903 mf->width = priv->win->width;
866 mf->height = priv->win->height; 904 mf->height = priv->win->height;
867 mf->code = priv->cfmt_code; 905 mf->code = priv->cfmt_code;
868 906 mf->colorspace = V4L2_COLORSPACE_SRGB;
869 switch (mf->code) {
870 case MEDIA_BUS_FMT_RGB565_2X8_BE:
871 case MEDIA_BUS_FMT_RGB565_2X8_LE:
872 mf->colorspace = V4L2_COLORSPACE_SRGB;
873 break;
874 default:
875 case MEDIA_BUS_FMT_YUYV8_2X8:
876 case MEDIA_BUS_FMT_UYVY8_2X8:
877 mf->colorspace = V4L2_COLORSPACE_JPEG;
878 }
879 mf->field = V4L2_FIELD_NONE; 907 mf->field = V4L2_FIELD_NONE;
880 908
881 return 0; 909 return 0;
@@ -887,32 +915,34 @@ static int ov2640_set_fmt(struct v4l2_subdev *sd,
887{ 915{
888 struct v4l2_mbus_framefmt *mf = &format->format; 916 struct v4l2_mbus_framefmt *mf = &format->format;
889 struct i2c_client *client = v4l2_get_subdevdata(sd); 917 struct i2c_client *client = v4l2_get_subdevdata(sd);
918 const struct ov2640_win_size *win;
890 919
891 if (format->pad) 920 if (format->pad)
892 return -EINVAL; 921 return -EINVAL;
893 922
894 /* 923 /* select suitable win */
895 * select suitable win, but don't store it 924 win = ov2640_select_win(mf->width, mf->height);
896 */ 925 mf->width = win->width;
897 ov2640_select_win(&mf->width, &mf->height); 926 mf->height = win->height;
898 927
899 mf->field = V4L2_FIELD_NONE; 928 mf->field = V4L2_FIELD_NONE;
929 mf->colorspace = V4L2_COLORSPACE_SRGB;
900 930
901 switch (mf->code) { 931 switch (mf->code) {
902 case MEDIA_BUS_FMT_RGB565_2X8_BE: 932 case MEDIA_BUS_FMT_RGB565_2X8_BE:
903 case MEDIA_BUS_FMT_RGB565_2X8_LE: 933 case MEDIA_BUS_FMT_RGB565_2X8_LE:
904 mf->colorspace = V4L2_COLORSPACE_SRGB; 934 case MEDIA_BUS_FMT_YUYV8_2X8:
935 case MEDIA_BUS_FMT_UYVY8_2X8:
936 case MEDIA_BUS_FMT_YVYU8_2X8:
937 case MEDIA_BUS_FMT_VYUY8_2X8:
905 break; 938 break;
906 default: 939 default:
907 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; 940 mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
908 case MEDIA_BUS_FMT_YUYV8_2X8: 941 break;
909 case MEDIA_BUS_FMT_UYVY8_2X8:
910 mf->colorspace = V4L2_COLORSPACE_JPEG;
911 } 942 }
912 943
913 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 944 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
914 return ov2640_set_params(client, &mf->width, 945 return ov2640_set_params(client, win, mf->code);
915 &mf->height, mf->code);
916 cfg->try_fmt = *mf; 946 cfg->try_fmt = *mf;
917 return 0; 947 return 0;
918} 948}
@@ -995,7 +1025,7 @@ static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
995 .s_ctrl = ov2640_s_ctrl, 1025 .s_ctrl = ov2640_s_ctrl,
996}; 1026};
997 1027
998static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { 1028static const struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
999#ifdef CONFIG_VIDEO_ADV_DEBUG 1029#ifdef CONFIG_VIDEO_ADV_DEBUG
1000 .g_register = ov2640_g_register, 1030 .g_register = ov2640_g_register,
1001 .s_register = ov2640_s_register, 1031 .s_register = ov2640_s_register,
@@ -1003,26 +1033,6 @@ static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1003 .s_power = ov2640_s_power, 1033 .s_power = ov2640_s_power,
1004}; 1034};
1005 1035
1006static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
1007 struct v4l2_mbus_config *cfg)
1008{
1009 struct i2c_client *client = v4l2_get_subdevdata(sd);
1010 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1011
1012 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1013 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1014 V4L2_MBUS_DATA_ACTIVE_HIGH;
1015 cfg->type = V4L2_MBUS_PARALLEL;
1016 cfg->flags = soc_camera_apply_board_flags(ssdd, cfg);
1017
1018 return 0;
1019}
1020
1021static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1022 .s_stream = ov2640_s_stream,
1023 .g_mbus_config = ov2640_g_mbus_config,
1024};
1025
1026static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = { 1036static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = {
1027 .enum_mbus_code = ov2640_enum_mbus_code, 1037 .enum_mbus_code = ov2640_enum_mbus_code,
1028 .get_selection = ov2640_get_selection, 1038 .get_selection = ov2640_get_selection,
@@ -1030,65 +1040,43 @@ static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = {
1030 .set_fmt = ov2640_set_fmt, 1040 .set_fmt = ov2640_set_fmt,
1031}; 1041};
1032 1042
1033static struct v4l2_subdev_ops ov2640_subdev_ops = { 1043static const struct v4l2_subdev_ops ov2640_subdev_ops = {
1034 .core = &ov2640_subdev_core_ops, 1044 .core = &ov2640_subdev_core_ops,
1035 .video = &ov2640_subdev_video_ops,
1036 .pad = &ov2640_subdev_pad_ops, 1045 .pad = &ov2640_subdev_pad_ops,
1037}; 1046};
1038 1047
1039/* OF probe functions */
1040static int ov2640_hw_power(struct device *dev, int on)
1041{
1042 struct i2c_client *client = to_i2c_client(dev);
1043 struct ov2640_priv *priv = to_ov2640(client);
1044
1045 dev_dbg(&client->dev, "%s: %s the camera\n",
1046 __func__, on ? "ENABLE" : "DISABLE");
1047
1048 if (priv->pwdn_gpio)
1049 gpiod_direction_output(priv->pwdn_gpio, !on);
1050
1051 return 0;
1052}
1053
1054static int ov2640_hw_reset(struct device *dev)
1055{
1056 struct i2c_client *client = to_i2c_client(dev);
1057 struct ov2640_priv *priv = to_ov2640(client);
1058
1059 if (priv->resetb_gpio) {
1060 /* Active the resetb pin to perform a reset pulse */
1061 gpiod_direction_output(priv->resetb_gpio, 1);
1062 usleep_range(3000, 5000);
1063 gpiod_direction_output(priv->resetb_gpio, 0);
1064 }
1065
1066 return 0;
1067}
1068
1069static int ov2640_probe_dt(struct i2c_client *client, 1048static int ov2640_probe_dt(struct i2c_client *client,
1070 struct ov2640_priv *priv) 1049 struct ov2640_priv *priv)
1071{ 1050{
1051 int ret;
1052
1072 /* Request the reset GPIO deasserted */ 1053 /* Request the reset GPIO deasserted */
1073 priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", 1054 priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb",
1074 GPIOD_OUT_LOW); 1055 GPIOD_OUT_LOW);
1056
1075 if (!priv->resetb_gpio) 1057 if (!priv->resetb_gpio)
1076 dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); 1058 dev_dbg(&client->dev, "resetb gpio is not assigned!\n");
1077 else if (IS_ERR(priv->resetb_gpio)) 1059
1078 return PTR_ERR(priv->resetb_gpio); 1060 ret = PTR_ERR_OR_ZERO(priv->resetb_gpio);
1061 if (ret && ret != -ENOSYS) {
1062 dev_dbg(&client->dev,
1063 "Error %d while getting resetb gpio\n", ret);
1064 return ret;
1065 }
1079 1066
1080 /* Request the power down GPIO asserted */ 1067 /* Request the power down GPIO asserted */
1081 priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", 1068 priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn",
1082 GPIOD_OUT_HIGH); 1069 GPIOD_OUT_HIGH);
1070
1083 if (!priv->pwdn_gpio) 1071 if (!priv->pwdn_gpio)
1084 dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); 1072 dev_dbg(&client->dev, "pwdn gpio is not assigned!\n");
1085 else if (IS_ERR(priv->pwdn_gpio))
1086 return PTR_ERR(priv->pwdn_gpio);
1087 1073
1088 /* Initialize the soc_camera_subdev_desc */ 1074 ret = PTR_ERR_OR_ZERO(priv->pwdn_gpio);
1089 priv->ssdd_dt.power = ov2640_hw_power; 1075 if (ret && ret != -ENOSYS) {
1090 priv->ssdd_dt.reset = ov2640_hw_reset; 1076 dev_dbg(&client->dev,
1091 client->dev.platform_data = &priv->ssdd_dt; 1077 "Error %d while getting pwdn gpio\n", ret);
1078 return ret;
1079 }
1092 1080
1093 return 0; 1081 return 0;
1094} 1082}
@@ -1100,7 +1088,6 @@ static int ov2640_probe(struct i2c_client *client,
1100 const struct i2c_device_id *did) 1088 const struct i2c_device_id *did)
1101{ 1089{
1102 struct ov2640_priv *priv; 1090 struct ov2640_priv *priv;
1103 struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
1104 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1091 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1105 int ret; 1092 int ret;
1106 1093
@@ -1117,23 +1104,19 @@ static int ov2640_probe(struct i2c_client *client,
1117 return -ENOMEM; 1104 return -ENOMEM;
1118 } 1105 }
1119 1106
1120 priv->clk = v4l2_clk_get(&client->dev, "xvclk"); 1107 if (client->dev.of_node) {
1121 if (IS_ERR(priv->clk)) 1108 priv->clk = devm_clk_get(&client->dev, "xvclk");
1122 return -EPROBE_DEFER; 1109 if (IS_ERR(priv->clk))
1123 1110 return -EPROBE_DEFER;
1124 if (!ssdd && !client->dev.of_node) { 1111 clk_prepare_enable(priv->clk);
1125 dev_err(&client->dev, "Missing platform_data for driver\n");
1126 ret = -EINVAL;
1127 goto err_clk;
1128 } 1112 }
1129 1113
1130 if (!ssdd) { 1114 ret = ov2640_probe_dt(client, priv);
1131 ret = ov2640_probe_dt(client, priv); 1115 if (ret)
1132 if (ret) 1116 goto err_clk;
1133 goto err_clk;
1134 }
1135 1117
1136 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); 1118 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1119 priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1137 v4l2_ctrl_handler_init(&priv->hdl, 2); 1120 v4l2_ctrl_handler_init(&priv->hdl, 2);
1138 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, 1121 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1139 V4L2_CID_VFLIP, 0, 1, 1, 0); 1122 V4L2_CID_VFLIP, 0, 1, 1, 0);
@@ -1142,8 +1125,15 @@ static int ov2640_probe(struct i2c_client *client,
1142 priv->subdev.ctrl_handler = &priv->hdl; 1125 priv->subdev.ctrl_handler = &priv->hdl;
1143 if (priv->hdl.error) { 1126 if (priv->hdl.error) {
1144 ret = priv->hdl.error; 1127 ret = priv->hdl.error;
1145 goto err_clk; 1128 goto err_hdl;
1146 } 1129 }
1130#if defined(CONFIG_MEDIA_CONTROLLER)
1131 priv->pad.flags = MEDIA_PAD_FL_SOURCE;
1132 priv->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1133 ret = media_entity_pads_init(&priv->subdev.entity, 1, &priv->pad);
1134 if (ret < 0)
1135 goto err_hdl;
1136#endif
1147 1137
1148 ret = ov2640_video_probe(client); 1138 ret = ov2640_video_probe(client);
1149 if (ret < 0) 1139 if (ret < 0)
@@ -1158,9 +1148,13 @@ static int ov2640_probe(struct i2c_client *client,
1158 return 0; 1148 return 0;
1159 1149
1160err_videoprobe: 1150err_videoprobe:
1151#if defined(CONFIG_MEDIA_CONTROLLER)
1152 media_entity_cleanup(&priv->subdev.entity);
1153#endif
1154err_hdl:
1161 v4l2_ctrl_handler_free(&priv->hdl); 1155 v4l2_ctrl_handler_free(&priv->hdl);
1162err_clk: 1156err_clk:
1163 v4l2_clk_put(priv->clk); 1157 clk_disable_unprepare(priv->clk);
1164 return ret; 1158 return ret;
1165} 1159}
1166 1160
@@ -1169,9 +1163,12 @@ static int ov2640_remove(struct i2c_client *client)
1169 struct ov2640_priv *priv = to_ov2640(client); 1163 struct ov2640_priv *priv = to_ov2640(client);
1170 1164
1171 v4l2_async_unregister_subdev(&priv->subdev); 1165 v4l2_async_unregister_subdev(&priv->subdev);
1172 v4l2_clk_put(priv->clk);
1173 v4l2_device_unregister_subdev(&priv->subdev);
1174 v4l2_ctrl_handler_free(&priv->hdl); 1166 v4l2_ctrl_handler_free(&priv->hdl);
1167#if defined(CONFIG_MEDIA_CONTROLLER)
1168 media_entity_cleanup(&priv->subdev.entity);
1169#endif
1170 v4l2_device_unregister_subdev(&priv->subdev);
1171 clk_disable_unprepare(priv->clk);
1175 return 0; 1172 return 0;
1176} 1173}
1177 1174
@@ -1199,6 +1196,6 @@ static struct i2c_driver ov2640_i2c_driver = {
1199 1196
1200module_i2c_driver(ov2640_i2c_driver); 1197module_i2c_driver(ov2640_i2c_driver);
1201 1198
1202MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor"); 1199MODULE_DESCRIPTION("Driver for Omni Vision 2640 sensor");
1203MODULE_AUTHOR("Alberto Panizzo"); 1200MODULE_AUTHOR("Alberto Panizzo");
1204MODULE_LICENSE("GPL v2"); 1201MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
new file mode 100644
index 000000000000..57bd591ea54b
--- /dev/null
+++ b/drivers/media/i2c/ov5645.c
@@ -0,0 +1,1345 @@
1/*
2 * Driver for the OV5645 camera sensor.
3 *
4 * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
5 * Copyright (C) 2015 By Tech Design S.L. All Rights Reserved.
6 * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
7 *
8 * Based on:
9 * - the OV5645 driver from QC msm-3.10 kernel on codeaurora.org:
10 * https://us.codeaurora.org/cgit/quic/la/kernel/msm-3.10/tree/drivers/
11 * media/platform/msm/camera_v2/sensor/ov5645.c?h=LA.BR.1.2.4_rb1.41
12 * - the OV5640 driver posted on linux-media:
13 * https://www.mail-archive.com/linux-media%40vger.kernel.org/msg92671.html
14 */
15
16/*
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 */
27
28#include <linux/bitops.h>
29#include <linux/clk.h>
30#include <linux/delay.h>
31#include <linux/device.h>
32#include <linux/gpio/consumer.h>
33#include <linux/i2c.h>
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/of.h>
37#include <linux/of_graph.h>
38#include <linux/regulator/consumer.h>
39#include <linux/slab.h>
40#include <linux/types.h>
41#include <media/v4l2-ctrls.h>
42#include <media/v4l2-of.h>
43#include <media/v4l2-subdev.h>
44
45#define OV5645_VOLTAGE_ANALOG 2800000
46#define OV5645_VOLTAGE_DIGITAL_CORE 1500000
47#define OV5645_VOLTAGE_DIGITAL_IO 1800000
48
49#define OV5645_SYSTEM_CTRL0 0x3008
50#define OV5645_SYSTEM_CTRL0_START 0x02
51#define OV5645_SYSTEM_CTRL0_STOP 0x42
52#define OV5645_CHIP_ID_HIGH 0x300a
53#define OV5645_CHIP_ID_HIGH_BYTE 0x56
54#define OV5645_CHIP_ID_LOW 0x300b
55#define OV5645_CHIP_ID_LOW_BYTE 0x45
56#define OV5645_AWB_MANUAL_CONTROL 0x3406
57#define OV5645_AWB_MANUAL_ENABLE BIT(0)
58#define OV5645_AEC_PK_MANUAL 0x3503
59#define OV5645_AEC_MANUAL_ENABLE BIT(0)
60#define OV5645_AGC_MANUAL_ENABLE BIT(1)
61#define OV5645_TIMING_TC_REG20 0x3820
62#define OV5645_SENSOR_VFLIP BIT(1)
63#define OV5645_ISP_VFLIP BIT(2)
64#define OV5645_TIMING_TC_REG21 0x3821
65#define OV5645_SENSOR_MIRROR BIT(1)
66#define OV5645_PRE_ISP_TEST_SETTING_1 0x503d
67#define OV5645_TEST_PATTERN_MASK 0x3
68#define OV5645_SET_TEST_PATTERN(x) ((x) & OV5645_TEST_PATTERN_MASK)
69#define OV5645_TEST_PATTERN_ENABLE BIT(7)
70#define OV5645_SDE_SAT_U 0x5583
71#define OV5645_SDE_SAT_V 0x5584
72
73struct reg_value {
74 u16 reg;
75 u8 val;
76};
77
78struct ov5645_mode_info {
79 u32 width;
80 u32 height;
81 const struct reg_value *data;
82 u32 data_size;
83};
84
85struct ov5645 {
86 struct i2c_client *i2c_client;
87 struct device *dev;
88 struct v4l2_subdev sd;
89 struct media_pad pad;
90 struct v4l2_of_endpoint ep;
91 struct v4l2_mbus_framefmt fmt;
92 struct v4l2_rect crop;
93 struct clk *xclk;
94
95 struct regulator *io_regulator;
96 struct regulator *core_regulator;
97 struct regulator *analog_regulator;
98
99 const struct ov5645_mode_info *current_mode;
100
101 struct v4l2_ctrl_handler ctrls;
102
103 /* Cached register values */
104 u8 aec_pk_manual;
105 u8 timing_tc_reg20;
106 u8 timing_tc_reg21;
107
108 struct mutex power_lock; /* lock to protect power state */
109 int power_count;
110
111 struct gpio_desc *enable_gpio;
112 struct gpio_desc *rst_gpio;
113};
114
115static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd)
116{
117 return container_of(sd, struct ov5645, sd);
118}
119
120static const struct reg_value ov5645_global_init_setting[] = {
121 { 0x3103, 0x11 },
122 { 0x3008, 0x82 },
123 { 0x3008, 0x42 },
124 { 0x3103, 0x03 },
125 { 0x3503, 0x07 },
126 { 0x3002, 0x1c },
127 { 0x3006, 0xc3 },
128 { 0x300e, 0x45 },
129 { 0x3017, 0x00 },
130 { 0x3018, 0x00 },
131 { 0x302e, 0x0b },
132 { 0x3037, 0x13 },
133 { 0x3108, 0x01 },
134 { 0x3611, 0x06 },
135 { 0x3500, 0x00 },
136 { 0x3501, 0x01 },
137 { 0x3502, 0x00 },
138 { 0x350a, 0x00 },
139 { 0x350b, 0x3f },
140 { 0x3620, 0x33 },
141 { 0x3621, 0xe0 },
142 { 0x3622, 0x01 },
143 { 0x3630, 0x2e },
144 { 0x3631, 0x00 },
145 { 0x3632, 0x32 },
146 { 0x3633, 0x52 },
147 { 0x3634, 0x70 },
148 { 0x3635, 0x13 },
149 { 0x3636, 0x03 },
150 { 0x3703, 0x5a },
151 { 0x3704, 0xa0 },
152 { 0x3705, 0x1a },
153 { 0x3709, 0x12 },
154 { 0x370b, 0x61 },
155 { 0x370f, 0x10 },
156 { 0x3715, 0x78 },
157 { 0x3717, 0x01 },
158 { 0x371b, 0x20 },
159 { 0x3731, 0x12 },
160 { 0x3901, 0x0a },
161 { 0x3905, 0x02 },
162 { 0x3906, 0x10 },
163 { 0x3719, 0x86 },
164 { 0x3810, 0x00 },
165 { 0x3811, 0x10 },
166 { 0x3812, 0x00 },
167 { 0x3821, 0x01 },
168 { 0x3824, 0x01 },
169 { 0x3826, 0x03 },
170 { 0x3828, 0x08 },
171 { 0x3a19, 0xf8 },
172 { 0x3c01, 0x34 },
173 { 0x3c04, 0x28 },
174 { 0x3c05, 0x98 },
175 { 0x3c07, 0x07 },
176 { 0x3c09, 0xc2 },
177 { 0x3c0a, 0x9c },
178 { 0x3c0b, 0x40 },
179 { 0x3c01, 0x34 },
180 { 0x4001, 0x02 },
181 { 0x4514, 0x00 },
182 { 0x4520, 0xb0 },
183 { 0x460b, 0x37 },
184 { 0x460c, 0x20 },
185 { 0x4818, 0x01 },
186 { 0x481d, 0xf0 },
187 { 0x481f, 0x50 },
188 { 0x4823, 0x70 },
189 { 0x4831, 0x14 },
190 { 0x5000, 0xa7 },
191 { 0x5001, 0x83 },
192 { 0x501d, 0x00 },
193 { 0x501f, 0x00 },
194 { 0x503d, 0x00 },
195 { 0x505c, 0x30 },
196 { 0x5181, 0x59 },
197 { 0x5183, 0x00 },
198 { 0x5191, 0xf0 },
199 { 0x5192, 0x03 },
200 { 0x5684, 0x10 },
201 { 0x5685, 0xa0 },
202 { 0x5686, 0x0c },
203 { 0x5687, 0x78 },
204 { 0x5a00, 0x08 },
205 { 0x5a21, 0x00 },
206 { 0x5a24, 0x00 },
207 { 0x3008, 0x02 },
208 { 0x3503, 0x00 },
209 { 0x5180, 0xff },
210 { 0x5181, 0xf2 },
211 { 0x5182, 0x00 },
212 { 0x5183, 0x14 },
213 { 0x5184, 0x25 },
214 { 0x5185, 0x24 },
215 { 0x5186, 0x09 },
216 { 0x5187, 0x09 },
217 { 0x5188, 0x0a },
218 { 0x5189, 0x75 },
219 { 0x518a, 0x52 },
220 { 0x518b, 0xea },
221 { 0x518c, 0xa8 },
222 { 0x518d, 0x42 },
223 { 0x518e, 0x38 },
224 { 0x518f, 0x56 },
225 { 0x5190, 0x42 },
226 { 0x5191, 0xf8 },
227 { 0x5192, 0x04 },
228 { 0x5193, 0x70 },
229 { 0x5194, 0xf0 },
230 { 0x5195, 0xf0 },
231 { 0x5196, 0x03 },
232 { 0x5197, 0x01 },
233 { 0x5198, 0x04 },
234 { 0x5199, 0x12 },
235 { 0x519a, 0x04 },
236 { 0x519b, 0x00 },
237 { 0x519c, 0x06 },
238 { 0x519d, 0x82 },
239 { 0x519e, 0x38 },
240 { 0x5381, 0x1e },
241 { 0x5382, 0x5b },
242 { 0x5383, 0x08 },
243 { 0x5384, 0x0a },
244 { 0x5385, 0x7e },
245 { 0x5386, 0x88 },
246 { 0x5387, 0x7c },
247 { 0x5388, 0x6c },
248 { 0x5389, 0x10 },
249 { 0x538a, 0x01 },
250 { 0x538b, 0x98 },
251 { 0x5300, 0x08 },
252 { 0x5301, 0x30 },
253 { 0x5302, 0x10 },
254 { 0x5303, 0x00 },
255 { 0x5304, 0x08 },
256 { 0x5305, 0x30 },
257 { 0x5306, 0x08 },
258 { 0x5307, 0x16 },
259 { 0x5309, 0x08 },
260 { 0x530a, 0x30 },
261 { 0x530b, 0x04 },
262 { 0x530c, 0x06 },
263 { 0x5480, 0x01 },
264 { 0x5481, 0x08 },
265 { 0x5482, 0x14 },
266 { 0x5483, 0x28 },
267 { 0x5484, 0x51 },
268 { 0x5485, 0x65 },
269 { 0x5486, 0x71 },
270 { 0x5487, 0x7d },
271 { 0x5488, 0x87 },
272 { 0x5489, 0x91 },
273 { 0x548a, 0x9a },
274 { 0x548b, 0xaa },
275 { 0x548c, 0xb8 },
276 { 0x548d, 0xcd },
277 { 0x548e, 0xdd },
278 { 0x548f, 0xea },
279 { 0x5490, 0x1d },
280 { 0x5580, 0x02 },
281 { 0x5583, 0x40 },
282 { 0x5584, 0x10 },
283 { 0x5589, 0x10 },
284 { 0x558a, 0x00 },
285 { 0x558b, 0xf8 },
286 { 0x5800, 0x3f },
287 { 0x5801, 0x16 },
288 { 0x5802, 0x0e },
289 { 0x5803, 0x0d },
290 { 0x5804, 0x17 },
291 { 0x5805, 0x3f },
292 { 0x5806, 0x0b },
293 { 0x5807, 0x06 },
294 { 0x5808, 0x04 },
295 { 0x5809, 0x04 },
296 { 0x580a, 0x06 },
297 { 0x580b, 0x0b },
298 { 0x580c, 0x09 },
299 { 0x580d, 0x03 },
300 { 0x580e, 0x00 },
301 { 0x580f, 0x00 },
302 { 0x5810, 0x03 },
303 { 0x5811, 0x08 },
304 { 0x5812, 0x0a },
305 { 0x5813, 0x03 },
306 { 0x5814, 0x00 },
307 { 0x5815, 0x00 },
308 { 0x5816, 0x04 },
309 { 0x5817, 0x09 },
310 { 0x5818, 0x0f },
311 { 0x5819, 0x08 },
312 { 0x581a, 0x06 },
313 { 0x581b, 0x06 },
314 { 0x581c, 0x08 },
315 { 0x581d, 0x0c },
316 { 0x581e, 0x3f },
317 { 0x581f, 0x1e },
318 { 0x5820, 0x12 },
319 { 0x5821, 0x13 },
320 { 0x5822, 0x21 },
321 { 0x5823, 0x3f },
322 { 0x5824, 0x68 },
323 { 0x5825, 0x28 },
324 { 0x5826, 0x2c },
325 { 0x5827, 0x28 },
326 { 0x5828, 0x08 },
327 { 0x5829, 0x48 },
328 { 0x582a, 0x64 },
329 { 0x582b, 0x62 },
330 { 0x582c, 0x64 },
331 { 0x582d, 0x28 },
332 { 0x582e, 0x46 },
333 { 0x582f, 0x62 },
334 { 0x5830, 0x60 },
335 { 0x5831, 0x62 },
336 { 0x5832, 0x26 },
337 { 0x5833, 0x48 },
338 { 0x5834, 0x66 },
339 { 0x5835, 0x44 },
340 { 0x5836, 0x64 },
341 { 0x5837, 0x28 },
342 { 0x5838, 0x66 },
343 { 0x5839, 0x48 },
344 { 0x583a, 0x2c },
345 { 0x583b, 0x28 },
346 { 0x583c, 0x26 },
347 { 0x583d, 0xae },
348 { 0x5025, 0x00 },
349 { 0x3a0f, 0x30 },
350 { 0x3a10, 0x28 },
351 { 0x3a1b, 0x30 },
352 { 0x3a1e, 0x26 },
353 { 0x3a11, 0x60 },
354 { 0x3a1f, 0x14 },
355 { 0x0601, 0x02 },
356 { 0x3008, 0x42 },
357 { 0x3008, 0x02 }
358};
359
360static const struct reg_value ov5645_setting_sxga[] = {
361 { 0x3612, 0xa9 },
362 { 0x3614, 0x50 },
363 { 0x3618, 0x00 },
364 { 0x3034, 0x18 },
365 { 0x3035, 0x21 },
366 { 0x3036, 0x70 },
367 { 0x3600, 0x09 },
368 { 0x3601, 0x43 },
369 { 0x3708, 0x66 },
370 { 0x370c, 0xc3 },
371 { 0x3800, 0x00 },
372 { 0x3801, 0x00 },
373 { 0x3802, 0x00 },
374 { 0x3803, 0x06 },
375 { 0x3804, 0x0a },
376 { 0x3805, 0x3f },
377 { 0x3806, 0x07 },
378 { 0x3807, 0x9d },
379 { 0x3808, 0x05 },
380 { 0x3809, 0x00 },
381 { 0x380a, 0x03 },
382 { 0x380b, 0xc0 },
383 { 0x380c, 0x07 },
384 { 0x380d, 0x68 },
385 { 0x380e, 0x03 },
386 { 0x380f, 0xd8 },
387 { 0x3813, 0x06 },
388 { 0x3814, 0x31 },
389 { 0x3815, 0x31 },
390 { 0x3820, 0x47 },
391 { 0x3a02, 0x03 },
392 { 0x3a03, 0xd8 },
393 { 0x3a08, 0x01 },
394 { 0x3a09, 0xf8 },
395 { 0x3a0a, 0x01 },
396 { 0x3a0b, 0xa4 },
397 { 0x3a0e, 0x02 },
398 { 0x3a0d, 0x02 },
399 { 0x3a14, 0x03 },
400 { 0x3a15, 0xd8 },
401 { 0x3a18, 0x00 },
402 { 0x4004, 0x02 },
403 { 0x4005, 0x18 },
404 { 0x4300, 0x32 },
405 { 0x4202, 0x00 }
406};
407
408static const struct reg_value ov5645_setting_1080p[] = {
409 { 0x3612, 0xab },
410 { 0x3614, 0x50 },
411 { 0x3618, 0x04 },
412 { 0x3034, 0x18 },
413 { 0x3035, 0x11 },
414 { 0x3036, 0x54 },
415 { 0x3600, 0x08 },
416 { 0x3601, 0x33 },
417 { 0x3708, 0x63 },
418 { 0x370c, 0xc0 },
419 { 0x3800, 0x01 },
420 { 0x3801, 0x50 },
421 { 0x3802, 0x01 },
422 { 0x3803, 0xb2 },
423 { 0x3804, 0x08 },
424 { 0x3805, 0xef },
425 { 0x3806, 0x05 },
426 { 0x3807, 0xf1 },
427 { 0x3808, 0x07 },
428 { 0x3809, 0x80 },
429 { 0x380a, 0x04 },
430 { 0x380b, 0x38 },
431 { 0x380c, 0x09 },
432 { 0x380d, 0xc4 },
433 { 0x380e, 0x04 },
434 { 0x380f, 0x60 },
435 { 0x3813, 0x04 },
436 { 0x3814, 0x11 },
437 { 0x3815, 0x11 },
438 { 0x3820, 0x47 },
439 { 0x4514, 0x88 },
440 { 0x3a02, 0x04 },
441 { 0x3a03, 0x60 },
442 { 0x3a08, 0x01 },
443 { 0x3a09, 0x50 },
444 { 0x3a0a, 0x01 },
445 { 0x3a0b, 0x18 },
446 { 0x3a0e, 0x03 },
447 { 0x3a0d, 0x04 },
448 { 0x3a14, 0x04 },
449 { 0x3a15, 0x60 },
450 { 0x3a18, 0x00 },
451 { 0x4004, 0x06 },
452 { 0x4005, 0x18 },
453 { 0x4300, 0x32 },
454 { 0x4202, 0x00 },
455 { 0x4837, 0x0b }
456};
457
458static const struct reg_value ov5645_setting_full[] = {
459 { 0x3612, 0xab },
460 { 0x3614, 0x50 },
461 { 0x3618, 0x04 },
462 { 0x3034, 0x18 },
463 { 0x3035, 0x11 },
464 { 0x3036, 0x54 },
465 { 0x3600, 0x08 },
466 { 0x3601, 0x33 },
467 { 0x3708, 0x63 },
468 { 0x370c, 0xc0 },
469 { 0x3800, 0x00 },
470 { 0x3801, 0x00 },
471 { 0x3802, 0x00 },
472 { 0x3803, 0x00 },
473 { 0x3804, 0x0a },
474 { 0x3805, 0x3f },
475 { 0x3806, 0x07 },
476 { 0x3807, 0x9f },
477 { 0x3808, 0x0a },
478 { 0x3809, 0x20 },
479 { 0x380a, 0x07 },
480 { 0x380b, 0x98 },
481 { 0x380c, 0x0b },
482 { 0x380d, 0x1c },
483 { 0x380e, 0x07 },
484 { 0x380f, 0xb0 },
485 { 0x3813, 0x06 },
486 { 0x3814, 0x11 },
487 { 0x3815, 0x11 },
488 { 0x3820, 0x47 },
489 { 0x4514, 0x88 },
490 { 0x3a02, 0x07 },
491 { 0x3a03, 0xb0 },
492 { 0x3a08, 0x01 },
493 { 0x3a09, 0x27 },
494 { 0x3a0a, 0x00 },
495 { 0x3a0b, 0xf6 },
496 { 0x3a0e, 0x06 },
497 { 0x3a0d, 0x08 },
498 { 0x3a14, 0x07 },
499 { 0x3a15, 0xb0 },
500 { 0x3a18, 0x01 },
501 { 0x4004, 0x06 },
502 { 0x4005, 0x18 },
503 { 0x4300, 0x32 },
504 { 0x4837, 0x0b },
505 { 0x4202, 0x00 }
506};
507
508static const struct ov5645_mode_info ov5645_mode_info_data[] = {
509 {
510 .width = 1280,
511 .height = 960,
512 .data = ov5645_setting_sxga,
513 .data_size = ARRAY_SIZE(ov5645_setting_sxga)
514 },
515 {
516 .width = 1920,
517 .height = 1080,
518 .data = ov5645_setting_1080p,
519 .data_size = ARRAY_SIZE(ov5645_setting_1080p)
520 },
521 {
522 .width = 2592,
523 .height = 1944,
524 .data = ov5645_setting_full,
525 .data_size = ARRAY_SIZE(ov5645_setting_full)
526 },
527};
528
529static int ov5645_regulators_enable(struct ov5645 *ov5645)
530{
531 int ret;
532
533 ret = regulator_enable(ov5645->io_regulator);
534 if (ret < 0) {
535 dev_err(ov5645->dev, "set io voltage failed\n");
536 return ret;
537 }
538
539 ret = regulator_enable(ov5645->analog_regulator);
540 if (ret) {
541 dev_err(ov5645->dev, "set analog voltage failed\n");
542 goto err_disable_io;
543 }
544
545 ret = regulator_enable(ov5645->core_regulator);
546 if (ret) {
547 dev_err(ov5645->dev, "set core voltage failed\n");
548 goto err_disable_analog;
549 }
550
551 return 0;
552
553err_disable_analog:
554 regulator_disable(ov5645->analog_regulator);
555err_disable_io:
556 regulator_disable(ov5645->io_regulator);
557
558 return ret;
559}
560
561static void ov5645_regulators_disable(struct ov5645 *ov5645)
562{
563 int ret;
564
565 ret = regulator_disable(ov5645->core_regulator);
566 if (ret < 0)
567 dev_err(ov5645->dev, "core regulator disable failed\n");
568
569 ret = regulator_disable(ov5645->analog_regulator);
570 if (ret < 0)
571 dev_err(ov5645->dev, "analog regulator disable failed\n");
572
573 ret = regulator_disable(ov5645->io_regulator);
574 if (ret < 0)
575 dev_err(ov5645->dev, "io regulator disable failed\n");
576}
577
578static int ov5645_write_reg(struct ov5645 *ov5645, u16 reg, u8 val)
579{
580 u8 regbuf[3];
581 int ret;
582
583 regbuf[0] = reg >> 8;
584 regbuf[1] = reg & 0xff;
585 regbuf[2] = val;
586
587 ret = i2c_master_send(ov5645->i2c_client, regbuf, 3);
588 if (ret < 0)
589 dev_err(ov5645->dev, "%s: write reg error %d: reg=%x, val=%x\n",
590 __func__, ret, reg, val);
591
592 return ret;
593}
594
595static int ov5645_read_reg(struct ov5645 *ov5645, u16 reg, u8 *val)
596{
597 u8 regbuf[2];
598 int ret;
599
600 regbuf[0] = reg >> 8;
601 regbuf[1] = reg & 0xff;
602
603 ret = i2c_master_send(ov5645->i2c_client, regbuf, 2);
604 if (ret < 0) {
605 dev_err(ov5645->dev, "%s: write reg error %d: reg=%x\n",
606 __func__, ret, reg);
607 return ret;
608 }
609
610 ret = i2c_master_recv(ov5645->i2c_client, val, 1);
611 if (ret < 0) {
612 dev_err(ov5645->dev, "%s: read reg error %d: reg=%x\n",
613 __func__, ret, reg);
614 return ret;
615 }
616
617 return 0;
618}
619
620static int ov5645_set_aec_mode(struct ov5645 *ov5645, u32 mode)
621{
622 u8 val = ov5645->aec_pk_manual;
623 int ret;
624
625 if (mode == V4L2_EXPOSURE_AUTO)
626 val &= ~OV5645_AEC_MANUAL_ENABLE;
627 else /* V4L2_EXPOSURE_MANUAL */
628 val |= OV5645_AEC_MANUAL_ENABLE;
629
630 ret = ov5645_write_reg(ov5645, OV5645_AEC_PK_MANUAL, val);
631 if (!ret)
632 ov5645->aec_pk_manual = val;
633
634 return ret;
635}
636
637static int ov5645_set_agc_mode(struct ov5645 *ov5645, u32 enable)
638{
639 u8 val = ov5645->aec_pk_manual;
640 int ret;
641
642 if (enable)
643 val &= ~OV5645_AGC_MANUAL_ENABLE;
644 else
645 val |= OV5645_AGC_MANUAL_ENABLE;
646
647 ret = ov5645_write_reg(ov5645, OV5645_AEC_PK_MANUAL, val);
648 if (!ret)
649 ov5645->aec_pk_manual = val;
650
651 return ret;
652}
653
654static int ov5645_set_register_array(struct ov5645 *ov5645,
655 const struct reg_value *settings,
656 unsigned int num_settings)
657{
658 unsigned int i;
659 int ret;
660
661 for (i = 0; i < num_settings; ++i, ++settings) {
662 ret = ov5645_write_reg(ov5645, settings->reg, settings->val);
663 if (ret < 0)
664 return ret;
665 }
666
667 return 0;
668}
669
670static int ov5645_set_power_on(struct ov5645 *ov5645)
671{
672 int ret;
673
674 ret = ov5645_regulators_enable(ov5645);
675 if (ret < 0) {
676 return ret;
677 }
678
679 ret = clk_prepare_enable(ov5645->xclk);
680 if (ret < 0) {
681 dev_err(ov5645->dev, "clk prepare enable failed\n");
682 ov5645_regulators_disable(ov5645);
683 return ret;
684 }
685
686 usleep_range(5000, 15000);
687 gpiod_set_value_cansleep(ov5645->enable_gpio, 1);
688
689 usleep_range(1000, 2000);
690 gpiod_set_value_cansleep(ov5645->rst_gpio, 0);
691
692 msleep(20);
693
694 return 0;
695}
696
697static void ov5645_set_power_off(struct ov5645 *ov5645)
698{
699 gpiod_set_value_cansleep(ov5645->rst_gpio, 1);
700 gpiod_set_value_cansleep(ov5645->enable_gpio, 0);
701 clk_disable_unprepare(ov5645->xclk);
702 ov5645_regulators_disable(ov5645);
703}
704
705static int ov5645_s_power(struct v4l2_subdev *sd, int on)
706{
707 struct ov5645 *ov5645 = to_ov5645(sd);
708 int ret = 0;
709
710 mutex_lock(&ov5645->power_lock);
711
712 /* If the power count is modified from 0 to != 0 or from != 0 to 0,
713 * update the power state.
714 */
715 if (ov5645->power_count == !on) {
716 if (on) {
717 ret = ov5645_set_power_on(ov5645);
718 if (ret < 0)
719 goto exit;
720
721 ret = ov5645_set_register_array(ov5645,
722 ov5645_global_init_setting,
723 ARRAY_SIZE(ov5645_global_init_setting));
724 if (ret < 0) {
725 dev_err(ov5645->dev,
726 "could not set init registers\n");
727 ov5645_set_power_off(ov5645);
728 goto exit;
729 }
730
731 ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
732 OV5645_SYSTEM_CTRL0_STOP);
733 if (ret < 0) {
734 ov5645_set_power_off(ov5645);
735 goto exit;
736 }
737 } else {
738 ov5645_set_power_off(ov5645);
739 }
740 }
741
742 /* Update the power count. */
743 ov5645->power_count += on ? 1 : -1;
744 WARN_ON(ov5645->power_count < 0);
745
746exit:
747 mutex_unlock(&ov5645->power_lock);
748
749 return ret;
750}
751
752static int ov5645_set_saturation(struct ov5645 *ov5645, s32 value)
753{
754 u32 reg_value = (value * 0x10) + 0x40;
755 int ret;
756
757 ret = ov5645_write_reg(ov5645, OV5645_SDE_SAT_U, reg_value);
758 if (ret < 0)
759 return ret;
760
761 return ov5645_write_reg(ov5645, OV5645_SDE_SAT_V, reg_value);
762}
763
764static int ov5645_set_hflip(struct ov5645 *ov5645, s32 value)
765{
766 u8 val = ov5645->timing_tc_reg21;
767 int ret;
768
769 if (value == 0)
770 val &= ~(OV5645_SENSOR_MIRROR);
771 else
772 val |= (OV5645_SENSOR_MIRROR);
773
774 ret = ov5645_write_reg(ov5645, OV5645_TIMING_TC_REG21, val);
775 if (!ret)
776 ov5645->timing_tc_reg21 = val;
777
778 return ret;
779}
780
781static int ov5645_set_vflip(struct ov5645 *ov5645, s32 value)
782{
783 u8 val = ov5645->timing_tc_reg20;
784 int ret;
785
786 if (value == 0)
787 val |= (OV5645_SENSOR_VFLIP | OV5645_ISP_VFLIP);
788 else
789 val &= ~(OV5645_SENSOR_VFLIP | OV5645_ISP_VFLIP);
790
791 ret = ov5645_write_reg(ov5645, OV5645_TIMING_TC_REG20, val);
792 if (!ret)
793 ov5645->timing_tc_reg20 = val;
794
795 return ret;
796}
797
798static int ov5645_set_test_pattern(struct ov5645 *ov5645, s32 value)
799{
800 u8 val = 0;
801
802 if (value) {
803 val = OV5645_SET_TEST_PATTERN(value - 1);
804 val |= OV5645_TEST_PATTERN_ENABLE;
805 }
806
807 return ov5645_write_reg(ov5645, OV5645_PRE_ISP_TEST_SETTING_1, val);
808}
809
810static const char * const ov5645_test_pattern_menu[] = {
811 "Disabled",
812 "Vertical Color Bars",
813 "Pseudo-Random Data",
814 "Color Square",
815 "Black Image",
816};
817
818static int ov5645_set_awb(struct ov5645 *ov5645, s32 enable_auto)
819{
820 u8 val = 0;
821
822 if (!enable_auto)
823 val = OV5645_AWB_MANUAL_ENABLE;
824
825 return ov5645_write_reg(ov5645, OV5645_AWB_MANUAL_CONTROL, val);
826}
827
828static int ov5645_s_ctrl(struct v4l2_ctrl *ctrl)
829{
830 struct ov5645 *ov5645 = container_of(ctrl->handler,
831 struct ov5645, ctrls);
832 int ret;
833
834 mutex_lock(&ov5645->power_lock);
835 if (!ov5645->power_count) {
836 mutex_unlock(&ov5645->power_lock);
837 return 0;
838 }
839
840 switch (ctrl->id) {
841 case V4L2_CID_SATURATION:
842 ret = ov5645_set_saturation(ov5645, ctrl->val);
843 break;
844 case V4L2_CID_AUTO_WHITE_BALANCE:
845 ret = ov5645_set_awb(ov5645, ctrl->val);
846 break;
847 case V4L2_CID_AUTOGAIN:
848 ret = ov5645_set_agc_mode(ov5645, ctrl->val);
849 break;
850 case V4L2_CID_EXPOSURE_AUTO:
851 ret = ov5645_set_aec_mode(ov5645, ctrl->val);
852 break;
853 case V4L2_CID_TEST_PATTERN:
854 ret = ov5645_set_test_pattern(ov5645, ctrl->val);
855 break;
856 case V4L2_CID_HFLIP:
857 ret = ov5645_set_hflip(ov5645, ctrl->val);
858 break;
859 case V4L2_CID_VFLIP:
860 ret = ov5645_set_vflip(ov5645, ctrl->val);
861 break;
862 default:
863 ret = -EINVAL;
864 break;
865 }
866
867 mutex_unlock(&ov5645->power_lock);
868
869 return ret;
870}
871
872static struct v4l2_ctrl_ops ov5645_ctrl_ops = {
873 .s_ctrl = ov5645_s_ctrl,
874};
875
876static int ov5645_enum_mbus_code(struct v4l2_subdev *sd,
877 struct v4l2_subdev_pad_config *cfg,
878 struct v4l2_subdev_mbus_code_enum *code)
879{
880 if (code->index > 0)
881 return -EINVAL;
882
883 code->code = MEDIA_BUS_FMT_UYVY8_2X8;
884
885 return 0;
886}
887
888static int ov5645_enum_frame_size(struct v4l2_subdev *subdev,
889 struct v4l2_subdev_pad_config *cfg,
890 struct v4l2_subdev_frame_size_enum *fse)
891{
892 if (fse->code != MEDIA_BUS_FMT_UYVY8_2X8)
893 return -EINVAL;
894
895 if (fse->index >= ARRAY_SIZE(ov5645_mode_info_data))
896 return -EINVAL;
897
898 fse->min_width = ov5645_mode_info_data[fse->index].width;
899 fse->max_width = ov5645_mode_info_data[fse->index].width;
900 fse->min_height = ov5645_mode_info_data[fse->index].height;
901 fse->max_height = ov5645_mode_info_data[fse->index].height;
902
903 return 0;
904}
905
906static struct v4l2_mbus_framefmt *
907__ov5645_get_pad_format(struct ov5645 *ov5645,
908 struct v4l2_subdev_pad_config *cfg,
909 unsigned int pad,
910 enum v4l2_subdev_format_whence which)
911{
912 switch (which) {
913 case V4L2_SUBDEV_FORMAT_TRY:
914 return v4l2_subdev_get_try_format(&ov5645->sd, cfg, pad);
915 case V4L2_SUBDEV_FORMAT_ACTIVE:
916 return &ov5645->fmt;
917 default:
918 return NULL;
919 }
920}
921
922static int ov5645_get_format(struct v4l2_subdev *sd,
923 struct v4l2_subdev_pad_config *cfg,
924 struct v4l2_subdev_format *format)
925{
926 struct ov5645 *ov5645 = to_ov5645(sd);
927
928 format->format = *__ov5645_get_pad_format(ov5645, cfg, format->pad,
929 format->which);
930 return 0;
931}
932
933static struct v4l2_rect *
934__ov5645_get_pad_crop(struct ov5645 *ov5645, struct v4l2_subdev_pad_config *cfg,
935 unsigned int pad, enum v4l2_subdev_format_whence which)
936{
937 switch (which) {
938 case V4L2_SUBDEV_FORMAT_TRY:
939 return v4l2_subdev_get_try_crop(&ov5645->sd, cfg, pad);
940 case V4L2_SUBDEV_FORMAT_ACTIVE:
941 return &ov5645->crop;
942 default:
943 return NULL;
944 }
945}
946
947static const struct ov5645_mode_info *
948ov5645_find_nearest_mode(unsigned int width, unsigned int height)
949{
950 int i;
951
952 for (i = ARRAY_SIZE(ov5645_mode_info_data) - 1; i >= 0; i--) {
953 if (ov5645_mode_info_data[i].width <= width &&
954 ov5645_mode_info_data[i].height <= height)
955 break;
956 }
957
958 if (i < 0)
959 i = 0;
960
961 return &ov5645_mode_info_data[i];
962}
963
964static int ov5645_set_format(struct v4l2_subdev *sd,
965 struct v4l2_subdev_pad_config *cfg,
966 struct v4l2_subdev_format *format)
967{
968 struct ov5645 *ov5645 = to_ov5645(sd);
969 struct v4l2_mbus_framefmt *__format;
970 struct v4l2_rect *__crop;
971 const struct ov5645_mode_info *new_mode;
972
973 __crop = __ov5645_get_pad_crop(ov5645, cfg, format->pad,
974 format->which);
975
976 new_mode = ov5645_find_nearest_mode(format->format.width,
977 format->format.height);
978 __crop->width = new_mode->width;
979 __crop->height = new_mode->height;
980
981 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
982 ov5645->current_mode = new_mode;
983
984 __format = __ov5645_get_pad_format(ov5645, cfg, format->pad,
985 format->which);
986 __format->width = __crop->width;
987 __format->height = __crop->height;
988 __format->code = MEDIA_BUS_FMT_UYVY8_2X8;
989 __format->field = V4L2_FIELD_NONE;
990 __format->colorspace = V4L2_COLORSPACE_SRGB;
991
992 format->format = *__format;
993
994 return 0;
995}
996
997static int ov5645_entity_init_cfg(struct v4l2_subdev *subdev,
998 struct v4l2_subdev_pad_config *cfg)
999{
1000 struct v4l2_subdev_format fmt = { 0 };
1001
1002 fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1003 fmt.format.width = 1920;
1004 fmt.format.height = 1080;
1005
1006 ov5645_set_format(subdev, cfg, &fmt);
1007
1008 return 0;
1009}
1010
1011static int ov5645_get_selection(struct v4l2_subdev *sd,
1012 struct v4l2_subdev_pad_config *cfg,
1013 struct v4l2_subdev_selection *sel)
1014{
1015 struct ov5645 *ov5645 = to_ov5645(sd);
1016
1017 if (sel->target != V4L2_SEL_TGT_CROP)
1018 return -EINVAL;
1019
1020 sel->r = *__ov5645_get_pad_crop(ov5645, cfg, sel->pad,
1021 sel->which);
1022 return 0;
1023}
1024
1025static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable)
1026{
1027 struct ov5645 *ov5645 = to_ov5645(subdev);
1028 int ret;
1029
1030 if (enable) {
1031 ret = ov5645_set_register_array(ov5645,
1032 ov5645->current_mode->data,
1033 ov5645->current_mode->data_size);
1034 if (ret < 0) {
1035 dev_err(ov5645->dev, "could not set mode %dx%d\n",
1036 ov5645->current_mode->width,
1037 ov5645->current_mode->height);
1038 return ret;
1039 }
1040 ret = v4l2_ctrl_handler_setup(&ov5645->ctrls);
1041 if (ret < 0) {
1042 dev_err(ov5645->dev, "could not sync v4l2 controls\n");
1043 return ret;
1044 }
1045 ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
1046 OV5645_SYSTEM_CTRL0_START);
1047 if (ret < 0)
1048 return ret;
1049 } else {
1050 ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
1051 OV5645_SYSTEM_CTRL0_STOP);
1052 if (ret < 0)
1053 return ret;
1054 }
1055
1056 return 0;
1057}
1058
1059static const struct v4l2_subdev_core_ops ov5645_core_ops = {
1060 .s_power = ov5645_s_power,
1061};
1062
1063static const struct v4l2_subdev_video_ops ov5645_video_ops = {
1064 .s_stream = ov5645_s_stream,
1065};
1066
1067static const struct v4l2_subdev_pad_ops ov5645_subdev_pad_ops = {
1068 .init_cfg = ov5645_entity_init_cfg,
1069 .enum_mbus_code = ov5645_enum_mbus_code,
1070 .enum_frame_size = ov5645_enum_frame_size,
1071 .get_fmt = ov5645_get_format,
1072 .set_fmt = ov5645_set_format,
1073 .get_selection = ov5645_get_selection,
1074};
1075
1076static const struct v4l2_subdev_ops ov5645_subdev_ops = {
1077 .core = &ov5645_core_ops,
1078 .video = &ov5645_video_ops,
1079 .pad = &ov5645_subdev_pad_ops,
1080};
1081
1082static int ov5645_probe(struct i2c_client *client,
1083 const struct i2c_device_id *id)
1084{
1085 struct device *dev = &client->dev;
1086 struct device_node *endpoint;
1087 struct ov5645 *ov5645;
1088 u8 chip_id_high, chip_id_low;
1089 u32 xclk_freq;
1090 int ret;
1091
1092 ov5645 = devm_kzalloc(dev, sizeof(struct ov5645), GFP_KERNEL);
1093 if (!ov5645)
1094 return -ENOMEM;
1095
1096 ov5645->i2c_client = client;
1097 ov5645->dev = dev;
1098
1099 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
1100 if (!endpoint) {
1101 dev_err(dev, "endpoint node not found\n");
1102 return -EINVAL;
1103 }
1104
1105 ret = v4l2_of_parse_endpoint(endpoint, &ov5645->ep);
1106 if (ret < 0) {
1107 dev_err(dev, "parsing endpoint node failed\n");
1108 return ret;
1109 }
1110
1111 of_node_put(endpoint);
1112
1113 if (ov5645->ep.bus_type != V4L2_MBUS_CSI2) {
1114 dev_err(dev, "invalid bus type, must be CSI2\n");
1115 return -EINVAL;
1116 }
1117
1118 /* get system clock (xclk) */
1119 ov5645->xclk = devm_clk_get(dev, "xclk");
1120 if (IS_ERR(ov5645->xclk)) {
1121 dev_err(dev, "could not get xclk");
1122 return PTR_ERR(ov5645->xclk);
1123 }
1124
1125 ret = of_property_read_u32(dev->of_node, "clock-frequency", &xclk_freq);
1126 if (ret) {
1127 dev_err(dev, "could not get xclk frequency\n");
1128 return ret;
1129 }
1130
1131 if (xclk_freq != 23880000) {
1132 dev_err(dev, "external clock frequency %u is not supported\n",
1133 xclk_freq);
1134 return -EINVAL;
1135 }
1136
1137 ret = clk_set_rate(ov5645->xclk, xclk_freq);
1138 if (ret) {
1139 dev_err(dev, "could not set xclk frequency\n");
1140 return ret;
1141 }
1142
1143 ov5645->io_regulator = devm_regulator_get(dev, "vdddo");
1144 if (IS_ERR(ov5645->io_regulator)) {
1145 dev_err(dev, "cannot get io regulator\n");
1146 return PTR_ERR(ov5645->io_regulator);
1147 }
1148
1149 ret = regulator_set_voltage(ov5645->io_regulator,
1150 OV5645_VOLTAGE_DIGITAL_IO,
1151 OV5645_VOLTAGE_DIGITAL_IO);
1152 if (ret < 0) {
1153 dev_err(dev, "cannot set io voltage\n");
1154 return ret;
1155 }
1156
1157 ov5645->core_regulator = devm_regulator_get(dev, "vddd");
1158 if (IS_ERR(ov5645->core_regulator)) {
1159 dev_err(dev, "cannot get core regulator\n");
1160 return PTR_ERR(ov5645->core_regulator);
1161 }
1162
1163 ret = regulator_set_voltage(ov5645->core_regulator,
1164 OV5645_VOLTAGE_DIGITAL_CORE,
1165 OV5645_VOLTAGE_DIGITAL_CORE);
1166 if (ret < 0) {
1167 dev_err(dev, "cannot set core voltage\n");
1168 return ret;
1169 }
1170
1171 ov5645->analog_regulator = devm_regulator_get(dev, "vdda");
1172 if (IS_ERR(ov5645->analog_regulator)) {
1173 dev_err(dev, "cannot get analog regulator\n");
1174 return PTR_ERR(ov5645->analog_regulator);
1175 }
1176
1177 ret = regulator_set_voltage(ov5645->analog_regulator,
1178 OV5645_VOLTAGE_ANALOG,
1179 OV5645_VOLTAGE_ANALOG);
1180 if (ret < 0) {
1181 dev_err(dev, "cannot set analog voltage\n");
1182 return ret;
1183 }
1184
1185 ov5645->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
1186 if (IS_ERR(ov5645->enable_gpio)) {
1187 dev_err(dev, "cannot get enable gpio\n");
1188 return PTR_ERR(ov5645->enable_gpio);
1189 }
1190
1191 ov5645->rst_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
1192 if (IS_ERR(ov5645->rst_gpio)) {
1193 dev_err(dev, "cannot get reset gpio\n");
1194 return PTR_ERR(ov5645->rst_gpio);
1195 }
1196
1197 mutex_init(&ov5645->power_lock);
1198
1199 v4l2_ctrl_handler_init(&ov5645->ctrls, 7);
1200 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
1201 V4L2_CID_SATURATION, -4, 4, 1, 0);
1202 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
1203 V4L2_CID_HFLIP, 0, 1, 1, 0);
1204 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
1205 V4L2_CID_VFLIP, 0, 1, 1, 0);
1206 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
1207 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1208 v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
1209 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1210 v4l2_ctrl_new_std_menu(&ov5645->ctrls, &ov5645_ctrl_ops,
1211 V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL,
1212 0, V4L2_EXPOSURE_AUTO);
1213 v4l2_ctrl_new_std_menu_items(&ov5645->ctrls, &ov5645_ctrl_ops,
1214 V4L2_CID_TEST_PATTERN,
1215 ARRAY_SIZE(ov5645_test_pattern_menu) - 1,
1216 0, 0, ov5645_test_pattern_menu);
1217
1218 ov5645->sd.ctrl_handler = &ov5645->ctrls;
1219
1220 if (ov5645->ctrls.error) {
1221 dev_err(dev, "%s: control initialization error %d\n",
1222 __func__, ov5645->ctrls.error);
1223 ret = ov5645->ctrls.error;
1224 goto free_ctrl;
1225 }
1226
1227 v4l2_i2c_subdev_init(&ov5645->sd, client, &ov5645_subdev_ops);
1228 ov5645->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1229 ov5645->pad.flags = MEDIA_PAD_FL_SOURCE;
1230 ov5645->sd.dev = &client->dev;
1231
1232 ret = media_entity_pads_init(&ov5645->sd.entity, 1, &ov5645->pad);
1233 if (ret < 0) {
1234 dev_err(dev, "could not register media entity\n");
1235 goto free_ctrl;
1236 }
1237
1238 ret = ov5645_s_power(&ov5645->sd, true);
1239 if (ret < 0) {
1240 dev_err(dev, "could not power up OV5645\n");
1241 goto free_entity;
1242 }
1243
1244 ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_HIGH, &chip_id_high);
1245 if (ret < 0 || chip_id_high != OV5645_CHIP_ID_HIGH_BYTE) {
1246 dev_err(dev, "could not read ID high\n");
1247 ret = -ENODEV;
1248 goto power_down;
1249 }
1250 ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_LOW, &chip_id_low);
1251 if (ret < 0 || chip_id_low != OV5645_CHIP_ID_LOW_BYTE) {
1252 dev_err(dev, "could not read ID low\n");
1253 ret = -ENODEV;
1254 goto power_down;
1255 }
1256
1257 dev_info(dev, "OV5645 detected at address 0x%02x\n", client->addr);
1258
1259 ret = ov5645_read_reg(ov5645, OV5645_AEC_PK_MANUAL,
1260 &ov5645->aec_pk_manual);
1261 if (ret < 0) {
1262 dev_err(dev, "could not read AEC/AGC mode\n");
1263 ret = -ENODEV;
1264 goto power_down;
1265 }
1266
1267 ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG20,
1268 &ov5645->timing_tc_reg20);
1269 if (ret < 0) {
1270 dev_err(dev, "could not read vflip value\n");
1271 ret = -ENODEV;
1272 goto power_down;
1273 }
1274
1275 ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG21,
1276 &ov5645->timing_tc_reg21);
1277 if (ret < 0) {
1278 dev_err(dev, "could not read hflip value\n");
1279 ret = -ENODEV;
1280 goto power_down;
1281 }
1282
1283 ov5645_s_power(&ov5645->sd, false);
1284
1285 ret = v4l2_async_register_subdev(&ov5645->sd);
1286 if (ret < 0) {
1287 dev_err(dev, "could not register v4l2 device\n");
1288 goto free_entity;
1289 }
1290
1291 ov5645_entity_init_cfg(&ov5645->sd, NULL);
1292
1293 return 0;
1294
1295power_down:
1296 ov5645_s_power(&ov5645->sd, false);
1297free_entity:
1298 media_entity_cleanup(&ov5645->sd.entity);
1299free_ctrl:
1300 v4l2_ctrl_handler_free(&ov5645->ctrls);
1301 mutex_destroy(&ov5645->power_lock);
1302
1303 return ret;
1304}
1305
1306static int ov5645_remove(struct i2c_client *client)
1307{
1308 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1309 struct ov5645 *ov5645 = to_ov5645(sd);
1310
1311 v4l2_async_unregister_subdev(&ov5645->sd);
1312 media_entity_cleanup(&ov5645->sd.entity);
1313 v4l2_ctrl_handler_free(&ov5645->ctrls);
1314 mutex_destroy(&ov5645->power_lock);
1315
1316 return 0;
1317}
1318
1319static const struct i2c_device_id ov5645_id[] = {
1320 { "ov5645", 0 },
1321 {}
1322};
1323MODULE_DEVICE_TABLE(i2c, ov5645_id);
1324
1325static const struct of_device_id ov5645_of_match[] = {
1326 { .compatible = "ovti,ov5645" },
1327 { /* sentinel */ }
1328};
1329MODULE_DEVICE_TABLE(of, ov5645_of_match);
1330
1331static struct i2c_driver ov5645_i2c_driver = {
1332 .driver = {
1333 .of_match_table = of_match_ptr(ov5645_of_match),
1334 .name = "ov5645",
1335 },
1336 .probe = ov5645_probe,
1337 .remove = ov5645_remove,
1338 .id_table = ov5645_id,
1339};
1340
1341module_i2c_driver(ov5645_i2c_driver);
1342
1343MODULE_DESCRIPTION("Omnivision OV5645 Camera Driver");
1344MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
1345MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
new file mode 100644
index 000000000000..f57a0b354cf6
--- /dev/null
+++ b/drivers/media/i2c/ov5647.c
@@ -0,0 +1,634 @@
1/*
2 * A V4L2 driver for OmniVision OV5647 cameras.
3 *
4 * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
5 * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * Based on Omnivision OV7670 Camera Driver
8 * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
9 *
10 * Copyright (C) 2016, Synopsys, Inc.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation version 2.
15 *
16 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
17 * kind, whether express or implied; without even the implied warranty
18 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 */
21
22#include <linux/clk.h>
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/init.h>
26#include <linux/io.h>
27#include <linux/module.h>
28#include <linux/slab.h>
29#include <linux/videodev2.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-image-sizes.h>
32#include <media/v4l2-mediabus.h>
33#include <media/v4l2-of.h>
34
35#define SENSOR_NAME "ov5647"
36
37#define OV5647_SW_RESET 0x0103
38#define OV5647_REG_CHIPID_H 0x300A
39#define OV5647_REG_CHIPID_L 0x300B
40
41#define REG_TERM 0xfffe
42#define VAL_TERM 0xfe
43#define REG_DLY 0xffff
44
45#define OV5647_ROW_START 0x01
46#define OV5647_ROW_START_MIN 0
47#define OV5647_ROW_START_MAX 2004
48#define OV5647_ROW_START_DEF 54
49
50#define OV5647_COLUMN_START 0x02
51#define OV5647_COLUMN_START_MIN 0
52#define OV5647_COLUMN_START_MAX 2750
53#define OV5647_COLUMN_START_DEF 16
54
55#define OV5647_WINDOW_HEIGHT 0x03
56#define OV5647_WINDOW_HEIGHT_MIN 2
57#define OV5647_WINDOW_HEIGHT_MAX 2006
58#define OV5647_WINDOW_HEIGHT_DEF 1944
59
60#define OV5647_WINDOW_WIDTH 0x04
61#define OV5647_WINDOW_WIDTH_MIN 2
62#define OV5647_WINDOW_WIDTH_MAX 2752
63#define OV5647_WINDOW_WIDTH_DEF 2592
64
65struct regval_list {
66 u16 addr;
67 u8 data;
68};
69
70struct ov5647 {
71 struct v4l2_subdev sd;
72 struct media_pad pad;
73 struct mutex lock;
74 struct v4l2_mbus_framefmt format;
75 unsigned int width;
76 unsigned int height;
77 int power_count;
78 struct clk *xclk;
79};
80
81static inline struct ov5647 *to_state(struct v4l2_subdev *sd)
82{
83 return container_of(sd, struct ov5647, sd);
84}
85
86static struct regval_list sensor_oe_disable_regs[] = {
87 {0x3000, 0x00},
88 {0x3001, 0x00},
89 {0x3002, 0x00},
90};
91
92static struct regval_list sensor_oe_enable_regs[] = {
93 {0x3000, 0x0f},
94 {0x3001, 0xff},
95 {0x3002, 0xe4},
96};
97
98static struct regval_list ov5647_640x480[] = {
99 {0x0100, 0x00},
100 {0x0103, 0x01},
101 {0x3034, 0x08},
102 {0x3035, 0x21},
103 {0x3036, 0x46},
104 {0x303c, 0x11},
105 {0x3106, 0xf5},
106 {0x3821, 0x07},
107 {0x3820, 0x41},
108 {0x3827, 0xec},
109 {0x370c, 0x0f},
110 {0x3612, 0x59},
111 {0x3618, 0x00},
112 {0x5000, 0x06},
113 {0x5001, 0x01},
114 {0x5002, 0x41},
115 {0x5003, 0x08},
116 {0x5a00, 0x08},
117 {0x3000, 0x00},
118 {0x3001, 0x00},
119 {0x3002, 0x00},
120 {0x3016, 0x08},
121 {0x3017, 0xe0},
122 {0x3018, 0x44},
123 {0x301c, 0xf8},
124 {0x301d, 0xf0},
125 {0x3a18, 0x00},
126 {0x3a19, 0xf8},
127 {0x3c01, 0x80},
128 {0x3b07, 0x0c},
129 {0x380c, 0x07},
130 {0x380d, 0x68},
131 {0x380e, 0x03},
132 {0x380f, 0xd8},
133 {0x3814, 0x31},
134 {0x3815, 0x31},
135 {0x3708, 0x64},
136 {0x3709, 0x52},
137 {0x3808, 0x02},
138 {0x3809, 0x80},
139 {0x380a, 0x01},
140 {0x380b, 0xE0},
141 {0x3801, 0x00},
142 {0x3802, 0x00},
143 {0x3803, 0x00},
144 {0x3804, 0x0a},
145 {0x3805, 0x3f},
146 {0x3806, 0x07},
147 {0x3807, 0xa1},
148 {0x3811, 0x08},
149 {0x3813, 0x02},
150 {0x3630, 0x2e},
151 {0x3632, 0xe2},
152 {0x3633, 0x23},
153 {0x3634, 0x44},
154 {0x3636, 0x06},
155 {0x3620, 0x64},
156 {0x3621, 0xe0},
157 {0x3600, 0x37},
158 {0x3704, 0xa0},
159 {0x3703, 0x5a},
160 {0x3715, 0x78},
161 {0x3717, 0x01},
162 {0x3731, 0x02},
163 {0x370b, 0x60},
164 {0x3705, 0x1a},
165 {0x3f05, 0x02},
166 {0x3f06, 0x10},
167 {0x3f01, 0x0a},
168 {0x3a08, 0x01},
169 {0x3a09, 0x27},
170 {0x3a0a, 0x00},
171 {0x3a0b, 0xf6},
172 {0x3a0d, 0x04},
173 {0x3a0e, 0x03},
174 {0x3a0f, 0x58},
175 {0x3a10, 0x50},
176 {0x3a1b, 0x58},
177 {0x3a1e, 0x50},
178 {0x3a11, 0x60},
179 {0x3a1f, 0x28},
180 {0x4001, 0x02},
181 {0x4004, 0x02},
182 {0x4000, 0x09},
183 {0x4837, 0x24},
184 {0x4050, 0x6e},
185 {0x4051, 0x8f},
186 {0x0100, 0x01},
187};
188
189static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
190{
191 int ret;
192 unsigned char data[3] = { reg >> 8, reg & 0xff, val};
193 struct i2c_client *client = v4l2_get_subdevdata(sd);
194
195 ret = i2c_master_send(client, data, 3);
196 if (ret < 0)
197 dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
198 __func__, reg);
199
200 return ret;
201}
202
203static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val)
204{
205 int ret;
206 unsigned char data_w[2] = { reg >> 8, reg & 0xff };
207 struct i2c_client *client = v4l2_get_subdevdata(sd);
208
209 ret = i2c_master_send(client, data_w, 2);
210 if (ret < 0) {
211 dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n",
212 __func__, reg);
213 return ret;
214 }
215
216 ret = i2c_master_recv(client, val, 1);
217 if (ret < 0)
218 dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n",
219 __func__, reg);
220
221 return ret;
222}
223
224static int ov5647_write_array(struct v4l2_subdev *sd,
225 struct regval_list *regs, int array_size)
226{
227 int i, ret;
228
229 for (i = 0; i < array_size; i++) {
230 ret = ov5647_write(sd, regs[i].addr, regs[i].data);
231 if (ret < 0)
232 return ret;
233 }
234
235 return 0;
236}
237
238static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel)
239{
240 u8 channel_id;
241 int ret;
242
243 ret = ov5647_read(sd, 0x4814, &channel_id);
244 if (ret < 0)
245 return ret;
246
247 channel_id &= ~(3 << 6);
248 return ov5647_write(sd, 0x4814, channel_id | (channel << 6));
249}
250
251static int ov5647_stream_on(struct v4l2_subdev *sd)
252{
253 int ret;
254
255 ret = ov5647_write(sd, 0x4202, 0x00);
256 if (ret < 0)
257 return ret;
258
259 return ov5647_write(sd, 0x300D, 0x00);
260}
261
262static int ov5647_stream_off(struct v4l2_subdev *sd)
263{
264 int ret;
265
266 ret = ov5647_write(sd, 0x4202, 0x0f);
267 if (ret < 0)
268 return ret;
269
270 return ov5647_write(sd, 0x300D, 0x01);
271}
272
273static int set_sw_standby(struct v4l2_subdev *sd, bool standby)
274{
275 int ret;
276 u8 rdval;
277
278 ret = ov5647_read(sd, 0x0100, &rdval);
279 if (ret < 0)
280 return ret;
281
282 if (standby)
283 rdval &= ~0x01;
284 else
285 rdval |= 0x01;
286
287 return ov5647_write(sd, 0x0100, rdval);
288}
289
290static int __sensor_init(struct v4l2_subdev *sd)
291{
292 int ret;
293 u8 resetval, rdval;
294 struct i2c_client *client = v4l2_get_subdevdata(sd);
295
296 ret = ov5647_read(sd, 0x0100, &rdval);
297 if (ret < 0)
298 return ret;
299
300 ret = ov5647_write_array(sd, ov5647_640x480,
301 ARRAY_SIZE(ov5647_640x480));
302 if (ret < 0) {
303 dev_err(&client->dev, "write sensor default regs error\n");
304 return ret;
305 }
306
307 ret = ov5647_set_virtual_channel(sd, 0);
308 if (ret < 0)
309 return ret;
310
311 ret = ov5647_read(sd, 0x0100, &resetval);
312 if (ret < 0)
313 return ret;
314
315 if (!(resetval & 0x01)) {
316 dev_err(&client->dev, "Device was in SW standby");
317 ret = ov5647_write(sd, 0x0100, 0x01);
318 if (ret < 0)
319 return ret;
320 }
321
322 return ov5647_write(sd, 0x4800, 0x04);
323}
324
325static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
326{
327 int ret = 0;
328 struct ov5647 *ov5647 = to_state(sd);
329 struct i2c_client *client = v4l2_get_subdevdata(sd);
330
331 mutex_lock(&ov5647->lock);
332
333 if (on && !ov5647->power_count) {
334 dev_dbg(&client->dev, "OV5647 power on\n");
335
336 ret = clk_prepare_enable(ov5647->xclk);
337 if (ret < 0) {
338 dev_err(&client->dev, "clk prepare enable failed\n");
339 goto out;
340 }
341
342 ret = ov5647_write_array(sd, sensor_oe_enable_regs,
343 ARRAY_SIZE(sensor_oe_enable_regs));
344 if (ret < 0) {
345 clk_disable_unprepare(ov5647->xclk);
346 dev_err(&client->dev,
347 "write sensor_oe_enable_regs error\n");
348 goto out;
349 }
350
351 ret = __sensor_init(sd);
352 if (ret < 0) {
353 clk_disable_unprepare(ov5647->xclk);
354 dev_err(&client->dev,
355 "Camera not available, check Power\n");
356 goto out;
357 }
358 } else if (!on && ov5647->power_count == 1) {
359 dev_dbg(&client->dev, "OV5647 power off\n");
360
361 ret = ov5647_write_array(sd, sensor_oe_disable_regs,
362 ARRAY_SIZE(sensor_oe_disable_regs));
363
364 if (ret < 0)
365 dev_dbg(&client->dev, "disable oe failed\n");
366
367 ret = set_sw_standby(sd, true);
368
369 if (ret < 0)
370 dev_dbg(&client->dev, "soft stby failed\n");
371
372 clk_disable_unprepare(ov5647->xclk);
373 }
374
375 /* Update the power count. */
376 ov5647->power_count += on ? 1 : -1;
377 WARN_ON(ov5647->power_count < 0);
378
379out:
380 mutex_unlock(&ov5647->lock);
381
382 return ret;
383}
384
385#ifdef CONFIG_VIDEO_ADV_DEBUG
386static int ov5647_sensor_get_register(struct v4l2_subdev *sd,
387 struct v4l2_dbg_register *reg)
388{
389 u8 val;
390 int ret;
391
392 ret = ov5647_read(sd, reg->reg & 0xff, &val);
393 if (ret < 0)
394 return ret;
395
396 reg->val = val;
397 reg->size = 1;
398
399 return 0;
400}
401
402static int ov5647_sensor_set_register(struct v4l2_subdev *sd,
403 const struct v4l2_dbg_register *reg)
404{
405 return ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff);
406}
407#endif
408
409/**
410 * @short Subdev core operations registration
411 */
412static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = {
413 .s_power = ov5647_sensor_power,
414#ifdef CONFIG_VIDEO_ADV_DEBUG
415 .g_register = ov5647_sensor_get_register,
416 .s_register = ov5647_sensor_set_register,
417#endif
418};
419
420static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
421{
422 if (enable)
423 return ov5647_stream_on(sd);
424 else
425 return ov5647_stream_off(sd);
426}
427
428static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
429 .s_stream = ov5647_s_stream,
430};
431
432static int ov5647_enum_mbus_code(struct v4l2_subdev *sd,
433 struct v4l2_subdev_pad_config *cfg,
434 struct v4l2_subdev_mbus_code_enum *code)
435{
436 if (code->index > 0)
437 return -EINVAL;
438
439 code->code = MEDIA_BUS_FMT_SBGGR8_1X8;
440
441 return 0;
442}
443
444static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
445 .enum_mbus_code = ov5647_enum_mbus_code,
446};
447
448static const struct v4l2_subdev_ops ov5647_subdev_ops = {
449 .core = &ov5647_subdev_core_ops,
450 .video = &ov5647_subdev_video_ops,
451 .pad = &ov5647_subdev_pad_ops,
452};
453
454static int ov5647_detect(struct v4l2_subdev *sd)
455{
456 u8 read;
457 int ret;
458 struct i2c_client *client = v4l2_get_subdevdata(sd);
459
460 ret = ov5647_write(sd, OV5647_SW_RESET, 0x01);
461 if (ret < 0)
462 return ret;
463
464 ret = ov5647_read(sd, OV5647_REG_CHIPID_H, &read);
465 if (ret < 0)
466 return ret;
467
468 if (read != 0x56) {
469 dev_err(&client->dev, "ID High expected 0x56 got %x", read);
470 return -ENODEV;
471 }
472
473 ret = ov5647_read(sd, OV5647_REG_CHIPID_L, &read);
474 if (ret < 0)
475 return ret;
476
477 if (read != 0x47) {
478 dev_err(&client->dev, "ID Low expected 0x47 got %x", read);
479 return -ENODEV;
480 }
481
482 return ov5647_write(sd, OV5647_SW_RESET, 0x00);
483}
484
485static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
486{
487 struct v4l2_mbus_framefmt *format =
488 v4l2_subdev_get_try_format(sd, fh->pad, 0);
489 struct v4l2_rect *crop =
490 v4l2_subdev_get_try_crop(sd, fh->pad, 0);
491
492 crop->left = OV5647_COLUMN_START_DEF;
493 crop->top = OV5647_ROW_START_DEF;
494 crop->width = OV5647_WINDOW_WIDTH_DEF;
495 crop->height = OV5647_WINDOW_HEIGHT_DEF;
496
497 format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
498
499 format->width = OV5647_WINDOW_WIDTH_DEF;
500 format->height = OV5647_WINDOW_HEIGHT_DEF;
501 format->field = V4L2_FIELD_NONE;
502 format->colorspace = V4L2_COLORSPACE_SRGB;
503
504 return 0;
505}
506
507static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
508 .open = ov5647_open,
509};
510
511static int ov5647_parse_dt(struct device_node *np)
512{
513 struct v4l2_of_endpoint bus_cfg;
514 struct device_node *ep;
515
516 int ret;
517
518 ep = of_graph_get_next_endpoint(np, NULL);
519 if (!ep)
520 return -EINVAL;
521
522 ret = v4l2_of_parse_endpoint(ep, &bus_cfg);
523
524 of_node_put(ep);
525 return ret;
526}
527
528static int ov5647_probe(struct i2c_client *client,
529 const struct i2c_device_id *id)
530{
531 struct device *dev = &client->dev;
532 struct ov5647 *sensor;
533 int ret;
534 struct v4l2_subdev *sd;
535 struct device_node *np = client->dev.of_node;
536 u32 xclk_freq;
537
538 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
539 if (!sensor)
540 return -ENOMEM;
541
542 if (IS_ENABLED(CONFIG_OF) && np) {
543 ret = ov5647_parse_dt(np);
544 if (ret) {
545 dev_err(dev, "DT parsing error: %d\n", ret);
546 return ret;
547 }
548 }
549
550 /* get system clock (xclk) */
551 sensor->xclk = devm_clk_get(dev, NULL);
552 if (IS_ERR(sensor->xclk)) {
553 dev_err(dev, "could not get xclk");
554 return PTR_ERR(sensor->xclk);
555 }
556
557 xclk_freq = clk_get_rate(sensor->xclk);
558 if (xclk_freq != 25000000) {
559 dev_err(dev, "Unsupported clock frequency: %u\n", xclk_freq);
560 return -EINVAL;
561 }
562
563 mutex_init(&sensor->lock);
564
565 sd = &sensor->sd;
566 v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
567 sensor->sd.internal_ops = &ov5647_subdev_internal_ops;
568 sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
569
570 sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
571 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
572 ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
573 if (ret < 0)
574 goto mutex_remove;
575
576 ret = ov5647_detect(sd);
577 if (ret < 0)
578 goto error;
579
580 ret = v4l2_async_register_subdev(sd);
581 if (ret < 0)
582 goto error;
583
584 dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
585 return 0;
586error:
587 media_entity_cleanup(&sd->entity);
588mutex_remove:
589 mutex_destroy(&sensor->lock);
590 return ret;
591}
592
593static int ov5647_remove(struct i2c_client *client)
594{
595 struct v4l2_subdev *sd = i2c_get_clientdata(client);
596 struct ov5647 *ov5647 = to_state(sd);
597
598 v4l2_async_unregister_subdev(&ov5647->sd);
599 media_entity_cleanup(&ov5647->sd.entity);
600 v4l2_device_unregister_subdev(sd);
601 mutex_destroy(&ov5647->lock);
602
603 return 0;
604}
605
606static const struct i2c_device_id ov5647_id[] = {
607 { "ov5647", 0 },
608 { }
609};
610MODULE_DEVICE_TABLE(i2c, ov5647_id);
611
612#if IS_ENABLED(CONFIG_OF)
613static const struct of_device_id ov5647_of_match[] = {
614 { .compatible = "ovti,ov5647" },
615 { /* sentinel */ },
616};
617MODULE_DEVICE_TABLE(of, ov5647_of_match);
618#endif
619
620static struct i2c_driver ov5647_driver = {
621 .driver = {
622 .of_match_table = of_match_ptr(ov5647_of_match),
623 .name = SENSOR_NAME,
624 },
625 .probe = ov5647_probe,
626 .remove = ov5647_remove,
627 .id_table = ov5647_id,
628};
629
630module_i2c_driver(ov5647_driver);
631
632MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>");
633MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors");
634MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 56cfb5ca9c95..7270c68ed18a 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -10,12 +10,15 @@
10 * This file may be distributed under the terms of the GNU General 10 * This file may be distributed under the terms of the GNU General
11 * Public License, version 2. 11 * Public License, version 2.
12 */ 12 */
13#include <linux/clk.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
18#include <linux/videodev2.h> 19#include <linux/videodev2.h>
20#include <linux/gpio.h>
21#include <linux/gpio/consumer.h>
19#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
20#include <media/v4l2-ctrls.h> 23#include <media/v4l2-ctrls.h>
21#include <media/v4l2-mediabus.h> 24#include <media/v4l2-mediabus.h>
@@ -227,6 +230,9 @@ struct ov7670_info {
227 struct v4l2_ctrl *hue; 230 struct v4l2_ctrl *hue;
228 }; 231 };
229 struct ov7670_format_struct *fmt; /* Current format */ 232 struct ov7670_format_struct *fmt; /* Current format */
233 struct clk *clk;
234 struct gpio_desc *resetb_gpio;
235 struct gpio_desc *pwdn_gpio;
230 int min_width; /* Filter out smaller sizes */ 236 int min_width; /* Filter out smaller sizes */
231 int min_height; /* Filter out smaller sizes */ 237 int min_height; /* Filter out smaller sizes */
232 int clock_speed; /* External clock speed (MHz) */ 238 int clock_speed; /* External clock speed (MHz) */
@@ -589,8 +595,6 @@ static int ov7670_init(struct v4l2_subdev *sd, u32 val)
589 return ov7670_write_array(sd, ov7670_default_regs); 595 return ov7670_write_array(sd, ov7670_default_regs);
590} 596}
591 597
592
593
594static int ov7670_detect(struct v4l2_subdev *sd) 598static int ov7670_detect(struct v4l2_subdev *sd)
595{ 599{
596 unsigned char v; 600 unsigned char v;
@@ -1046,7 +1050,6 @@ static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
1046 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1050 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1047 return -EINVAL; 1051 return -EINVAL;
1048 1052
1049 memset(cp, 0, sizeof(struct v4l2_captureparm));
1050 cp->capability = V4L2_CAP_TIMEPERFRAME; 1053 cp->capability = V4L2_CAP_TIMEPERFRAME;
1051 info->devtype->get_framerate(sd, &cp->timeperframe); 1054 info->devtype->get_framerate(sd, &cp->timeperframe);
1052 1055
@@ -1061,9 +1064,8 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
1061 1064
1062 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1065 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1063 return -EINVAL; 1066 return -EINVAL;
1064 if (cp->extendedmode != 0)
1065 return -EINVAL;
1066 1067
1068 cp->capability = V4L2_CAP_TIMEPERFRAME;
1067 return info->devtype->set_framerate(sd, tpf); 1069 return info->devtype->set_framerate(sd, tpf);
1068} 1070}
1069 1071
@@ -1549,6 +1551,27 @@ static const struct ov7670_devtype ov7670_devdata[] = {
1549 }, 1551 },
1550}; 1552};
1551 1553
1554static int ov7670_init_gpio(struct i2c_client *client, struct ov7670_info *info)
1555{
1556 info->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
1557 GPIOD_OUT_LOW);
1558 if (IS_ERR(info->pwdn_gpio)) {
1559 dev_info(&client->dev, "can't get %s GPIO\n", "powerdown");
1560 return PTR_ERR(info->pwdn_gpio);
1561 }
1562
1563 info->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
1564 GPIOD_OUT_LOW);
1565 if (IS_ERR(info->resetb_gpio)) {
1566 dev_info(&client->dev, "can't get %s GPIO\n", "reset");
1567 return PTR_ERR(info->resetb_gpio);
1568 }
1569
1570 usleep_range(3000, 5000);
1571
1572 return 0;
1573}
1574
1552static int ov7670_probe(struct i2c_client *client, 1575static int ov7670_probe(struct i2c_client *client,
1553 const struct i2c_device_id *id) 1576 const struct i2c_device_id *id)
1554{ 1577{
@@ -1589,13 +1612,28 @@ static int ov7670_probe(struct i2c_client *client,
1589 info->pclk_hb_disable = true; 1612 info->pclk_hb_disable = true;
1590 } 1613 }
1591 1614
1615 info->clk = devm_clk_get(&client->dev, "xclk");
1616 if (IS_ERR(info->clk))
1617 return -EPROBE_DEFER;
1618 clk_prepare_enable(info->clk);
1619
1620 ret = ov7670_init_gpio(client, info);
1621 if (ret)
1622 goto clk_disable;
1623
1624 info->clock_speed = clk_get_rate(info->clk) / 1000000;
1625 if (info->clock_speed < 10 || info->clock_speed > 48) {
1626 ret = -EINVAL;
1627 goto clk_disable;
1628 }
1629
1592 /* Make sure it's an ov7670 */ 1630 /* Make sure it's an ov7670 */
1593 ret = ov7670_detect(sd); 1631 ret = ov7670_detect(sd);
1594 if (ret) { 1632 if (ret) {
1595 v4l_dbg(1, debug, client, 1633 v4l_dbg(1, debug, client,
1596 "chip found @ 0x%x (%s) is not an ov7670 chip.\n", 1634 "chip found @ 0x%x (%s) is not an ov7670 chip.\n",
1597 client->addr << 1, client->adapter->name); 1635 client->addr << 1, client->adapter->name);
1598 return ret; 1636 goto clk_disable;
1599 } 1637 }
1600 v4l_info(client, "chip found @ 0x%02x (%s)\n", 1638 v4l_info(client, "chip found @ 0x%02x (%s)\n",
1601 client->addr << 1, client->adapter->name); 1639 client->addr << 1, client->adapter->name);
@@ -1636,10 +1674,9 @@ static int ov7670_probe(struct i2c_client *client,
1636 V4L2_EXPOSURE_AUTO); 1674 V4L2_EXPOSURE_AUTO);
1637 sd->ctrl_handler = &info->hdl; 1675 sd->ctrl_handler = &info->hdl;
1638 if (info->hdl.error) { 1676 if (info->hdl.error) {
1639 int err = info->hdl.error; 1677 ret = info->hdl.error;
1640 1678
1641 v4l2_ctrl_handler_free(&info->hdl); 1679 goto hdl_free;
1642 return err;
1643 } 1680 }
1644 /* 1681 /*
1645 * We have checked empirically that hw allows to read back the gain 1682 * We have checked empirically that hw allows to read back the gain
@@ -1651,7 +1688,17 @@ static int ov7670_probe(struct i2c_client *client,
1651 v4l2_ctrl_cluster(2, &info->saturation); 1688 v4l2_ctrl_cluster(2, &info->saturation);
1652 v4l2_ctrl_handler_setup(&info->hdl); 1689 v4l2_ctrl_handler_setup(&info->hdl);
1653 1690
1691 ret = v4l2_async_register_subdev(&info->sd);
1692 if (ret < 0)
1693 goto hdl_free;
1694
1654 return 0; 1695 return 0;
1696
1697hdl_free:
1698 v4l2_ctrl_handler_free(&info->hdl);
1699clk_disable:
1700 clk_disable_unprepare(info->clk);
1701 return ret;
1655} 1702}
1656 1703
1657 1704
@@ -1662,6 +1709,7 @@ static int ov7670_remove(struct i2c_client *client)
1662 1709
1663 v4l2_device_unregister_subdev(sd); 1710 v4l2_device_unregister_subdev(sd);
1664 v4l2_ctrl_handler_free(&info->hdl); 1711 v4l2_ctrl_handler_free(&info->hdl);
1712 clk_disable_unprepare(info->clk);
1665 return 0; 1713 return 0;
1666} 1714}
1667 1715
@@ -1672,9 +1720,18 @@ static const struct i2c_device_id ov7670_id[] = {
1672}; 1720};
1673MODULE_DEVICE_TABLE(i2c, ov7670_id); 1721MODULE_DEVICE_TABLE(i2c, ov7670_id);
1674 1722
1723#if IS_ENABLED(CONFIG_OF)
1724static const struct of_device_id ov7670_of_match[] = {
1725 { .compatible = "ovti,ov7670", },
1726 { /* sentinel */ },
1727};
1728MODULE_DEVICE_TABLE(of, ov7670_of_match);
1729#endif
1730
1675static struct i2c_driver ov7670_driver = { 1731static struct i2c_driver ov7670_driver = {
1676 .driver = { 1732 .driver = {
1677 .name = "ov7670", 1733 .name = "ov7670",
1734 .of_match_table = of_match_ptr(ov7670_of_match),
1678 }, 1735 },
1679 .probe = ov7670_probe, 1736 .probe = ov7670_probe,
1680 .remove = ov7670_remove, 1737 .remove = ov7670_remove,
diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
index 7704bcf5cc25..96859f37cb1c 100644
--- a/drivers/media/i2c/soc_camera/Kconfig
+++ b/drivers/media/i2c/soc_camera/Kconfig
@@ -41,12 +41,6 @@ config SOC_CAMERA_MT9V022
41 help 41 help
42 This driver supports MT9V022 cameras from Micron 42 This driver supports MT9V022 cameras from Micron
43 43
44config SOC_CAMERA_OV2640
45 tristate "ov2640 camera support"
46 depends on SOC_CAMERA && I2C
47 help
48 This is a ov2640 camera driver
49
50config SOC_CAMERA_OV5642 44config SOC_CAMERA_OV5642
51 tristate "ov5642 camera support" 45 tristate "ov5642 camera support"
52 depends on SOC_CAMERA && I2C 46 depends on SOC_CAMERA && I2C
diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
index 6f994f9353a0..974bdb721dbe 100644
--- a/drivers/media/i2c/soc_camera/Makefile
+++ b/drivers/media/i2c/soc_camera/Makefile
@@ -3,7 +3,6 @@ obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
3obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o 3obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
4obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o 4obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
5obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o 5obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
6obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
7obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o 6obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
8obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o 7obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
9obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o 8obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c
index 05b55cfe8147..77f1e0243d6e 100644
--- a/drivers/media/i2c/soc_camera/imx074.c
+++ b/drivers/media/i2c/soc_camera/imx074.c
@@ -180,7 +180,7 @@ static int imx074_set_fmt(struct v4l2_subdev *sd,
180 mf->field = V4L2_FIELD_NONE; 180 mf->field = V4L2_FIELD_NONE;
181 181
182 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 182 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
183 priv->fmt = imx074_find_datafmt(mf->code); 183 priv->fmt = fmt;
184 else 184 else
185 cfg->try_fmt = *mf; 185 cfg->try_fmt = *mf;
186 186
@@ -271,12 +271,12 @@ static int imx074_g_mbus_config(struct v4l2_subdev *sd,
271 return 0; 271 return 0;
272} 272}
273 273
274static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { 274static const struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
275 .s_stream = imx074_s_stream, 275 .s_stream = imx074_s_stream,
276 .g_mbus_config = imx074_g_mbus_config, 276 .g_mbus_config = imx074_g_mbus_config,
277}; 277};
278 278
279static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { 279static const struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
280 .s_power = imx074_s_power, 280 .s_power = imx074_s_power,
281}; 281};
282 282
@@ -287,7 +287,7 @@ static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = {
287 .set_fmt = imx074_set_fmt, 287 .set_fmt = imx074_set_fmt,
288}; 288};
289 289
290static struct v4l2_subdev_ops imx074_subdev_ops = { 290static const struct v4l2_subdev_ops imx074_subdev_ops = {
291 .core = &imx074_subdev_core_ops, 291 .core = &imx074_subdev_core_ops,
292 .video = &imx074_subdev_video_ops, 292 .video = &imx074_subdev_video_ops,
293 .pad = &imx074_subdev_pad_ops, 293 .pad = &imx074_subdev_pad_ops,
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index 3d6378d4491c..1bfb0d53059e 100644
--- a/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -278,6 +278,7 @@ static int mt9m001_get_fmt(struct v4l2_subdev *sd,
278} 278}
279 279
280static int mt9m001_s_fmt(struct v4l2_subdev *sd, 280static int mt9m001_s_fmt(struct v4l2_subdev *sd,
281 const struct mt9m001_datafmt *fmt,
281 struct v4l2_mbus_framefmt *mf) 282 struct v4l2_mbus_framefmt *mf)
282{ 283{
283 struct i2c_client *client = v4l2_get_subdevdata(sd); 284 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -297,9 +298,8 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd,
297 if (!ret) { 298 if (!ret) {
298 mf->width = mt9m001->rect.width; 299 mf->width = mt9m001->rect.width;
299 mf->height = mt9m001->rect.height; 300 mf->height = mt9m001->rect.height;
300 mt9m001->fmt = mt9m001_find_datafmt(mf->code, 301 mt9m001->fmt = fmt;
301 mt9m001->fmts, mt9m001->num_fmts); 302 mf->colorspace = fmt->colorspace;
302 mf->colorspace = mt9m001->fmt->colorspace;
303 } 303 }
304 304
305 return ret; 305 return ret;
@@ -335,7 +335,7 @@ static int mt9m001_set_fmt(struct v4l2_subdev *sd,
335 mf->colorspace = fmt->colorspace; 335 mf->colorspace = fmt->colorspace;
336 336
337 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 337 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
338 return mt9m001_s_fmt(sd, mf); 338 return mt9m001_s_fmt(sd, fmt, mf);
339 cfg->try_fmt = *mf; 339 cfg->try_fmt = *mf;
340 return 0; 340 return 0;
341} 341}
@@ -574,7 +574,7 @@ static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
574 .s_ctrl = mt9m001_s_ctrl, 574 .s_ctrl = mt9m001_s_ctrl,
575}; 575};
576 576
577static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { 577static const struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
578#ifdef CONFIG_VIDEO_ADV_DEBUG 578#ifdef CONFIG_VIDEO_ADV_DEBUG
579 .g_register = mt9m001_g_register, 579 .g_register = mt9m001_g_register,
580 .s_register = mt9m001_s_register, 580 .s_register = mt9m001_s_register,
@@ -630,7 +630,7 @@ static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
630 return bps == 10 ? 0 : -EINVAL; 630 return bps == 10 ? 0 : -EINVAL;
631} 631}
632 632
633static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { 633static const struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
634 .s_stream = mt9m001_s_stream, 634 .s_stream = mt9m001_s_stream,
635 .g_mbus_config = mt9m001_g_mbus_config, 635 .g_mbus_config = mt9m001_g_mbus_config,
636 .s_mbus_config = mt9m001_s_mbus_config, 636 .s_mbus_config = mt9m001_s_mbus_config,
@@ -648,7 +648,7 @@ static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = {
648 .set_fmt = mt9m001_set_fmt, 648 .set_fmt = mt9m001_set_fmt,
649}; 649};
650 650
651static struct v4l2_subdev_ops mt9m001_subdev_ops = { 651static const struct v4l2_subdev_ops mt9m001_subdev_ops = {
652 .core = &mt9m001_subdev_core_ops, 652 .core = &mt9m001_subdev_core_ops,
653 .video = &mt9m001_subdev_video_ops, 653 .video = &mt9m001_subdev_video_ops,
654 .sensor = &mt9m001_subdev_sensor_ops, 654 .sensor = &mt9m001_subdev_sensor_ops,
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index 3aa5569065ad..714fb3555b34 100644
--- a/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/drivers/media/i2c/soc_camera/mt9t031.c
@@ -679,7 +679,7 @@ static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
679 .s_ctrl = mt9t031_s_ctrl, 679 .s_ctrl = mt9t031_s_ctrl,
680}; 680};
681 681
682static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { 682static const struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
683 .s_power = mt9t031_s_power, 683 .s_power = mt9t031_s_power,
684#ifdef CONFIG_VIDEO_ADV_DEBUG 684#ifdef CONFIG_VIDEO_ADV_DEBUG
685 .g_register = mt9t031_g_register, 685 .g_register = mt9t031_g_register,
@@ -726,7 +726,7 @@ static int mt9t031_s_mbus_config(struct v4l2_subdev *sd,
726 return reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); 726 return reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
727} 727}
728 728
729static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { 729static const struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
730 .s_stream = mt9t031_s_stream, 730 .s_stream = mt9t031_s_stream,
731 .g_mbus_config = mt9t031_g_mbus_config, 731 .g_mbus_config = mt9t031_g_mbus_config,
732 .s_mbus_config = mt9t031_s_mbus_config, 732 .s_mbus_config = mt9t031_s_mbus_config,
@@ -744,7 +744,7 @@ static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = {
744 .set_fmt = mt9t031_set_fmt, 744 .set_fmt = mt9t031_set_fmt,
745}; 745};
746 746
747static struct v4l2_subdev_ops mt9t031_subdev_ops = { 747static const struct v4l2_subdev_ops mt9t031_subdev_ops = {
748 .core = &mt9t031_subdev_core_ops, 748 .core = &mt9t031_subdev_core_ops,
749 .video = &mt9t031_subdev_video_ops, 749 .video = &mt9t031_subdev_video_ops,
750 .sensor = &mt9t031_subdev_sensor_ops, 750 .sensor = &mt9t031_subdev_sensor_ops,
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index 2ef22241ec14..297d22ebcb18 100644
--- a/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -773,7 +773,7 @@ static int mt9t112_s_power(struct v4l2_subdev *sd, int on)
773 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); 773 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
774} 774}
775 775
776static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { 776static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
777#ifdef CONFIG_VIDEO_ADV_DEBUG 777#ifdef CONFIG_VIDEO_ADV_DEBUG
778 .g_register = mt9t112_g_register, 778 .g_register = mt9t112_g_register,
779 .s_register = mt9t112_s_register, 779 .s_register = mt9t112_s_register,
@@ -1031,7 +1031,7 @@ static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
1031 return 0; 1031 return 0;
1032} 1032}
1033 1033
1034static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { 1034static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
1035 .s_stream = mt9t112_s_stream, 1035 .s_stream = mt9t112_s_stream,
1036 .g_mbus_config = mt9t112_g_mbus_config, 1036 .g_mbus_config = mt9t112_g_mbus_config,
1037 .s_mbus_config = mt9t112_s_mbus_config, 1037 .s_mbus_config = mt9t112_s_mbus_config,
@@ -1048,7 +1048,7 @@ static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = {
1048/************************************************************************ 1048/************************************************************************
1049 i2c driver 1049 i2c driver
1050************************************************************************/ 1050************************************************************************/
1051static struct v4l2_subdev_ops mt9t112_subdev_ops = { 1051static const struct v4l2_subdev_ops mt9t112_subdev_ops = {
1052 .core = &mt9t112_subdev_core_ops, 1052 .core = &mt9t112_subdev_core_ops,
1053 .video = &mt9t112_subdev_video_ops, 1053 .video = &mt9t112_subdev_video_ops,
1054 .pad = &mt9t112_subdev_pad_ops, 1054 .pad = &mt9t112_subdev_pad_ops,
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index 6a14ab5e4f2d..762f06919329 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -403,6 +403,7 @@ static int mt9v022_get_fmt(struct v4l2_subdev *sd,
403} 403}
404 404
405static int mt9v022_s_fmt(struct v4l2_subdev *sd, 405static int mt9v022_s_fmt(struct v4l2_subdev *sd,
406 const struct mt9v022_datafmt *fmt,
406 struct v4l2_mbus_framefmt *mf) 407 struct v4l2_mbus_framefmt *mf)
407{ 408{
408 struct i2c_client *client = v4l2_get_subdevdata(sd); 409 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -441,9 +442,8 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
441 if (!ret) { 442 if (!ret) {
442 mf->width = mt9v022->rect.width; 443 mf->width = mt9v022->rect.width;
443 mf->height = mt9v022->rect.height; 444 mf->height = mt9v022->rect.height;
444 mt9v022->fmt = mt9v022_find_datafmt(mf->code, 445 mt9v022->fmt = fmt;
445 mt9v022->fmts, mt9v022->num_fmts); 446 mf->colorspace = fmt->colorspace;
446 mf->colorspace = mt9v022->fmt->colorspace;
447 } 447 }
448 448
449 return ret; 449 return ret;
@@ -478,7 +478,7 @@ static int mt9v022_set_fmt(struct v4l2_subdev *sd,
478 mf->colorspace = fmt->colorspace; 478 mf->colorspace = fmt->colorspace;
479 479
480 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 480 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
481 return mt9v022_s_fmt(sd, mf); 481 return mt9v022_s_fmt(sd, fmt, mf);
482 cfg->try_fmt = *mf; 482 cfg->try_fmt = *mf;
483 return 0; 483 return 0;
484} 484}
@@ -770,7 +770,7 @@ static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
770 .s_ctrl = mt9v022_s_ctrl, 770 .s_ctrl = mt9v022_s_ctrl,
771}; 771};
772 772
773static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { 773static const struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
774#ifdef CONFIG_VIDEO_ADV_DEBUG 774#ifdef CONFIG_VIDEO_ADV_DEBUG
775 .g_register = mt9v022_g_register, 775 .g_register = mt9v022_g_register,
776 .s_register = mt9v022_s_register, 776 .s_register = mt9v022_s_register,
@@ -858,7 +858,7 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
858 return 0; 858 return 0;
859} 859}
860 860
861static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 861static const struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
862 .s_stream = mt9v022_s_stream, 862 .s_stream = mt9v022_s_stream,
863 .g_mbus_config = mt9v022_g_mbus_config, 863 .g_mbus_config = mt9v022_g_mbus_config,
864 .s_mbus_config = mt9v022_s_mbus_config, 864 .s_mbus_config = mt9v022_s_mbus_config,
@@ -876,7 +876,7 @@ static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = {
876 .set_fmt = mt9v022_set_fmt, 876 .set_fmt = mt9v022_set_fmt,
877}; 877};
878 878
879static struct v4l2_subdev_ops mt9v022_subdev_ops = { 879static const struct v4l2_subdev_ops mt9v022_subdev_ops = {
880 .core = &mt9v022_subdev_core_ops, 880 .core = &mt9v022_subdev_core_ops,
881 .video = &mt9v022_subdev_video_ops, 881 .video = &mt9v022_subdev_video_ops,
882 .sensor = &mt9v022_subdev_sensor_ops, 882 .sensor = &mt9v022_subdev_sensor_ops,
diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
index 3d185bd622a3..39f420db9c70 100644
--- a/drivers/media/i2c/soc_camera/ov5642.c
+++ b/drivers/media/i2c/soc_camera/ov5642.c
@@ -811,7 +811,7 @@ static int ov5642_set_fmt(struct v4l2_subdev *sd,
811 mf->field = V4L2_FIELD_NONE; 811 mf->field = V4L2_FIELD_NONE;
812 812
813 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 813 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
814 priv->fmt = ov5642_find_datafmt(mf->code); 814 priv->fmt = fmt;
815 else 815 else
816 cfg->try_fmt = *mf; 816 cfg->try_fmt = *mf;
817 return 0; 817 return 0;
@@ -943,7 +943,7 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on)
943 return ret; 943 return ret;
944} 944}
945 945
946static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { 946static const struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
947 .g_mbus_config = ov5642_g_mbus_config, 947 .g_mbus_config = ov5642_g_mbus_config,
948}; 948};
949 949
@@ -955,7 +955,7 @@ static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = {
955 .set_fmt = ov5642_set_fmt, 955 .set_fmt = ov5642_set_fmt,
956}; 956};
957 957
958static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { 958static const struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
959 .s_power = ov5642_s_power, 959 .s_power = ov5642_s_power,
960#ifdef CONFIG_VIDEO_ADV_DEBUG 960#ifdef CONFIG_VIDEO_ADV_DEBUG
961 .g_register = ov5642_get_register, 961 .g_register = ov5642_get_register,
@@ -963,7 +963,7 @@ static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
963#endif 963#endif
964}; 964};
965 965
966static struct v4l2_subdev_ops ov5642_subdev_ops = { 966static const struct v4l2_subdev_ops ov5642_subdev_ops = {
967 .core = &ov5642_subdev_core_ops, 967 .core = &ov5642_subdev_core_ops,
968 .video = &ov5642_subdev_video_ops, 968 .video = &ov5642_subdev_video_ops,
969 .pad = &ov5642_subdev_pad_ops, 969 .pad = &ov5642_subdev_pad_ops,
@@ -1063,9 +1063,18 @@ static const struct i2c_device_id ov5642_id[] = {
1063}; 1063};
1064MODULE_DEVICE_TABLE(i2c, ov5642_id); 1064MODULE_DEVICE_TABLE(i2c, ov5642_id);
1065 1065
1066#if IS_ENABLED(CONFIG_OF)
1067static const struct of_device_id ov5642_of_match[] = {
1068 { .compatible = "ovti,ov5642" },
1069 { },
1070};
1071MODULE_DEVICE_TABLE(of, ov5642_of_match);
1072#endif
1073
1066static struct i2c_driver ov5642_i2c_driver = { 1074static struct i2c_driver ov5642_i2c_driver = {
1067 .driver = { 1075 .driver = {
1068 .name = "ov5642", 1076 .name = "ov5642",
1077 .of_match_table = of_match_ptr(ov5642_of_match),
1069 }, 1078 },
1070 .probe = ov5642_probe, 1079 .probe = ov5642_probe,
1071 .remove = ov5642_remove, 1080 .remove = ov5642_remove,
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index 4bf2995e1cb8..dbd6d92c589f 100644
--- a/drivers/media/i2c/soc_camera/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -885,7 +885,7 @@ static const struct v4l2_ctrl_ops ov6550_ctrl_ops = {
885 .s_ctrl = ov6550_s_ctrl, 885 .s_ctrl = ov6550_s_ctrl,
886}; 886};
887 887
888static struct v4l2_subdev_core_ops ov6650_core_ops = { 888static const struct v4l2_subdev_core_ops ov6650_core_ops = {
889#ifdef CONFIG_VIDEO_ADV_DEBUG 889#ifdef CONFIG_VIDEO_ADV_DEBUG
890 .g_register = ov6650_get_register, 890 .g_register = ov6650_get_register,
891 .s_register = ov6650_set_register, 891 .s_register = ov6650_set_register,
@@ -942,7 +942,7 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
942 return ret; 942 return ret;
943} 943}
944 944
945static struct v4l2_subdev_video_ops ov6650_video_ops = { 945static const struct v4l2_subdev_video_ops ov6650_video_ops = {
946 .s_stream = ov6650_s_stream, 946 .s_stream = ov6650_s_stream,
947 .g_parm = ov6650_g_parm, 947 .g_parm = ov6650_g_parm,
948 .s_parm = ov6650_s_parm, 948 .s_parm = ov6650_s_parm,
@@ -958,7 +958,7 @@ static const struct v4l2_subdev_pad_ops ov6650_pad_ops = {
958 .set_fmt = ov6650_set_fmt, 958 .set_fmt = ov6650_set_fmt,
959}; 959};
960 960
961static struct v4l2_subdev_ops ov6650_subdev_ops = { 961static const struct v4l2_subdev_ops ov6650_subdev_ops = {
962 .core = &ov6650_core_ops, 962 .core = &ov6650_core_ops,
963 .video = &ov6650_video_ops, 963 .video = &ov6650_video_ops,
964 .pad = &ov6650_pad_ops, 964 .pad = &ov6650_pad_ops,
@@ -1033,7 +1033,7 @@ static int ov6650_probe(struct i2c_client *client,
1033 priv->code = MEDIA_BUS_FMT_YUYV8_2X8; 1033 priv->code = MEDIA_BUS_FMT_YUYV8_2X8;
1034 priv->colorspace = V4L2_COLORSPACE_JPEG; 1034 priv->colorspace = V4L2_COLORSPACE_JPEG;
1035 1035
1036 priv->clk = v4l2_clk_get(&client->dev, "mclk"); 1036 priv->clk = v4l2_clk_get(&client->dev, NULL);
1037 if (IS_ERR(priv->clk)) { 1037 if (IS_ERR(priv->clk)) {
1038 ret = PTR_ERR(priv->clk); 1038 ret = PTR_ERR(priv->clk);
1039 goto eclkget; 1039 goto eclkget;
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index 985a3672b243..0f7b9d1b9c57 100644
--- a/drivers/media/i2c/soc_camera/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -894,38 +894,15 @@ static int ov772x_get_fmt(struct v4l2_subdev *sd,
894 return 0; 894 return 0;
895} 895}
896 896
897static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
898{
899 struct ov772x_priv *priv = to_ov772x(sd);
900 const struct ov772x_color_format *cfmt;
901 const struct ov772x_win_size *win;
902 int ret;
903
904 ov772x_select_params(mf, &cfmt, &win);
905
906 ret = ov772x_set_params(priv, cfmt, win);
907 if (ret < 0)
908 return ret;
909
910 priv->win = win;
911 priv->cfmt = cfmt;
912
913 mf->code = cfmt->code;
914 mf->width = win->rect.width;
915 mf->height = win->rect.height;
916 mf->field = V4L2_FIELD_NONE;
917 mf->colorspace = cfmt->colorspace;
918
919 return 0;
920}
921
922static int ov772x_set_fmt(struct v4l2_subdev *sd, 897static int ov772x_set_fmt(struct v4l2_subdev *sd,
923 struct v4l2_subdev_pad_config *cfg, 898 struct v4l2_subdev_pad_config *cfg,
924 struct v4l2_subdev_format *format) 899 struct v4l2_subdev_format *format)
925{ 900{
901 struct ov772x_priv *priv = to_ov772x(sd);
926 struct v4l2_mbus_framefmt *mf = &format->format; 902 struct v4l2_mbus_framefmt *mf = &format->format;
927 const struct ov772x_color_format *cfmt; 903 const struct ov772x_color_format *cfmt;
928 const struct ov772x_win_size *win; 904 const struct ov772x_win_size *win;
905 int ret;
929 906
930 if (format->pad) 907 if (format->pad)
931 return -EINVAL; 908 return -EINVAL;
@@ -938,9 +915,17 @@ static int ov772x_set_fmt(struct v4l2_subdev *sd,
938 mf->field = V4L2_FIELD_NONE; 915 mf->field = V4L2_FIELD_NONE;
939 mf->colorspace = cfmt->colorspace; 916 mf->colorspace = cfmt->colorspace;
940 917
941 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 918 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
942 return ov772x_s_fmt(sd, mf); 919 cfg->try_fmt = *mf;
943 cfg->try_fmt = *mf; 920 return 0;
921 }
922
923 ret = ov772x_set_params(priv, cfmt, win);
924 if (ret < 0)
925 return ret;
926
927 priv->win = win;
928 priv->cfmt = cfmt;
944 return 0; 929 return 0;
945} 930}
946 931
@@ -993,7 +978,7 @@ static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
993 .s_ctrl = ov772x_s_ctrl, 978 .s_ctrl = ov772x_s_ctrl,
994}; 979};
995 980
996static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { 981static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
997#ifdef CONFIG_VIDEO_ADV_DEBUG 982#ifdef CONFIG_VIDEO_ADV_DEBUG
998 .g_register = ov772x_g_register, 983 .g_register = ov772x_g_register,
999 .s_register = ov772x_s_register, 984 .s_register = ov772x_s_register,
@@ -1027,7 +1012,7 @@ static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
1027 return 0; 1012 return 0;
1028} 1013}
1029 1014
1030static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1015static const struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1031 .s_stream = ov772x_s_stream, 1016 .s_stream = ov772x_s_stream,
1032 .g_mbus_config = ov772x_g_mbus_config, 1017 .g_mbus_config = ov772x_g_mbus_config,
1033}; 1018};
@@ -1039,7 +1024,7 @@ static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = {
1039 .set_fmt = ov772x_set_fmt, 1024 .set_fmt = ov772x_set_fmt,
1040}; 1025};
1041 1026
1042static struct v4l2_subdev_ops ov772x_subdev_ops = { 1027static const struct v4l2_subdev_ops ov772x_subdev_ops = {
1043 .core = &ov772x_subdev_core_ops, 1028 .core = &ov772x_subdev_core_ops,
1044 .video = &ov772x_subdev_video_ops, 1029 .video = &ov772x_subdev_video_ops,
1045 .pad = &ov772x_subdev_pad_ops, 1030 .pad = &ov772x_subdev_pad_ops,
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 65085a235128..0146d1f7aacb 100644
--- a/drivers/media/i2c/soc_camera/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -486,11 +486,8 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd,
486{ 486{
487 struct i2c_client *client = v4l2_get_subdevdata(sd); 487 struct i2c_client *client = v4l2_get_subdevdata(sd);
488 struct ov9640_reg_alt alts = {0}; 488 struct ov9640_reg_alt alts = {0};
489 enum v4l2_colorspace cspace;
490 u32 code = mf->code;
491 int ret; 489 int ret;
492 490
493 ov9640_res_roundup(&mf->width, &mf->height);
494 ov9640_alter_regs(mf->code, &alts); 491 ov9640_alter_regs(mf->code, &alts);
495 492
496 ov9640_reset(client); 493 ov9640_reset(client);
@@ -499,24 +496,7 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd,
499 if (ret) 496 if (ret)
500 return ret; 497 return ret;
501 498
502 switch (code) { 499 return ov9640_write_regs(client, mf->width, mf->code, &alts);
503 case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
504 case MEDIA_BUS_FMT_RGB565_2X8_LE:
505 cspace = V4L2_COLORSPACE_SRGB;
506 break;
507 default:
508 code = MEDIA_BUS_FMT_UYVY8_2X8;
509 case MEDIA_BUS_FMT_UYVY8_2X8:
510 cspace = V4L2_COLORSPACE_JPEG;
511 }
512
513 ret = ov9640_write_regs(client, mf->width, code, &alts);
514 if (!ret) {
515 mf->code = code;
516 mf->colorspace = cspace;
517 }
518
519 return ret;
520} 500}
521 501
522static int ov9640_set_fmt(struct v4l2_subdev *sd, 502static int ov9640_set_fmt(struct v4l2_subdev *sd,
@@ -539,8 +519,10 @@ static int ov9640_set_fmt(struct v4l2_subdev *sd,
539 break; 519 break;
540 default: 520 default:
541 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; 521 mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
522 /* fall through */
542 case MEDIA_BUS_FMT_UYVY8_2X8: 523 case MEDIA_BUS_FMT_UYVY8_2X8:
543 mf->colorspace = V4L2_COLORSPACE_JPEG; 524 mf->colorspace = V4L2_COLORSPACE_JPEG;
525 break;
544 } 526 }
545 527
546 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) 528 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
@@ -637,7 +619,7 @@ static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
637 .s_ctrl = ov9640_s_ctrl, 619 .s_ctrl = ov9640_s_ctrl,
638}; 620};
639 621
640static struct v4l2_subdev_core_ops ov9640_core_ops = { 622static const struct v4l2_subdev_core_ops ov9640_core_ops = {
641#ifdef CONFIG_VIDEO_ADV_DEBUG 623#ifdef CONFIG_VIDEO_ADV_DEBUG
642 .g_register = ov9640_get_register, 624 .g_register = ov9640_get_register,
643 .s_register = ov9640_set_register, 625 .s_register = ov9640_set_register,
@@ -661,7 +643,7 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
661 return 0; 643 return 0;
662} 644}
663 645
664static struct v4l2_subdev_video_ops ov9640_video_ops = { 646static const struct v4l2_subdev_video_ops ov9640_video_ops = {
665 .s_stream = ov9640_s_stream, 647 .s_stream = ov9640_s_stream,
666 .g_mbus_config = ov9640_g_mbus_config, 648 .g_mbus_config = ov9640_g_mbus_config,
667}; 649};
@@ -672,7 +654,7 @@ static const struct v4l2_subdev_pad_ops ov9640_pad_ops = {
672 .set_fmt = ov9640_set_fmt, 654 .set_fmt = ov9640_set_fmt,
673}; 655};
674 656
675static struct v4l2_subdev_ops ov9640_subdev_ops = { 657static const struct v4l2_subdev_ops ov9640_subdev_ops = {
676 .core = &ov9640_core_ops, 658 .core = &ov9640_core_ops,
677 .video = &ov9640_video_ops, 659 .video = &ov9640_video_ops,
678 .pad = &ov9640_pad_ops, 660 .pad = &ov9640_pad_ops,
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index f11f76cdacad..cc07b7ae5407 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -673,20 +673,8 @@ static int ov9740_s_fmt(struct v4l2_subdev *sd,
673{ 673{
674 struct i2c_client *client = v4l2_get_subdevdata(sd); 674 struct i2c_client *client = v4l2_get_subdevdata(sd);
675 struct ov9740_priv *priv = to_ov9740(sd); 675 struct ov9740_priv *priv = to_ov9740(sd);
676 enum v4l2_colorspace cspace;
677 u32 code = mf->code;
678 int ret; 676 int ret;
679 677
680 ov9740_res_roundup(&mf->width, &mf->height);
681
682 switch (code) {
683 case MEDIA_BUS_FMT_YUYV8_2X8:
684 cspace = V4L2_COLORSPACE_SRGB;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 ret = ov9740_reg_write_array(client, ov9740_defaults, 678 ret = ov9740_reg_write_array(client, ov9740_defaults,
691 ARRAY_SIZE(ov9740_defaults)); 679 ARRAY_SIZE(ov9740_defaults));
692 if (ret < 0) 680 if (ret < 0)
@@ -696,11 +684,7 @@ static int ov9740_s_fmt(struct v4l2_subdev *sd,
696 if (ret < 0) 684 if (ret < 0)
697 return ret; 685 return ret;
698 686
699 mf->code = code; 687 priv->current_mf = *mf;
700 mf->colorspace = cspace;
701
702 memcpy(&priv->current_mf, mf, sizeof(struct v4l2_mbus_framefmt));
703
704 return ret; 688 return ret;
705} 689}
706 690
@@ -907,12 +891,12 @@ static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
907 return 0; 891 return 0;
908} 892}
909 893
910static struct v4l2_subdev_video_ops ov9740_video_ops = { 894static const struct v4l2_subdev_video_ops ov9740_video_ops = {
911 .s_stream = ov9740_s_stream, 895 .s_stream = ov9740_s_stream,
912 .g_mbus_config = ov9740_g_mbus_config, 896 .g_mbus_config = ov9740_g_mbus_config,
913}; 897};
914 898
915static struct v4l2_subdev_core_ops ov9740_core_ops = { 899static const struct v4l2_subdev_core_ops ov9740_core_ops = {
916 .s_power = ov9740_s_power, 900 .s_power = ov9740_s_power,
917#ifdef CONFIG_VIDEO_ADV_DEBUG 901#ifdef CONFIG_VIDEO_ADV_DEBUG
918 .g_register = ov9740_get_register, 902 .g_register = ov9740_get_register,
@@ -926,7 +910,7 @@ static const struct v4l2_subdev_pad_ops ov9740_pad_ops = {
926 .set_fmt = ov9740_set_fmt, 910 .set_fmt = ov9740_set_fmt,
927}; 911};
928 912
929static struct v4l2_subdev_ops ov9740_subdev_ops = { 913static const struct v4l2_subdev_ops ov9740_subdev_ops = {
930 .core = &ov9740_core_ops, 914 .core = &ov9740_core_ops,
931 .video = &ov9740_video_ops, 915 .video = &ov9740_video_ops,
932 .pad = &ov9740_pad_ops, 916 .pad = &ov9740_pad_ops,
diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index bc8ec59a3fbd..02398d0bc649 100644
--- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c
+++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -1213,7 +1213,7 @@ static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
1213 .s_ctrl = rj54n1_s_ctrl, 1213 .s_ctrl = rj54n1_s_ctrl,
1214}; 1214};
1215 1215
1216static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { 1216static const struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1217#ifdef CONFIG_VIDEO_ADV_DEBUG 1217#ifdef CONFIG_VIDEO_ADV_DEBUG
1218 .g_register = rj54n1_g_register, 1218 .g_register = rj54n1_g_register,
1219 .s_register = rj54n1_s_register, 1219 .s_register = rj54n1_s_register,
@@ -1251,7 +1251,7 @@ static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
1251 return reg_write(client, RJ54N1_OUT_SIGPO, 0); 1251 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
1252} 1252}
1253 1253
1254static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { 1254static const struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1255 .s_stream = rj54n1_s_stream, 1255 .s_stream = rj54n1_s_stream,
1256 .g_mbus_config = rj54n1_g_mbus_config, 1256 .g_mbus_config = rj54n1_g_mbus_config,
1257 .s_mbus_config = rj54n1_s_mbus_config, 1257 .s_mbus_config = rj54n1_s_mbus_config,
@@ -1265,7 +1265,7 @@ static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = {
1265 .set_fmt = rj54n1_set_fmt, 1265 .set_fmt = rj54n1_set_fmt,
1266}; 1266};
1267 1267
1268static struct v4l2_subdev_ops rj54n1_subdev_ops = { 1268static const struct v4l2_subdev_ops rj54n1_subdev_ops = {
1269 .core = &rj54n1_subdev_core_ops, 1269 .core = &rj54n1_subdev_core_ops,
1270 .video = &rj54n1_subdev_video_ops, 1270 .video = &rj54n1_subdev_video_ops,
1271 .pad = &rj54n1_subdev_pad_ops, 1271 .pad = &rj54n1_subdev_pad_ops,
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
index c9c49ed707b8..bdb5e0a431e9 100644
--- a/drivers/media/i2c/soc_camera/tw9910.c
+++ b/drivers/media/i2c/soc_camera/tw9910.c
@@ -837,7 +837,7 @@ done:
837 return ret; 837 return ret;
838} 838}
839 839
840static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { 840static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
841#ifdef CONFIG_VIDEO_ADV_DEBUG 841#ifdef CONFIG_VIDEO_ADV_DEBUG
842 .g_register = tw9910_g_register, 842 .g_register = tw9910_g_register,
843 .s_register = tw9910_s_register, 843 .s_register = tw9910_s_register,
@@ -901,7 +901,7 @@ static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
901 return 0; 901 return 0;
902} 902}
903 903
904static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { 904static const struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
905 .s_std = tw9910_s_std, 905 .s_std = tw9910_s_std,
906 .g_std = tw9910_g_std, 906 .g_std = tw9910_g_std,
907 .s_stream = tw9910_s_stream, 907 .s_stream = tw9910_s_stream,
@@ -917,7 +917,7 @@ static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
917 .set_fmt = tw9910_set_fmt, 917 .set_fmt = tw9910_set_fmt,
918}; 918};
919 919
920static struct v4l2_subdev_ops tw9910_subdev_ops = { 920static const struct v4l2_subdev_ops tw9910_subdev_ops = {
921 .core = &tw9910_subdev_core_ops, 921 .core = &tw9910_subdev_core_ops,
922 .video = &tw9910_subdev_video_ops, 922 .video = &tw9910_subdev_video_ops,
923 .pad = &tw9910_subdev_pad_ops, 923 .pad = &tw9910_subdev_pad_ops,
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index f569a05fe105..acef4eca269f 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -194,57 +194,61 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
194 } 194 }
195} 195}
196 196
197static u8 i2c_rd8(struct v4l2_subdev *sd, u16 reg) 197static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
198{ 198{
199 u8 val; 199 __le32 val = 0;
200
201 i2c_rd(sd, reg, (u8 __force *)&val, n);
200 202
201 i2c_rd(sd, reg, &val, 1); 203 return le32_to_cpu(val);
204}
205
206static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)
207{
208 __le32 raw = cpu_to_le32(val);
202 209
203 return val; 210 i2c_wr(sd, reg, (u8 __force *)&raw, n);
211}
212
213static u8 i2c_rd8(struct v4l2_subdev *sd, u16 reg)
214{
215 return i2c_rdreg(sd, reg, 1);
204} 216}
205 217
206static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val) 218static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val)
207{ 219{
208 i2c_wr(sd, reg, &val, 1); 220 i2c_wrreg(sd, reg, val, 1);
209} 221}
210 222
211static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg, 223static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg,
212 u8 mask, u8 val) 224 u8 mask, u8 val)
213{ 225{
214 i2c_wr8(sd, reg, (i2c_rd8(sd, reg) & mask) | val); 226 i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2);
215} 227}
216 228
217static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) 229static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)
218{ 230{
219 u16 val; 231 return i2c_rdreg(sd, reg, 2);
220
221 i2c_rd(sd, reg, (u8 *)&val, 2);
222
223 return val;
224} 232}
225 233
226static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val) 234static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)
227{ 235{
228 i2c_wr(sd, reg, (u8 *)&val, 2); 236 i2c_wrreg(sd, reg, val, 2);
229} 237}
230 238
231static void i2c_wr16_and_or(struct v4l2_subdev *sd, u16 reg, u16 mask, u16 val) 239static void i2c_wr16_and_or(struct v4l2_subdev *sd, u16 reg, u16 mask, u16 val)
232{ 240{
233 i2c_wr16(sd, reg, (i2c_rd16(sd, reg) & mask) | val); 241 i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2);
234} 242}
235 243
236static u32 i2c_rd32(struct v4l2_subdev *sd, u16 reg) 244static u32 i2c_rd32(struct v4l2_subdev *sd, u16 reg)
237{ 245{
238 u32 val; 246 return i2c_rdreg(sd, reg, 4);
239
240 i2c_rd(sd, reg, (u8 *)&val, 4);
241
242 return val;
243} 247}
244 248
245static void i2c_wr32(struct v4l2_subdev *sd, u16 reg, u32 val) 249static void i2c_wr32(struct v4l2_subdev *sd, u16 reg, u32 val)
246{ 250{
247 i2c_wr(sd, reg, (u8 *)&val, 4); 251 i2c_wrreg(sd, reg, val, 4);
248} 252}
249 253
250/* --------------- STATUS --------------- */ 254/* --------------- STATUS --------------- */
@@ -1227,7 +1231,7 @@ static int tc358743_g_register(struct v4l2_subdev *sd,
1227 1231
1228 reg->size = tc358743_get_reg_size(reg->reg); 1232 reg->size = tc358743_get_reg_size(reg->reg);
1229 1233
1230 i2c_rd(sd, reg->reg, (u8 *)&reg->val, reg->size); 1234 reg->val = i2c_rdreg(sd, reg->reg, reg->size);
1231 1235
1232 return 0; 1236 return 0;
1233} 1237}
@@ -1253,7 +1257,7 @@ static int tc358743_s_register(struct v4l2_subdev *sd,
1253 reg->reg == BCAPS) 1257 reg->reg == BCAPS)
1254 return 0; 1258 return 0;
1255 1259
1256 i2c_wr(sd, (u16)reg->reg, (u8 *)&reg->val, 1260 i2c_wrreg(sd, (u16)reg->reg, reg->val,
1257 tc358743_get_reg_size(reg->reg)); 1261 tc358743_get_reg_size(reg->reg));
1258 1262
1259 return 0; 1263 return 0;
@@ -1459,6 +1463,10 @@ static int tc358743_g_mbus_config(struct v4l2_subdev *sd,
1459static int tc358743_s_stream(struct v4l2_subdev *sd, int enable) 1463static int tc358743_s_stream(struct v4l2_subdev *sd, int enable)
1460{ 1464{
1461 enable_stream(sd, enable); 1465 enable_stream(sd, enable);
1466 if (!enable) {
1467 /* Put all lanes in PL-11 state (STOPSTATE) */
1468 tc358743_set_csi(sd);
1469 }
1462 1470
1463 return 0; 1471 return 0;
1464} 1472}
@@ -1951,9 +1959,18 @@ static struct i2c_device_id tc358743_id[] = {
1951 1959
1952MODULE_DEVICE_TABLE(i2c, tc358743_id); 1960MODULE_DEVICE_TABLE(i2c, tc358743_id);
1953 1961
1962#if IS_ENABLED(CONFIG_OF)
1963static const struct of_device_id tc358743_of_match[] = {
1964 { .compatible = "toshiba,tc358743" },
1965 {},
1966};
1967MODULE_DEVICE_TABLE(of, tc358743_of_match);
1968#endif
1969
1954static struct i2c_driver tc358743_driver = { 1970static struct i2c_driver tc358743_driver = {
1955 .driver = { 1971 .driver = {
1956 .name = "tc358743", 1972 .name = "tc358743",
1973 .of_match_table = of_match_ptr(tc358743_of_match),
1957 }, 1974 },
1958 .probe = tc358743_probe, 1975 .probe = tc358743_probe,
1959 .remove = tc358743_remove, 1976 .remove = tc358743_remove,
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 48646a7f3fb0..04e96b3057bb 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -865,13 +865,13 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
865 struct v4l2_mbus_framefmt *f; 865 struct v4l2_mbus_framefmt *f;
866 struct tvp5150 *decoder = to_tvp5150(sd); 866 struct tvp5150 *decoder = to_tvp5150(sd);
867 867
868 if (!format || format->pad) 868 if (!format || (format->pad != DEMOD_PAD_VID_OUT))
869 return -EINVAL; 869 return -EINVAL;
870 870
871 f = &format->format; 871 f = &format->format;
872 872
873 f->width = decoder->rect.width; 873 f->width = decoder->rect.width;
874 f->height = decoder->rect.height / 2; 874 f->height = decoder->rect.height;
875 875
876 f->code = MEDIA_BUS_FMT_UYVY8_2X8; 876 f->code = MEDIA_BUS_FMT_UYVY8_2X8;
877 f->field = V4L2_FIELD_ALTERNATE; 877 f->field = V4L2_FIELD_ALTERNATE;
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 5640ca29da8c..bc44193efa47 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -199,12 +199,12 @@ void media_gobj_create(struct media_device *mdev,
199 199
200void media_gobj_destroy(struct media_gobj *gobj) 200void media_gobj_destroy(struct media_gobj *gobj)
201{ 201{
202 dev_dbg_obj(__func__, gobj);
203
204 /* Do nothing if the object is not linked. */ 202 /* Do nothing if the object is not linked. */
205 if (gobj->mdev == NULL) 203 if (gobj->mdev == NULL)
206 return; 204 return;
207 205
206 dev_dbg_obj(__func__, gobj);
207
208 gobj->mdev->topology_version++; 208 gobj->mdev->topology_version++;
209 209
210 /* Remove the object from mdev list */ 210 /* Remove the object from mdev list */
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index a1b0f3193bc0..5cc42b426715 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -3717,7 +3717,7 @@ static void hauppauge_eeprom(struct bttv *btv)
3717{ 3717{
3718 struct tveeprom tv; 3718 struct tveeprom tv;
3719 3719
3720 tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data); 3720 tveeprom_hauppauge_analog(&tv, eeprom_data);
3721 btv->tuner_type = tv.tuner_type; 3721 btv->tuner_type = tv.tuner_type;
3722 btv->has_radio = tv.has_radio; 3722 btv->has_radio = tv.has_radio;
3723 3723
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index fb4aefbcc8f8..ed319f18ba48 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -4043,9 +4043,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
4043 INIT_LIST_HEAD(&btv->capture); 4043 INIT_LIST_HEAD(&btv->capture);
4044 INIT_LIST_HEAD(&btv->vcapture); 4044 INIT_LIST_HEAD(&btv->vcapture);
4045 4045
4046 init_timer(&btv->timeout); 4046 setup_timer(&btv->timeout, bttv_irq_timeout, (unsigned long)btv);
4047 btv->timeout.function = bttv_irq_timeout;
4048 btv->timeout.data = (unsigned long)btv;
4049 4047
4050 btv->i2c_rc = -1; 4048 btv->i2c_rc = -1;
4051 btv->tuner_type = UNSET; 4049 btv->tuner_type = UNSET;
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
index 206db81ef78e..8bce49cdad46 100644
--- a/drivers/media/pci/cx18/cx18-driver.c
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -339,7 +339,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
339 case CX18_CARD_HVR_1600_ESMT: 339 case CX18_CARD_HVR_1600_ESMT:
340 case CX18_CARD_HVR_1600_SAMSUNG: 340 case CX18_CARD_HVR_1600_SAMSUNG:
341 case CX18_CARD_HVR_1600_S5H1411: 341 case CX18_CARD_HVR_1600_S5H1411:
342 tveeprom_hauppauge_analog(c, tv, eedata); 342 tveeprom_hauppauge_analog(tv, eedata);
343 break; 343 break;
344 case CX18_CARD_YUAN_MPC718: 344 case CX18_CARD_YUAN_MPC718:
345 case CX18_CARD_GOTVIEW_PCI_DVD3: 345 case CX18_CARD_GOTVIEW_PCI_DVD3:
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index 7c9381448966..3c45e0071530 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -282,9 +282,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
282 INIT_WORK(&s->out_work_order, cx18_out_work_handler); 282 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
283 283
284 INIT_LIST_HEAD(&s->vb_capture); 284 INIT_LIST_HEAD(&s->vb_capture);
285 s->vb_timeout.function = cx18_vb_timeout; 285 setup_timer(&s->vb_timeout, cx18_vb_timeout, (unsigned long)s);
286 s->vb_timeout.data = (unsigned long)s;
287 init_timer(&s->vb_timeout);
288 spin_lock_init(&s->vb_lock); 286 spin_lock_init(&s->vb_lock);
289 if (type == CX18_ENC_STREAM_TYPE_YUV) { 287 if (type == CX18_ENC_STREAM_TYPE_YUV) {
290 spin_lock_init(&s->vbuf_q_lock); 288 spin_lock_init(&s->vbuf_q_lock);
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 0350f13c5a9f..9e39aea85df6 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -1143,8 +1143,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
1143{ 1143{
1144 struct tveeprom tv; 1144 struct tveeprom tv;
1145 1145
1146 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, 1146 tveeprom_hauppauge_analog(&tv, eeprom_data);
1147 eeprom_data);
1148 1147
1149 /* Make sure we support the board model */ 1148 /* Make sure we support the board model */
1150 switch (tv.model) { 1149 switch (tv.model) {
diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
index cdfbde277b8b..73cc7a67a8bc 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -2854,7 +2854,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
2854{ 2854{
2855 struct tveeprom tv; 2855 struct tveeprom tv;
2856 2856
2857 tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); 2857 tveeprom_hauppauge_analog(&tv, eeprom_data);
2858 core->board.tuner_type = tv.tuner_type; 2858 core->board.tuner_type = tv.tuner_type;
2859 core->tuner_formats = tv.tuner_formats; 2859 core->tuner_formats = tv.tuner_formats;
2860 core->board.radio.type = tv.has_radio ? CX88_RADIO : 0; 2860 core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
@@ -3670,7 +3670,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
3670 if (!core) 3670 if (!core)
3671 return NULL; 3671 return NULL;
3672 3672
3673 atomic_inc(&core->refcount); 3673 refcount_set(&core->refcount, 1);
3674 core->pci_bus = pci->bus->number; 3674 core->pci_bus = pci->bus->number;
3675 core->pci_slot = PCI_SLOT(pci->devfn); 3675 core->pci_slot = PCI_SLOT(pci->devfn);
3676 core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT | 3676 core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index 973a9cd4c635..8bfa5b7ed91b 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -1052,7 +1052,7 @@ struct cx88_core *cx88_core_get(struct pci_dev *pci)
1052 mutex_unlock(&devlist); 1052 mutex_unlock(&devlist);
1053 return NULL; 1053 return NULL;
1054 } 1054 }
1055 atomic_inc(&core->refcount); 1055 refcount_inc(&core->refcount);
1056 mutex_unlock(&devlist); 1056 mutex_unlock(&devlist);
1057 return core; 1057 return core;
1058 } 1058 }
@@ -1073,7 +1073,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1073 release_mem_region(pci_resource_start(pci, 0), 1073 release_mem_region(pci_resource_start(pci, 0),
1074 pci_resource_len(pci, 0)); 1074 pci_resource_len(pci, 0));
1075 1075
1076 if (!atomic_dec_and_test(&core->refcount)) 1076 if (!refcount_dec_and_test(&core->refcount))
1077 return; 1077 return;
1078 1078
1079 mutex_lock(&devlist); 1079 mutex_lock(&devlist);
diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c
index ddf90678df34..49a335f4603e 100644
--- a/drivers/media/pci/cx88/cx88-dvb.c
+++ b/drivers/media/pci/cx88/cx88-dvb.c
@@ -306,7 +306,7 @@ static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
306 .if2 = 45600, 306 .if2 = 45600,
307}; 307};
308 308
309static struct mb86a16_config twinhan_vp1027 = { 309static const struct mb86a16_config twinhan_vp1027 = {
310 .demod_address = 0x08, 310 .demod_address = 0x08,
311}; 311};
312 312
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 115414cf520f..6777926f20f2 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -24,6 +24,7 @@
24#include <linux/i2c-algo-bit.h> 24#include <linux/i2c-algo-bit.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <linux/kdev_t.h> 26#include <linux/kdev_t.h>
27#include <linux/refcount.h>
27 28
28#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
29#include <media/v4l2-fh.h> 30#include <media/v4l2-fh.h>
@@ -339,7 +340,7 @@ struct cx8802_dev;
339 340
340struct cx88_core { 341struct cx88_core {
341 struct list_head devlist; 342 struct list_head devlist;
342 atomic_t refcount; 343 refcount_t refcount;
343 344
344 /* board name */ 345 /* board name */
345 int nr; 346 int nr;
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index a7724b78fbb4..1d41934cfaf5 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -815,7 +815,7 @@ static void dm1105_hw_exit(struct dm1105_dev *dev)
815 dm1105_dma_unmap(dev); 815 dm1105_dma_unmap(dev);
816} 816}
817 817
818static struct stv0299_config sharp_z0194a_config = { 818static const struct stv0299_config sharp_z0194a_config = {
819 .demod_address = 0x68, 819 .demod_address = 0x68,
820 .inittab = sharp_z0194a_inittab, 820 .inittab = sharp_z0194a_inittab,
821 .mclk = 88000000UL, 821 .mclk = 88000000UL,
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index e73c153285f0..e8fa99b6c7b4 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -409,7 +409,7 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
409 409
410 itv->i2c_client.addr = 0xA0 >> 1; 410 itv->i2c_client.addr = 0xA0 >> 1;
411 tveeprom_read(&itv->i2c_client, eedata, sizeof(eedata)); 411 tveeprom_read(&itv->i2c_client, eedata, sizeof(eedata));
412 tveeprom_hauppauge_analog(&itv->i2c_client, tv, eedata); 412 tveeprom_hauppauge_analog(tv, eedata);
413} 413}
414 414
415static void ivtv_process_eeprom(struct ivtv *itv) 415static void ivtv_process_eeprom(struct ivtv *itv)
@@ -770,9 +770,8 @@ static int ivtv_init_struct1(struct ivtv *itv)
770 init_waitqueue_head(&itv->event_waitq); 770 init_waitqueue_head(&itv->event_waitq);
771 init_waitqueue_head(&itv->vsync_waitq); 771 init_waitqueue_head(&itv->vsync_waitq);
772 init_waitqueue_head(&itv->dma_waitq); 772 init_waitqueue_head(&itv->dma_waitq);
773 init_timer(&itv->dma_timer); 773 setup_timer(&itv->dma_timer, ivtv_unfinished_dma,
774 itv->dma_timer.function = ivtv_unfinished_dma; 774 (unsigned long)itv);
775 itv->dma_timer.data = (unsigned long)itv;
776 775
777 itv->cur_dma_stream = -1; 776 itv->cur_dma_stream = -1;
778 itv->cur_pio_stream = -1; 777 itv->cur_pio_stream = -1;
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index f956188f7f19..670462d195b5 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -1506,10 +1506,8 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subs
1506 case V4L2_EVENT_VSYNC: 1506 case V4L2_EVENT_VSYNC:
1507 case V4L2_EVENT_EOS: 1507 case V4L2_EVENT_EOS:
1508 return v4l2_event_subscribe(fh, sub, 0, NULL); 1508 return v4l2_event_subscribe(fh, sub, 0, NULL);
1509 case V4L2_EVENT_CTRL:
1510 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
1511 default: 1509 default:
1512 return -EINVAL; 1510 return v4l2_ctrl_subscribe_event(fh, sub);
1513 } 1511 }
1514} 1512}
1515 1513
diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
index 2c9232ef7baa..3b33e87ed73b 100644
--- a/drivers/media/pci/ivtv/ivtv-udma.c
+++ b/drivers/media/pci/ivtv/ivtv-udma.c
@@ -76,7 +76,7 @@ void ivtv_udma_fill_sg_array (struct ivtv_user_dma *dma, u32 buffer_offset, u32
76 int i; 76 int i;
77 struct scatterlist *sg; 77 struct scatterlist *sg;
78 78
79 for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg = sg_next(sg)) { 79 for_each_sg(dma->SGlist, sg, dma->SG_length, i) {
80 dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg)); 80 dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg));
81 dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg)); 81 dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg));
82 dma->SGarray[i].dst = cpu_to_le32(buffer_offset); 82 dma->SGarray[i].dst = cpu_to_le32(buffer_offset);
diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c
index 3b1928594b12..e4972ff823c2 100644
--- a/drivers/media/pci/mantis/mantis_vp1034.c
+++ b/drivers/media/pci/mantis/mantis_vp1034.c
@@ -36,7 +36,7 @@
36#include "mantis_vp1034.h" 36#include "mantis_vp1034.h"
37#include "mantis_reg.h" 37#include "mantis_reg.h"
38 38
39static struct mb86a16_config vp1034_mb86a16_config = { 39static const struct mb86a16_config vp1034_mb86a16_config = {
40 .demod_address = 0x08, 40 .demod_address = 0x08,
41 .set_voltage = vp1034_set_voltage, 41 .set_voltage = vp1034_set_voltage,
42}; 42};
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 191bd8299dc3..9444483fb942 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -663,9 +663,8 @@ static int netup_unidvb_dma_init(struct netup_unidvb_dev *ndev, int num)
663 spin_lock_init(&dma->lock); 663 spin_lock_init(&dma->lock);
664 INIT_WORK(&dma->work, netup_unidvb_dma_worker); 664 INIT_WORK(&dma->work, netup_unidvb_dma_worker);
665 INIT_LIST_HEAD(&dma->free_buffers); 665 INIT_LIST_HEAD(&dma->free_buffers);
666 dma->timeout.function = netup_unidvb_dma_timeout; 666 setup_timer(&dma->timeout, netup_unidvb_dma_timeout,
667 dma->timeout.data = (unsigned long)dma; 667 (unsigned long)dma);
668 init_timer(&dma->timeout);
669 dma->ring_buffer_size = ndev->dma_size / 2; 668 dma->ring_buffer_size = ndev->dma_size / 2;
670 dma->addr_virt = ndev->dma_virt + dma->ring_buffer_size * num; 669 dma->addr_virt = ndev->dma_virt + dma->ring_buffer_size * num;
671 dma->addr_phys = (dma_addr_t)((u64)ndev->dma_phys + 670 dma->addr_phys = (dma_addr_t)((u64)ndev->dma_phys +
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index 321253827997..f79380faf499 100644
--- a/drivers/media/pci/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
@@ -7319,7 +7319,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
7319{ 7319{
7320 struct tveeprom tv; 7320 struct tveeprom tv;
7321 7321
7322 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); 7322 tveeprom_hauppauge_analog(&tv, eeprom_data);
7323 7323
7324 /* Make sure we support the board model */ 7324 /* Make sure we support the board model */
7325 switch (tv.model) { 7325 switch (tv.model) {
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index efdece5ab11c..731dee0a66e7 100644
--- a/drivers/media/pci/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -1042,11 +1042,11 @@ static int md8800_set_high_voltage2(struct dvb_frontend *fe, long arg)
1042 * nxt200x based ATSC cards, helper functions 1042 * nxt200x based ATSC cards, helper functions
1043 */ 1043 */
1044 1044
1045static struct nxt200x_config avertvhda180 = { 1045static const struct nxt200x_config avertvhda180 = {
1046 .demod_address = 0x0a, 1046 .demod_address = 0x0a,
1047}; 1047};
1048 1048
1049static struct nxt200x_config kworldatsc110 = { 1049static const struct nxt200x_config kworldatsc110 = {
1050 .demod_address = 0x0a, 1050 .demod_address = 0x0a,
1051}; 1051};
1052 1052
diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c
index 578e03f8c041..7414878af9e0 100644
--- a/drivers/media/pci/saa7134/saa7134-ts.c
+++ b/drivers/media/pci/saa7134/saa7134-ts.c
@@ -223,9 +223,8 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
223 dev->ts.nr_packets = ts_nr_packets; 223 dev->ts.nr_packets = ts_nr_packets;
224 224
225 INIT_LIST_HEAD(&dev->ts_q.queue); 225 INIT_LIST_HEAD(&dev->ts_q.queue);
226 init_timer(&dev->ts_q.timeout); 226 setup_timer(&dev->ts_q.timeout, saa7134_buffer_timeout,
227 dev->ts_q.timeout.function = saa7134_buffer_timeout; 227 (unsigned long)(&dev->ts_q));
228 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
229 dev->ts_q.dev = dev; 228 dev->ts_q.dev = dev;
230 dev->ts_q.need_two = 1; 229 dev->ts_q.need_two = 1;
231 dev->ts_started = 0; 230 dev->ts_started = 0;
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c
index 46193370e41a..bcad9b2d9bb3 100644
--- a/drivers/media/pci/saa7134/saa7134-vbi.c
+++ b/drivers/media/pci/saa7134/saa7134-vbi.c
@@ -181,9 +181,8 @@ struct vb2_ops saa7134_vbi_qops = {
181int saa7134_vbi_init1(struct saa7134_dev *dev) 181int saa7134_vbi_init1(struct saa7134_dev *dev)
182{ 182{
183 INIT_LIST_HEAD(&dev->vbi_q.queue); 183 INIT_LIST_HEAD(&dev->vbi_q.queue);
184 init_timer(&dev->vbi_q.timeout); 184 setup_timer(&dev->vbi_q.timeout, saa7134_buffer_timeout,
185 dev->vbi_q.timeout.function = saa7134_buffer_timeout; 185 (unsigned long)(&dev->vbi_q));
186 dev->vbi_q.timeout.data = (unsigned long)(&dev->vbi_q);
187 dev->vbi_q.dev = dev; 186 dev->vbi_q.dev = dev;
188 187
189 if (vbibufs < 2) 188 if (vbibufs < 2)
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 4b1c4327f112..51d42bbf969e 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -2145,9 +2145,8 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2145 dev->automute = 0; 2145 dev->automute = 0;
2146 2146
2147 INIT_LIST_HEAD(&dev->video_q.queue); 2147 INIT_LIST_HEAD(&dev->video_q.queue);
2148 init_timer(&dev->video_q.timeout); 2148 setup_timer(&dev->video_q.timeout, saa7134_buffer_timeout,
2149 dev->video_q.timeout.function = saa7134_buffer_timeout; 2149 (unsigned long)(&dev->video_q));
2150 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
2151 dev->video_q.dev = dev; 2150 dev->video_q.dev = dev;
2152 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); 2151 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
2153 dev->width = 720; 2152 dev->width = 720;
diff --git a/drivers/media/pci/saa7164/saa7164-cards.c b/drivers/media/pci/saa7164/saa7164-cards.c
index 0e1cd7e153ca..3af16062e79d 100644
--- a/drivers/media/pci/saa7164/saa7164-cards.c
+++ b/drivers/media/pci/saa7164/saa7164-cards.c
@@ -780,9 +780,7 @@ static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
780{ 780{
781 struct tveeprom tv; 781 struct tveeprom tv;
782 782
783 /* TODO: Assumption: eeprom on bus 0 */ 783 tveeprom_hauppauge_analog(&tv, eeprom_data);
784 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
785 eeprom_data);
786 784
787 /* Make sure we support the board model */ 785 /* Make sure we support the board model */
788 switch (tv.model) { 786 switch (tv.model) {
diff --git a/drivers/media/pci/saa7164/saa7164-cmd.c b/drivers/media/pci/saa7164/saa7164-cmd.c
index f55c177fd1e4..175015ca79f2 100644
--- a/drivers/media/pci/saa7164/saa7164-cmd.c
+++ b/drivers/media/pci/saa7164/saa7164-cmd.c
@@ -130,14 +130,13 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
130 * -bus/c running buffer. */ 130 * -bus/c running buffer. */
131static int saa7164_cmd_dequeue(struct saa7164_dev *dev) 131static int saa7164_cmd_dequeue(struct saa7164_dev *dev)
132{ 132{
133 int loop = 1;
134 int ret; 133 int ret;
135 u32 timeout; 134 u32 timeout;
136 wait_queue_head_t *q = NULL; 135 wait_queue_head_t *q = NULL;
137 u8 tmp[512]; 136 u8 tmp[512];
138 dprintk(DBGLVL_CMD, "%s()\n", __func__); 137 dprintk(DBGLVL_CMD, "%s()\n", __func__);
139 138
140 while (loop) { 139 while (true) {
141 140
142 struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 }; 141 struct tmComResInfo tRsp = { 0, 0, 0, 0, 0, 0 };
143 ret = saa7164_bus_get(dev, &tRsp, NULL, 1); 142 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
@@ -178,8 +177,6 @@ static int saa7164_cmd_dequeue(struct saa7164_dev *dev)
178 wake_up(q); 177 wake_up(q);
179 return SAA_OK; 178 return SAA_OK;
180 } 179 }
181
182 return SAA_OK;
183} 180}
184 181
185static int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg, 182static int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 25a2137ab799..25f9f2ebff1d 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -1140,14 +1140,13 @@ static int solo_subscribe_event(struct v4l2_fh *fh,
1140{ 1140{
1141 1141
1142 switch (sub->type) { 1142 switch (sub->type) {
1143 case V4L2_EVENT_CTRL:
1144 return v4l2_ctrl_subscribe_event(fh, sub);
1145 case V4L2_EVENT_MOTION_DET: 1143 case V4L2_EVENT_MOTION_DET:
1146 /* Allow for up to 30 events (1 second for NTSC) to be 1144 /* Allow for up to 30 events (1 second for NTSC) to be
1147 * stored. */ 1145 * stored. */
1148 return v4l2_event_subscribe(fh, sub, 30, NULL); 1146 return v4l2_event_subscribe(fh, sub, 30, NULL);
1147 default:
1148 return v4l2_ctrl_subscribe_event(fh, sub);
1149 } 1149 }
1150 return -EINVAL;
1151} 1150}
1152 1151
1153static const struct v4l2_file_operations solo_enc_fops = { 1152static const struct v4l2_file_operations solo_enc_fops = {
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
index 896bec6627aa..3266fc21825f 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
@@ -341,6 +341,17 @@ static void solo_stop_streaming(struct vb2_queue *q)
341 struct solo_dev *solo_dev = vb2_get_drv_priv(q); 341 struct solo_dev *solo_dev = vb2_get_drv_priv(q);
342 342
343 solo_stop_thread(solo_dev); 343 solo_stop_thread(solo_dev);
344
345 spin_lock(&solo_dev->slock);
346 while (!list_empty(&solo_dev->vidq_active)) {
347 struct solo_vb2_buf *buf = list_entry(
348 solo_dev->vidq_active.next,
349 struct solo_vb2_buf, list);
350
351 list_del(&buf->list);
352 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
353 }
354 spin_unlock(&solo_dev->slock);
344 INIT_LIST_HEAD(&solo_dev->vidq_active); 355 INIT_LIST_HEAD(&solo_dev->vidq_active);
345} 356}
346 357
diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
index 10e28f067b45..ca05198de2c2 100644
--- a/drivers/media/pci/ttpci/av7110_ir.c
+++ b/drivers/media/pci/ttpci/av7110_ir.c
@@ -333,9 +333,8 @@ int av7110_ir_init(struct av7110 *av7110)
333 av_list[av_cnt++] = av7110; 333 av_list[av_cnt++] = av7110;
334 av7110_check_ir_config(av7110, true); 334 av7110_check_ir_config(av7110, true);
335 335
336 init_timer(&av7110->ir.keyup_timer); 336 setup_timer(&av7110->ir.keyup_timer, av7110_emit_keyup,
337 av7110->ir.keyup_timer.function = av7110_emit_keyup; 337 (unsigned long)&av7110->ir);
338 av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir;
339 338
340 input_dev = input_allocate_device(); 339 input_dev = input_allocate_device();
341 if (!input_dev) 340 if (!input_dev)
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index 19f07d4aba6a..dc7be8fac9a3 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -577,7 +577,7 @@ static u8 typhoon_cinergy1200s_inittab[] = {
577 0xff, 0xff 577 0xff, 0xff
578}; 578};
579 579
580static struct stv0299_config typhoon_config = { 580static const struct stv0299_config typhoon_config = {
581 .demod_address = 0x68, 581 .demod_address = 0x68,
582 .inittab = typhoon_cinergy1200s_inittab, 582 .inittab = typhoon_cinergy1200s_inittab,
583 .mclk = 88000000UL, 583 .mclk = 88000000UL,
@@ -590,7 +590,7 @@ static struct stv0299_config typhoon_config = {
590}; 590};
591 591
592 592
593static struct stv0299_config cinergy_1200s_config = { 593static const struct stv0299_config cinergy_1200s_config = {
594 .demod_address = 0x68, 594 .demod_address = 0x68,
595 .inittab = typhoon_cinergy1200s_inittab, 595 .inittab = typhoon_cinergy1200s_inittab,
596 .mclk = 88000000UL, 596 .mclk = 88000000UL,
@@ -602,7 +602,7 @@ static struct stv0299_config cinergy_1200s_config = {
602 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, 602 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
603}; 603};
604 604
605static struct stv0299_config cinergy_1200s_1894_0010_config = { 605static const struct stv0299_config cinergy_1200s_1894_0010_config = {
606 .demod_address = 0x68, 606 .demod_address = 0x68,
607 .inittab = typhoon_cinergy1200s_inittab, 607 .inittab = typhoon_cinergy1200s_inittab,
608 .mclk = 88000000UL, 608 .mclk = 88000000UL,
@@ -876,7 +876,7 @@ static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
876 return 0; 876 return 0;
877} 877}
878 878
879static struct stv0299_config philips_sd1878_config = { 879static const struct stv0299_config philips_sd1878_config = {
880 .demod_address = 0x68, 880 .demod_address = 0x68,
881 .inittab = philips_sd1878_inittab, 881 .inittab = philips_sd1878_inittab,
882 .mclk = 88000000UL, 882 .mclk = 88000000UL,
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 68355484ba7d..11b9227307bf 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -693,7 +693,7 @@ static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe)
693 return 0; 693 return 0;
694} 694}
695 695
696static struct stv0299_config philips_su1278_tt_config = { 696static const struct stv0299_config philips_su1278_tt_config = {
697 697
698 .demod_address = 0x68, 698 .demod_address = 0x68,
699 .inittab = philips_su1278_tt_inittab, 699 .inittab = philips_su1278_tt_inittab,
diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c
index 5f17e1c9a207..81fe35cedd10 100644
--- a/drivers/media/pci/ttpci/budget.c
+++ b/drivers/media/pci/ttpci/budget.c
@@ -397,7 +397,7 @@ static struct tda10086_config tda10086_config = {
397 .xtal_freq = TDA10086_XTAL_16M, 397 .xtal_freq = TDA10086_XTAL_16M,
398}; 398};
399 399
400static struct stv0299_config alps_bsru6_config_activy = { 400static const struct stv0299_config alps_bsru6_config_activy = {
401 .demod_address = 0x68, 401 .demod_address = 0x68,
402 .inittab = alps_bsru6_inittab, 402 .inittab = alps_bsru6_inittab,
403 .mclk = 88000000UL, 403 .mclk = 88000000UL,
@@ -407,7 +407,7 @@ static struct stv0299_config alps_bsru6_config_activy = {
407 .set_symbol_rate = alps_bsru6_set_symbol_rate, 407 .set_symbol_rate = alps_bsru6_set_symbol_rate,
408}; 408};
409 409
410static struct stv0299_config alps_bsbe1_config_activy = { 410static const struct stv0299_config alps_bsbe1_config_activy = {
411 .demod_address = 0x68, 411 .demod_address = 0x68,
412 .inittab = alps_bsbe1_inittab, 412 .inittab = alps_bsbe1_inittab,
413 .mclk = 88000000UL, 413 .mclk = 88000000UL,
diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c
index 9421216bb942..2a044be729da 100644
--- a/drivers/media/pci/tw5864/tw5864-video.c
+++ b/drivers/media/pci/tw5864/tw5864-video.c
@@ -664,15 +664,14 @@ static int tw5864_subscribe_event(struct v4l2_fh *fh,
664 const struct v4l2_event_subscription *sub) 664 const struct v4l2_event_subscription *sub)
665{ 665{
666 switch (sub->type) { 666 switch (sub->type) {
667 case V4L2_EVENT_CTRL:
668 return v4l2_ctrl_subscribe_event(fh, sub);
669 case V4L2_EVENT_MOTION_DET: 667 case V4L2_EVENT_MOTION_DET:
670 /* 668 /*
671 * Allow for up to 30 events (1 second for NTSC) to be stored. 669 * Allow for up to 30 events (1 second for NTSC) to be stored.
672 */ 670 */
673 return v4l2_event_subscribe(fh, sub, 30, NULL); 671 return v4l2_event_subscribe(fh, sub, 30, NULL);
672 default:
673 return v4l2_ctrl_subscribe_event(fh, sub);
674 } 674 }
675 return -EINVAL;
676} 675}
677 676
678static void tw5864_frame_interval_set(struct tw5864_input *input) 677static void tw5864_frame_interval_set(struct tw5864_input *input)
@@ -717,6 +716,8 @@ static void tw5864_frame_interval_set(struct tw5864_input *input)
717static int tw5864_frameinterval_get(struct tw5864_input *input, 716static int tw5864_frameinterval_get(struct tw5864_input *input,
718 struct v4l2_fract *frameinterval) 717 struct v4l2_fract *frameinterval)
719{ 718{
719 struct tw5864_dev *dev = input->root;
720
720 switch (input->std) { 721 switch (input->std) {
721 case STD_NTSC: 722 case STD_NTSC:
722 frameinterval->numerator = 1001; 723 frameinterval->numerator = 1001;
@@ -728,8 +729,8 @@ static int tw5864_frameinterval_get(struct tw5864_input *input,
728 frameinterval->denominator = 25; 729 frameinterval->denominator = 25;
729 break; 730 break;
730 default: 731 default:
731 WARN(1, "tw5864_frameinterval_get requested for unknown std %d\n", 732 dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n",
732 input->std); 733 input->std);
733 return -EINVAL; 734 return -EINVAL;
734 } 735 }
735 736
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index c9106e105bab..ac026ee1ca07 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -151,7 +151,7 @@ if V4L_MEM2MEM_DRIVERS
151 151
152config VIDEO_CODA 152config VIDEO_CODA
153 tristate "Chips&Media Coda multi-standard codec IP" 153 tristate "Chips&Media Coda multi-standard codec IP"
154 depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC 154 depends on VIDEO_DEV && VIDEO_V4L2 && (ARCH_MXC || COMPILE_TEST)
155 depends on HAS_DMA 155 depends on HAS_DMA
156 select SRAM 156 select SRAM
157 select VIDEOBUF2_DMA_CONTIG 157 select VIDEOBUF2_DMA_CONTIG
@@ -165,6 +165,21 @@ config VIDEO_CODA
165config VIDEO_IMX_VDOA 165config VIDEO_IMX_VDOA
166 def_tristate VIDEO_CODA if SOC_IMX6Q || COMPILE_TEST 166 def_tristate VIDEO_CODA if SOC_IMX6Q || COMPILE_TEST
167 167
168config VIDEO_MEDIATEK_JPEG
169 tristate "Mediatek JPEG Codec driver"
170 depends on MTK_IOMMU_V1 || COMPILE_TEST
171 depends on VIDEO_DEV && VIDEO_V4L2
172 depends on ARCH_MEDIATEK || COMPILE_TEST
173 depends on HAS_DMA
174 select VIDEOBUF2_DMA_CONTIG
175 select V4L2_MEM2MEM_DEV
176 ---help---
177 Mediatek jpeg codec driver provides HW capability to decode
178 JPEG format
179
180 To compile this driver as a module, choose M here: the
181 module will be called mtk-jpeg
182
168config VIDEO_MEDIATEK_VPU 183config VIDEO_MEDIATEK_VPU
169 tristate "Mediatek Video Processor Unit" 184 tristate "Mediatek Video Processor Unit"
170 depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA 185 depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
@@ -405,6 +420,7 @@ config VIDEO_RENESAS_VSP1
405 depends on (ARCH_RENESAS && OF) || COMPILE_TEST 420 depends on (ARCH_RENESAS && OF) || COMPILE_TEST
406 depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP 421 depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP
407 select VIDEOBUF2_DMA_CONTIG 422 select VIDEOBUF2_DMA_CONTIG
423 select VIDEOBUF2_VMALLOC
408 ---help--- 424 ---help---
409 This is a V4L2 driver for the Renesas VSP1 video processing engine. 425 This is a V4L2 driver for the Renesas VSP1 video processing engine.
410 426
@@ -451,6 +467,8 @@ menuconfig V4L_TEST_DRIVERS
451 467
452if V4L_TEST_DRIVERS 468if V4L_TEST_DRIVERS
453 469
470source "drivers/media/platform/vimc/Kconfig"
471
454source "drivers/media/platform/vivid/Kconfig" 472source "drivers/media/platform/vivid/Kconfig"
455 473
456config VIDEO_VIM2M 474config VIDEO_VIM2M
@@ -474,3 +492,31 @@ menuconfig DVB_PLATFORM_DRIVERS
474if DVB_PLATFORM_DRIVERS 492if DVB_PLATFORM_DRIVERS
475source "drivers/media/platform/sti/c8sectpfe/Kconfig" 493source "drivers/media/platform/sti/c8sectpfe/Kconfig"
476endif #DVB_PLATFORM_DRIVERS 494endif #DVB_PLATFORM_DRIVERS
495
496menuconfig CEC_PLATFORM_DRIVERS
497 bool "CEC platform devices"
498 depends on MEDIA_CEC_SUPPORT
499
500if CEC_PLATFORM_DRIVERS
501
502config VIDEO_SAMSUNG_S5P_CEC
503 tristate "Samsung S5P CEC driver"
504 depends on CEC_CORE && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST)
505 select MEDIA_CEC_NOTIFIER
506 ---help---
507 This is a driver for Samsung S5P HDMI CEC interface. It uses the
508 generic CEC framework interface.
509 CEC bus is present in the HDMI connector and enables communication
510 between compatible devices.
511
512config VIDEO_STI_HDMI_CEC
513 tristate "STMicroelectronics STiH4xx HDMI CEC driver"
514 depends on CEC_CORE && (ARCH_STI || COMPILE_TEST)
515 select MEDIA_CEC_NOTIFIER
516 ---help---
517 This is a driver for STIH4xx HDMI CEC interface. It uses the
518 generic CEC framework interface.
519 CEC bus is present in the HDMI connector and enables communication
520 between compatible devices.
521
522endif #CEC_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 349ddf6a69da..63303d63c64c 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
13 13
14obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o 14obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
15 15
16obj-$(CONFIG_VIDEO_VIMC) += vimc/
16obj-$(CONFIG_VIDEO_VIVID) += vivid/ 17obj-$(CONFIG_VIDEO_VIVID) += vivid/
17obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o 18obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o
18 19
@@ -33,11 +34,13 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
33obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ 34obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
34 35
35obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ 36obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/
37obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec/
36obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/ 38obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/
37 39
38obj-$(CONFIG_VIDEO_STI_BDISP) += sti/bdisp/ 40obj-$(CONFIG_VIDEO_STI_BDISP) += sti/bdisp/
39obj-$(CONFIG_VIDEO_STI_HVA) += sti/hva/ 41obj-$(CONFIG_VIDEO_STI_HVA) += sti/hva/
40obj-$(CONFIG_DVB_C8SECTPFE) += sti/c8sectpfe/ 42obj-$(CONFIG_DVB_C8SECTPFE) += sti/c8sectpfe/
43obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/
41 44
42obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/ 45obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/
43 46
@@ -63,6 +66,7 @@ obj-$(CONFIG_VIDEO_XILINX) += xilinx/
63obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/ 66obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/
64 67
65obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/ 68obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/
69obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/
66 70
67ccflags-y += -I$(srctree)/drivers/media/i2c 71ccflags-y += -I$(srctree)/drivers/media/i2c
68 72
@@ -71,3 +75,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/
71obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/ 75obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/
72 76
73obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ 77obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/
78
79obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/
diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig
index 867dca22a473..9bd0f19b127f 100644
--- a/drivers/media/platform/atmel/Kconfig
+++ b/drivers/media/platform/atmel/Kconfig
@@ -6,4 +6,13 @@ config VIDEO_ATMEL_ISC
6 select REGMAP_MMIO 6 select REGMAP_MMIO
7 help 7 help
8 This module makes the ATMEL Image Sensor Controller available 8 This module makes the ATMEL Image Sensor Controller available
9 as a v4l2 device. \ No newline at end of file 9 as a v4l2 device.
10
11config VIDEO_ATMEL_ISI
12 tristate "ATMEL Image Sensor Interface (ISI) support"
13 depends on VIDEO_V4L2 && OF && HAS_DMA
14 depends on ARCH_AT91 || COMPILE_TEST
15 select VIDEOBUF2_DMA_CONTIG
16 ---help---
17 This module makes the ATMEL Image Sensor Interface available
18 as a v4l2 device.
diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
index 9d7c999d434d..27000d099a5e 100644
--- a/drivers/media/platform/atmel/Makefile
+++ b/drivers/media/platform/atmel/Makefile
@@ -1 +1,2 @@
1obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o 1obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o
2obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h
index 00c449717cde..6936ac467609 100644
--- a/drivers/media/platform/atmel/atmel-isc-regs.h
+++ b/drivers/media/platform/atmel/atmel-isc-regs.h
@@ -65,6 +65,7 @@
65#define ISC_INTSR 0x00000034 65#define ISC_INTSR 0x00000034
66 66
67#define ISC_INT_DDONE BIT(8) 67#define ISC_INT_DDONE BIT(8)
68#define ISC_INT_HISDONE BIT(12)
68 69
69/* ISC White Balance Control Register */ 70/* ISC White Balance Control Register */
70#define ISC_WB_CTRL 0x00000058 71#define ISC_WB_CTRL 0x00000058
@@ -72,30 +73,98 @@
72/* ISC White Balance Configuration Register */ 73/* ISC White Balance Configuration Register */
73#define ISC_WB_CFG 0x0000005c 74#define ISC_WB_CFG 0x0000005c
74 75
76/* ISC White Balance Offset for R, GR Register */
77#define ISC_WB_O_RGR 0x00000060
78
79/* ISC White Balance Offset for B, GB Register */
80#define ISC_WB_O_BGR 0x00000064
81
82/* ISC White Balance Gain for R, GR Register */
83#define ISC_WB_G_RGR 0x00000068
84
85/* ISC White Balance Gain for B, GB Register */
86#define ISC_WB_G_BGR 0x0000006c
87
75/* ISC Color Filter Array Control Register */ 88/* ISC Color Filter Array Control Register */
76#define ISC_CFA_CTRL 0x00000070 89#define ISC_CFA_CTRL 0x00000070
77 90
78/* ISC Color Filter Array Configuration Register */ 91/* ISC Color Filter Array Configuration Register */
79#define ISC_CFA_CFG 0x00000074 92#define ISC_CFA_CFG 0x00000074
93#define ISC_CFA_CFG_EITPOL BIT(4)
80 94
81#define ISC_BAY_CFG_GRGR 0x0 95#define ISC_BAY_CFG_GRGR 0x0
82#define ISC_BAY_CFG_RGRG 0x1 96#define ISC_BAY_CFG_RGRG 0x1
83#define ISC_BAY_CFG_GBGB 0x2 97#define ISC_BAY_CFG_GBGB 0x2
84#define ISC_BAY_CFG_BGBG 0x3 98#define ISC_BAY_CFG_BGBG 0x3
85#define ISC_BAY_CFG_MASK GENMASK(1, 0)
86 99
87/* ISC Color Correction Control Register */ 100/* ISC Color Correction Control Register */
88#define ISC_CC_CTRL 0x00000078 101#define ISC_CC_CTRL 0x00000078
89 102
103/* ISC Color Correction RR RG Register */
104#define ISC_CC_RR_RG 0x0000007c
105
106/* ISC Color Correction RB OR Register */
107#define ISC_CC_RB_OR 0x00000080
108
109/* ISC Color Correction GR GG Register */
110#define ISC_CC_GR_GG 0x00000084
111
112/* ISC Color Correction GB OG Register */
113#define ISC_CC_GB_OG 0x00000088
114
115/* ISC Color Correction BR BG Register */
116#define ISC_CC_BR_BG 0x0000008c
117
118/* ISC Color Correction BB OB Register */
119#define ISC_CC_BB_OB 0x00000090
120
90/* ISC Gamma Correction Control Register */ 121/* ISC Gamma Correction Control Register */
91#define ISC_GAM_CTRL 0x00000094 122#define ISC_GAM_CTRL 0x00000094
92 123
124/* ISC_Gamma Correction Blue Entry Register */
125#define ISC_GAM_BENTRY 0x00000098
126
127/* ISC_Gamma Correction Green Entry Register */
128#define ISC_GAM_GENTRY 0x00000198
129
130/* ISC_Gamma Correction Green Entry Register */
131#define ISC_GAM_RENTRY 0x00000298
132
93/* Color Space Conversion Control Register */ 133/* Color Space Conversion Control Register */
94#define ISC_CSC_CTRL 0x00000398 134#define ISC_CSC_CTRL 0x00000398
95 135
136/* Color Space Conversion YR YG Register */
137#define ISC_CSC_YR_YG 0x0000039c
138
139/* Color Space Conversion YB OY Register */
140#define ISC_CSC_YB_OY 0x000003a0
141
142/* Color Space Conversion CBR CBG Register */
143#define ISC_CSC_CBR_CBG 0x000003a4
144
145/* Color Space Conversion CBB OCB Register */
146#define ISC_CSC_CBB_OCB 0x000003a8
147
148/* Color Space Conversion CRR CRG Register */
149#define ISC_CSC_CRR_CRG 0x000003ac
150
151/* Color Space Conversion CRB OCR Register */
152#define ISC_CSC_CRB_OCR 0x000003b0
153
96/* Contrast And Brightness Control Register */ 154/* Contrast And Brightness Control Register */
97#define ISC_CBC_CTRL 0x000003b4 155#define ISC_CBC_CTRL 0x000003b4
98 156
157/* Contrast And Brightness Configuration Register */
158#define ISC_CBC_CFG 0x000003b8
159
160/* Brightness Register */
161#define ISC_CBC_BRIGHT 0x000003bc
162#define ISC_CBC_BRIGHT_MASK GENMASK(10, 0)
163
164/* Contrast Register */
165#define ISC_CBC_CONTRAST 0x000003c0
166#define ISC_CBC_CONTRAST_MASK GENMASK(11, 0)
167
99/* Subsampling 4:4:4 to 4:2:2 Control Register */ 168/* Subsampling 4:4:4 to 4:2:2 Control Register */
100#define ISC_SUB422_CTRL 0x000003c4 169#define ISC_SUB422_CTRL 0x000003c4
101 170
@@ -120,6 +189,27 @@
120#define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc 189#define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc
121#define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0) 190#define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0)
122 191
192/* Histogram Control Register */
193#define ISC_HIS_CTRL 0x000003d4
194
195#define ISC_HIS_CTRL_EN BIT(0)
196#define ISC_HIS_CTRL_DIS 0x0
197
198/* Histogram Configuration Register */
199#define ISC_HIS_CFG 0x000003d8
200
201#define ISC_HIS_CFG_MODE_GR 0x0
202#define ISC_HIS_CFG_MODE_R 0x1
203#define ISC_HIS_CFG_MODE_GB 0x2
204#define ISC_HIS_CFG_MODE_B 0x3
205#define ISC_HIS_CFG_MODE_Y 0x4
206#define ISC_HIS_CFG_MODE_RAW 0x5
207#define ISC_HIS_CFG_MODE_YCCIR656 0x6
208
209#define ISC_HIS_CFG_BAYSEL_SHIFT 4
210
211#define ISC_HIS_CFG_RAR BIT(8)
212
123/* DMA Configuration Register */ 213/* DMA Configuration Register */
124#define ISC_DCFG 0x000003e0 214#define ISC_DCFG 0x000003e0
125#define ISC_DCFG_IMODE_PACKED8 0x0 215#define ISC_DCFG_IMODE_PACKED8 0x0
@@ -159,7 +249,13 @@
159/* DMA Address 0 Register */ 249/* DMA Address 0 Register */
160#define ISC_DAD0 0x000003ec 250#define ISC_DAD0 0x000003ec
161 251
162/* DMA Stride 0 Register */ 252/* DMA Address 1 Register */
163#define ISC_DST0 0x000003f0 253#define ISC_DAD1 0x000003f4
254
255/* DMA Address 2 Register */
256#define ISC_DAD2 0x000003fc
257
258/* Histogram Entry */
259#define ISC_HIS_ENTRY 0x00000410
164 260
165#endif 261#endif
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index fa68fe912c95..c4b2115559a5 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -29,6 +29,7 @@
29#include <linux/clk-provider.h> 29#include <linux/clk-provider.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/math64.h>
32#include <linux/module.h> 33#include <linux/module.h>
33#include <linux/of.h> 34#include <linux/of.h>
34#include <linux/platform_device.h> 35#include <linux/platform_device.h>
@@ -36,7 +37,9 @@
36#include <linux/regmap.h> 37#include <linux/regmap.h>
37#include <linux/videodev2.h> 38#include <linux/videodev2.h>
38 39
40#include <media/v4l2-ctrls.h>
39#include <media/v4l2-device.h> 41#include <media/v4l2-device.h>
42#include <media/v4l2-event.h>
40#include <media/v4l2-image-sizes.h> 43#include <media/v4l2-image-sizes.h>
41#include <media/v4l2-ioctl.h> 44#include <media/v4l2-ioctl.h>
42#include <media/v4l2-of.h> 45#include <media/v4l2-of.h>
@@ -89,10 +92,12 @@ struct isc_subdev_entity {
89 * struct isc_format - ISC media bus format information 92 * struct isc_format - ISC media bus format information
90 * @fourcc: Fourcc code for this format 93 * @fourcc: Fourcc code for this format
91 * @mbus_code: V4L2 media bus format code. 94 * @mbus_code: V4L2 media bus format code.
92 * @bpp: Bytes per pixel (when stored in memory) 95 * @bpp: Bits per pixel (when stored in memory)
93 * @reg_bps: reg value for bits per sample 96 * @reg_bps: reg value for bits per sample
94 * (when transferred over a bus) 97 * (when transferred over a bus)
95 * @support: Indicates format supported by subdev 98 * @pipeline: pipeline switch
99 * @sd_support: Subdev supports this format
100 * @isc_support: ISC can convert raw format to this format
96 */ 101 */
97struct isc_format { 102struct isc_format {
98 u32 fourcc; 103 u32 fourcc;
@@ -100,11 +105,42 @@ struct isc_format {
100 u8 bpp; 105 u8 bpp;
101 106
102 u32 reg_bps; 107 u32 reg_bps;
108 u32 reg_bay_cfg;
103 u32 reg_rlp_mode; 109 u32 reg_rlp_mode;
104 u32 reg_dcfg_imode; 110 u32 reg_dcfg_imode;
105 u32 reg_dctrl_dview; 111 u32 reg_dctrl_dview;
106 112
107 bool support; 113 u32 pipeline;
114
115 bool sd_support;
116 bool isc_support;
117};
118
119
120#define HIST_ENTRIES 512
121#define HIST_BAYER (ISC_HIS_CFG_MODE_B + 1)
122
123enum{
124 HIST_INIT = 0,
125 HIST_ENABLED,
126 HIST_DISABLED,
127};
128
129struct isc_ctrls {
130 struct v4l2_ctrl_handler handler;
131
132 u32 brightness;
133 u32 contrast;
134 u8 gamma_index;
135 u8 awb;
136
137 u32 r_gain;
138 u32 b_gain;
139
140 u32 hist_entry[HIST_ENTRIES];
141 u32 hist_count[HIST_BAYER];
142 u8 hist_id;
143 u8 hist_stat;
108}; 144};
109 145
110#define ISC_PIPE_LINE_NODE_NUM 11 146#define ISC_PIPE_LINE_NODE_NUM 11
@@ -131,6 +167,10 @@ struct isc_device {
131 struct isc_format **user_formats; 167 struct isc_format **user_formats;
132 unsigned int num_user_formats; 168 unsigned int num_user_formats;
133 const struct isc_format *current_fmt; 169 const struct isc_format *current_fmt;
170 const struct isc_format *raw_fmt;
171
172 struct isc_ctrls ctrls;
173 struct work_struct awb_work;
134 174
135 struct mutex lock; 175 struct mutex lock;
136 176
@@ -140,51 +180,134 @@ struct isc_device {
140 struct list_head subdev_entities; 180 struct list_head subdev_entities;
141}; 181};
142 182
183#define RAW_FMT_IND_START 0
184#define RAW_FMT_IND_END 11
185#define ISC_FMT_IND_START 12
186#define ISC_FMT_IND_END 14
187
143static struct isc_format isc_formats[] = { 188static struct isc_format isc_formats[] = {
144 { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 189 { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 8,
145 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 190 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8,
146 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 191 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
147 { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 192 false, false },
148 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 193 { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 8,
149 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 194 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT8,
150 { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 195 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
151 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 196 false, false },
152 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 197 { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 8,
153 { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 198 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT8,
154 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 199 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
155 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 200 false, false },
156 201 { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 8,
157 { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 202 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT8,
158 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 203 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
159 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 204 false, false },
160 { V4L2_PIX_FMT_SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10, 205
161 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 206 { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 16,
162 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 207 ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT10,
163 { V4L2_PIX_FMT_SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10, 208 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
164 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 209 false, false },
165 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 210 { V4L2_PIX_FMT_SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10, 16,
166 { V4L2_PIX_FMT_SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10, 211 ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT10,
167 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 212 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
168 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 213 false, false },
169 214 { V4L2_PIX_FMT_SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10, 16,
170 { V4L2_PIX_FMT_SBGGR12, MEDIA_BUS_FMT_SBGGR12_1X12, 215 ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT10,
171 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 216 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
172 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 217 false, false },
173 { V4L2_PIX_FMT_SGBRG12, MEDIA_BUS_FMT_SGBRG12_1X12, 218 { V4L2_PIX_FMT_SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10, 16,
174 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 219 ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT10,
175 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 220 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
176 { V4L2_PIX_FMT_SGRBG12, MEDIA_BUS_FMT_SGRBG12_1X12, 221 false, false },
177 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 222
178 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 223 { V4L2_PIX_FMT_SBGGR12, MEDIA_BUS_FMT_SBGGR12_1X12, 16,
179 { V4L2_PIX_FMT_SRGGB12, MEDIA_BUS_FMT_SRGGB12_1X12, 224 ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT12,
180 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 225 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
181 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 226 false, false },
182 227 { V4L2_PIX_FMT_SGBRG12, MEDIA_BUS_FMT_SGBRG12_1X12, 16,
183 { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_YUYV8_2X8, 228 ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT12,
184 2, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 229 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
185 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 230 false, false },
231 { V4L2_PIX_FMT_SGRBG12, MEDIA_BUS_FMT_SGRBG12_1X12, 16,
232 ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT12,
233 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
234 false, false },
235 { V4L2_PIX_FMT_SRGGB12, MEDIA_BUS_FMT_SRGGB12_1X12, 16,
236 ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT12,
237 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0,
238 false, false },
239
240 { V4L2_PIX_FMT_YUV420, 0x0, 12,
241 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_YYCC,
242 ISC_DCFG_IMODE_YC420P | ISC_DCFG_YMBSIZE_BEATS8 |
243 ISC_DCFG_CMBSIZE_BEATS8, ISC_DCTRL_DVIEW_PLANAR, 0x7fb,
244 false, false },
245 { V4L2_PIX_FMT_YUV422P, 0x0, 16,
246 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_YYCC,
247 ISC_DCFG_IMODE_YC422P | ISC_DCFG_YMBSIZE_BEATS8 |
248 ISC_DCFG_CMBSIZE_BEATS8, ISC_DCTRL_DVIEW_PLANAR, 0x3fb,
249 false, false },
250 { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_RGB565_2X8_LE, 16,
251 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_RGB565,
252 ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x7b,
253 false, false },
254
255 { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_YUYV8_2X8, 16,
256 ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8,
257 ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0,
258 false, false },
259};
260
261#define GAMMA_MAX 2
262#define GAMMA_ENTRIES 64
263
264/* Gamma table with gamma 1/2.2 */
265static const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = {
266 /* 0 --> gamma 1/1.8 */
267 { 0x65, 0x66002F, 0x950025, 0xBB0020, 0xDB001D, 0xF8001A,
268 0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012,
269 0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F,
270 0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E,
271 0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C,
272 0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B,
273 0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A,
274 0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A,
275 0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A,
276 0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009,
277 0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 },
278
279 /* 1 --> gamma 1/2 */
280 { 0x7F, 0x800034, 0xB50028, 0xDE0021, 0x100001E, 0x11E001B,
281 0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013,
282 0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F,
283 0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D,
284 0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B,
285 0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A,
286 0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A,
287 0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009,
288 0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009,
289 0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009,
290 0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 },
291
292 /* 2 --> gamma 1/2.2 */
293 { 0x99, 0x9B0038, 0xD4002A, 0xFF0023, 0x122001F, 0x141001B,
294 0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012,
295 0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F,
296 0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C,
297 0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B,
298 0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A,
299 0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009,
300 0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009,
301 0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008,
302 0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007,
303 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 },
186}; 304};
187 305
306static unsigned int sensor_preferred = 1;
307module_param(sensor_preferred, uint, 0644);
308MODULE_PARM_DESC(sensor_preferred,
309 "Sensor is preferred to output the specified format (1-on 0-off), default 1");
310
188static int isc_clk_enable(struct clk_hw *hw) 311static int isc_clk_enable(struct clk_hw *hw)
189{ 312{
190 struct isc_clk *isc_clk = to_isc_clk(hw); 313 struct isc_clk *isc_clk = to_isc_clk(hw);
@@ -447,27 +570,155 @@ static int isc_buffer_prepare(struct vb2_buffer *vb)
447 return 0; 570 return 0;
448} 571}
449 572
450static inline void isc_start_dma(struct regmap *regmap, 573static inline bool sensor_is_preferred(const struct isc_format *isc_fmt)
451 struct isc_buffer *frm, u32 dview) 574{
575 return (sensor_preferred && isc_fmt->sd_support) ||
576 !isc_fmt->isc_support;
577}
578
579static void isc_start_dma(struct isc_device *isc)
452{ 580{
453 dma_addr_t addr; 581 struct regmap *regmap = isc->regmap;
582 struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
583 u32 sizeimage = pixfmt->sizeimage;
584 u32 dctrl_dview;
585 dma_addr_t addr0;
586
587 addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0);
588 regmap_write(regmap, ISC_DAD0, addr0);
589
590 switch (pixfmt->pixelformat) {
591 case V4L2_PIX_FMT_YUV420:
592 regmap_write(regmap, ISC_DAD1, addr0 + (sizeimage * 2) / 3);
593 regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 5) / 6);
594 break;
595 case V4L2_PIX_FMT_YUV422P:
596 regmap_write(regmap, ISC_DAD1, addr0 + sizeimage / 2);
597 regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 3) / 4);
598 break;
599 default:
600 break;
601 }
454 602
455 addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0); 603 if (sensor_is_preferred(isc->current_fmt))
604 dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
605 else
606 dctrl_dview = isc->current_fmt->reg_dctrl_dview;
456 607
457 regmap_write(regmap, ISC_DCTRL, dview | ISC_DCTRL_IE_IS); 608 regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS);
458 regmap_write(regmap, ISC_DAD0, addr);
459 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); 609 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE);
460} 610}
461 611
462static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) 612static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
463{ 613{
464 u32 val; 614 struct regmap *regmap = isc->regmap;
615 struct isc_ctrls *ctrls = &isc->ctrls;
616 u32 val, bay_cfg;
617 const u32 *gamma;
465 unsigned int i; 618 unsigned int i;
466 619
620 /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */
467 for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) { 621 for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) {
468 val = pipeline & BIT(i) ? 1 : 0; 622 val = pipeline & BIT(i) ? 1 : 0;
469 regmap_field_write(isc->pipeline[i], val); 623 regmap_field_write(isc->pipeline[i], val);
470 } 624 }
625
626 if (!pipeline)
627 return;
628
629 bay_cfg = isc->raw_fmt->reg_bay_cfg;
630
631 regmap_write(regmap, ISC_WB_CFG, bay_cfg);
632 regmap_write(regmap, ISC_WB_O_RGR, 0x0);
633 regmap_write(regmap, ISC_WB_O_BGR, 0x0);
634 regmap_write(regmap, ISC_WB_G_RGR, ctrls->r_gain | (0x1 << 25));
635 regmap_write(regmap, ISC_WB_G_BGR, ctrls->b_gain | (0x1 << 25));
636
637 regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL);
638
639 gamma = &isc_gamma_table[ctrls->gamma_index][0];
640 regmap_bulk_write(regmap, ISC_GAM_BENTRY, gamma, GAMMA_ENTRIES);
641 regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES);
642 regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES);
643
644 /* Convert RGB to YUV */
645 regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16));
646 regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16));
647 regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16));
648 regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16));
649 regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16));
650 regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16));
651
652 regmap_write(regmap, ISC_CBC_BRIGHT, ctrls->brightness);
653 regmap_write(regmap, ISC_CBC_CONTRAST, ctrls->contrast);
654}
655
656static int isc_update_profile(struct isc_device *isc)
657{
658 struct regmap *regmap = isc->regmap;
659 u32 sr;
660 int counter = 100;
661
662 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_UPPRO);
663
664 regmap_read(regmap, ISC_CTRLSR, &sr);
665 while ((sr & ISC_CTRL_UPPRO) && counter--) {
666 usleep_range(1000, 2000);
667 regmap_read(regmap, ISC_CTRLSR, &sr);
668 }
669
670 if (counter < 0) {
671 v4l2_warn(&isc->v4l2_dev, "Time out to update profie\n");
672 return -ETIMEDOUT;
673 }
674
675 return 0;
676}
677
678static void isc_set_histogram(struct isc_device *isc)
679{
680 struct regmap *regmap = isc->regmap;
681 struct isc_ctrls *ctrls = &isc->ctrls;
682
683 if (ctrls->awb && (ctrls->hist_stat != HIST_ENABLED)) {
684 regmap_write(regmap, ISC_HIS_CFG, ISC_HIS_CFG_MODE_R |
685 (isc->raw_fmt->reg_bay_cfg << ISC_HIS_CFG_BAYSEL_SHIFT) |
686 ISC_HIS_CFG_RAR);
687 regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN);
688 regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE);
689 ctrls->hist_id = ISC_HIS_CFG_MODE_R;
690 isc_update_profile(isc);
691 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
692
693 ctrls->hist_stat = HIST_ENABLED;
694 } else if (!ctrls->awb && (ctrls->hist_stat != HIST_DISABLED)) {
695 regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE);
696 regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_DIS);
697
698 ctrls->hist_stat = HIST_DISABLED;
699 }
700}
701
702static inline void isc_get_param(const struct isc_format *fmt,
703 u32 *rlp_mode, u32 *dcfg_imode)
704{
705 switch (fmt->fourcc) {
706 case V4L2_PIX_FMT_SBGGR10:
707 case V4L2_PIX_FMT_SGBRG10:
708 case V4L2_PIX_FMT_SGRBG10:
709 case V4L2_PIX_FMT_SRGGB10:
710 case V4L2_PIX_FMT_SBGGR12:
711 case V4L2_PIX_FMT_SGBRG12:
712 case V4L2_PIX_FMT_SGRBG12:
713 case V4L2_PIX_FMT_SRGGB12:
714 *rlp_mode = fmt->reg_rlp_mode;
715 *dcfg_imode = fmt->reg_dcfg_imode;
716 break;
717 default:
718 *rlp_mode = ISC_RLP_CFG_MODE_DAT8;
719 *dcfg_imode = ISC_DCFG_IMODE_PACKED8;
720 break;
721 }
471} 722}
472 723
473static int isc_configure(struct isc_device *isc) 724static int isc_configure(struct isc_device *isc)
@@ -475,39 +726,40 @@ static int isc_configure(struct isc_device *isc)
475 struct regmap *regmap = isc->regmap; 726 struct regmap *regmap = isc->regmap;
476 const struct isc_format *current_fmt = isc->current_fmt; 727 const struct isc_format *current_fmt = isc->current_fmt;
477 struct isc_subdev_entity *subdev = isc->current_subdev; 728 struct isc_subdev_entity *subdev = isc->current_subdev;
478 u32 val, mask; 729 u32 pfe_cfg0, rlp_mode, dcfg_imode, mask, pipeline;
479 int counter = 10; 730
731 if (sensor_is_preferred(current_fmt)) {
732 pfe_cfg0 = current_fmt->reg_bps;
733 pipeline = 0x0;
734 isc_get_param(current_fmt, &rlp_mode, &dcfg_imode);
735 isc->ctrls.hist_stat = HIST_INIT;
736 } else {
737 pfe_cfg0 = isc->raw_fmt->reg_bps;
738 pipeline = current_fmt->pipeline;
739 rlp_mode = current_fmt->reg_rlp_mode;
740 dcfg_imode = current_fmt->reg_dcfg_imode;
741 }
480 742
481 val = current_fmt->reg_bps | subdev->pfe_cfg0 | 743 pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE;
482 ISC_PFE_CFG0_MODE_PROGRESSIVE;
483 mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | 744 mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW |
484 ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW | 745 ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW |
485 ISC_PFE_CFG0_MODE_MASK; 746 ISC_PFE_CFG0_MODE_MASK;
486 747
487 regmap_update_bits(regmap, ISC_PFE_CFG0, mask, val); 748 regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0);
488 749
489 regmap_update_bits(regmap, ISC_RLP_CFG, ISC_RLP_CFG_MODE_MASK, 750 regmap_update_bits(regmap, ISC_RLP_CFG, ISC_RLP_CFG_MODE_MASK,
490 current_fmt->reg_rlp_mode); 751 rlp_mode);
491 752
492 regmap_update_bits(regmap, ISC_DCFG, ISC_DCFG_IMODE_MASK, 753 regmap_update_bits(regmap, ISC_DCFG, ISC_DCFG_IMODE_MASK, dcfg_imode);
493 current_fmt->reg_dcfg_imode);
494 754
495 /* Disable the pipeline */ 755 /* Set the pipeline */
496 isc_set_pipeline(isc, 0x0); 756 isc_set_pipeline(isc, pipeline);
497 757
498 /* Update profile */ 758 if (pipeline)
499 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_UPPRO); 759 isc_set_histogram(isc);
500
501 regmap_read(regmap, ISC_CTRLSR, &val);
502 while ((val & ISC_CTRL_UPPRO) && counter--) {
503 usleep_range(1000, 2000);
504 regmap_read(regmap, ISC_CTRLSR, &val);
505 }
506 760
507 if (counter < 0) 761 /* Update profile */
508 return -ETIMEDOUT; 762 return isc_update_profile(isc);
509
510 return 0;
511} 763}
512 764
513static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) 765static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
@@ -517,7 +769,6 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
517 struct isc_buffer *buf; 769 struct isc_buffer *buf;
518 unsigned long flags; 770 unsigned long flags;
519 int ret; 771 int ret;
520 u32 val;
521 772
522 /* Enable stream on the sub device */ 773 /* Enable stream on the sub device */
523 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1); 774 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1);
@@ -528,12 +779,6 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
528 779
529 pm_runtime_get_sync(isc->dev); 780 pm_runtime_get_sync(isc->dev);
530 781
531 /* Disable all the interrupts */
532 regmap_write(isc->regmap, ISC_INTDIS, (u32)~0UL);
533
534 /* Clean the interrupt status register */
535 regmap_read(regmap, ISC_INTSR, &val);
536
537 ret = isc_configure(isc); 782 ret = isc_configure(isc);
538 if (unlikely(ret)) 783 if (unlikely(ret))
539 goto err_configure; 784 goto err_configure;
@@ -551,7 +796,7 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
551 struct isc_buffer, list); 796 struct isc_buffer, list);
552 list_del(&isc->cur_frm->list); 797 list_del(&isc->cur_frm->list);
553 798
554 isc_start_dma(regmap, isc->cur_frm, isc->current_fmt->reg_dctrl_dview); 799 isc_start_dma(isc);
555 800
556 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); 801 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
557 802
@@ -620,8 +865,7 @@ static void isc_buffer_queue(struct vb2_buffer *vb)
620 if (!isc->cur_frm && list_empty(&isc->dma_queue) && 865 if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
621 vb2_is_streaming(vb->vb2_queue)) { 866 vb2_is_streaming(vb->vb2_queue)) {
622 isc->cur_frm = buf; 867 isc->cur_frm = buf;
623 isc_start_dma(isc->regmap, isc->cur_frm, 868 isc_start_dma(isc);
624 isc->current_fmt->reg_dctrl_dview);
625 } else 869 } else
626 list_add_tail(&buf->list, &isc->dma_queue); 870 list_add_tail(&buf->list, &isc->dma_queue);
627 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); 871 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
@@ -691,13 +935,14 @@ static struct isc_format *find_format_by_fourcc(struct isc_device *isc,
691} 935}
692 936
693static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, 937static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
694 struct isc_format **current_fmt) 938 struct isc_format **current_fmt, u32 *code)
695{ 939{
696 struct isc_format *isc_fmt; 940 struct isc_format *isc_fmt;
697 struct v4l2_pix_format *pixfmt = &f->fmt.pix; 941 struct v4l2_pix_format *pixfmt = &f->fmt.pix;
698 struct v4l2_subdev_format format = { 942 struct v4l2_subdev_format format = {
699 .which = V4L2_SUBDEV_FORMAT_TRY, 943 .which = V4L2_SUBDEV_FORMAT_TRY,
700 }; 944 };
945 u32 mbus_code;
701 int ret; 946 int ret;
702 947
703 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 948 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -717,7 +962,12 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
717 if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) 962 if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT)
718 pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; 963 pixfmt->height = ISC_MAX_SUPPORT_HEIGHT;
719 964
720 v4l2_fill_mbus_format(&format.format, pixfmt, isc_fmt->mbus_code); 965 if (sensor_is_preferred(isc_fmt))
966 mbus_code = isc_fmt->mbus_code;
967 else
968 mbus_code = isc->raw_fmt->mbus_code;
969
970 v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
721 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, 971 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
722 isc->current_subdev->config, &format); 972 isc->current_subdev->config, &format);
723 if (ret < 0) 973 if (ret < 0)
@@ -726,12 +976,15 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
726 v4l2_fill_pix_format(pixfmt, &format.format); 976 v4l2_fill_pix_format(pixfmt, &format.format);
727 977
728 pixfmt->field = V4L2_FIELD_NONE; 978 pixfmt->field = V4L2_FIELD_NONE;
729 pixfmt->bytesperline = pixfmt->width * isc_fmt->bpp; 979 pixfmt->bytesperline = (pixfmt->width * isc_fmt->bpp) >> 3;
730 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 980 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
731 981
732 if (current_fmt) 982 if (current_fmt)
733 *current_fmt = isc_fmt; 983 *current_fmt = isc_fmt;
734 984
985 if (code)
986 *code = mbus_code;
987
735 return 0; 988 return 0;
736} 989}
737 990
@@ -741,14 +994,14 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
741 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 994 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
742 }; 995 };
743 struct isc_format *current_fmt; 996 struct isc_format *current_fmt;
997 u32 mbus_code;
744 int ret; 998 int ret;
745 999
746 ret = isc_try_fmt(isc, f, &current_fmt); 1000 ret = isc_try_fmt(isc, f, &current_fmt, &mbus_code);
747 if (ret) 1001 if (ret)
748 return ret; 1002 return ret;
749 1003
750 v4l2_fill_mbus_format(&format.format, &f->fmt.pix, 1004 v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
751 current_fmt->mbus_code);
752 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, 1005 ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
753 set_fmt, NULL, &format); 1006 set_fmt, NULL, &format);
754 if (ret < 0) 1007 if (ret < 0)
@@ -776,7 +1029,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv,
776{ 1029{
777 struct isc_device *isc = video_drvdata(file); 1030 struct isc_device *isc = video_drvdata(file);
778 1031
779 return isc_try_fmt(isc, f, NULL); 1032 return isc_try_fmt(isc, f, NULL, NULL);
780} 1033}
781 1034
782static int isc_enum_input(struct file *file, void *priv, 1035static int isc_enum_input(struct file *file, void *priv,
@@ -842,7 +1095,10 @@ static int isc_enum_framesizes(struct file *file, void *fh,
842 if (!isc_fmt) 1095 if (!isc_fmt)
843 return -EINVAL; 1096 return -EINVAL;
844 1097
845 fse.code = isc_fmt->mbus_code; 1098 if (sensor_is_preferred(isc_fmt))
1099 fse.code = isc_fmt->mbus_code;
1100 else
1101 fse.code = isc->raw_fmt->mbus_code;
846 1102
847 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, 1103 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
848 NULL, &fse); 1104 NULL, &fse);
@@ -873,7 +1129,10 @@ static int isc_enum_frameintervals(struct file *file, void *fh,
873 if (!isc_fmt) 1129 if (!isc_fmt)
874 return -EINVAL; 1130 return -EINVAL;
875 1131
876 fie.code = isc_fmt->mbus_code; 1132 if (sensor_is_preferred(isc_fmt))
1133 fie.code = isc_fmt->mbus_code;
1134 else
1135 fie.code = isc->raw_fmt->mbus_code;
877 1136
878 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, 1137 ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
879 enum_frame_interval, NULL, &fie); 1138 enum_frame_interval, NULL, &fie);
@@ -911,6 +1170,10 @@ static const struct v4l2_ioctl_ops isc_ioctl_ops = {
911 .vidioc_s_parm = isc_s_parm, 1170 .vidioc_s_parm = isc_s_parm,
912 .vidioc_enum_framesizes = isc_enum_framesizes, 1171 .vidioc_enum_framesizes = isc_enum_framesizes,
913 .vidioc_enum_frameintervals = isc_enum_frameintervals, 1172 .vidioc_enum_frameintervals = isc_enum_frameintervals,
1173
1174 .vidioc_log_status = v4l2_ctrl_log_status,
1175 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1176 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
914}; 1177};
915 1178
916static int isc_open(struct file *file) 1179static int isc_open(struct file *file)
@@ -984,14 +1247,13 @@ static irqreturn_t isc_interrupt(int irq, void *dev_id)
984 u32 isc_intsr, isc_intmask, pending; 1247 u32 isc_intsr, isc_intmask, pending;
985 irqreturn_t ret = IRQ_NONE; 1248 irqreturn_t ret = IRQ_NONE;
986 1249
987 spin_lock(&isc->dma_queue_lock);
988
989 regmap_read(regmap, ISC_INTSR, &isc_intsr); 1250 regmap_read(regmap, ISC_INTSR, &isc_intsr);
990 regmap_read(regmap, ISC_INTMASK, &isc_intmask); 1251 regmap_read(regmap, ISC_INTMASK, &isc_intmask);
991 1252
992 pending = isc_intsr & isc_intmask; 1253 pending = isc_intsr & isc_intmask;
993 1254
994 if (likely(pending & ISC_INT_DDONE)) { 1255 if (likely(pending & ISC_INT_DDONE)) {
1256 spin_lock(&isc->dma_queue_lock);
995 if (isc->cur_frm) { 1257 if (isc->cur_frm) {
996 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb; 1258 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb;
997 struct vb2_buffer *vb = &vbuf->vb2_buf; 1259 struct vb2_buffer *vb = &vbuf->vb2_buf;
@@ -1007,21 +1269,144 @@ static irqreturn_t isc_interrupt(int irq, void *dev_id)
1007 struct isc_buffer, list); 1269 struct isc_buffer, list);
1008 list_del(&isc->cur_frm->list); 1270 list_del(&isc->cur_frm->list);
1009 1271
1010 isc_start_dma(regmap, isc->cur_frm, 1272 isc_start_dma(isc);
1011 isc->current_fmt->reg_dctrl_dview);
1012 } 1273 }
1013 1274
1014 if (isc->stop) 1275 if (isc->stop)
1015 complete(&isc->comp); 1276 complete(&isc->comp);
1016 1277
1017 ret = IRQ_HANDLED; 1278 ret = IRQ_HANDLED;
1279 spin_unlock(&isc->dma_queue_lock);
1018 } 1280 }
1019 1281
1020 spin_unlock(&isc->dma_queue_lock); 1282 if (pending & ISC_INT_HISDONE) {
1283 schedule_work(&isc->awb_work);
1284 ret = IRQ_HANDLED;
1285 }
1021 1286
1022 return ret; 1287 return ret;
1023} 1288}
1024 1289
1290static void isc_hist_count(struct isc_device *isc)
1291{
1292 struct regmap *regmap = isc->regmap;
1293 struct isc_ctrls *ctrls = &isc->ctrls;
1294 u32 *hist_count = &ctrls->hist_count[ctrls->hist_id];
1295 u32 *hist_entry = &ctrls->hist_entry[0];
1296 u32 i;
1297
1298 regmap_bulk_read(regmap, ISC_HIS_ENTRY, hist_entry, HIST_ENTRIES);
1299
1300 *hist_count = 0;
1301 for (i = 0; i < HIST_ENTRIES; i++)
1302 *hist_count += i * (*hist_entry++);
1303}
1304
1305static void isc_wb_update(struct isc_ctrls *ctrls)
1306{
1307 u32 *hist_count = &ctrls->hist_count[0];
1308 u64 g_count = (u64)hist_count[ISC_HIS_CFG_MODE_GB] << 9;
1309 u32 hist_r = hist_count[ISC_HIS_CFG_MODE_R];
1310 u32 hist_b = hist_count[ISC_HIS_CFG_MODE_B];
1311
1312 if (hist_r)
1313 ctrls->r_gain = div_u64(g_count, hist_r);
1314
1315 if (hist_b)
1316 ctrls->b_gain = div_u64(g_count, hist_b);
1317}
1318
1319static void isc_awb_work(struct work_struct *w)
1320{
1321 struct isc_device *isc =
1322 container_of(w, struct isc_device, awb_work);
1323 struct regmap *regmap = isc->regmap;
1324 struct isc_ctrls *ctrls = &isc->ctrls;
1325 u32 hist_id = ctrls->hist_id;
1326 u32 baysel;
1327
1328 if (ctrls->hist_stat != HIST_ENABLED)
1329 return;
1330
1331 isc_hist_count(isc);
1332
1333 if (hist_id != ISC_HIS_CFG_MODE_B) {
1334 hist_id++;
1335 } else {
1336 isc_wb_update(ctrls);
1337 hist_id = ISC_HIS_CFG_MODE_R;
1338 }
1339
1340 ctrls->hist_id = hist_id;
1341 baysel = isc->raw_fmt->reg_bay_cfg << ISC_HIS_CFG_BAYSEL_SHIFT;
1342
1343 pm_runtime_get_sync(isc->dev);
1344
1345 regmap_write(regmap, ISC_HIS_CFG, hist_id | baysel | ISC_HIS_CFG_RAR);
1346 isc_update_profile(isc);
1347 regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
1348
1349 pm_runtime_put_sync(isc->dev);
1350}
1351
1352static int isc_s_ctrl(struct v4l2_ctrl *ctrl)
1353{
1354 struct isc_device *isc = container_of(ctrl->handler,
1355 struct isc_device, ctrls.handler);
1356 struct isc_ctrls *ctrls = &isc->ctrls;
1357
1358 switch (ctrl->id) {
1359 case V4L2_CID_BRIGHTNESS:
1360 ctrls->brightness = ctrl->val & ISC_CBC_BRIGHT_MASK;
1361 break;
1362 case V4L2_CID_CONTRAST:
1363 ctrls->contrast = ctrl->val & ISC_CBC_CONTRAST_MASK;
1364 break;
1365 case V4L2_CID_GAMMA:
1366 ctrls->gamma_index = ctrl->val;
1367 break;
1368 case V4L2_CID_AUTO_WHITE_BALANCE:
1369 ctrls->awb = ctrl->val;
1370 if (ctrls->hist_stat != HIST_ENABLED) {
1371 ctrls->r_gain = 0x1 << 9;
1372 ctrls->b_gain = 0x1 << 9;
1373 }
1374 break;
1375 default:
1376 return -EINVAL;
1377 }
1378
1379 return 0;
1380}
1381
1382static const struct v4l2_ctrl_ops isc_ctrl_ops = {
1383 .s_ctrl = isc_s_ctrl,
1384};
1385
1386static int isc_ctrl_init(struct isc_device *isc)
1387{
1388 const struct v4l2_ctrl_ops *ops = &isc_ctrl_ops;
1389 struct isc_ctrls *ctrls = &isc->ctrls;
1390 struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1391 int ret;
1392
1393 ctrls->hist_stat = HIST_INIT;
1394
1395 ret = v4l2_ctrl_handler_init(hdl, 4);
1396 if (ret < 0)
1397 return ret;
1398
1399 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0);
1400 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256);
1401 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2);
1402 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1403
1404 v4l2_ctrl_handler_setup(hdl);
1405
1406 return 0;
1407}
1408
1409
1025static int isc_async_bound(struct v4l2_async_notifier *notifier, 1410static int isc_async_bound(struct v4l2_async_notifier *notifier,
1026 struct v4l2_subdev *subdev, 1411 struct v4l2_subdev *subdev,
1027 struct v4l2_async_subdev *asd) 1412 struct v4l2_async_subdev *asd)
@@ -1047,10 +1432,11 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
1047{ 1432{
1048 struct isc_device *isc = container_of(notifier->v4l2_dev, 1433 struct isc_device *isc = container_of(notifier->v4l2_dev,
1049 struct isc_device, v4l2_dev); 1434 struct isc_device, v4l2_dev);
1050 1435 cancel_work_sync(&isc->awb_work);
1051 video_unregister_device(&isc->video_dev); 1436 video_unregister_device(&isc->video_dev);
1052 if (isc->current_subdev->config) 1437 if (isc->current_subdev->config)
1053 v4l2_subdev_free_pad_config(isc->current_subdev->config); 1438 v4l2_subdev_free_pad_config(isc->current_subdev->config);
1439 v4l2_ctrl_handler_free(&isc->ctrls.handler);
1054} 1440}
1055 1441
1056static struct isc_format *find_format_by_code(unsigned int code, int *index) 1442static struct isc_format *find_format_by_code(unsigned int code, int *index)
@@ -1074,14 +1460,16 @@ static int isc_formats_init(struct isc_device *isc)
1074{ 1460{
1075 struct isc_format *fmt; 1461 struct isc_format *fmt;
1076 struct v4l2_subdev *subdev = isc->current_subdev->sd; 1462 struct v4l2_subdev *subdev = isc->current_subdev->sd;
1077 int num_fmts = 0, i, j; 1463 unsigned int num_fmts, i, j;
1078 struct v4l2_subdev_mbus_code_enum mbus_code = { 1464 struct v4l2_subdev_mbus_code_enum mbus_code = {
1079 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1465 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1080 }; 1466 };
1081 1467
1082 fmt = &isc_formats[0]; 1468 fmt = &isc_formats[0];
1083 for (i = 0; i < ARRAY_SIZE(isc_formats); i++) { 1469 for (i = 0; i < ARRAY_SIZE(isc_formats); i++) {
1084 fmt->support = false; 1470 fmt->isc_support = false;
1471 fmt->sd_support = false;
1472
1085 fmt++; 1473 fmt++;
1086 } 1474 }
1087 1475
@@ -1092,8 +1480,22 @@ static int isc_formats_init(struct isc_device *isc)
1092 if (!fmt) 1480 if (!fmt)
1093 continue; 1481 continue;
1094 1482
1095 fmt->support = true; 1483 fmt->sd_support = true;
1096 num_fmts++; 1484
1485 if (i <= RAW_FMT_IND_END) {
1486 for (j = ISC_FMT_IND_START; j <= ISC_FMT_IND_END; j++)
1487 isc_formats[j].isc_support = true;
1488
1489 isc->raw_fmt = fmt;
1490 }
1491 }
1492
1493 fmt = &isc_formats[0];
1494 for (i = 0, num_fmts = 0; i < ARRAY_SIZE(isc_formats); i++) {
1495 if (fmt->isc_support || fmt->sd_support)
1496 num_fmts++;
1497
1498 fmt++;
1097 } 1499 }
1098 1500
1099 if (!num_fmts) 1501 if (!num_fmts)
@@ -1110,7 +1512,7 @@ static int isc_formats_init(struct isc_device *isc)
1110 1512
1111 fmt = &isc_formats[0]; 1513 fmt = &isc_formats[0];
1112 for (i = 0, j = 0; i < ARRAY_SIZE(isc_formats); i++) { 1514 for (i = 0, j = 0; i < ARRAY_SIZE(isc_formats); i++) {
1113 if (fmt->support) 1515 if (fmt->isc_support || fmt->sd_support)
1114 isc->user_formats[j++] = fmt; 1516 isc->user_formats[j++] = fmt;
1115 1517
1116 fmt++; 1518 fmt++;
@@ -1132,7 +1534,7 @@ static int isc_set_default_fmt(struct isc_device *isc)
1132 }; 1534 };
1133 int ret; 1535 int ret;
1134 1536
1135 ret = isc_try_fmt(isc, &f, NULL); 1537 ret = isc_try_fmt(isc, &f, NULL, NULL);
1136 if (ret) 1538 if (ret)
1137 return ret; 1539 return ret;
1138 1540
@@ -1151,6 +1553,12 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
1151 struct vb2_queue *q = &isc->vb2_vidq; 1553 struct vb2_queue *q = &isc->vb2_vidq;
1152 int ret; 1554 int ret;
1153 1555
1556 ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
1557 if (ret < 0) {
1558 v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n");
1559 return ret;
1560 }
1561
1154 isc->current_subdev = container_of(notifier, 1562 isc->current_subdev = container_of(notifier,
1155 struct isc_subdev_entity, notifier); 1563 struct isc_subdev_entity, notifier);
1156 sd_entity = isc->current_subdev; 1564 sd_entity = isc->current_subdev;
@@ -1198,6 +1606,14 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
1198 return ret; 1606 return ret;
1199 } 1607 }
1200 1608
1609 ret = isc_ctrl_init(isc);
1610 if (ret) {
1611 v4l2_err(&isc->v4l2_dev, "Init isc ctrols failed: %d\n", ret);
1612 return ret;
1613 }
1614
1615 INIT_WORK(&isc->awb_work, isc_awb_work);
1616
1201 /* Register video device */ 1617 /* Register video device */
1202 strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); 1618 strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
1203 vdev->release = video_device_release_empty; 1619 vdev->release = video_device_release_empty;
@@ -1207,7 +1623,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
1207 vdev->vfl_dir = VFL_DIR_RX; 1623 vdev->vfl_dir = VFL_DIR_RX;
1208 vdev->queue = q; 1624 vdev->queue = q;
1209 vdev->lock = &isc->lock; 1625 vdev->lock = &isc->lock;
1210 vdev->ctrl_handler = isc->current_subdev->sd->ctrl_handler; 1626 vdev->ctrl_handler = &isc->ctrls.handler;
1211 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; 1627 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
1212 video_set_drvdata(vdev, isc); 1628 video_set_drvdata(vdev, isc);
1213 1629
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
new file mode 100644
index 000000000000..e4867f84514c
--- /dev/null
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -0,0 +1,1368 @@
1/*
2 * Copyright (c) 2011 Atmel Corporation
3 * Josh Wu, <josh.wu@atmel.com>
4 *
5 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
6 * and Sedji Gaouaou
7 * Based on the bttv driver for Bt848 with respective copyright holders
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/clk.h>
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/slab.h>
25#include <linux/of.h>
26
27#include <linux/videodev2.h>
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-dev.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-event.h>
33#include <media/v4l2-of.h>
34#include <media/videobuf2-dma-contig.h>
35#include <media/v4l2-image-sizes.h>
36
37#include "atmel-isi.h"
38
39#define MAX_SUPPORT_WIDTH 2048
40#define MAX_SUPPORT_HEIGHT 2048
41#define MIN_FRAME_RATE 15
42#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
43
44/* Frame buffer descriptor */
45struct fbd {
46 /* Physical address of the frame buffer */
47 u32 fb_address;
48 /* DMA Control Register(only in HISI2) */
49 u32 dma_ctrl;
50 /* Physical address of the next fbd */
51 u32 next_fbd_address;
52};
53
54static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
55{
56 fb_desc->dma_ctrl = ctrl;
57}
58
59struct isi_dma_desc {
60 struct list_head list;
61 struct fbd *p_fbd;
62 dma_addr_t fbd_phys;
63};
64
65/* Frame buffer data */
66struct frame_buffer {
67 struct vb2_v4l2_buffer vb;
68 struct isi_dma_desc *p_dma_desc;
69 struct list_head list;
70};
71
72struct isi_graph_entity {
73 struct device_node *node;
74
75 struct v4l2_async_subdev asd;
76 struct v4l2_subdev *subdev;
77};
78
79/*
80 * struct isi_format - ISI media bus format information
81 * @fourcc: Fourcc code for this format
82 * @mbus_code: V4L2 media bus format code.
83 * @bpp: Bytes per pixel (when stored in memory)
84 * @swap: Byte swap configuration value
85 * @support: Indicates format supported by subdev
86 * @skip: Skip duplicate format supported by subdev
87 */
88struct isi_format {
89 u32 fourcc;
90 u32 mbus_code;
91 u8 bpp;
92 u32 swap;
93};
94
95
96struct atmel_isi {
97 /* Protects the access of variables shared with the ISR */
98 spinlock_t irqlock;
99 struct device *dev;
100 void __iomem *regs;
101
102 int sequence;
103
104 /* Allocate descriptors for dma buffer use */
105 struct fbd *p_fb_descriptors;
106 dma_addr_t fb_descriptors_phys;
107 struct list_head dma_desc_head;
108 struct isi_dma_desc dma_desc[VIDEO_MAX_FRAME];
109 bool enable_preview_path;
110
111 struct completion complete;
112 /* ISI peripherial clock */
113 struct clk *pclk;
114 unsigned int irq;
115
116 struct isi_platform_data pdata;
117 u16 width_flags; /* max 12 bits */
118
119 struct list_head video_buffer_list;
120 struct frame_buffer *active;
121
122 struct v4l2_device v4l2_dev;
123 struct video_device *vdev;
124 struct v4l2_async_notifier notifier;
125 struct isi_graph_entity entity;
126 struct v4l2_format fmt;
127
128 const struct isi_format **user_formats;
129 unsigned int num_user_formats;
130 const struct isi_format *current_fmt;
131
132 struct mutex lock;
133 struct vb2_queue queue;
134};
135
136#define notifier_to_isi(n) container_of(n, struct atmel_isi, notifier)
137
138static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
139{
140 writel(val, isi->regs + reg);
141}
142static u32 isi_readl(struct atmel_isi *isi, u32 reg)
143{
144 return readl(isi->regs + reg);
145}
146
147static void configure_geometry(struct atmel_isi *isi)
148{
149 u32 cfg2, psize;
150 u32 fourcc = isi->current_fmt->fourcc;
151
152 isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
153 fourcc == V4L2_PIX_FMT_RGB32;
154
155 /* According to sensor's output format to set cfg2 */
156 cfg2 = isi->current_fmt->swap;
157
158 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
159 /* Set width */
160 cfg2 |= ((isi->fmt.fmt.pix.width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
161 ISI_CFG2_IM_HSIZE_MASK;
162 /* Set height */
163 cfg2 |= ((isi->fmt.fmt.pix.height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
164 & ISI_CFG2_IM_VSIZE_MASK;
165 isi_writel(isi, ISI_CFG2, cfg2);
166
167 /* No down sampling, preview size equal to sensor output size */
168 psize = ((isi->fmt.fmt.pix.width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) &
169 ISI_PSIZE_PREV_HSIZE_MASK;
170 psize |= ((isi->fmt.fmt.pix.height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) &
171 ISI_PSIZE_PREV_VSIZE_MASK;
172 isi_writel(isi, ISI_PSIZE, psize);
173 isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING);
174}
175
176static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
177{
178 if (isi->active) {
179 struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
180 struct frame_buffer *buf = isi->active;
181
182 list_del_init(&buf->list);
183 vbuf->vb2_buf.timestamp = ktime_get_ns();
184 vbuf->sequence = isi->sequence++;
185 vbuf->field = V4L2_FIELD_NONE;
186 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
187 }
188
189 if (list_empty(&isi->video_buffer_list)) {
190 isi->active = NULL;
191 } else {
192 /* start next dma frame. */
193 isi->active = list_entry(isi->video_buffer_list.next,
194 struct frame_buffer, list);
195 if (!isi->enable_preview_path) {
196 isi_writel(isi, ISI_DMA_C_DSCR,
197 (u32)isi->active->p_dma_desc->fbd_phys);
198 isi_writel(isi, ISI_DMA_C_CTRL,
199 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
200 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
201 } else {
202 isi_writel(isi, ISI_DMA_P_DSCR,
203 (u32)isi->active->p_dma_desc->fbd_phys);
204 isi_writel(isi, ISI_DMA_P_CTRL,
205 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
206 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
207 }
208 }
209 return IRQ_HANDLED;
210}
211
212/* ISI interrupt service routine */
213static irqreturn_t isi_interrupt(int irq, void *dev_id)
214{
215 struct atmel_isi *isi = dev_id;
216 u32 status, mask, pending;
217 irqreturn_t ret = IRQ_NONE;
218
219 spin_lock(&isi->irqlock);
220
221 status = isi_readl(isi, ISI_STATUS);
222 mask = isi_readl(isi, ISI_INTMASK);
223 pending = status & mask;
224
225 if (pending & ISI_CTRL_SRST) {
226 complete(&isi->complete);
227 isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
228 ret = IRQ_HANDLED;
229 } else if (pending & ISI_CTRL_DIS) {
230 complete(&isi->complete);
231 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
232 ret = IRQ_HANDLED;
233 } else {
234 if (likely(pending & ISI_SR_CXFR_DONE) ||
235 likely(pending & ISI_SR_PXFR_DONE))
236 ret = atmel_isi_handle_streaming(isi);
237 }
238
239 spin_unlock(&isi->irqlock);
240 return ret;
241}
242
243#define WAIT_ISI_RESET 1
244#define WAIT_ISI_DISABLE 0
245static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
246{
247 unsigned long timeout;
248 /*
249 * The reset or disable will only succeed if we have a
250 * pixel clock from the camera.
251 */
252 init_completion(&isi->complete);
253
254 if (wait_reset) {
255 isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
256 isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
257 } else {
258 isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
259 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
260 }
261
262 timeout = wait_for_completion_timeout(&isi->complete,
263 msecs_to_jiffies(500));
264 if (timeout == 0)
265 return -ETIMEDOUT;
266
267 return 0;
268}
269
270/* ------------------------------------------------------------------
271 Videobuf operations
272 ------------------------------------------------------------------*/
273static int queue_setup(struct vb2_queue *vq,
274 unsigned int *nbuffers, unsigned int *nplanes,
275 unsigned int sizes[], struct device *alloc_devs[])
276{
277 struct atmel_isi *isi = vb2_get_drv_priv(vq);
278 unsigned long size;
279
280 size = isi->fmt.fmt.pix.sizeimage;
281
282 /* Make sure the image size is large enough. */
283 if (*nplanes)
284 return sizes[0] < size ? -EINVAL : 0;
285
286 *nplanes = 1;
287 sizes[0] = size;
288
289 isi->active = NULL;
290
291 dev_dbg(isi->dev, "%s, count=%d, size=%ld\n", __func__,
292 *nbuffers, size);
293
294 return 0;
295}
296
297static int buffer_init(struct vb2_buffer *vb)
298{
299 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
300 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
301
302 buf->p_dma_desc = NULL;
303 INIT_LIST_HEAD(&buf->list);
304
305 return 0;
306}
307
308static int buffer_prepare(struct vb2_buffer *vb)
309{
310 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
311 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
312 struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
313 unsigned long size;
314 struct isi_dma_desc *desc;
315
316 size = isi->fmt.fmt.pix.sizeimage;
317
318 if (vb2_plane_size(vb, 0) < size) {
319 dev_err(isi->dev, "%s data will not fit into plane (%lu < %lu)\n",
320 __func__, vb2_plane_size(vb, 0), size);
321 return -EINVAL;
322 }
323
324 vb2_set_plane_payload(vb, 0, size);
325
326 if (!buf->p_dma_desc) {
327 if (list_empty(&isi->dma_desc_head)) {
328 dev_err(isi->dev, "Not enough dma descriptors.\n");
329 return -EINVAL;
330 } else {
331 /* Get an available descriptor */
332 desc = list_entry(isi->dma_desc_head.next,
333 struct isi_dma_desc, list);
334 /* Delete the descriptor since now it is used */
335 list_del_init(&desc->list);
336
337 /* Initialize the dma descriptor */
338 desc->p_fbd->fb_address =
339 vb2_dma_contig_plane_dma_addr(vb, 0);
340 desc->p_fbd->next_fbd_address = 0;
341 set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
342
343 buf->p_dma_desc = desc;
344 }
345 }
346 return 0;
347}
348
349static void buffer_cleanup(struct vb2_buffer *vb)
350{
351 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
352 struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
353 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
354
355 /* This descriptor is available now and we add to head list */
356 if (buf->p_dma_desc)
357 list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
358}
359
360static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
361{
362 u32 ctrl, cfg1;
363
364 cfg1 = isi_readl(isi, ISI_CFG1);
365 /* Enable irq: cxfr for the codec path, pxfr for the preview path */
366 isi_writel(isi, ISI_INTEN,
367 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
368
369 /* Check if already in a frame */
370 if (!isi->enable_preview_path) {
371 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
372 dev_err(isi->dev, "Already in frame handling.\n");
373 return;
374 }
375
376 isi_writel(isi, ISI_DMA_C_DSCR,
377 (u32)buffer->p_dma_desc->fbd_phys);
378 isi_writel(isi, ISI_DMA_C_CTRL,
379 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
380 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
381 } else {
382 isi_writel(isi, ISI_DMA_P_DSCR,
383 (u32)buffer->p_dma_desc->fbd_phys);
384 isi_writel(isi, ISI_DMA_P_CTRL,
385 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
386 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
387 }
388
389 cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
390 /* Enable linked list */
391 cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
392
393 /* Enable ISI */
394 ctrl = ISI_CTRL_EN;
395
396 if (!isi->enable_preview_path)
397 ctrl |= ISI_CTRL_CDC;
398
399 isi_writel(isi, ISI_CTRL, ctrl);
400 isi_writel(isi, ISI_CFG1, cfg1);
401}
402
403static void buffer_queue(struct vb2_buffer *vb)
404{
405 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
406 struct atmel_isi *isi = vb2_get_drv_priv(vb->vb2_queue);
407 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
408 unsigned long flags = 0;
409
410 spin_lock_irqsave(&isi->irqlock, flags);
411 list_add_tail(&buf->list, &isi->video_buffer_list);
412
413 if (isi->active == NULL) {
414 isi->active = buf;
415 if (vb2_is_streaming(vb->vb2_queue))
416 start_dma(isi, buf);
417 }
418 spin_unlock_irqrestore(&isi->irqlock, flags);
419}
420
421static int start_streaming(struct vb2_queue *vq, unsigned int count)
422{
423 struct atmel_isi *isi = vb2_get_drv_priv(vq);
424 struct frame_buffer *buf, *node;
425 int ret;
426
427 /* Enable stream on the sub device */
428 ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 1);
429 if (ret && ret != -ENOIOCTLCMD) {
430 dev_err(isi->dev, "stream on failed in subdev\n");
431 goto err_start_stream;
432 }
433
434 pm_runtime_get_sync(isi->dev);
435
436 /* Reset ISI */
437 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
438 if (ret < 0) {
439 dev_err(isi->dev, "Reset ISI timed out\n");
440 goto err_reset;
441 }
442 /* Disable all interrupts */
443 isi_writel(isi, ISI_INTDIS, (u32)~0UL);
444
445 isi->sequence = 0;
446 configure_geometry(isi);
447
448 spin_lock_irq(&isi->irqlock);
449 /* Clear any pending interrupt */
450 isi_readl(isi, ISI_STATUS);
451
452 start_dma(isi, isi->active);
453 spin_unlock_irq(&isi->irqlock);
454
455 return 0;
456
457err_reset:
458 pm_runtime_put(isi->dev);
459 v4l2_subdev_call(isi->entity.subdev, video, s_stream, 0);
460
461err_start_stream:
462 spin_lock_irq(&isi->irqlock);
463 isi->active = NULL;
464 /* Release all active buffers */
465 list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
466 list_del_init(&buf->list);
467 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
468 }
469 spin_unlock_irq(&isi->irqlock);
470
471 return ret;
472}
473
474/* abort streaming and wait for last buffer */
475static void stop_streaming(struct vb2_queue *vq)
476{
477 struct atmel_isi *isi = vb2_get_drv_priv(vq);
478 struct frame_buffer *buf, *node;
479 int ret = 0;
480 unsigned long timeout;
481
482 /* Disable stream on the sub device */
483 ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 0);
484 if (ret && ret != -ENOIOCTLCMD)
485 dev_err(isi->dev, "stream off failed in subdev\n");
486
487 spin_lock_irq(&isi->irqlock);
488 isi->active = NULL;
489 /* Release all active buffers */
490 list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
491 list_del_init(&buf->list);
492 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
493 }
494 spin_unlock_irq(&isi->irqlock);
495
496 if (!isi->enable_preview_path) {
497 timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
498 /* Wait until the end of the current frame. */
499 while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
500 time_before(jiffies, timeout))
501 msleep(1);
502
503 if (time_after(jiffies, timeout))
504 dev_err(isi->dev,
505 "Timeout waiting for finishing codec request\n");
506 }
507
508 /* Disable interrupts */
509 isi_writel(isi, ISI_INTDIS,
510 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
511
512 /* Disable ISI and wait for it is done */
513 ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
514 if (ret < 0)
515 dev_err(isi->dev, "Disable ISI timed out\n");
516
517 pm_runtime_put(isi->dev);
518}
519
520static const struct vb2_ops isi_video_qops = {
521 .queue_setup = queue_setup,
522 .buf_init = buffer_init,
523 .buf_prepare = buffer_prepare,
524 .buf_cleanup = buffer_cleanup,
525 .buf_queue = buffer_queue,
526 .start_streaming = start_streaming,
527 .stop_streaming = stop_streaming,
528 .wait_prepare = vb2_ops_wait_prepare,
529 .wait_finish = vb2_ops_wait_finish,
530};
531
532static int isi_g_fmt_vid_cap(struct file *file, void *priv,
533 struct v4l2_format *fmt)
534{
535 struct atmel_isi *isi = video_drvdata(file);
536
537 *fmt = isi->fmt;
538
539 return 0;
540}
541
542static const struct isi_format *find_format_by_fourcc(struct atmel_isi *isi,
543 unsigned int fourcc)
544{
545 unsigned int num_formats = isi->num_user_formats;
546 const struct isi_format *fmt;
547 unsigned int i;
548
549 for (i = 0; i < num_formats; i++) {
550 fmt = isi->user_formats[i];
551 if (fmt->fourcc == fourcc)
552 return fmt;
553 }
554
555 return NULL;
556}
557
558static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
559 const struct isi_format **current_fmt)
560{
561 const struct isi_format *isi_fmt;
562 struct v4l2_pix_format *pixfmt = &f->fmt.pix;
563 struct v4l2_subdev_pad_config pad_cfg;
564 struct v4l2_subdev_format format = {
565 .which = V4L2_SUBDEV_FORMAT_TRY,
566 };
567 int ret;
568
569 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
570 return -EINVAL;
571
572 isi_fmt = find_format_by_fourcc(isi, pixfmt->pixelformat);
573 if (!isi_fmt) {
574 isi_fmt = isi->user_formats[isi->num_user_formats - 1];
575 pixfmt->pixelformat = isi_fmt->fourcc;
576 }
577
578 /* Limit to Atmel ISC hardware capabilities */
579 if (pixfmt->width > MAX_SUPPORT_WIDTH)
580 pixfmt->width = MAX_SUPPORT_WIDTH;
581 if (pixfmt->height > MAX_SUPPORT_HEIGHT)
582 pixfmt->height = MAX_SUPPORT_HEIGHT;
583
584 v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
585 ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
586 &pad_cfg, &format);
587 if (ret < 0)
588 return ret;
589
590 v4l2_fill_pix_format(pixfmt, &format.format);
591
592 pixfmt->field = V4L2_FIELD_NONE;
593 pixfmt->bytesperline = pixfmt->width * isi_fmt->bpp;
594 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
595
596 if (current_fmt)
597 *current_fmt = isi_fmt;
598
599 return 0;
600}
601
602static int isi_set_fmt(struct atmel_isi *isi, struct v4l2_format *f)
603{
604 struct v4l2_subdev_format format = {
605 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
606 };
607 const struct isi_format *current_fmt;
608 int ret;
609
610 ret = isi_try_fmt(isi, f, &current_fmt);
611 if (ret)
612 return ret;
613
614 v4l2_fill_mbus_format(&format.format, &f->fmt.pix,
615 current_fmt->mbus_code);
616 ret = v4l2_subdev_call(isi->entity.subdev, pad,
617 set_fmt, NULL, &format);
618 if (ret < 0)
619 return ret;
620
621 isi->fmt = *f;
622 isi->current_fmt = current_fmt;
623
624 return 0;
625}
626
627static int isi_s_fmt_vid_cap(struct file *file, void *priv,
628 struct v4l2_format *f)
629{
630 struct atmel_isi *isi = video_drvdata(file);
631
632 if (vb2_is_streaming(&isi->queue))
633 return -EBUSY;
634
635 return isi_set_fmt(isi, f);
636}
637
638static int isi_try_fmt_vid_cap(struct file *file, void *priv,
639 struct v4l2_format *f)
640{
641 struct atmel_isi *isi = video_drvdata(file);
642
643 return isi_try_fmt(isi, f, NULL);
644}
645
646static int isi_enum_fmt_vid_cap(struct file *file, void *priv,
647 struct v4l2_fmtdesc *f)
648{
649 struct atmel_isi *isi = video_drvdata(file);
650
651 if (f->index >= isi->num_user_formats)
652 return -EINVAL;
653
654 f->pixelformat = isi->user_formats[f->index]->fourcc;
655 return 0;
656}
657
658static int isi_querycap(struct file *file, void *priv,
659 struct v4l2_capability *cap)
660{
661 strlcpy(cap->driver, "atmel-isi", sizeof(cap->driver));
662 strlcpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
663 strlcpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
664 return 0;
665}
666
667static int isi_enum_input(struct file *file, void *priv,
668 struct v4l2_input *i)
669{
670 if (i->index != 0)
671 return -EINVAL;
672
673 i->type = V4L2_INPUT_TYPE_CAMERA;
674 strlcpy(i->name, "Camera", sizeof(i->name));
675 return 0;
676}
677
678static int isi_g_input(struct file *file, void *priv, unsigned int *i)
679{
680 *i = 0;
681 return 0;
682}
683
684static int isi_s_input(struct file *file, void *priv, unsigned int i)
685{
686 if (i > 0)
687 return -EINVAL;
688 return 0;
689}
690
691static int isi_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
692{
693 struct atmel_isi *isi = video_drvdata(file);
694
695 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
696 return -EINVAL;
697
698 a->parm.capture.readbuffers = 2;
699 return v4l2_subdev_call(isi->entity.subdev, video, g_parm, a);
700}
701
702static int isi_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
703{
704 struct atmel_isi *isi = video_drvdata(file);
705
706 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
707 return -EINVAL;
708
709 a->parm.capture.readbuffers = 2;
710 return v4l2_subdev_call(isi->entity.subdev, video, s_parm, a);
711}
712
713static int isi_enum_framesizes(struct file *file, void *fh,
714 struct v4l2_frmsizeenum *fsize)
715{
716 struct atmel_isi *isi = video_drvdata(file);
717 const struct isi_format *isi_fmt;
718 struct v4l2_subdev_frame_size_enum fse = {
719 .index = fsize->index,
720 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
721 };
722 int ret;
723
724 isi_fmt = find_format_by_fourcc(isi, fsize->pixel_format);
725 if (!isi_fmt)
726 return -EINVAL;
727
728 fse.code = isi_fmt->mbus_code;
729
730 ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
731 NULL, &fse);
732 if (ret)
733 return ret;
734
735 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
736 fsize->discrete.width = fse.max_width;
737 fsize->discrete.height = fse.max_height;
738
739 return 0;
740}
741
742static int isi_enum_frameintervals(struct file *file, void *fh,
743 struct v4l2_frmivalenum *fival)
744{
745 struct atmel_isi *isi = video_drvdata(file);
746 const struct isi_format *isi_fmt;
747 struct v4l2_subdev_frame_interval_enum fie = {
748 .index = fival->index,
749 .width = fival->width,
750 .height = fival->height,
751 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
752 };
753 int ret;
754
755 isi_fmt = find_format_by_fourcc(isi, fival->pixel_format);
756 if (!isi_fmt)
757 return -EINVAL;
758
759 fie.code = isi_fmt->mbus_code;
760
761 ret = v4l2_subdev_call(isi->entity.subdev, pad,
762 enum_frame_interval, NULL, &fie);
763 if (ret)
764 return ret;
765
766 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
767 fival->discrete = fie.interval;
768
769 return 0;
770}
771
772static void isi_camera_set_bus_param(struct atmel_isi *isi)
773{
774 u32 cfg1 = 0;
775
776 /* set bus param for ISI */
777 if (isi->pdata.hsync_act_low)
778 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
779 if (isi->pdata.vsync_act_low)
780 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
781 if (isi->pdata.pclk_act_falling)
782 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
783 if (isi->pdata.has_emb_sync)
784 cfg1 |= ISI_CFG1_EMB_SYNC;
785 if (isi->pdata.full_mode)
786 cfg1 |= ISI_CFG1_FULL_MODE;
787
788 cfg1 |= ISI_CFG1_THMASK_BEATS_16;
789
790 /* Enable PM and peripheral clock before operate isi registers */
791 pm_runtime_get_sync(isi->dev);
792
793 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
794 isi_writel(isi, ISI_CFG1, cfg1);
795
796 pm_runtime_put(isi->dev);
797}
798
799/* -----------------------------------------------------------------------*/
800static int atmel_isi_parse_dt(struct atmel_isi *isi,
801 struct platform_device *pdev)
802{
803 struct device_node *np = pdev->dev.of_node;
804 struct v4l2_of_endpoint ep;
805 int err;
806
807 /* Default settings for ISI */
808 isi->pdata.full_mode = 1;
809 isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
810
811 np = of_graph_get_next_endpoint(np, NULL);
812 if (!np) {
813 dev_err(&pdev->dev, "Could not find the endpoint\n");
814 return -EINVAL;
815 }
816
817 err = v4l2_of_parse_endpoint(np, &ep);
818 of_node_put(np);
819 if (err) {
820 dev_err(&pdev->dev, "Could not parse the endpoint\n");
821 return err;
822 }
823
824 switch (ep.bus.parallel.bus_width) {
825 case 8:
826 isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
827 break;
828 case 10:
829 isi->pdata.data_width_flags =
830 ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
831 break;
832 default:
833 dev_err(&pdev->dev, "Unsupported bus width: %d\n",
834 ep.bus.parallel.bus_width);
835 return -EINVAL;
836 }
837
838 if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
839 isi->pdata.hsync_act_low = true;
840 if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
841 isi->pdata.vsync_act_low = true;
842 if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
843 isi->pdata.pclk_act_falling = true;
844
845 if (ep.bus_type == V4L2_MBUS_BT656)
846 isi->pdata.has_emb_sync = true;
847
848 return 0;
849}
850
851static int isi_open(struct file *file)
852{
853 struct atmel_isi *isi = video_drvdata(file);
854 struct v4l2_subdev *sd = isi->entity.subdev;
855 int ret;
856
857 if (mutex_lock_interruptible(&isi->lock))
858 return -ERESTARTSYS;
859
860 ret = v4l2_fh_open(file);
861 if (ret < 0)
862 goto unlock;
863
864 if (!v4l2_fh_is_singular_file(file))
865 goto fh_rel;
866
867 ret = v4l2_subdev_call(sd, core, s_power, 1);
868 if (ret < 0 && ret != -ENOIOCTLCMD)
869 goto fh_rel;
870
871 ret = isi_set_fmt(isi, &isi->fmt);
872 if (ret)
873 v4l2_subdev_call(sd, core, s_power, 0);
874fh_rel:
875 if (ret)
876 v4l2_fh_release(file);
877unlock:
878 mutex_unlock(&isi->lock);
879 return ret;
880}
881
882static int isi_release(struct file *file)
883{
884 struct atmel_isi *isi = video_drvdata(file);
885 struct v4l2_subdev *sd = isi->entity.subdev;
886 bool fh_singular;
887 int ret;
888
889 mutex_lock(&isi->lock);
890
891 fh_singular = v4l2_fh_is_singular_file(file);
892
893 ret = _vb2_fop_release(file, NULL);
894
895 if (fh_singular)
896 v4l2_subdev_call(sd, core, s_power, 0);
897
898 mutex_unlock(&isi->lock);
899
900 return ret;
901}
902
903static const struct v4l2_ioctl_ops isi_ioctl_ops = {
904 .vidioc_querycap = isi_querycap,
905
906 .vidioc_try_fmt_vid_cap = isi_try_fmt_vid_cap,
907 .vidioc_g_fmt_vid_cap = isi_g_fmt_vid_cap,
908 .vidioc_s_fmt_vid_cap = isi_s_fmt_vid_cap,
909 .vidioc_enum_fmt_vid_cap = isi_enum_fmt_vid_cap,
910
911 .vidioc_enum_input = isi_enum_input,
912 .vidioc_g_input = isi_g_input,
913 .vidioc_s_input = isi_s_input,
914
915 .vidioc_g_parm = isi_g_parm,
916 .vidioc_s_parm = isi_s_parm,
917 .vidioc_enum_framesizes = isi_enum_framesizes,
918 .vidioc_enum_frameintervals = isi_enum_frameintervals,
919
920 .vidioc_reqbufs = vb2_ioctl_reqbufs,
921 .vidioc_create_bufs = vb2_ioctl_create_bufs,
922 .vidioc_querybuf = vb2_ioctl_querybuf,
923 .vidioc_qbuf = vb2_ioctl_qbuf,
924 .vidioc_dqbuf = vb2_ioctl_dqbuf,
925 .vidioc_expbuf = vb2_ioctl_expbuf,
926 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
927 .vidioc_streamon = vb2_ioctl_streamon,
928 .vidioc_streamoff = vb2_ioctl_streamoff,
929
930 .vidioc_log_status = v4l2_ctrl_log_status,
931 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
932 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
933};
934
935static const struct v4l2_file_operations isi_fops = {
936 .owner = THIS_MODULE,
937 .unlocked_ioctl = video_ioctl2,
938 .open = isi_open,
939 .release = isi_release,
940 .poll = vb2_fop_poll,
941 .mmap = vb2_fop_mmap,
942 .read = vb2_fop_read,
943};
944
945static int isi_set_default_fmt(struct atmel_isi *isi)
946{
947 struct v4l2_format f = {
948 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
949 .fmt.pix = {
950 .width = VGA_WIDTH,
951 .height = VGA_HEIGHT,
952 .field = V4L2_FIELD_NONE,
953 .pixelformat = isi->user_formats[0]->fourcc,
954 },
955 };
956 int ret;
957
958 ret = isi_try_fmt(isi, &f, NULL);
959 if (ret)
960 return ret;
961 isi->current_fmt = isi->user_formats[0];
962 isi->fmt = f;
963 return 0;
964}
965
966static const struct isi_format isi_formats[] = {
967 {
968 .fourcc = V4L2_PIX_FMT_YUYV,
969 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
970 .bpp = 2,
971 .swap = ISI_CFG2_YCC_SWAP_DEFAULT,
972 }, {
973 .fourcc = V4L2_PIX_FMT_YUYV,
974 .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
975 .bpp = 2,
976 .swap = ISI_CFG2_YCC_SWAP_MODE_1,
977 }, {
978 .fourcc = V4L2_PIX_FMT_YUYV,
979 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
980 .bpp = 2,
981 .swap = ISI_CFG2_YCC_SWAP_MODE_2,
982 }, {
983 .fourcc = V4L2_PIX_FMT_YUYV,
984 .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
985 .bpp = 2,
986 .swap = ISI_CFG2_YCC_SWAP_MODE_3,
987 }, {
988 .fourcc = V4L2_PIX_FMT_RGB565,
989 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
990 .bpp = 2,
991 .swap = ISI_CFG2_YCC_SWAP_MODE_2,
992 }, {
993 .fourcc = V4L2_PIX_FMT_RGB565,
994 .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
995 .bpp = 2,
996 .swap = ISI_CFG2_YCC_SWAP_MODE_3,
997 }, {
998 .fourcc = V4L2_PIX_FMT_RGB565,
999 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
1000 .bpp = 2,
1001 .swap = ISI_CFG2_YCC_SWAP_DEFAULT,
1002 }, {
1003 .fourcc = V4L2_PIX_FMT_RGB565,
1004 .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
1005 .bpp = 2,
1006 .swap = ISI_CFG2_YCC_SWAP_MODE_1,
1007 },
1008};
1009
1010static int isi_formats_init(struct atmel_isi *isi)
1011{
1012 const struct isi_format *isi_fmts[ARRAY_SIZE(isi_formats)];
1013 unsigned int num_fmts = 0, i, j;
1014 struct v4l2_subdev *subdev = isi->entity.subdev;
1015 struct v4l2_subdev_mbus_code_enum mbus_code = {
1016 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1017 };
1018
1019 while (!v4l2_subdev_call(subdev, pad, enum_mbus_code,
1020 NULL, &mbus_code)) {
1021 for (i = 0; i < ARRAY_SIZE(isi_formats); i++) {
1022 if (isi_formats[i].mbus_code != mbus_code.code)
1023 continue;
1024
1025 /* Code supported, have we got this fourcc yet? */
1026 for (j = 0; j < num_fmts; j++)
1027 if (isi_fmts[j]->fourcc == isi_formats[i].fourcc)
1028 /* Already available */
1029 break;
1030 if (j == num_fmts)
1031 /* new */
1032 isi_fmts[num_fmts++] = isi_formats + i;
1033 }
1034 mbus_code.index++;
1035 }
1036
1037 if (!num_fmts)
1038 return -ENXIO;
1039
1040 isi->num_user_formats = num_fmts;
1041 isi->user_formats = devm_kcalloc(isi->dev,
1042 num_fmts, sizeof(struct isi_format *),
1043 GFP_KERNEL);
1044 if (!isi->user_formats) {
1045 dev_err(isi->dev, "could not allocate memory\n");
1046 return -ENOMEM;
1047 }
1048
1049 memcpy(isi->user_formats, isi_fmts,
1050 num_fmts * sizeof(struct isi_format *));
1051 isi->current_fmt = isi->user_formats[0];
1052
1053 return 0;
1054}
1055
1056static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier)
1057{
1058 struct atmel_isi *isi = notifier_to_isi(notifier);
1059 int ret;
1060
1061 isi->vdev->ctrl_handler = isi->entity.subdev->ctrl_handler;
1062 ret = isi_formats_init(isi);
1063 if (ret) {
1064 dev_err(isi->dev, "No supported mediabus format found\n");
1065 return ret;
1066 }
1067 isi_camera_set_bus_param(isi);
1068
1069 ret = isi_set_default_fmt(isi);
1070 if (ret) {
1071 dev_err(isi->dev, "Could not set default format\n");
1072 return ret;
1073 }
1074
1075 ret = video_register_device(isi->vdev, VFL_TYPE_GRABBER, -1);
1076 if (ret) {
1077 dev_err(isi->dev, "Failed to register video device\n");
1078 return ret;
1079 }
1080
1081 dev_dbg(isi->dev, "Device registered as %s\n",
1082 video_device_node_name(isi->vdev));
1083 return 0;
1084}
1085
1086static void isi_graph_notify_unbind(struct v4l2_async_notifier *notifier,
1087 struct v4l2_subdev *sd,
1088 struct v4l2_async_subdev *asd)
1089{
1090 struct atmel_isi *isi = notifier_to_isi(notifier);
1091
1092 dev_dbg(isi->dev, "Removing %s\n", video_device_node_name(isi->vdev));
1093
1094 /* Checks internaly if vdev have been init or not */
1095 video_unregister_device(isi->vdev);
1096}
1097
1098static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier,
1099 struct v4l2_subdev *subdev,
1100 struct v4l2_async_subdev *asd)
1101{
1102 struct atmel_isi *isi = notifier_to_isi(notifier);
1103
1104 dev_dbg(isi->dev, "subdev %s bound\n", subdev->name);
1105
1106 isi->entity.subdev = subdev;
1107
1108 return 0;
1109}
1110
1111static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
1112{
1113 struct device_node *ep = NULL;
1114 struct device_node *remote;
1115
1116 while (1) {
1117 ep = of_graph_get_next_endpoint(node, ep);
1118 if (!ep)
1119 return -EINVAL;
1120
1121 remote = of_graph_get_remote_port_parent(ep);
1122 if (!remote) {
1123 of_node_put(ep);
1124 return -EINVAL;
1125 }
1126
1127 /* Remote node to connect */
1128 isi->entity.node = remote;
1129 isi->entity.asd.match_type = V4L2_ASYNC_MATCH_OF;
1130 isi->entity.asd.match.of.node = remote;
1131 return 0;
1132 }
1133}
1134
1135static int isi_graph_init(struct atmel_isi *isi)
1136{
1137 struct v4l2_async_subdev **subdevs = NULL;
1138 int ret;
1139
1140 /* Parse the graph to extract a list of subdevice DT nodes. */
1141 ret = isi_graph_parse(isi, isi->dev->of_node);
1142 if (ret < 0) {
1143 dev_err(isi->dev, "Graph parsing failed\n");
1144 return ret;
1145 }
1146
1147 /* Register the subdevices notifier. */
1148 subdevs = devm_kzalloc(isi->dev, sizeof(*subdevs), GFP_KERNEL);
1149 if (subdevs == NULL) {
1150 of_node_put(isi->entity.node);
1151 return -ENOMEM;
1152 }
1153
1154 subdevs[0] = &isi->entity.asd;
1155
1156 isi->notifier.subdevs = subdevs;
1157 isi->notifier.num_subdevs = 1;
1158 isi->notifier.bound = isi_graph_notify_bound;
1159 isi->notifier.unbind = isi_graph_notify_unbind;
1160 isi->notifier.complete = isi_graph_notify_complete;
1161
1162 ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
1163 if (ret < 0) {
1164 dev_err(isi->dev, "Notifier registration failed\n");
1165 of_node_put(isi->entity.node);
1166 return ret;
1167 }
1168
1169 return 0;
1170}
1171
1172
1173static int atmel_isi_probe(struct platform_device *pdev)
1174{
1175 int irq;
1176 struct atmel_isi *isi;
1177 struct vb2_queue *q;
1178 struct resource *regs;
1179 int ret, i;
1180
1181 isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
1182 if (!isi) {
1183 dev_err(&pdev->dev, "Can't allocate interface!\n");
1184 return -ENOMEM;
1185 }
1186
1187 isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
1188 if (IS_ERR(isi->pclk))
1189 return PTR_ERR(isi->pclk);
1190
1191 ret = atmel_isi_parse_dt(isi, pdev);
1192 if (ret)
1193 return ret;
1194
1195 isi->active = NULL;
1196 isi->dev = &pdev->dev;
1197 mutex_init(&isi->lock);
1198 spin_lock_init(&isi->irqlock);
1199 INIT_LIST_HEAD(&isi->video_buffer_list);
1200 INIT_LIST_HEAD(&isi->dma_desc_head);
1201
1202 q = &isi->queue;
1203
1204 /* Initialize the top-level structure */
1205 ret = v4l2_device_register(&pdev->dev, &isi->v4l2_dev);
1206 if (ret)
1207 return ret;
1208
1209 isi->vdev = video_device_alloc();
1210 if (isi->vdev == NULL) {
1211 ret = -ENOMEM;
1212 goto err_vdev_alloc;
1213 }
1214
1215 /* video node */
1216 isi->vdev->fops = &isi_fops;
1217 isi->vdev->v4l2_dev = &isi->v4l2_dev;
1218 isi->vdev->queue = &isi->queue;
1219 strlcpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
1220 isi->vdev->release = video_device_release;
1221 isi->vdev->ioctl_ops = &isi_ioctl_ops;
1222 isi->vdev->lock = &isi->lock;
1223 isi->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1224 V4L2_CAP_READWRITE;
1225 video_set_drvdata(isi->vdev, isi);
1226
1227 /* buffer queue */
1228 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1229 q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1230 q->lock = &isi->lock;
1231 q->drv_priv = isi;
1232 q->buf_struct_size = sizeof(struct frame_buffer);
1233 q->ops = &isi_video_qops;
1234 q->mem_ops = &vb2_dma_contig_memops;
1235 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1236 q->min_buffers_needed = 2;
1237 q->dev = &pdev->dev;
1238
1239 ret = vb2_queue_init(q);
1240 if (ret < 0) {
1241 dev_err(&pdev->dev, "failed to initialize VB2 queue\n");
1242 goto err_vb2_queue;
1243 }
1244 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
1245 sizeof(struct fbd) * VIDEO_MAX_FRAME,
1246 &isi->fb_descriptors_phys,
1247 GFP_KERNEL);
1248 if (!isi->p_fb_descriptors) {
1249 dev_err(&pdev->dev, "Can't allocate descriptors!\n");
1250 ret = -ENOMEM;
1251 goto err_dma_alloc;
1252 }
1253
1254 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1255 isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
1256 isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
1257 i * sizeof(struct fbd);
1258 list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
1259 }
1260
1261 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1262 isi->regs = devm_ioremap_resource(&pdev->dev, regs);
1263 if (IS_ERR(isi->regs)) {
1264 ret = PTR_ERR(isi->regs);
1265 goto err_ioremap;
1266 }
1267
1268 if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1269 isi->width_flags = 1 << 7;
1270 if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1271 isi->width_flags |= 1 << 9;
1272
1273 irq = platform_get_irq(pdev, 0);
1274 if (irq < 0) {
1275 ret = irq;
1276 goto err_req_irq;
1277 }
1278
1279 ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1280 if (ret) {
1281 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1282 goto err_req_irq;
1283 }
1284 isi->irq = irq;
1285
1286 ret = isi_graph_init(isi);
1287 if (ret < 0)
1288 goto err_req_irq;
1289
1290 pm_suspend_ignore_children(&pdev->dev, true);
1291 pm_runtime_enable(&pdev->dev);
1292 platform_set_drvdata(pdev, isi);
1293 return 0;
1294
1295err_req_irq:
1296err_ioremap:
1297 dma_free_coherent(&pdev->dev,
1298 sizeof(struct fbd) * VIDEO_MAX_FRAME,
1299 isi->p_fb_descriptors,
1300 isi->fb_descriptors_phys);
1301err_dma_alloc:
1302err_vb2_queue:
1303 video_device_release(isi->vdev);
1304err_vdev_alloc:
1305 v4l2_device_unregister(&isi->v4l2_dev);
1306
1307 return ret;
1308}
1309
1310static int atmel_isi_remove(struct platform_device *pdev)
1311{
1312 struct atmel_isi *isi = platform_get_drvdata(pdev);
1313
1314 dma_free_coherent(&pdev->dev,
1315 sizeof(struct fbd) * VIDEO_MAX_FRAME,
1316 isi->p_fb_descriptors,
1317 isi->fb_descriptors_phys);
1318 pm_runtime_disable(&pdev->dev);
1319 v4l2_async_notifier_unregister(&isi->notifier);
1320 v4l2_device_unregister(&isi->v4l2_dev);
1321
1322 return 0;
1323}
1324
1325#ifdef CONFIG_PM
1326static int atmel_isi_runtime_suspend(struct device *dev)
1327{
1328 struct atmel_isi *isi = dev_get_drvdata(dev);
1329
1330 clk_disable_unprepare(isi->pclk);
1331
1332 return 0;
1333}
1334static int atmel_isi_runtime_resume(struct device *dev)
1335{
1336 struct atmel_isi *isi = dev_get_drvdata(dev);
1337
1338 return clk_prepare_enable(isi->pclk);
1339}
1340#endif /* CONFIG_PM */
1341
1342static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1343 SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1344 atmel_isi_runtime_resume, NULL)
1345};
1346
1347static const struct of_device_id atmel_isi_of_match[] = {
1348 { .compatible = "atmel,at91sam9g45-isi" },
1349 { }
1350};
1351MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1352
1353static struct platform_driver atmel_isi_driver = {
1354 .driver = {
1355 .name = "atmel_isi",
1356 .of_match_table = of_match_ptr(atmel_isi_of_match),
1357 .pm = &atmel_isi_dev_pm_ops,
1358 },
1359 .probe = atmel_isi_probe,
1360 .remove = atmel_isi_remove,
1361};
1362
1363module_platform_driver(atmel_isi_driver);
1364
1365MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1366MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1367MODULE_LICENSE("GPL");
1368MODULE_SUPPORTED_DEVICE("video");
diff --git a/drivers/media/platform/soc_camera/atmel-isi.h b/drivers/media/platform/atmel/atmel-isi.h
index 0acb32a2b65c..0acb32a2b65c 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.h
+++ b/drivers/media/platform/atmel/atmel-isi.h
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index 466a44e4549e..403214e00e95 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -179,6 +179,25 @@ static void coda_kfifo_sync_to_device_write(struct coda_ctx *ctx)
179 coda_write(dev, wr_ptr, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); 179 coda_write(dev, wr_ptr, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
180} 180}
181 181
182static int coda_bitstream_pad(struct coda_ctx *ctx, u32 size)
183{
184 unsigned char *buf;
185 u32 n;
186
187 if (size < 6)
188 size = 6;
189
190 buf = kmalloc(size, GFP_KERNEL);
191 if (!buf)
192 return -ENOMEM;
193
194 coda_h264_filler_nal(size, buf);
195 n = kfifo_in(&ctx->bitstream_fifo, buf, size);
196 kfree(buf);
197
198 return (n < size) ? -ENOSPC : 0;
199}
200
182static int coda_bitstream_queue(struct coda_ctx *ctx, 201static int coda_bitstream_queue(struct coda_ctx *ctx,
183 struct vb2_v4l2_buffer *src_buf) 202 struct vb2_v4l2_buffer *src_buf)
184{ 203{
@@ -198,10 +217,10 @@ static int coda_bitstream_queue(struct coda_ctx *ctx,
198static bool coda_bitstream_try_queue(struct coda_ctx *ctx, 217static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
199 struct vb2_v4l2_buffer *src_buf) 218 struct vb2_v4l2_buffer *src_buf)
200{ 219{
220 unsigned long payload = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
201 int ret; 221 int ret;
202 222
203 if (coda_get_bitstream_payload(ctx) + 223 if (coda_get_bitstream_payload(ctx) + payload + 512 >=
204 vb2_get_plane_payload(&src_buf->vb2_buf, 0) + 512 >=
205 ctx->bitstream.size) 224 ctx->bitstream.size)
206 return false; 225 return false;
207 226
@@ -210,6 +229,11 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
210 return true; 229 return true;
211 } 230 }
212 231
232 /* Add zero padding before the first H.264 buffer, if it is too small */
233 if (ctx->qsequence == 0 && payload < 512 &&
234 ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
235 coda_bitstream_pad(ctx, 512 - payload);
236
213 ret = coda_bitstream_queue(ctx, src_buf); 237 ret = coda_bitstream_queue(ctx, src_buf);
214 if (ret < 0) { 238 if (ret < 0) {
215 v4l2_err(&ctx->dev->v4l2_dev, "bitstream buffer overflow\n"); 239 v4l2_err(&ctx->dev->v4l2_dev, "bitstream buffer overflow\n");
@@ -224,7 +248,7 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
224 return true; 248 return true;
225} 249}
226 250
227void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming) 251void coda_fill_bitstream(struct coda_ctx *ctx, struct list_head *buffer_list)
228{ 252{
229 struct vb2_v4l2_buffer *src_buf; 253 struct vb2_v4l2_buffer *src_buf;
230 struct coda_buffer_meta *meta; 254 struct coda_buffer_meta *meta;
@@ -252,9 +276,16 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
252 "dropping invalid JPEG frame %d\n", 276 "dropping invalid JPEG frame %d\n",
253 ctx->qsequence); 277 ctx->qsequence);
254 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 278 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
255 v4l2_m2m_buf_done(src_buf, streaming ? 279 if (buffer_list) {
256 VB2_BUF_STATE_ERROR : 280 struct v4l2_m2m_buffer *m2m_buf;
257 VB2_BUF_STATE_QUEUED); 281
282 m2m_buf = container_of(src_buf,
283 struct v4l2_m2m_buffer,
284 vb);
285 list_add_tail(&m2m_buf->list, buffer_list);
286 } else {
287 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
288 }
258 continue; 289 continue;
259 } 290 }
260 291
@@ -295,7 +326,16 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
295 trace_coda_bit_queue(ctx, src_buf, meta); 326 trace_coda_bit_queue(ctx, src_buf, meta);
296 } 327 }
297 328
298 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 329 if (buffer_list) {
330 struct v4l2_m2m_buffer *m2m_buf;
331
332 m2m_buf = container_of(src_buf,
333 struct v4l2_m2m_buffer,
334 vb);
335 list_add_tail(&m2m_buf->list, buffer_list);
336 } else {
337 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
338 }
299 } else { 339 } else {
300 break; 340 break;
301 } 341 }
@@ -1508,6 +1548,47 @@ static int coda_decoder_reqbufs(struct coda_ctx *ctx,
1508 return 0; 1548 return 0;
1509} 1549}
1510 1550
1551static bool coda_reorder_enable(struct coda_ctx *ctx)
1552{
1553 const char * const *profile_names;
1554 const char * const *level_names;
1555 struct coda_dev *dev = ctx->dev;
1556 int profile, level;
1557
1558 if (dev->devtype->product != CODA_7541 &&
1559 dev->devtype->product != CODA_960)
1560 return false;
1561
1562 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG)
1563 return false;
1564
1565 if (ctx->codec->src_fourcc != V4L2_PIX_FMT_H264)
1566 return true;
1567
1568 profile = coda_h264_profile(ctx->params.h264_profile_idc);
1569 if (profile < 0) {
1570 v4l2_warn(&dev->v4l2_dev, "Invalid H264 Profile: %d\n",
1571 ctx->params.h264_profile_idc);
1572 return false;
1573 }
1574
1575 level = coda_h264_level(ctx->params.h264_level_idc);
1576 if (level < 0) {
1577 v4l2_warn(&dev->v4l2_dev, "Invalid H264 Level: %d\n",
1578 ctx->params.h264_level_idc);
1579 return false;
1580 }
1581
1582 profile_names = v4l2_ctrl_get_menu(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
1583 level_names = v4l2_ctrl_get_menu(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
1584
1585 v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "H264 Profile/Level: %s L%s\n",
1586 profile_names[profile], level_names[level]);
1587
1588 /* Baseline profile does not support reordering */
1589 return profile > V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1590}
1591
1511static int __coda_start_decoding(struct coda_ctx *ctx) 1592static int __coda_start_decoding(struct coda_ctx *ctx)
1512{ 1593{
1513 struct coda_q_data *q_data_src, *q_data_dst; 1594 struct coda_q_data *q_data_src, *q_data_dst;
@@ -1554,8 +1635,7 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
1554 coda_write(dev, bitstream_buf, CODA_CMD_DEC_SEQ_BB_START); 1635 coda_write(dev, bitstream_buf, CODA_CMD_DEC_SEQ_BB_START);
1555 coda_write(dev, bitstream_size / 1024, CODA_CMD_DEC_SEQ_BB_SIZE); 1636 coda_write(dev, bitstream_size / 1024, CODA_CMD_DEC_SEQ_BB_SIZE);
1556 val = 0; 1637 val = 0;
1557 if ((dev->devtype->product == CODA_7541) || 1638 if (coda_reorder_enable(ctx))
1558 (dev->devtype->product == CODA_960))
1559 val |= CODA_REORDER_ENABLE; 1639 val |= CODA_REORDER_ENABLE;
1560 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG) 1640 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG)
1561 val |= CODA_NO_INT_ENABLE; 1641 val |= CODA_NO_INT_ENABLE;
@@ -1747,7 +1827,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
1747 1827
1748 /* Try to copy source buffer contents into the bitstream ringbuffer */ 1828 /* Try to copy source buffer contents into the bitstream ringbuffer */
1749 mutex_lock(&ctx->bitstream_mutex); 1829 mutex_lock(&ctx->bitstream_mutex);
1750 coda_fill_bitstream(ctx, true); 1830 coda_fill_bitstream(ctx, NULL);
1751 mutex_unlock(&ctx->bitstream_mutex); 1831 mutex_unlock(&ctx->bitstream_mutex);
1752 1832
1753 if (coda_get_bitstream_payload(ctx) < 512 && 1833 if (coda_get_bitstream_payload(ctx) < 512 &&
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index eb6548f46cba..d523e990d509 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -71,6 +71,10 @@ static int disable_vdoa;
71module_param(disable_vdoa, int, 0644); 71module_param(disable_vdoa, int, 0644);
72MODULE_PARM_DESC(disable_vdoa, "Disable Video Data Order Adapter tiled to raster-scan conversion"); 72MODULE_PARM_DESC(disable_vdoa, "Disable Video Data Order Adapter tiled to raster-scan conversion");
73 73
74static int enable_bwb = 0;
75module_param(enable_bwb, int, 0644);
76MODULE_PARM_DESC(enable_bwb, "Enable BWB unit, may crash on certain streams");
77
74void coda_write(struct coda_dev *dev, u32 data, u32 reg) 78void coda_write(struct coda_dev *dev, u32 data, u32 reg)
75{ 79{
76 v4l2_dbg(2, coda_debug, &dev->v4l2_dev, 80 v4l2_dbg(2, coda_debug, &dev->v4l2_dev,
@@ -386,6 +390,7 @@ static int coda_enum_fmt(struct file *file, void *priv,
386{ 390{
387 struct video_device *vdev = video_devdata(file); 391 struct video_device *vdev = video_devdata(file);
388 const struct coda_video_device *cvd = to_coda_video_device(vdev); 392 const struct coda_video_device *cvd = to_coda_video_device(vdev);
393 struct coda_ctx *ctx = fh_to_ctx(priv);
389 const u32 *formats; 394 const u32 *formats;
390 395
391 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 396 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -398,6 +403,11 @@ static int coda_enum_fmt(struct file *file, void *priv,
398 if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0) 403 if (f->index >= CODA_MAX_FORMATS || formats[f->index] == 0)
399 return -EINVAL; 404 return -EINVAL;
400 405
406 /* Skip YUYV if the vdoa is not available */
407 if (!ctx->vdoa && f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
408 formats[f->index] == V4L2_PIX_FMT_YUYV)
409 return -EINVAL;
410
401 f->pixelformat = formats[f->index]; 411 f->pixelformat = formats[f->index];
402 412
403 return 0; 413 return 0;
@@ -813,10 +823,6 @@ static int coda_qbuf(struct file *file, void *priv,
813static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx, 823static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx,
814 struct vb2_v4l2_buffer *buf) 824 struct vb2_v4l2_buffer *buf)
815{ 825{
816 struct vb2_queue *src_vq;
817
818 src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
819
820 return ((ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) && 826 return ((ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) &&
821 (buf->sequence == (ctx->qsequence - 1))); 827 (buf->sequence == (ctx->qsequence - 1)));
822} 828}
@@ -881,6 +887,47 @@ static int coda_g_selection(struct file *file, void *fh,
881 return 0; 887 return 0;
882} 888}
883 889
890static int coda_try_encoder_cmd(struct file *file, void *fh,
891 struct v4l2_encoder_cmd *ec)
892{
893 if (ec->cmd != V4L2_ENC_CMD_STOP)
894 return -EINVAL;
895
896 if (ec->flags & V4L2_ENC_CMD_STOP_AT_GOP_END)
897 return -EINVAL;
898
899 return 0;
900}
901
902static int coda_encoder_cmd(struct file *file, void *fh,
903 struct v4l2_encoder_cmd *ec)
904{
905 struct coda_ctx *ctx = fh_to_ctx(fh);
906 struct vb2_queue *dst_vq;
907 int ret;
908
909 ret = coda_try_encoder_cmd(file, fh, ec);
910 if (ret < 0)
911 return ret;
912
913 /* Ignore encoder stop command silently in decoder context */
914 if (ctx->inst_type != CODA_INST_ENCODER)
915 return 0;
916
917 /* Set the stream-end flag on this context */
918 ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
919
920 /* If there is no buffer in flight, wake up */
921 if (ctx->qsequence == ctx->osequence) {
922 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
923 V4L2_BUF_TYPE_VIDEO_CAPTURE);
924 dst_vq->last_buffer_dequeued = true;
925 wake_up(&dst_vq->done_wq);
926 }
927
928 return 0;
929}
930
884static int coda_try_decoder_cmd(struct file *file, void *fh, 931static int coda_try_decoder_cmd(struct file *file, void *fh,
885 struct v4l2_decoder_cmd *dc) 932 struct v4l2_decoder_cmd *dc)
886{ 933{
@@ -1054,6 +1101,8 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
1054 1101
1055 .vidioc_g_selection = coda_g_selection, 1102 .vidioc_g_selection = coda_g_selection,
1056 1103
1104 .vidioc_try_encoder_cmd = coda_try_encoder_cmd,
1105 .vidioc_encoder_cmd = coda_encoder_cmd,
1057 .vidioc_try_decoder_cmd = coda_try_decoder_cmd, 1106 .vidioc_try_decoder_cmd = coda_try_decoder_cmd,
1058 .vidioc_decoder_cmd = coda_decoder_cmd, 1107 .vidioc_decoder_cmd = coda_decoder_cmd,
1059 1108
@@ -1327,12 +1376,28 @@ static void coda_buf_queue(struct vb2_buffer *vb)
1327 */ 1376 */
1328 if (vb2_get_plane_payload(vb, 0) == 0) 1377 if (vb2_get_plane_payload(vb, 0) == 0)
1329 coda_bit_stream_end_flag(ctx); 1378 coda_bit_stream_end_flag(ctx);
1379
1380 if (q_data->fourcc == V4L2_PIX_FMT_H264) {
1381 /*
1382 * Unless already done, try to obtain profile_idc and
1383 * level_idc from the SPS header. This allows to decide
1384 * whether to enable reordering during sequence
1385 * initialization.
1386 */
1387 if (!ctx->params.h264_profile_idc)
1388 coda_sps_parse_profile(ctx, vb);
1389 }
1390
1330 mutex_lock(&ctx->bitstream_mutex); 1391 mutex_lock(&ctx->bitstream_mutex);
1331 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 1392 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1332 if (vb2_is_streaming(vb->vb2_queue)) 1393 if (vb2_is_streaming(vb->vb2_queue))
1333 coda_fill_bitstream(ctx, true); 1394 /* This set buf->sequence = ctx->qsequence++ */
1395 coda_fill_bitstream(ctx, NULL);
1334 mutex_unlock(&ctx->bitstream_mutex); 1396 mutex_unlock(&ctx->bitstream_mutex);
1335 } else { 1397 } else {
1398 if (ctx->inst_type == CODA_INST_ENCODER &&
1399 vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1400 vbuf->sequence = ctx->qsequence++;
1336 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 1401 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1337 } 1402 }
1338} 1403}
@@ -1344,7 +1409,7 @@ int coda_alloc_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf,
1344 GFP_KERNEL); 1409 GFP_KERNEL);
1345 if (!buf->vaddr) { 1410 if (!buf->vaddr) {
1346 v4l2_err(&dev->v4l2_dev, 1411 v4l2_err(&dev->v4l2_dev,
1347 "Failed to allocate %s buffer of size %u\n", 1412 "Failed to allocate %s buffer of size %zu\n",
1348 name, size); 1413 name, size);
1349 return -ENOMEM; 1414 return -ENOMEM;
1350 } 1415 }
@@ -1382,18 +1447,22 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
1382 struct coda_ctx *ctx = vb2_get_drv_priv(q); 1447 struct coda_ctx *ctx = vb2_get_drv_priv(q);
1383 struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev; 1448 struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
1384 struct coda_q_data *q_data_src, *q_data_dst; 1449 struct coda_q_data *q_data_src, *q_data_dst;
1450 struct v4l2_m2m_buffer *m2m_buf, *tmp;
1385 struct vb2_v4l2_buffer *buf; 1451 struct vb2_v4l2_buffer *buf;
1452 struct list_head list;
1386 int ret = 0; 1453 int ret = 0;
1387 1454
1388 if (count < 1) 1455 if (count < 1)
1389 return -EINVAL; 1456 return -EINVAL;
1390 1457
1458 INIT_LIST_HEAD(&list);
1459
1391 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 1460 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1392 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1461 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1393 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) { 1462 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) {
1394 /* copy the buffers that were queued before streamon */ 1463 /* copy the buffers that were queued before streamon */
1395 mutex_lock(&ctx->bitstream_mutex); 1464 mutex_lock(&ctx->bitstream_mutex);
1396 coda_fill_bitstream(ctx, false); 1465 coda_fill_bitstream(ctx, &list);
1397 mutex_unlock(&ctx->bitstream_mutex); 1466 mutex_unlock(&ctx->bitstream_mutex);
1398 1467
1399 if (coda_get_bitstream_payload(ctx) < 512) { 1468 if (coda_get_bitstream_payload(ctx) < 512) {
@@ -1408,8 +1477,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
1408 } 1477 }
1409 1478
1410 /* Don't start the coda unless both queues are on */ 1479 /* Don't start the coda unless both queues are on */
1411 if (!(ctx->streamon_out & ctx->streamon_cap)) 1480 if (!(ctx->streamon_out && ctx->streamon_cap))
1412 return 0; 1481 goto out;
1413 1482
1414 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 1483 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1415 if ((q_data_src->width != q_data_dst->width && 1484 if ((q_data_src->width != q_data_dst->width &&
@@ -1444,15 +1513,26 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
1444 ret = ctx->ops->start_streaming(ctx); 1513 ret = ctx->ops->start_streaming(ctx);
1445 if (ctx->inst_type == CODA_INST_DECODER) { 1514 if (ctx->inst_type == CODA_INST_DECODER) {
1446 if (ret == -EAGAIN) 1515 if (ret == -EAGAIN)
1447 return 0; 1516 goto out;
1448 else if (ret < 0)
1449 goto err;
1450 } 1517 }
1518 if (ret < 0)
1519 goto err;
1451 1520
1452 return ret; 1521out:
1522 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1523 list_for_each_entry_safe(m2m_buf, tmp, &list, list) {
1524 list_del(&m2m_buf->list);
1525 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_DONE);
1526 }
1527 }
1528 return 0;
1453 1529
1454err: 1530err:
1455 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1531 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1532 list_for_each_entry_safe(m2m_buf, tmp, &list, list) {
1533 list_del(&m2m_buf->list);
1534 v4l2_m2m_buf_done(&m2m_buf->vb, VB2_BUF_STATE_QUEUED);
1535 }
1456 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) 1536 while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
1457 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); 1537 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
1458 } else { 1538 } else {
@@ -1832,7 +1912,8 @@ static int coda_open(struct file *file)
1832 ctx->idx = idx; 1912 ctx->idx = idx;
1833 switch (dev->devtype->product) { 1913 switch (dev->devtype->product) {
1834 case CODA_960: 1914 case CODA_960:
1835 ctx->frame_mem_ctrl = 1 << 12; 1915 if (enable_bwb)
1916 ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB;
1836 /* fallthrough */ 1917 /* fallthrough */
1837 case CODA_7541: 1918 case CODA_7541:
1838 ctx->reg_idx = 0; 1919 ctx->reg_idx = 0;
@@ -2126,7 +2207,12 @@ static void coda_fw_callback(const struct firmware *fw, void *context);
2126 2207
2127static int coda_firmware_request(struct coda_dev *dev) 2208static int coda_firmware_request(struct coda_dev *dev)
2128{ 2209{
2129 char *fw = dev->devtype->firmware[dev->firmware]; 2210 char *fw;
2211
2212 if (dev->firmware >= ARRAY_SIZE(dev->devtype->firmware))
2213 return -EINVAL;
2214
2215 fw = dev->devtype->firmware[dev->firmware];
2130 2216
2131 dev_dbg(&dev->plat_dev->dev, "requesting firmware '%s' for %s\n", fw, 2217 dev_dbg(&dev->plat_dev->dev, "requesting firmware '%s' for %s\n", fw,
2132 coda_product_name(dev->devtype->product)); 2218 coda_product_name(dev->devtype->product));
@@ -2142,16 +2228,16 @@ static void coda_fw_callback(const struct firmware *fw, void *context)
2142 struct platform_device *pdev = dev->plat_dev; 2228 struct platform_device *pdev = dev->plat_dev;
2143 int i, ret; 2229 int i, ret;
2144 2230
2145 if (!fw && dev->firmware == 1) {
2146 v4l2_err(&dev->v4l2_dev, "firmware request failed\n");
2147 goto put_pm;
2148 }
2149 if (!fw) { 2231 if (!fw) {
2150 dev->firmware = 1; 2232 dev->firmware++;
2151 coda_firmware_request(dev); 2233 ret = coda_firmware_request(dev);
2234 if (ret < 0) {
2235 v4l2_err(&dev->v4l2_dev, "firmware request failed\n");
2236 goto put_pm;
2237 }
2152 return; 2238 return;
2153 } 2239 }
2154 if (dev->firmware == 1) { 2240 if (dev->firmware > 0) {
2155 /* 2241 /*
2156 * Since we can't suppress warnings for failed asynchronous 2242 * Since we can't suppress warnings for failed asynchronous
2157 * firmware requests, report that the fallback firmware was 2243 * firmware requests, report that the fallback firmware was
diff --git a/drivers/media/platform/coda/coda-h264.c b/drivers/media/platform/coda/coda-h264.c
index 09dfcca7cc50..0e27412e01f5 100644
--- a/drivers/media/platform/coda/coda-h264.c
+++ b/drivers/media/platform/coda/coda-h264.c
@@ -13,12 +13,59 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/videodev2.h>
16#include <coda.h> 17#include <coda.h>
17 18
18static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff,
19 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 };
20static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 }; 19static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
21 20
21static const u8 *coda_find_nal_header(const u8 *buf, const u8 *end)
22{
23 u32 val = 0xffffffff;
24
25 do {
26 val = val << 8 | *buf++;
27 if (buf >= end)
28 return NULL;
29 } while (val != 0x00000001);
30
31 return buf;
32}
33
34int coda_sps_parse_profile(struct coda_ctx *ctx, struct vb2_buffer *vb)
35{
36 const u8 *buf = vb2_plane_vaddr(vb, 0);
37 const u8 *end = buf + vb2_get_plane_payload(vb, 0);
38
39 /* Find SPS header */
40 do {
41 buf = coda_find_nal_header(buf, end);
42 if (!buf)
43 return -EINVAL;
44 } while ((*buf++ & 0x1f) != 0x7);
45
46 ctx->params.h264_profile_idc = buf[0];
47 ctx->params.h264_level_idc = buf[2];
48
49 return 0;
50}
51
52int coda_h264_filler_nal(int size, char *p)
53{
54 if (size < 6)
55 return -EINVAL;
56
57 p[0] = 0x00;
58 p[1] = 0x00;
59 p[2] = 0x00;
60 p[3] = 0x01;
61 p[4] = 0x0c;
62 memset(p + 5, 0xff, size - 6);
63 /* Add rbsp stop bit and trailing at the end */
64 p[size - 1] = 0x80;
65
66 return 0;
67}
68
22int coda_h264_padding(int size, char *p) 69int coda_h264_padding(int size, char *p)
23{ 70{
24 int nal_size; 71 int nal_size;
@@ -29,10 +76,38 @@ int coda_h264_padding(int size, char *p)
29 return 0; 76 return 0;
30 77
31 nal_size = coda_filler_size[diff]; 78 nal_size = coda_filler_size[diff];
32 memcpy(p, coda_filler_nal, nal_size); 79 coda_h264_filler_nal(nal_size, p);
33
34 /* Add rbsp stop bit and trailing at the end */
35 *(p + nal_size - 1) = 0x80;
36 80
37 return nal_size; 81 return nal_size;
38} 82}
83
84int coda_h264_profile(int profile_idc)
85{
86 switch (profile_idc) {
87 case 66: return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
88 case 77: return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
89 case 88: return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
90 case 100: return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
91 default: return -EINVAL;
92 }
93}
94
95int coda_h264_level(int level_idc)
96{
97 switch (level_idc) {
98 case 10: return V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
99 case 9: return V4L2_MPEG_VIDEO_H264_LEVEL_1B;
100 case 11: return V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
101 case 12: return V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
102 case 13: return V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
103 case 20: return V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
104 case 21: return V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
105 case 22: return V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
106 case 30: return V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
107 case 31: return V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
108 case 32: return V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
109 case 40: return V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
110 case 41: return V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
111 default: return -EINVAL;
112 }
113}
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 4b831c91ae4a..20222befb9b2 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -28,7 +28,7 @@
28 28
29#include "coda_regs.h" 29#include "coda_regs.h"
30 30
31#define CODA_MAX_FRAMEBUFFERS 8 31#define CODA_MAX_FRAMEBUFFERS 17
32#define FMO_SLICE_SAVE_BUF_SIZE (32) 32#define FMO_SLICE_SAVE_BUF_SIZE (32)
33 33
34enum { 34enum {
@@ -117,6 +117,8 @@ struct coda_params {
117 u8 h264_deblk_enabled; 117 u8 h264_deblk_enabled;
118 u8 h264_deblk_alpha; 118 u8 h264_deblk_alpha;
119 u8 h264_deblk_beta; 119 u8 h264_deblk_beta;
120 u8 h264_profile_idc;
121 u8 h264_level_idc;
120 u8 mpeg4_intra_qp; 122 u8 mpeg4_intra_qp;
121 u8 mpeg4_inter_qp; 123 u8 mpeg4_inter_qp;
122 u8 gop_size; 124 u8 gop_size;
@@ -259,7 +261,7 @@ int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq,
259 261
260int coda_hw_reset(struct coda_ctx *ctx); 262int coda_hw_reset(struct coda_ctx *ctx);
261 263
262void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming); 264void coda_fill_bitstream(struct coda_ctx *ctx, struct list_head *buffer_list);
263 265
264void coda_set_gdi_regs(struct coda_ctx *ctx); 266void coda_set_gdi_regs(struct coda_ctx *ctx);
265 267
@@ -290,7 +292,11 @@ void coda_bit_stream_end_flag(struct coda_ctx *ctx);
290void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf, 292void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
291 enum vb2_buffer_state state); 293 enum vb2_buffer_state state);
292 294
295int coda_h264_filler_nal(int size, char *p);
293int coda_h264_padding(int size, char *p); 296int coda_h264_padding(int size, char *p);
297int coda_h264_profile(int profile_idc);
298int coda_h264_level(int level_idc);
299int coda_sps_parse_profile(struct coda_ctx *ctx, struct vb2_buffer *vb);
294 300
295bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb); 301bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb);
296int coda_jpeg_write_tables(struct coda_ctx *ctx); 302int coda_jpeg_write_tables(struct coda_ctx *ctx);
diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h
index 3490602fa6e1..77ee46a93427 100644
--- a/drivers/media/platform/coda/coda_regs.h
+++ b/drivers/media/platform/coda/coda_regs.h
@@ -51,6 +51,7 @@
51#define CODA7_STREAM_SEL_64BITS_ENDIAN (1 << 1) 51#define CODA7_STREAM_SEL_64BITS_ENDIAN (1 << 1)
52#define CODA_STREAM_ENDIAN_SELECT (1 << 0) 52#define CODA_STREAM_ENDIAN_SELECT (1 << 0)
53#define CODA_REG_BIT_FRAME_MEM_CTRL 0x110 53#define CODA_REG_BIT_FRAME_MEM_CTRL 0x110
54#define CODA9_FRAME_ENABLE_BWB (1 << 12)
54#define CODA9_FRAME_TILED2LINEAR (1 << 11) 55#define CODA9_FRAME_TILED2LINEAR (1 << 11)
55#define CODA_FRAME_CHROMA_INTERLEAVE (1 << 2) 56#define CODA_FRAME_CHROMA_INTERLEAVE (1 << 2)
56#define CODA_IMAGE_ENDIAN_SELECT (1 << 0) 57#define CODA_IMAGE_ENDIAN_SELECT (1 << 0)
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 50c30731bb78..7e5cf9923c8d 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -1287,7 +1287,7 @@ static __init int vpif_probe(struct platform_device *pdev)
1287 } 1287 }
1288 1288
1289 if (!vpif_obj.config->asd_sizes) { 1289 if (!vpif_obj.config->asd_sizes) {
1290 i2c_adap = i2c_get_adapter(1); 1290 i2c_adap = i2c_get_adapter(vpif_obj.config->i2c_adapter_id);
1291 for (i = 0; i < subdev_count; i++) { 1291 for (i = 0; i < subdev_count; i++) {
1292 vpif_obj.sd[i] = 1292 vpif_obj.sd[i] =
1293 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, 1293 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index 0f0c389f8897..59a634201830 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -112,6 +112,15 @@ static const struct gsc_fmt gsc_formats[] = {
112 .num_planes = 1, 112 .num_planes = 1,
113 .num_comp = 2, 113 .num_comp = 2,
114 }, { 114 }, {
115 .name = "YUV 4:2:2 non-contig, Y/CbCr",
116 .pixelformat = V4L2_PIX_FMT_NV16M,
117 .depth = { 8, 8 },
118 .color = GSC_YUV422,
119 .yorder = GSC_LSB_Y,
120 .corder = GSC_CBCR,
121 .num_planes = 2,
122 .num_comp = 2,
123 }, {
115 .name = "YUV 4:2:2 planar, Y/CrCb", 124 .name = "YUV 4:2:2 planar, Y/CrCb",
116 .pixelformat = V4L2_PIX_FMT_NV61, 125 .pixelformat = V4L2_PIX_FMT_NV61,
117 .depth = { 16 }, 126 .depth = { 16 },
@@ -121,6 +130,15 @@ static const struct gsc_fmt gsc_formats[] = {
121 .num_planes = 1, 130 .num_planes = 1,
122 .num_comp = 2, 131 .num_comp = 2,
123 }, { 132 }, {
133 .name = "YUV 4:2:2 non-contig, Y/CrCb",
134 .pixelformat = V4L2_PIX_FMT_NV61M,
135 .depth = { 8, 8 },
136 .color = GSC_YUV422,
137 .yorder = GSC_LSB_Y,
138 .corder = GSC_CRCB,
139 .num_planes = 2,
140 .num_comp = 2,
141 }, {
124 .name = "YUV 4:2:0 planar, YCbCr", 142 .name = "YUV 4:2:0 planar, YCbCr",
125 .pixelformat = V4L2_PIX_FMT_YUV420, 143 .pixelformat = V4L2_PIX_FMT_YUV420,
126 .depth = { 12 }, 144 .depth = { 12 },
@@ -158,6 +176,15 @@ static const struct gsc_fmt gsc_formats[] = {
158 .num_planes = 1, 176 .num_planes = 1,
159 .num_comp = 2, 177 .num_comp = 2,
160 }, { 178 }, {
179 .name = "YUV 4:2:0 non-contig. 2p, Y/CrCb",
180 .pixelformat = V4L2_PIX_FMT_NV21M,
181 .depth = { 8, 4 },
182 .color = GSC_YUV420,
183 .yorder = GSC_LSB_Y,
184 .corder = GSC_CRCB,
185 .num_planes = 2,
186 .num_comp = 2,
187 }, {
161 .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr", 188 .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr",
162 .pixelformat = V4L2_PIX_FMT_NV12M, 189 .pixelformat = V4L2_PIX_FMT_NV12M,
163 .depth = { 8, 4 }, 190 .depth = { 8, 4 },
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index ae8c6b35a357..97e164b2075a 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -1466,9 +1466,8 @@ static int viu_of_probe(struct platform_device *op)
1466 viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad, 1466 viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
1467 "saa7113", VIU_VIDEO_DECODER_ADDR, NULL); 1467 "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
1468 1468
1469 viu_dev->vidq.timeout.function = viu_vid_timeout; 1469 setup_timer(&viu_dev->vidq.timeout, viu_vid_timeout,
1470 viu_dev->vidq.timeout.data = (unsigned long)viu_dev; 1470 (unsigned long)viu_dev);
1471 init_timer(&viu_dev->vidq.timeout);
1472 viu_dev->std = V4L2_STD_NTSC_M; 1471 viu_dev->std = V4L2_STD_NTSC_M;
1473 viu_dev->first = 1; 1472 viu_dev->first = 1;
1474 1473
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index bedc7cc4c7d6..980066b8d32a 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -1017,6 +1017,7 @@ static int deinterlace_probe(struct platform_device *pdev)
1017 1017
1018 if (!dma_has_cap(DMA_INTERLEAVE, pcdev->dma_chan->device->cap_mask)) { 1018 if (!dma_has_cap(DMA_INTERLEAVE, pcdev->dma_chan->device->cap_mask)) {
1019 dev_err(&pdev->dev, "DMA does not support INTERLEAVE\n"); 1019 dev_err(&pdev->dev, "DMA does not support INTERLEAVE\n");
1020 ret = -ENODEV;
1020 goto rel_dma; 1021 goto rel_dma;
1021 } 1022 }
1022 1023
diff --git a/drivers/media/platform/mtk-jpeg/Makefile b/drivers/media/platform/mtk-jpeg/Makefile
new file mode 100644
index 000000000000..b2e6069f3959
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/Makefile
@@ -0,0 +1,2 @@
1mtk_jpeg-objs := mtk_jpeg_core.o mtk_jpeg_hw.o mtk_jpeg_parse.o
2obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
new file mode 100644
index 000000000000..451a54039e65
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -0,0 +1,1292 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk.h>
17#include <linux/err.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of_platform.h>
23#include <linux/platform_device.h>
24#include <linux/pm_runtime.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <media/v4l2-event.h>
28#include <media/v4l2-mem2mem.h>
29#include <media/v4l2-ioctl.h>
30#include <media/videobuf2-core.h>
31#include <media/videobuf2-dma-contig.h>
32#include <soc/mediatek/smi.h>
33
34#include "mtk_jpeg_hw.h"
35#include "mtk_jpeg_core.h"
36#include "mtk_jpeg_parse.h"
37
38static struct mtk_jpeg_fmt mtk_jpeg_formats[] = {
39 {
40 .fourcc = V4L2_PIX_FMT_JPEG,
41 .colplanes = 1,
42 .flags = MTK_JPEG_FMT_FLAG_DEC_OUTPUT,
43 },
44 {
45 .fourcc = V4L2_PIX_FMT_YUV420M,
46 .h_sample = {4, 2, 2},
47 .v_sample = {4, 2, 2},
48 .colplanes = 3,
49 .h_align = 5,
50 .v_align = 4,
51 .flags = MTK_JPEG_FMT_FLAG_DEC_CAPTURE,
52 },
53 {
54 .fourcc = V4L2_PIX_FMT_YUV422M,
55 .h_sample = {4, 2, 2},
56 .v_sample = {4, 4, 4},
57 .colplanes = 3,
58 .h_align = 5,
59 .v_align = 3,
60 .flags = MTK_JPEG_FMT_FLAG_DEC_CAPTURE,
61 },
62};
63
64#define MTK_JPEG_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_formats)
65
66enum {
67 MTK_JPEG_BUF_FLAGS_INIT = 0,
68 MTK_JPEG_BUF_FLAGS_LAST_FRAME = 1,
69};
70
71struct mtk_jpeg_src_buf {
72 struct vb2_v4l2_buffer b;
73 struct list_head list;
74 int flags;
75 struct mtk_jpeg_dec_param dec_param;
76};
77
78static int debug;
79module_param(debug, int, 0644);
80
81static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh)
82{
83 return container_of(fh, struct mtk_jpeg_ctx, fh);
84}
85
86static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf(
87 struct vb2_buffer *vb)
88{
89 return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b);
90}
91
92static int mtk_jpeg_querycap(struct file *file, void *priv,
93 struct v4l2_capability *cap)
94{
95 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
96
97 strlcpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver));
98 strlcpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card));
99 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
100 dev_name(jpeg->dev));
101
102 return 0;
103}
104
105static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n,
106 struct v4l2_fmtdesc *f, u32 type)
107{
108 int i, num = 0;
109
110 for (i = 0; i < n; ++i) {
111 if (mtk_jpeg_formats[i].flags & type) {
112 if (num == f->index)
113 break;
114 ++num;
115 }
116 }
117
118 if (i >= n)
119 return -EINVAL;
120
121 f->pixelformat = mtk_jpeg_formats[i].fourcc;
122
123 return 0;
124}
125
126static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
127 struct v4l2_fmtdesc *f)
128{
129 return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f,
130 MTK_JPEG_FMT_FLAG_DEC_CAPTURE);
131}
132
133static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
134 struct v4l2_fmtdesc *f)
135{
136 return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f,
137 MTK_JPEG_FMT_FLAG_DEC_OUTPUT);
138}
139
140static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx,
141 enum v4l2_buf_type type)
142{
143 if (V4L2_TYPE_IS_OUTPUT(type))
144 return &ctx->out_q;
145 return &ctx->cap_q;
146}
147
148static struct mtk_jpeg_fmt *mtk_jpeg_find_format(struct mtk_jpeg_ctx *ctx,
149 u32 pixelformat,
150 unsigned int fmt_type)
151{
152 unsigned int k, fmt_flag;
153
154 fmt_flag = (fmt_type == MTK_JPEG_FMT_TYPE_OUTPUT) ?
155 MTK_JPEG_FMT_FLAG_DEC_OUTPUT :
156 MTK_JPEG_FMT_FLAG_DEC_CAPTURE;
157
158 for (k = 0; k < MTK_JPEG_NUM_FORMATS; k++) {
159 struct mtk_jpeg_fmt *fmt = &mtk_jpeg_formats[k];
160
161 if (fmt->fourcc == pixelformat && fmt->flags & fmt_flag)
162 return fmt;
163 }
164
165 return NULL;
166}
167
168static void mtk_jpeg_bound_align_image(u32 *w, unsigned int wmin,
169 unsigned int wmax, unsigned int walign,
170 u32 *h, unsigned int hmin,
171 unsigned int hmax, unsigned int halign)
172{
173 int width, height, w_step, h_step;
174
175 width = *w;
176 height = *h;
177 w_step = 1 << walign;
178 h_step = 1 << halign;
179
180 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
181 if (*w < width && (*w + w_step) <= wmax)
182 *w += w_step;
183 if (*h < height && (*h + h_step) <= hmax)
184 *h += h_step;
185}
186
187static void mtk_jpeg_adjust_fmt_mplane(struct mtk_jpeg_ctx *ctx,
188 struct v4l2_format *f)
189{
190 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
191 struct mtk_jpeg_q_data *q_data;
192 int i;
193
194 q_data = mtk_jpeg_get_q_data(ctx, f->type);
195
196 pix_mp->width = q_data->w;
197 pix_mp->height = q_data->h;
198 pix_mp->pixelformat = q_data->fmt->fourcc;
199 pix_mp->num_planes = q_data->fmt->colplanes;
200
201 for (i = 0; i < pix_mp->num_planes; i++) {
202 pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
203 pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
204 }
205}
206
207static int mtk_jpeg_try_fmt_mplane(struct v4l2_format *f,
208 struct mtk_jpeg_fmt *fmt,
209 struct mtk_jpeg_ctx *ctx, int q_type)
210{
211 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
212 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
213 int i;
214
215 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
216 pix_mp->field = V4L2_FIELD_NONE;
217
218 if (ctx->state != MTK_JPEG_INIT) {
219 mtk_jpeg_adjust_fmt_mplane(ctx, f);
220 goto end;
221 }
222
223 pix_mp->num_planes = fmt->colplanes;
224 pix_mp->pixelformat = fmt->fourcc;
225
226 if (q_type == MTK_JPEG_FMT_TYPE_OUTPUT) {
227 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0];
228
229 mtk_jpeg_bound_align_image(&pix_mp->width, MTK_JPEG_MIN_WIDTH,
230 MTK_JPEG_MAX_WIDTH, 0,
231 &pix_mp->height, MTK_JPEG_MIN_HEIGHT,
232 MTK_JPEG_MAX_HEIGHT, 0);
233
234 memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
235 pfmt->bytesperline = 0;
236 /* Source size must be aligned to 128 */
237 pfmt->sizeimage = mtk_jpeg_align(pfmt->sizeimage, 128);
238 if (pfmt->sizeimage == 0)
239 pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE;
240 goto end;
241 }
242
243 /* type is MTK_JPEG_FMT_TYPE_CAPTURE */
244 mtk_jpeg_bound_align_image(&pix_mp->width, MTK_JPEG_MIN_WIDTH,
245 MTK_JPEG_MAX_WIDTH, fmt->h_align,
246 &pix_mp->height, MTK_JPEG_MIN_HEIGHT,
247 MTK_JPEG_MAX_HEIGHT, fmt->v_align);
248
249 for (i = 0; i < fmt->colplanes; i++) {
250 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
251 u32 stride = pix_mp->width * fmt->h_sample[i] / 4;
252 u32 h = pix_mp->height * fmt->v_sample[i] / 4;
253
254 memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
255 pfmt->bytesperline = stride;
256 pfmt->sizeimage = stride * h;
257 }
258end:
259 v4l2_dbg(2, debug, &jpeg->v4l2_dev, "wxh:%ux%u\n",
260 pix_mp->width, pix_mp->height);
261 for (i = 0; i < pix_mp->num_planes; i++) {
262 v4l2_dbg(2, debug, &jpeg->v4l2_dev,
263 "plane[%d] bpl=%u, size=%u\n",
264 i,
265 pix_mp->plane_fmt[i].bytesperline,
266 pix_mp->plane_fmt[i].sizeimage);
267 }
268 return 0;
269}
270
271static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv,
272 struct v4l2_format *f)
273{
274 struct vb2_queue *vq;
275 struct mtk_jpeg_q_data *q_data = NULL;
276 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
277 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
278 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
279 int i;
280
281 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
282 if (!vq)
283 return -EINVAL;
284
285 q_data = mtk_jpeg_get_q_data(ctx, f->type);
286
287 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
288 pix_mp->width = q_data->w;
289 pix_mp->height = q_data->h;
290 pix_mp->field = V4L2_FIELD_NONE;
291 pix_mp->pixelformat = q_data->fmt->fourcc;
292 pix_mp->num_planes = q_data->fmt->colplanes;
293 pix_mp->colorspace = ctx->colorspace;
294 pix_mp->ycbcr_enc = ctx->ycbcr_enc;
295 pix_mp->xfer_func = ctx->xfer_func;
296 pix_mp->quantization = ctx->quantization;
297
298 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) g_fmt:%c%c%c%c wxh:%ux%u\n",
299 f->type,
300 (pix_mp->pixelformat & 0xff),
301 (pix_mp->pixelformat >> 8 & 0xff),
302 (pix_mp->pixelformat >> 16 & 0xff),
303 (pix_mp->pixelformat >> 24 & 0xff),
304 pix_mp->width, pix_mp->height);
305
306 for (i = 0; i < pix_mp->num_planes; i++) {
307 struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i];
308
309 pfmt->bytesperline = q_data->bytesperline[i];
310 pfmt->sizeimage = q_data->sizeimage[i];
311 memset(pfmt->reserved, 0, sizeof(pfmt->reserved));
312
313 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
314 "plane[%d] bpl=%u, size=%u\n",
315 i,
316 pfmt->bytesperline,
317 pfmt->sizeimage);
318 }
319 return 0;
320}
321
322static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv,
323 struct v4l2_format *f)
324{
325 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
326 struct mtk_jpeg_fmt *fmt;
327
328 fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat,
329 MTK_JPEG_FMT_TYPE_CAPTURE);
330 if (!fmt)
331 fmt = ctx->cap_q.fmt;
332
333 v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
334 f->type,
335 (fmt->fourcc & 0xff),
336 (fmt->fourcc >> 8 & 0xff),
337 (fmt->fourcc >> 16 & 0xff),
338 (fmt->fourcc >> 24 & 0xff));
339
340 return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_CAPTURE);
341}
342
343static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv,
344 struct v4l2_format *f)
345{
346 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
347 struct mtk_jpeg_fmt *fmt;
348
349 fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat,
350 MTK_JPEG_FMT_TYPE_OUTPUT);
351 if (!fmt)
352 fmt = ctx->out_q.fmt;
353
354 v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n",
355 f->type,
356 (fmt->fourcc & 0xff),
357 (fmt->fourcc >> 8 & 0xff),
358 (fmt->fourcc >> 16 & 0xff),
359 (fmt->fourcc >> 24 & 0xff));
360
361 return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_OUTPUT);
362}
363
364static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx,
365 struct v4l2_format *f)
366{
367 struct vb2_queue *vq;
368 struct mtk_jpeg_q_data *q_data = NULL;
369 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
370 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
371 unsigned int f_type;
372 int i;
373
374 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
375 if (!vq)
376 return -EINVAL;
377
378 q_data = mtk_jpeg_get_q_data(ctx, f->type);
379
380 if (vb2_is_busy(vq)) {
381 v4l2_err(&jpeg->v4l2_dev, "queue busy\n");
382 return -EBUSY;
383 }
384
385 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
386 MTK_JPEG_FMT_TYPE_OUTPUT : MTK_JPEG_FMT_TYPE_CAPTURE;
387
388 q_data->fmt = mtk_jpeg_find_format(ctx, pix_mp->pixelformat, f_type);
389 q_data->w = pix_mp->width;
390 q_data->h = pix_mp->height;
391 ctx->colorspace = pix_mp->colorspace;
392 ctx->ycbcr_enc = pix_mp->ycbcr_enc;
393 ctx->xfer_func = pix_mp->xfer_func;
394 ctx->quantization = pix_mp->quantization;
395
396 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) s_fmt:%c%c%c%c wxh:%ux%u\n",
397 f->type,
398 (q_data->fmt->fourcc & 0xff),
399 (q_data->fmt->fourcc >> 8 & 0xff),
400 (q_data->fmt->fourcc >> 16 & 0xff),
401 (q_data->fmt->fourcc >> 24 & 0xff),
402 q_data->w, q_data->h);
403
404 for (i = 0; i < q_data->fmt->colplanes; i++) {
405 q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
406 q_data->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
407
408 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
409 "plane[%d] bpl=%u, size=%u\n",
410 i, q_data->bytesperline[i], q_data->sizeimage[i]);
411 }
412
413 return 0;
414}
415
416static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv,
417 struct v4l2_format *f)
418{
419 int ret;
420
421 ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f);
422 if (ret)
423 return ret;
424
425 return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f);
426}
427
428static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv,
429 struct v4l2_format *f)
430{
431 int ret;
432
433 ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f);
434 if (ret)
435 return ret;
436
437 return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f);
438}
439
440static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx)
441{
442 static const struct v4l2_event ev_src_ch = {
443 .type = V4L2_EVENT_SOURCE_CHANGE,
444 .u.src_change.changes =
445 V4L2_EVENT_SRC_CH_RESOLUTION,
446 };
447
448 v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
449}
450
451static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh,
452 const struct v4l2_event_subscription *sub)
453{
454 switch (sub->type) {
455 case V4L2_EVENT_SOURCE_CHANGE:
456 return v4l2_src_change_event_subscribe(fh, sub);
457 default:
458 return -EINVAL;
459 }
460}
461
462static int mtk_jpeg_g_selection(struct file *file, void *priv,
463 struct v4l2_selection *s)
464{
465 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
466
467 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
468 return -EINVAL;
469
470 switch (s->target) {
471 case V4L2_SEL_TGT_COMPOSE:
472 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
473 s->r.width = ctx->out_q.w;
474 s->r.height = ctx->out_q.h;
475 s->r.left = 0;
476 s->r.top = 0;
477 break;
478 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
479 case V4L2_SEL_TGT_COMPOSE_PADDED:
480 s->r.width = ctx->cap_q.w;
481 s->r.height = ctx->cap_q.h;
482 s->r.left = 0;
483 s->r.top = 0;
484 break;
485 default:
486 return -EINVAL;
487 }
488 return 0;
489}
490
491static int mtk_jpeg_s_selection(struct file *file, void *priv,
492 struct v4l2_selection *s)
493{
494 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
495
496 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
497 return -EINVAL;
498
499 switch (s->target) {
500 case V4L2_SEL_TGT_COMPOSE:
501 s->r.left = 0;
502 s->r.top = 0;
503 s->r.width = ctx->out_q.w;
504 s->r.height = ctx->out_q.h;
505 break;
506 default:
507 return -EINVAL;
508 }
509 return 0;
510}
511
512static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
513{
514 struct v4l2_fh *fh = file->private_data;
515 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv);
516 struct vb2_queue *vq;
517 struct vb2_buffer *vb;
518 struct mtk_jpeg_src_buf *jpeg_src_buf;
519
520 if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
521 goto end;
522
523 vq = v4l2_m2m_get_vq(fh->m2m_ctx, buf->type);
524 if (buf->index >= vq->num_buffers) {
525 dev_err(ctx->jpeg->dev, "buffer index out of range\n");
526 return -EINVAL;
527 }
528
529 vb = vq->bufs[buf->index];
530 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
531 jpeg_src_buf->flags = (buf->m.planes[0].bytesused == 0) ?
532 MTK_JPEG_BUF_FLAGS_LAST_FRAME : MTK_JPEG_BUF_FLAGS_INIT;
533end:
534 return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf);
535}
536
537static const struct v4l2_ioctl_ops mtk_jpeg_ioctl_ops = {
538 .vidioc_querycap = mtk_jpeg_querycap,
539 .vidioc_enum_fmt_vid_cap_mplane = mtk_jpeg_enum_fmt_vid_cap,
540 .vidioc_enum_fmt_vid_out_mplane = mtk_jpeg_enum_fmt_vid_out,
541 .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane,
542 .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane,
543 .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane,
544 .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane,
545 .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane,
546 .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane,
547 .vidioc_qbuf = mtk_jpeg_qbuf,
548 .vidioc_subscribe_event = mtk_jpeg_subscribe_event,
549 .vidioc_g_selection = mtk_jpeg_g_selection,
550 .vidioc_s_selection = mtk_jpeg_s_selection,
551
552 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
553 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
554 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
555 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
556 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
557 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
558 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
559 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
560
561 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
562};
563
564static int mtk_jpeg_queue_setup(struct vb2_queue *q,
565 unsigned int *num_buffers,
566 unsigned int *num_planes,
567 unsigned int sizes[],
568 struct device *alloc_ctxs[])
569{
570 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
571 struct mtk_jpeg_q_data *q_data = NULL;
572 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
573 int i;
574
575 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "(%d) buf_req count=%u\n",
576 q->type, *num_buffers);
577
578 q_data = mtk_jpeg_get_q_data(ctx, q->type);
579 if (!q_data)
580 return -EINVAL;
581
582 *num_planes = q_data->fmt->colplanes;
583 for (i = 0; i < q_data->fmt->colplanes; i++) {
584 sizes[i] = q_data->sizeimage[i];
585 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "sizeimage[%d]=%u\n",
586 i, sizes[i]);
587 }
588
589 return 0;
590}
591
592static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
593{
594 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
595 struct mtk_jpeg_q_data *q_data = NULL;
596 int i;
597
598 q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
599 if (!q_data)
600 return -EINVAL;
601
602 for (i = 0; i < q_data->fmt->colplanes; i++)
603 vb2_set_plane_payload(vb, i, q_data->sizeimage[i]);
604
605 return 0;
606}
607
608static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx,
609 struct mtk_jpeg_dec_param *param)
610{
611 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
612 struct mtk_jpeg_q_data *q_data;
613
614 q_data = &ctx->out_q;
615 if (q_data->w != param->pic_w || q_data->h != param->pic_h) {
616 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Picture size change\n");
617 return true;
618 }
619
620 q_data = &ctx->cap_q;
621 if (q_data->fmt != mtk_jpeg_find_format(ctx, param->dst_fourcc,
622 MTK_JPEG_FMT_TYPE_CAPTURE)) {
623 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n");
624 return true;
625 }
626 return false;
627}
628
629static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx,
630 struct mtk_jpeg_dec_param *param)
631{
632 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
633 struct mtk_jpeg_q_data *q_data;
634 int i;
635
636 q_data = &ctx->out_q;
637 q_data->w = param->pic_w;
638 q_data->h = param->pic_h;
639
640 q_data = &ctx->cap_q;
641 q_data->w = param->dec_w;
642 q_data->h = param->dec_h;
643 q_data->fmt = mtk_jpeg_find_format(ctx,
644 param->dst_fourcc,
645 MTK_JPEG_FMT_TYPE_CAPTURE);
646
647 for (i = 0; i < q_data->fmt->colplanes; i++) {
648 q_data->bytesperline[i] = param->mem_stride[i];
649 q_data->sizeimage[i] = param->comp_size[i];
650 }
651
652 v4l2_dbg(1, debug, &jpeg->v4l2_dev,
653 "set_parse cap:%c%c%c%c pic(%u, %u), buf(%u, %u)\n",
654 (param->dst_fourcc & 0xff),
655 (param->dst_fourcc >> 8 & 0xff),
656 (param->dst_fourcc >> 16 & 0xff),
657 (param->dst_fourcc >> 24 & 0xff),
658 param->pic_w, param->pic_h,
659 param->dec_w, param->dec_h);
660}
661
662static void mtk_jpeg_buf_queue(struct vb2_buffer *vb)
663{
664 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
665 struct mtk_jpeg_dec_param *param;
666 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
667 struct mtk_jpeg_src_buf *jpeg_src_buf;
668 bool header_valid;
669
670 v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n",
671 vb->vb2_queue->type, vb->index, vb);
672
673 if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
674 goto end;
675
676 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
677 param = &jpeg_src_buf->dec_param;
678 memset(param, 0, sizeof(*param));
679
680 if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) {
681 v4l2_dbg(1, debug, &jpeg->v4l2_dev, "Got eos\n");
682 goto end;
683 }
684 header_valid = mtk_jpeg_parse(param, (u8 *)vb2_plane_vaddr(vb, 0),
685 vb2_get_plane_payload(vb, 0));
686 if (!header_valid) {
687 v4l2_err(&jpeg->v4l2_dev, "Header invalid.\n");
688 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
689 return;
690 }
691
692 if (ctx->state == MTK_JPEG_INIT) {
693 struct vb2_queue *dst_vq = v4l2_m2m_get_vq(
694 ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
695
696 mtk_jpeg_queue_src_chg_event(ctx);
697 mtk_jpeg_set_queue_data(ctx, param);
698 ctx->state = vb2_is_streaming(dst_vq) ?
699 MTK_JPEG_SOURCE_CHANGE : MTK_JPEG_RUNNING;
700 }
701end:
702 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
703}
704
705static void *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx,
706 enum v4l2_buf_type type)
707{
708 if (V4L2_TYPE_IS_OUTPUT(type))
709 return v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
710 else
711 return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
712}
713
714static int mtk_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
715{
716 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
717 struct vb2_buffer *vb;
718 int ret = 0;
719
720 ret = pm_runtime_get_sync(ctx->jpeg->dev);
721 if (ret < 0)
722 goto err;
723
724 return 0;
725err:
726 while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
727 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_QUEUED);
728 return ret;
729}
730
731static void mtk_jpeg_stop_streaming(struct vb2_queue *q)
732{
733 struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q);
734 struct vb2_buffer *vb;
735
736 /*
737 * STREAMOFF is an acknowledgment for source change event.
738 * Before STREAMOFF, we still have to return the old resolution and
739 * subsampling. Update capture queue when the stream is off.
740 */
741 if (ctx->state == MTK_JPEG_SOURCE_CHANGE &&
742 !V4L2_TYPE_IS_OUTPUT(q->type)) {
743 struct mtk_jpeg_src_buf *src_buf;
744
745 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
746 src_buf = mtk_jpeg_vb2_to_srcbuf(vb);
747 mtk_jpeg_set_queue_data(ctx, &src_buf->dec_param);
748 ctx->state = MTK_JPEG_RUNNING;
749 } else if (V4L2_TYPE_IS_OUTPUT(q->type)) {
750 ctx->state = MTK_JPEG_INIT;
751 }
752
753 while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
754 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_ERROR);
755
756 pm_runtime_put_sync(ctx->jpeg->dev);
757}
758
759static struct vb2_ops mtk_jpeg_qops = {
760 .queue_setup = mtk_jpeg_queue_setup,
761 .buf_prepare = mtk_jpeg_buf_prepare,
762 .buf_queue = mtk_jpeg_buf_queue,
763 .wait_prepare = vb2_ops_wait_prepare,
764 .wait_finish = vb2_ops_wait_finish,
765 .start_streaming = mtk_jpeg_start_streaming,
766 .stop_streaming = mtk_jpeg_stop_streaming,
767};
768
769static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx,
770 struct vb2_buffer *src_buf,
771 struct mtk_jpeg_bs *bs)
772{
773 bs->str_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
774 bs->end_addr = bs->str_addr +
775 mtk_jpeg_align(vb2_get_plane_payload(src_buf, 0), 16);
776 bs->size = mtk_jpeg_align(vb2_plane_size(src_buf, 0), 128);
777}
778
779static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx,
780 struct mtk_jpeg_dec_param *param,
781 struct vb2_buffer *dst_buf,
782 struct mtk_jpeg_fb *fb)
783{
784 int i;
785
786 if (param->comp_num != dst_buf->num_planes) {
787 dev_err(ctx->jpeg->dev, "plane number mismatch (%u != %u)\n",
788 param->comp_num, dst_buf->num_planes);
789 return -EINVAL;
790 }
791
792 for (i = 0; i < dst_buf->num_planes; i++) {
793 if (vb2_plane_size(dst_buf, i) < param->comp_size[i]) {
794 dev_err(ctx->jpeg->dev,
795 "buffer size is underflow (%lu < %u)\n",
796 vb2_plane_size(dst_buf, 0),
797 param->comp_size[i]);
798 return -EINVAL;
799 }
800 fb->plane_addr[i] = vb2_dma_contig_plane_dma_addr(dst_buf, i);
801 }
802
803 return 0;
804}
805
806static void mtk_jpeg_device_run(void *priv)
807{
808 struct mtk_jpeg_ctx *ctx = priv;
809 struct mtk_jpeg_dev *jpeg = ctx->jpeg;
810 struct vb2_buffer *src_buf, *dst_buf;
811 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
812 unsigned long flags;
813 struct mtk_jpeg_src_buf *jpeg_src_buf;
814 struct mtk_jpeg_bs bs;
815 struct mtk_jpeg_fb fb;
816 int i;
817
818 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
819 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
820 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(src_buf);
821
822 if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) {
823 for (i = 0; i < dst_buf->num_planes; i++)
824 vb2_set_plane_payload(dst_buf, i, 0);
825 buf_state = VB2_BUF_STATE_DONE;
826 goto dec_end;
827 }
828
829 if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf->dec_param)) {
830 mtk_jpeg_queue_src_chg_event(ctx);
831 ctx->state = MTK_JPEG_SOURCE_CHANGE;
832 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
833 return;
834 }
835
836 mtk_jpeg_set_dec_src(ctx, src_buf, &bs);
837 if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, dst_buf, &fb))
838 goto dec_end;
839
840 spin_lock_irqsave(&jpeg->hw_lock, flags);
841 mtk_jpeg_dec_reset(jpeg->dec_reg_base);
842 mtk_jpeg_dec_set_config(jpeg->dec_reg_base,
843 &jpeg_src_buf->dec_param, &bs, &fb);
844
845 mtk_jpeg_dec_start(jpeg->dec_reg_base);
846 spin_unlock_irqrestore(&jpeg->hw_lock, flags);
847 return;
848
849dec_end:
850 v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
851 v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
852 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state);
853 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state);
854 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
855}
856
857static int mtk_jpeg_job_ready(void *priv)
858{
859 struct mtk_jpeg_ctx *ctx = priv;
860
861 return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0;
862}
863
864static void mtk_jpeg_job_abort(void *priv)
865{
866}
867
868static struct v4l2_m2m_ops mtk_jpeg_m2m_ops = {
869 .device_run = mtk_jpeg_device_run,
870 .job_ready = mtk_jpeg_job_ready,
871 .job_abort = mtk_jpeg_job_abort,
872};
873
874static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
875 struct vb2_queue *dst_vq)
876{
877 struct mtk_jpeg_ctx *ctx = priv;
878 int ret;
879
880 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
881 src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
882 src_vq->drv_priv = ctx;
883 src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
884 src_vq->ops = &mtk_jpeg_qops;
885 src_vq->mem_ops = &vb2_dma_contig_memops;
886 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
887 src_vq->lock = &ctx->jpeg->lock;
888 src_vq->dev = ctx->jpeg->dev;
889 ret = vb2_queue_init(src_vq);
890 if (ret)
891 return ret;
892
893 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
894 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
895 dst_vq->drv_priv = ctx;
896 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
897 dst_vq->ops = &mtk_jpeg_qops;
898 dst_vq->mem_ops = &vb2_dma_contig_memops;
899 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
900 dst_vq->lock = &ctx->jpeg->lock;
901 dst_vq->dev = ctx->jpeg->dev;
902 ret = vb2_queue_init(dst_vq);
903
904 return ret;
905}
906
907static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
908{
909 int ret;
910
911 ret = mtk_smi_larb_get(jpeg->larb);
912 if (ret)
913 dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
914 clk_prepare_enable(jpeg->clk_jdec_smi);
915 clk_prepare_enable(jpeg->clk_jdec);
916}
917
918static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
919{
920 clk_disable_unprepare(jpeg->clk_jdec);
921 clk_disable_unprepare(jpeg->clk_jdec_smi);
922 mtk_smi_larb_put(jpeg->larb);
923}
924
925static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
926{
927 struct mtk_jpeg_dev *jpeg = priv;
928 struct mtk_jpeg_ctx *ctx;
929 struct vb2_buffer *src_buf, *dst_buf;
930 struct mtk_jpeg_src_buf *jpeg_src_buf;
931 enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
932 u32 dec_irq_ret;
933 u32 dec_ret;
934 int i;
935
936 dec_ret = mtk_jpeg_dec_get_int_status(jpeg->dec_reg_base);
937 dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret);
938 ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
939 if (!ctx) {
940 v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n");
941 return IRQ_HANDLED;
942 }
943
944 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
945 dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
946 jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(src_buf);
947
948 if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)
949 mtk_jpeg_dec_reset(jpeg->dec_reg_base);
950
951 if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) {
952 dev_err(jpeg->dev, "decode failed\n");
953 goto dec_end;
954 }
955
956 for (i = 0; i < dst_buf->num_planes; i++)
957 vb2_set_plane_payload(dst_buf, i,
958 jpeg_src_buf->dec_param.comp_size[i]);
959
960 buf_state = VB2_BUF_STATE_DONE;
961
962dec_end:
963 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), buf_state);
964 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), buf_state);
965 v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
966 return IRQ_HANDLED;
967}
968
969static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx)
970{
971 struct mtk_jpeg_q_data *q = &ctx->out_q;
972 int i;
973
974 ctx->colorspace = V4L2_COLORSPACE_JPEG,
975 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
976 ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
977 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
978
979 q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
980 MTK_JPEG_FMT_TYPE_OUTPUT);
981 q->w = MTK_JPEG_MIN_WIDTH;
982 q->h = MTK_JPEG_MIN_HEIGHT;
983 q->bytesperline[0] = 0;
984 q->sizeimage[0] = MTK_JPEG_DEFAULT_SIZEIMAGE;
985
986 q = &ctx->cap_q;
987 q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_YUV420M,
988 MTK_JPEG_FMT_TYPE_CAPTURE);
989 q->w = MTK_JPEG_MIN_WIDTH;
990 q->h = MTK_JPEG_MIN_HEIGHT;
991
992 for (i = 0; i < q->fmt->colplanes; i++) {
993 u32 stride = q->w * q->fmt->h_sample[i] / 4;
994 u32 h = q->h * q->fmt->v_sample[i] / 4;
995
996 q->bytesperline[i] = stride;
997 q->sizeimage[i] = stride * h;
998 }
999}
1000
1001static int mtk_jpeg_open(struct file *file)
1002{
1003 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1004 struct video_device *vfd = video_devdata(file);
1005 struct mtk_jpeg_ctx *ctx;
1006 int ret = 0;
1007
1008 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1009 if (!ctx)
1010 return -ENOMEM;
1011
1012 if (mutex_lock_interruptible(&jpeg->lock)) {
1013 ret = -ERESTARTSYS;
1014 goto free;
1015 }
1016
1017 v4l2_fh_init(&ctx->fh, vfd);
1018 file->private_data = &ctx->fh;
1019 v4l2_fh_add(&ctx->fh);
1020
1021 ctx->jpeg = jpeg;
1022 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx,
1023 mtk_jpeg_queue_init);
1024 if (IS_ERR(ctx->fh.m2m_ctx)) {
1025 ret = PTR_ERR(ctx->fh.m2m_ctx);
1026 goto error;
1027 }
1028
1029 mtk_jpeg_set_default_params(ctx);
1030 mutex_unlock(&jpeg->lock);
1031 return 0;
1032
1033error:
1034 v4l2_fh_del(&ctx->fh);
1035 v4l2_fh_exit(&ctx->fh);
1036 mutex_unlock(&jpeg->lock);
1037free:
1038 kfree(ctx);
1039 return ret;
1040}
1041
1042static int mtk_jpeg_release(struct file *file)
1043{
1044 struct mtk_jpeg_dev *jpeg = video_drvdata(file);
1045 struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(file->private_data);
1046
1047 mutex_lock(&jpeg->lock);
1048 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1049 v4l2_fh_del(&ctx->fh);
1050 v4l2_fh_exit(&ctx->fh);
1051 kfree(ctx);
1052 mutex_unlock(&jpeg->lock);
1053 return 0;
1054}
1055
1056static const struct v4l2_file_operations mtk_jpeg_fops = {
1057 .owner = THIS_MODULE,
1058 .open = mtk_jpeg_open,
1059 .release = mtk_jpeg_release,
1060 .poll = v4l2_m2m_fop_poll,
1061 .unlocked_ioctl = video_ioctl2,
1062 .mmap = v4l2_m2m_fop_mmap,
1063};
1064
1065static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
1066{
1067 struct device_node *node;
1068 struct platform_device *pdev;
1069
1070 node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
1071 if (!node)
1072 return -EINVAL;
1073 pdev = of_find_device_by_node(node);
1074 if (WARN_ON(!pdev)) {
1075 of_node_put(node);
1076 return -EINVAL;
1077 }
1078 of_node_put(node);
1079
1080 jpeg->larb = &pdev->dev;
1081
1082 jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec");
1083 if (IS_ERR(jpeg->clk_jdec))
1084 return -EINVAL;
1085
1086 jpeg->clk_jdec_smi = devm_clk_get(jpeg->dev, "jpgdec-smi");
1087 if (IS_ERR(jpeg->clk_jdec_smi))
1088 return -EINVAL;
1089
1090 return 0;
1091}
1092
1093static int mtk_jpeg_probe(struct platform_device *pdev)
1094{
1095 struct mtk_jpeg_dev *jpeg;
1096 struct resource *res;
1097 int dec_irq;
1098 int ret;
1099
1100 jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL);
1101 if (!jpeg)
1102 return -ENOMEM;
1103
1104 mutex_init(&jpeg->lock);
1105 spin_lock_init(&jpeg->hw_lock);
1106 jpeg->dev = &pdev->dev;
1107
1108 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1109 jpeg->dec_reg_base = devm_ioremap_resource(&pdev->dev, res);
1110 if (IS_ERR(jpeg->dec_reg_base)) {
1111 ret = PTR_ERR(jpeg->dec_reg_base);
1112 return ret;
1113 }
1114
1115 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1116 dec_irq = platform_get_irq(pdev, 0);
1117 if (!res || dec_irq < 0) {
1118 dev_err(&pdev->dev, "Failed to get dec_irq %d.\n", dec_irq);
1119 ret = -EINVAL;
1120 return ret;
1121 }
1122
1123 ret = devm_request_irq(&pdev->dev, dec_irq, mtk_jpeg_dec_irq, 0,
1124 pdev->name, jpeg);
1125 if (ret) {
1126 dev_err(&pdev->dev, "Failed to request dec_irq %d (%d)\n",
1127 dec_irq, ret);
1128 ret = -EINVAL;
1129 goto err_req_irq;
1130 }
1131
1132 ret = mtk_jpeg_clk_init(jpeg);
1133 if (ret) {
1134 dev_err(&pdev->dev, "Failed to init clk, err %d\n", ret);
1135 goto err_clk_init;
1136 }
1137
1138 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1139 if (ret) {
1140 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1141 ret = -EINVAL;
1142 goto err_dev_register;
1143 }
1144
1145 jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_m2m_ops);
1146 if (IS_ERR(jpeg->m2m_dev)) {
1147 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1148 ret = PTR_ERR(jpeg->m2m_dev);
1149 goto err_m2m_init;
1150 }
1151
1152 jpeg->dec_vdev = video_device_alloc();
1153 if (!jpeg->dec_vdev) {
1154 ret = -ENOMEM;
1155 goto err_dec_vdev_alloc;
1156 }
1157 snprintf(jpeg->dec_vdev->name, sizeof(jpeg->dec_vdev->name),
1158 "%s-dec", MTK_JPEG_NAME);
1159 jpeg->dec_vdev->fops = &mtk_jpeg_fops;
1160 jpeg->dec_vdev->ioctl_ops = &mtk_jpeg_ioctl_ops;
1161 jpeg->dec_vdev->minor = -1;
1162 jpeg->dec_vdev->release = video_device_release;
1163 jpeg->dec_vdev->lock = &jpeg->lock;
1164 jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev;
1165 jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
1166 jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
1167 V4L2_CAP_VIDEO_M2M_MPLANE;
1168
1169 ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_GRABBER, 3);
1170 if (ret) {
1171 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1172 goto err_dec_vdev_register;
1173 }
1174
1175 video_set_drvdata(jpeg->dec_vdev, jpeg);
1176 v4l2_info(&jpeg->v4l2_dev,
1177 "decoder device registered as /dev/video%d (%d,%d)\n",
1178 jpeg->dec_vdev->num, VIDEO_MAJOR, jpeg->dec_vdev->minor);
1179
1180 platform_set_drvdata(pdev, jpeg);
1181
1182 pm_runtime_enable(&pdev->dev);
1183
1184 return 0;
1185
1186err_dec_vdev_register:
1187 video_device_release(jpeg->dec_vdev);
1188
1189err_dec_vdev_alloc:
1190 v4l2_m2m_release(jpeg->m2m_dev);
1191
1192err_m2m_init:
1193 v4l2_device_unregister(&jpeg->v4l2_dev);
1194
1195err_dev_register:
1196
1197err_clk_init:
1198
1199err_req_irq:
1200
1201 return ret;
1202}
1203
1204static int mtk_jpeg_remove(struct platform_device *pdev)
1205{
1206 struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);
1207
1208 pm_runtime_disable(&pdev->dev);
1209 video_unregister_device(jpeg->dec_vdev);
1210 video_device_release(jpeg->dec_vdev);
1211 v4l2_m2m_release(jpeg->m2m_dev);
1212 v4l2_device_unregister(&jpeg->v4l2_dev);
1213
1214 return 0;
1215}
1216
1217static __maybe_unused int mtk_jpeg_pm_suspend(struct device *dev)
1218{
1219 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1220
1221 mtk_jpeg_dec_reset(jpeg->dec_reg_base);
1222 mtk_jpeg_clk_off(jpeg);
1223
1224 return 0;
1225}
1226
1227static __maybe_unused int mtk_jpeg_pm_resume(struct device *dev)
1228{
1229 struct mtk_jpeg_dev *jpeg = dev_get_drvdata(dev);
1230
1231 mtk_jpeg_clk_on(jpeg);
1232 mtk_jpeg_dec_reset(jpeg->dec_reg_base);
1233
1234 return 0;
1235}
1236
1237static __maybe_unused int mtk_jpeg_suspend(struct device *dev)
1238{
1239 int ret;
1240
1241 if (pm_runtime_suspended(dev))
1242 return 0;
1243
1244 ret = mtk_jpeg_pm_suspend(dev);
1245 return ret;
1246}
1247
1248static __maybe_unused int mtk_jpeg_resume(struct device *dev)
1249{
1250 int ret;
1251
1252 if (pm_runtime_suspended(dev))
1253 return 0;
1254
1255 ret = mtk_jpeg_pm_resume(dev);
1256
1257 return ret;
1258}
1259
1260static const struct dev_pm_ops mtk_jpeg_pm_ops = {
1261 SET_SYSTEM_SLEEP_PM_OPS(mtk_jpeg_suspend, mtk_jpeg_resume)
1262 SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL)
1263};
1264
1265static const struct of_device_id mtk_jpeg_match[] = {
1266 {
1267 .compatible = "mediatek,mt8173-jpgdec",
1268 .data = NULL,
1269 },
1270 {
1271 .compatible = "mediatek,mt2701-jpgdec",
1272 .data = NULL,
1273 },
1274 {},
1275};
1276
1277MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
1278
1279static struct platform_driver mtk_jpeg_driver = {
1280 .probe = mtk_jpeg_probe,
1281 .remove = mtk_jpeg_remove,
1282 .driver = {
1283 .name = MTK_JPEG_NAME,
1284 .of_match_table = mtk_jpeg_match,
1285 .pm = &mtk_jpeg_pm_ops,
1286 },
1287};
1288
1289module_platform_driver(mtk_jpeg_driver);
1290
1291MODULE_DESCRIPTION("MediaTek JPEG codec driver");
1292MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
new file mode 100644
index 000000000000..1a6cdfd4ea70
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
@@ -0,0 +1,139 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _MTK_JPEG_CORE_H
17#define _MTK_JPEG_CORE_H
18
19#include <linux/interrupt.h>
20#include <media/v4l2-ctrls.h>
21#include <media/v4l2-device.h>
22#include <media/v4l2-fh.h>
23
24#define MTK_JPEG_NAME "mtk-jpeg"
25
26#define MTK_JPEG_FMT_FLAG_DEC_OUTPUT BIT(0)
27#define MTK_JPEG_FMT_FLAG_DEC_CAPTURE BIT(1)
28
29#define MTK_JPEG_FMT_TYPE_OUTPUT 1
30#define MTK_JPEG_FMT_TYPE_CAPTURE 2
31
32#define MTK_JPEG_MIN_WIDTH 32
33#define MTK_JPEG_MIN_HEIGHT 32
34#define MTK_JPEG_MAX_WIDTH 8192
35#define MTK_JPEG_MAX_HEIGHT 8192
36
37#define MTK_JPEG_DEFAULT_SIZEIMAGE (1 * 1024 * 1024)
38
39enum mtk_jpeg_ctx_state {
40 MTK_JPEG_INIT = 0,
41 MTK_JPEG_RUNNING,
42 MTK_JPEG_SOURCE_CHANGE,
43};
44
45/**
46 * struct mt_jpeg - JPEG IP abstraction
47 * @lock: the mutex protecting this structure
48 * @hw_lock: spinlock protecting the hw device resource
49 * @workqueue: decode work queue
50 * @dev: JPEG device
51 * @v4l2_dev: v4l2 device for mem2mem mode
52 * @m2m_dev: v4l2 mem2mem device data
53 * @alloc_ctx: videobuf2 memory allocator's context
54 * @dec_vdev: video device node for decoder mem2mem mode
55 * @dec_reg_base: JPEG registers mapping
56 * @clk_jdec: JPEG hw working clock
57 * @clk_jdec_smi: JPEG SMI bus clock
58 * @larb: SMI device
59 */
60struct mtk_jpeg_dev {
61 struct mutex lock;
62 spinlock_t hw_lock;
63 struct workqueue_struct *workqueue;
64 struct device *dev;
65 struct v4l2_device v4l2_dev;
66 struct v4l2_m2m_dev *m2m_dev;
67 void *alloc_ctx;
68 struct video_device *dec_vdev;
69 void __iomem *dec_reg_base;
70 struct clk *clk_jdec;
71 struct clk *clk_jdec_smi;
72 struct device *larb;
73};
74
75/**
76 * struct jpeg_fmt - driver's internal color format data
77 * @fourcc: the fourcc code, 0 if not applicable
78 * @h_sample: horizontal sample count of plane in 4 * 4 pixel image
79 * @v_sample: vertical sample count of plane in 4 * 4 pixel image
80 * @colplanes: number of color planes (1 for packed formats)
81 * @h_align: horizontal alignment order (align to 2^h_align)
82 * @v_align: vertical alignment order (align to 2^v_align)
83 * @flags: flags describing format applicability
84 */
85struct mtk_jpeg_fmt {
86 u32 fourcc;
87 int h_sample[VIDEO_MAX_PLANES];
88 int v_sample[VIDEO_MAX_PLANES];
89 int colplanes;
90 int h_align;
91 int v_align;
92 u32 flags;
93};
94
95/**
96 * mtk_jpeg_q_data - parameters of one queue
97 * @fmt: driver-specific format of this queue
98 * @w: image width
99 * @h: image height
100 * @bytesperline: distance in bytes between the leftmost pixels in two adjacent
101 * lines
102 * @sizeimage: image buffer size in bytes
103 */
104struct mtk_jpeg_q_data {
105 struct mtk_jpeg_fmt *fmt;
106 u32 w;
107 u32 h;
108 u32 bytesperline[VIDEO_MAX_PLANES];
109 u32 sizeimage[VIDEO_MAX_PLANES];
110};
111
112/**
113 * mtk_jpeg_ctx - the device context data
114 * @jpeg: JPEG IP device for this context
115 * @out_q: source (output) queue information
116 * @cap_q: destination (capture) queue queue information
117 * @fh: V4L2 file handle
118 * @dec_param parameters for HW decoding
119 * @state: state of the context
120 * @header_valid: set if header has been parsed and valid
121 * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
122 * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
123 * @quantization: enum v4l2_quantization, colorspace quantization
124 * @xfer_func: enum v4l2_xfer_func, colorspace transfer function
125 */
126struct mtk_jpeg_ctx {
127 struct mtk_jpeg_dev *jpeg;
128 struct mtk_jpeg_q_data out_q;
129 struct mtk_jpeg_q_data cap_q;
130 struct v4l2_fh fh;
131 enum mtk_jpeg_ctx_state state;
132
133 enum v4l2_colorspace colorspace;
134 enum v4l2_ycbcr_encoding ycbcr_enc;
135 enum v4l2_quantization quantization;
136 enum v4l2_xfer_func xfer_func;
137};
138
139#endif /* _MTK_JPEG_CORE_H */
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
new file mode 100644
index 000000000000..77b4cc6a8873
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.c
@@ -0,0 +1,417 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <media/videobuf2-core.h>
19
20#include "mtk_jpeg_hw.h"
21
22#define MTK_JPEG_DUNUM_MASK(val) (((val) - 1) & 0x3)
23
24enum mtk_jpeg_color {
25 MTK_JPEG_COLOR_420 = 0x00221111,
26 MTK_JPEG_COLOR_422 = 0x00211111,
27 MTK_JPEG_COLOR_444 = 0x00111111,
28 MTK_JPEG_COLOR_422V = 0x00121111,
29 MTK_JPEG_COLOR_422X2 = 0x00412121,
30 MTK_JPEG_COLOR_422VX2 = 0x00222121,
31 MTK_JPEG_COLOR_400 = 0x00110000
32};
33
34static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg)
35{
36 if (val & (align - 1)) {
37 pr_err("mtk-jpeg: write reg %x without %d align\n", reg, align);
38 return -1;
39 }
40
41 return 0;
42}
43
44static int mtk_jpeg_decide_format(struct mtk_jpeg_dec_param *param)
45{
46 param->src_color = (param->sampling_w[0] << 20) |
47 (param->sampling_h[0] << 16) |
48 (param->sampling_w[1] << 12) |
49 (param->sampling_h[1] << 8) |
50 (param->sampling_w[2] << 4) |
51 (param->sampling_h[2]);
52
53 param->uv_brz_w = 0;
54 switch (param->src_color) {
55 case MTK_JPEG_COLOR_444:
56 param->uv_brz_w = 1;
57 param->dst_fourcc = V4L2_PIX_FMT_YUV422M;
58 break;
59 case MTK_JPEG_COLOR_422X2:
60 case MTK_JPEG_COLOR_422:
61 param->dst_fourcc = V4L2_PIX_FMT_YUV422M;
62 break;
63 case MTK_JPEG_COLOR_422V:
64 case MTK_JPEG_COLOR_422VX2:
65 param->uv_brz_w = 1;
66 param->dst_fourcc = V4L2_PIX_FMT_YUV420M;
67 break;
68 case MTK_JPEG_COLOR_420:
69 param->dst_fourcc = V4L2_PIX_FMT_YUV420M;
70 break;
71 case MTK_JPEG_COLOR_400:
72 param->dst_fourcc = V4L2_PIX_FMT_GREY;
73 break;
74 default:
75 param->dst_fourcc = 0;
76 return -1;
77 }
78
79 return 0;
80}
81
82static void mtk_jpeg_calc_mcu(struct mtk_jpeg_dec_param *param)
83{
84 u32 factor_w, factor_h;
85 u32 i, comp, blk;
86
87 factor_w = 2 + param->sampling_w[0];
88 factor_h = 2 + param->sampling_h[0];
89 param->mcu_w = (param->pic_w + (1 << factor_w) - 1) >> factor_w;
90 param->mcu_h = (param->pic_h + (1 << factor_h) - 1) >> factor_h;
91 param->total_mcu = param->mcu_w * param->mcu_h;
92 param->unit_num = ((param->pic_w + 7) >> 3) * ((param->pic_h + 7) >> 3);
93 param->blk_num = 0;
94 for (i = 0; i < MTK_JPEG_COMP_MAX; i++) {
95 param->blk_comp[i] = 0;
96 if (i >= param->comp_num)
97 continue;
98 param->blk_comp[i] = param->sampling_w[i] *
99 param->sampling_h[i];
100 param->blk_num += param->blk_comp[i];
101 }
102
103 param->membership = 0;
104 for (i = 0, blk = 0, comp = 0; i < MTK_JPEG_BLOCK_MAX; i++) {
105 if (i < param->blk_num && comp < param->comp_num) {
106 u32 tmp;
107
108 tmp = (0x04 + (comp & 0x3));
109 param->membership |= tmp << (i * 3);
110 if (++blk == param->blk_comp[comp]) {
111 comp++;
112 blk = 0;
113 }
114 } else {
115 param->membership |= 7 << (i * 3);
116 }
117 }
118}
119
120static void mtk_jpeg_calc_dma_group(struct mtk_jpeg_dec_param *param)
121{
122 u32 factor_mcu = 3;
123
124 if (param->src_color == MTK_JPEG_COLOR_444 &&
125 param->dst_fourcc == V4L2_PIX_FMT_YUV422M)
126 factor_mcu = 4;
127 else if (param->src_color == MTK_JPEG_COLOR_422V &&
128 param->dst_fourcc == V4L2_PIX_FMT_YUV420M)
129 factor_mcu = 4;
130 else if (param->src_color == MTK_JPEG_COLOR_422X2 &&
131 param->dst_fourcc == V4L2_PIX_FMT_YUV422M)
132 factor_mcu = 2;
133 else if (param->src_color == MTK_JPEG_COLOR_400 ||
134 (param->src_color & 0x0FFFF) == 0)
135 factor_mcu = 4;
136
137 param->dma_mcu = 1 << factor_mcu;
138 param->dma_group = param->mcu_w / param->dma_mcu;
139 param->dma_last_mcu = param->mcu_w % param->dma_mcu;
140 if (param->dma_last_mcu)
141 param->dma_group++;
142 else
143 param->dma_last_mcu = param->dma_mcu;
144}
145
146static int mtk_jpeg_calc_dst_size(struct mtk_jpeg_dec_param *param)
147{
148 u32 i, padding_w;
149 u32 ds_row_h[3];
150 u32 brz_w[3];
151
152 brz_w[0] = 0;
153 brz_w[1] = param->uv_brz_w;
154 brz_w[2] = brz_w[1];
155
156 for (i = 0; i < param->comp_num; i++) {
157 if (brz_w[i] > 3)
158 return -1;
159
160 padding_w = param->mcu_w * MTK_JPEG_DCTSIZE *
161 param->sampling_w[i];
162 /* output format is 420/422 */
163 param->comp_w[i] = padding_w >> brz_w[i];
164 param->comp_w[i] = mtk_jpeg_align(param->comp_w[i],
165 MTK_JPEG_DCTSIZE);
166 param->img_stride[i] = i ? mtk_jpeg_align(param->comp_w[i], 16)
167 : mtk_jpeg_align(param->comp_w[i], 32);
168 ds_row_h[i] = (MTK_JPEG_DCTSIZE * param->sampling_h[i]);
169 }
170 param->dec_w = param->img_stride[0];
171 param->dec_h = ds_row_h[0] * param->mcu_h;
172
173 for (i = 0; i < MTK_JPEG_COMP_MAX; i++) {
174 /* They must be equal in frame mode. */
175 param->mem_stride[i] = param->img_stride[i];
176 param->comp_size[i] = param->mem_stride[i] * ds_row_h[i] *
177 param->mcu_h;
178 }
179
180 param->y_size = param->comp_size[0];
181 param->uv_size = param->comp_size[1];
182 param->dec_size = param->y_size + (param->uv_size << 1);
183
184 return 0;
185}
186
187int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param)
188{
189 if (mtk_jpeg_decide_format(param))
190 return -1;
191
192 mtk_jpeg_calc_mcu(param);
193 mtk_jpeg_calc_dma_group(param);
194 if (mtk_jpeg_calc_dst_size(param))
195 return -2;
196
197 return 0;
198}
199
200u32 mtk_jpeg_dec_get_int_status(void __iomem *base)
201{
202 u32 ret;
203
204 ret = readl(base + JPGDEC_REG_INTERRUPT_STATUS) & BIT_INQST_MASK_ALLIRQ;
205 if (ret)
206 writel(ret, base + JPGDEC_REG_INTERRUPT_STATUS);
207
208 return ret;
209}
210
211u32 mtk_jpeg_dec_enum_result(u32 irq_result)
212{
213 if (irq_result & BIT_INQST_MASK_EOF)
214 return MTK_JPEG_DEC_RESULT_EOF_DONE;
215 if (irq_result & BIT_INQST_MASK_PAUSE)
216 return MTK_JPEG_DEC_RESULT_PAUSE;
217 if (irq_result & BIT_INQST_MASK_UNDERFLOW)
218 return MTK_JPEG_DEC_RESULT_UNDERFLOW;
219 if (irq_result & BIT_INQST_MASK_OVERFLOW)
220 return MTK_JPEG_DEC_RESULT_OVERFLOW;
221 if (irq_result & BIT_INQST_MASK_ERROR_BS)
222 return MTK_JPEG_DEC_RESULT_ERROR_BS;
223
224 return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN;
225}
226
227void mtk_jpeg_dec_start(void __iomem *base)
228{
229 writel(0, base + JPGDEC_REG_TRIG);
230}
231
232static void mtk_jpeg_dec_soft_reset(void __iomem *base)
233{
234 writel(0x0000FFFF, base + JPGDEC_REG_INTERRUPT_STATUS);
235 writel(0x00, base + JPGDEC_REG_RESET);
236 writel(0x01, base + JPGDEC_REG_RESET);
237}
238
239static void mtk_jpeg_dec_hard_reset(void __iomem *base)
240{
241 writel(0x00, base + JPGDEC_REG_RESET);
242 writel(0x10, base + JPGDEC_REG_RESET);
243}
244
245void mtk_jpeg_dec_reset(void __iomem *base)
246{
247 mtk_jpeg_dec_soft_reset(base);
248 mtk_jpeg_dec_hard_reset(base);
249}
250
251static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w,
252 u8 yscale_h, u8 uvscale_w, u8 uvscale_h)
253{
254 u32 val;
255
256 val = (uvscale_h << 12) | (uvscale_w << 8) |
257 (yscale_h << 4) | yscale_w;
258 writel(val, base + JPGDEC_REG_BRZ_FACTOR);
259}
260
261static void mtk_jpeg_dec_set_dst_bank0(void __iomem *base, u32 addr_y,
262 u32 addr_u, u32 addr_v)
263{
264 mtk_jpeg_verify_align(addr_y, 16, JPGDEC_REG_DEST_ADDR0_Y);
265 writel(addr_y, base + JPGDEC_REG_DEST_ADDR0_Y);
266 mtk_jpeg_verify_align(addr_u, 16, JPGDEC_REG_DEST_ADDR0_U);
267 writel(addr_u, base + JPGDEC_REG_DEST_ADDR0_U);
268 mtk_jpeg_verify_align(addr_v, 16, JPGDEC_REG_DEST_ADDR0_V);
269 writel(addr_v, base + JPGDEC_REG_DEST_ADDR0_V);
270}
271
272static void mtk_jpeg_dec_set_dst_bank1(void __iomem *base, u32 addr_y,
273 u32 addr_u, u32 addr_v)
274{
275 writel(addr_y, base + JPGDEC_REG_DEST_ADDR1_Y);
276 writel(addr_u, base + JPGDEC_REG_DEST_ADDR1_U);
277 writel(addr_v, base + JPGDEC_REG_DEST_ADDR1_V);
278}
279
280static void mtk_jpeg_dec_set_mem_stride(void __iomem *base, u32 stride_y,
281 u32 stride_uv)
282{
283 writel((stride_y & 0xFFFF), base + JPGDEC_REG_STRIDE_Y);
284 writel((stride_uv & 0xFFFF), base + JPGDEC_REG_STRIDE_UV);
285}
286
287static void mtk_jpeg_dec_set_img_stride(void __iomem *base, u32 stride_y,
288 u32 stride_uv)
289{
290 writel((stride_y & 0xFFFF), base + JPGDEC_REG_IMG_STRIDE_Y);
291 writel((stride_uv & 0xFFFF), base + JPGDEC_REG_IMG_STRIDE_UV);
292}
293
294static void mtk_jpeg_dec_set_pause_mcu_idx(void __iomem *base, u32 idx)
295{
296 writel(idx & 0x0003FFFFFF, base + JPGDEC_REG_PAUSE_MCU_NUM);
297}
298
299static void mtk_jpeg_dec_set_dec_mode(void __iomem *base, u32 mode)
300{
301 writel(mode & 0x03, base + JPGDEC_REG_OPERATION_MODE);
302}
303
304static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem *base, u32 ptr)
305{
306 mtk_jpeg_verify_align(ptr, 16, JPGDEC_REG_FILE_BRP);
307 writel(ptr, base + JPGDEC_REG_FILE_BRP);
308}
309
310static void mtk_jpeg_dec_set_bs_info(void __iomem *base, u32 addr, u32 size)
311{
312 mtk_jpeg_verify_align(addr, 16, JPGDEC_REG_FILE_ADDR);
313 mtk_jpeg_verify_align(size, 128, JPGDEC_REG_FILE_TOTAL_SIZE);
314 writel(addr, base + JPGDEC_REG_FILE_ADDR);
315 writel(size, base + JPGDEC_REG_FILE_TOTAL_SIZE);
316}
317
318static void mtk_jpeg_dec_set_comp_id(void __iomem *base, u32 id_y, u32 id_u,
319 u32 id_v)
320{
321 u32 val;
322
323 val = ((id_y & 0x00FF) << 24) | ((id_u & 0x00FF) << 16) |
324 ((id_v & 0x00FF) << 8);
325 writel(val, base + JPGDEC_REG_COMP_ID);
326}
327
328static void mtk_jpeg_dec_set_total_mcu(void __iomem *base, u32 num)
329{
330 writel(num - 1, base + JPGDEC_REG_TOTAL_MCU_NUM);
331}
332
333static void mtk_jpeg_dec_set_comp0_du(void __iomem *base, u32 num)
334{
335 writel(num - 1, base + JPGDEC_REG_COMP0_DATA_UNIT_NUM);
336}
337
338static void mtk_jpeg_dec_set_du_membership(void __iomem *base, u32 member,
339 u32 gmc, u32 isgray)
340{
341 if (isgray)
342 member = 0x3FFFFFFC;
343 member |= (isgray << 31) | (gmc << 30);
344 writel(member, base + JPGDEC_REG_DU_CTRL);
345}
346
347static void mtk_jpeg_dec_set_q_table(void __iomem *base, u32 id0, u32 id1,
348 u32 id2)
349{
350 u32 val;
351
352 val = ((id0 & 0x0f) << 8) | ((id1 & 0x0f) << 4) | ((id2 & 0x0f) << 0);
353 writel(val, base + JPGDEC_REG_QT_ID);
354}
355
356static void mtk_jpeg_dec_set_dma_group(void __iomem *base, u32 mcu_group,
357 u32 group_num, u32 last_mcu)
358{
359 u32 val;
360
361 val = (((mcu_group - 1) & 0x00FF) << 16) |
362 (((group_num - 1) & 0x007F) << 8) |
363 ((last_mcu - 1) & 0x00FF);
364 writel(val, base + JPGDEC_REG_WDMA_CTRL);
365}
366
367static void mtk_jpeg_dec_set_sampling_factor(void __iomem *base, u32 comp_num,
368 u32 y_w, u32 y_h, u32 u_w,
369 u32 u_h, u32 v_w, u32 v_h)
370{
371 u32 val;
372 u32 y_wh = (MTK_JPEG_DUNUM_MASK(y_w) << 2) | MTK_JPEG_DUNUM_MASK(y_h);
373 u32 u_wh = (MTK_JPEG_DUNUM_MASK(u_w) << 2) | MTK_JPEG_DUNUM_MASK(u_h);
374 u32 v_wh = (MTK_JPEG_DUNUM_MASK(v_w) << 2) | MTK_JPEG_DUNUM_MASK(v_h);
375
376 if (comp_num == 1)
377 val = 0;
378 else
379 val = (y_wh << 8) | (u_wh << 4) | v_wh;
380 writel(val, base + JPGDEC_REG_DU_NUM);
381}
382
383void mtk_jpeg_dec_set_config(void __iomem *base,
384 struct mtk_jpeg_dec_param *config,
385 struct mtk_jpeg_bs *bs,
386 struct mtk_jpeg_fb *fb)
387{
388 mtk_jpeg_dec_set_brz_factor(base, 0, 0, config->uv_brz_w, 0);
389 mtk_jpeg_dec_set_dec_mode(base, 0);
390 mtk_jpeg_dec_set_comp0_du(base, config->unit_num);
391 mtk_jpeg_dec_set_total_mcu(base, config->total_mcu);
392 mtk_jpeg_dec_set_bs_info(base, bs->str_addr, bs->size);
393 mtk_jpeg_dec_set_bs_write_ptr(base, bs->end_addr);
394 mtk_jpeg_dec_set_du_membership(base, config->membership, 1,
395 (config->comp_num == 1) ? 1 : 0);
396 mtk_jpeg_dec_set_comp_id(base, config->comp_id[0], config->comp_id[1],
397 config->comp_id[2]);
398 mtk_jpeg_dec_set_q_table(base, config->qtbl_num[0],
399 config->qtbl_num[1], config->qtbl_num[2]);
400 mtk_jpeg_dec_set_sampling_factor(base, config->comp_num,
401 config->sampling_w[0],
402 config->sampling_h[0],
403 config->sampling_w[1],
404 config->sampling_h[1],
405 config->sampling_w[2],
406 config->sampling_h[2]);
407 mtk_jpeg_dec_set_mem_stride(base, config->mem_stride[0],
408 config->mem_stride[1]);
409 mtk_jpeg_dec_set_img_stride(base, config->img_stride[0],
410 config->img_stride[1]);
411 mtk_jpeg_dec_set_dst_bank0(base, fb->plane_addr[0],
412 fb->plane_addr[1], fb->plane_addr[2]);
413 mtk_jpeg_dec_set_dst_bank1(base, 0, 0, 0);
414 mtk_jpeg_dec_set_dma_group(base, config->dma_mcu, config->dma_group,
415 config->dma_last_mcu);
416 mtk_jpeg_dec_set_pause_mcu_idx(base, config->total_mcu);
417}
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
new file mode 100644
index 000000000000..37152a630dea
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_hw.h
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _MTK_JPEG_HW_H
17#define _MTK_JPEG_HW_H
18
19#include <media/videobuf2-core.h>
20
21#include "mtk_jpeg_core.h"
22#include "mtk_jpeg_reg.h"
23
24enum {
25 MTK_JPEG_DEC_RESULT_EOF_DONE = 0,
26 MTK_JPEG_DEC_RESULT_PAUSE = 1,
27 MTK_JPEG_DEC_RESULT_UNDERFLOW = 2,
28 MTK_JPEG_DEC_RESULT_OVERFLOW = 3,
29 MTK_JPEG_DEC_RESULT_ERROR_BS = 4,
30 MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN = 6
31};
32
33struct mtk_jpeg_dec_param {
34 u32 pic_w;
35 u32 pic_h;
36 u32 dec_w;
37 u32 dec_h;
38 u32 src_color;
39 u32 dst_fourcc;
40 u32 mcu_w;
41 u32 mcu_h;
42 u32 total_mcu;
43 u32 unit_num;
44 u32 comp_num;
45 u32 comp_id[MTK_JPEG_COMP_MAX];
46 u32 sampling_w[MTK_JPEG_COMP_MAX];
47 u32 sampling_h[MTK_JPEG_COMP_MAX];
48 u32 qtbl_num[MTK_JPEG_COMP_MAX];
49 u32 blk_num;
50 u32 blk_comp[MTK_JPEG_COMP_MAX];
51 u32 membership;
52 u32 dma_mcu;
53 u32 dma_group;
54 u32 dma_last_mcu;
55 u32 img_stride[MTK_JPEG_COMP_MAX];
56 u32 mem_stride[MTK_JPEG_COMP_MAX];
57 u32 comp_w[MTK_JPEG_COMP_MAX];
58 u32 comp_size[MTK_JPEG_COMP_MAX];
59 u32 y_size;
60 u32 uv_size;
61 u32 dec_size;
62 u8 uv_brz_w;
63};
64
65static inline u32 mtk_jpeg_align(u32 val, u32 align)
66{
67 return (val + align - 1) & ~(align - 1);
68}
69
70struct mtk_jpeg_bs {
71 dma_addr_t str_addr;
72 dma_addr_t end_addr;
73 size_t size;
74};
75
76struct mtk_jpeg_fb {
77 dma_addr_t plane_addr[MTK_JPEG_COMP_MAX];
78 size_t size;
79};
80
81int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param);
82u32 mtk_jpeg_dec_get_int_status(void __iomem *dec_reg_base);
83u32 mtk_jpeg_dec_enum_result(u32 irq_result);
84void mtk_jpeg_dec_set_config(void __iomem *base,
85 struct mtk_jpeg_dec_param *config,
86 struct mtk_jpeg_bs *bs,
87 struct mtk_jpeg_fb *fb);
88void mtk_jpeg_dec_reset(void __iomem *dec_reg_base);
89void mtk_jpeg_dec_start(void __iomem *dec_reg_base);
90
91#endif /* _MTK_JPEG_HW_H */
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
new file mode 100644
index 000000000000..38868547f5d4
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/videodev2.h>
18
19#include "mtk_jpeg_parse.h"
20
21#define TEM 0x01
22#define SOF0 0xc0
23#define RST 0xd0
24#define SOI 0xd8
25#define EOI 0xd9
26
27struct mtk_jpeg_stream {
28 u8 *addr;
29 u32 size;
30 u32 curr;
31};
32
33static int read_byte(struct mtk_jpeg_stream *stream)
34{
35 if (stream->curr >= stream->size)
36 return -1;
37 return stream->addr[stream->curr++];
38}
39
40static int read_word_be(struct mtk_jpeg_stream *stream, u32 *word)
41{
42 u32 temp;
43 int byte;
44
45 byte = read_byte(stream);
46 if (byte == -1)
47 return -1;
48 temp = byte << 8;
49 byte = read_byte(stream);
50 if (byte == -1)
51 return -1;
52 *word = (u32)byte | temp;
53
54 return 0;
55}
56
57static void read_skip(struct mtk_jpeg_stream *stream, long len)
58{
59 if (len <= 0)
60 return;
61 while (len--)
62 read_byte(stream);
63}
64
65static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
66 u32 src_size)
67{
68 bool notfound = true;
69 struct mtk_jpeg_stream stream;
70
71 stream.addr = src_addr_va;
72 stream.size = src_size;
73 stream.curr = 0;
74
75 while (notfound) {
76 int i, length, byte;
77 u32 word;
78
79 byte = read_byte(&stream);
80 if (byte == -1)
81 return false;
82 if (byte != 0xff)
83 continue;
84 do
85 byte = read_byte(&stream);
86 while (byte == 0xff);
87 if (byte == -1)
88 return false;
89 if (byte == 0)
90 continue;
91
92 length = 0;
93 switch (byte) {
94 case SOF0:
95 /* length */
96 if (read_word_be(&stream, &word))
97 break;
98
99 /* precision */
100 if (read_byte(&stream) == -1)
101 break;
102
103 if (read_word_be(&stream, &word))
104 break;
105 param->pic_h = word;
106
107 if (read_word_be(&stream, &word))
108 break;
109 param->pic_w = word;
110
111 param->comp_num = read_byte(&stream);
112 if (param->comp_num != 1 && param->comp_num != 3)
113 break;
114
115 for (i = 0; i < param->comp_num; i++) {
116 param->comp_id[i] = read_byte(&stream);
117 if (param->comp_id[i] == -1)
118 break;
119
120 /* sampling */
121 byte = read_byte(&stream);
122 if (byte == -1)
123 break;
124 param->sampling_w[i] = (byte >> 4) & 0x0F;
125 param->sampling_h[i] = byte & 0x0F;
126
127 param->qtbl_num[i] = read_byte(&stream);
128 if (param->qtbl_num[i] == -1)
129 break;
130 }
131
132 notfound = !(i == param->comp_num);
133 break;
134 case RST ... RST + 7:
135 case SOI:
136 case EOI:
137 case TEM:
138 break;
139 default:
140 if (read_word_be(&stream, &word))
141 break;
142 length = (long)word - 2;
143 read_skip(&stream, length);
144 break;
145 }
146 }
147
148 return !notfound;
149}
150
151bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
152 u32 src_size)
153{
154 if (!mtk_jpeg_do_parse(param, src_addr_va, src_size))
155 return false;
156 if (mtk_jpeg_dec_fill_param(param))
157 return false;
158
159 return true;
160}
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
new file mode 100644
index 000000000000..5d92340ea81b
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_parse.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _MTK_JPEG_PARSE_H
17#define _MTK_JPEG_PARSE_H
18
19#include "mtk_jpeg_hw.h"
20
21bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
22 u32 src_size);
23
24#endif /* _MTK_JPEG_PARSE_H */
25
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
new file mode 100644
index 000000000000..fc490d62b012
--- /dev/null
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_reg.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _MTK_JPEG_REG_H
17#define _MTK_JPEG_REG_H
18
19#define MTK_JPEG_COMP_MAX 3
20#define MTK_JPEG_BLOCK_MAX 10
21#define MTK_JPEG_DCTSIZE 8
22
23#define BIT_INQST_MASK_ERROR_BS 0x20
24#define BIT_INQST_MASK_PAUSE 0x10
25#define BIT_INQST_MASK_OVERFLOW 0x04
26#define BIT_INQST_MASK_UNDERFLOW 0x02
27#define BIT_INQST_MASK_EOF 0x01
28#define BIT_INQST_MASK_ALLIRQ 0x37
29
30#define JPGDEC_REG_RESET 0x0090
31#define JPGDEC_REG_BRZ_FACTOR 0x00F8
32#define JPGDEC_REG_DU_NUM 0x00FC
33#define JPGDEC_REG_DEST_ADDR0_Y 0x0140
34#define JPGDEC_REG_DEST_ADDR0_U 0x0144
35#define JPGDEC_REG_DEST_ADDR0_V 0x0148
36#define JPGDEC_REG_DEST_ADDR1_Y 0x014C
37#define JPGDEC_REG_DEST_ADDR1_U 0x0150
38#define JPGDEC_REG_DEST_ADDR1_V 0x0154
39#define JPGDEC_REG_STRIDE_Y 0x0158
40#define JPGDEC_REG_STRIDE_UV 0x015C
41#define JPGDEC_REG_IMG_STRIDE_Y 0x0160
42#define JPGDEC_REG_IMG_STRIDE_UV 0x0164
43#define JPGDEC_REG_WDMA_CTRL 0x016C
44#define JPGDEC_REG_PAUSE_MCU_NUM 0x0170
45#define JPGDEC_REG_OPERATION_MODE 0x017C
46#define JPGDEC_REG_FILE_ADDR 0x0200
47#define JPGDEC_REG_COMP_ID 0x020C
48#define JPGDEC_REG_TOTAL_MCU_NUM 0x0210
49#define JPGDEC_REG_COMP0_DATA_UNIT_NUM 0x0224
50#define JPGDEC_REG_DU_CTRL 0x023C
51#define JPGDEC_REG_TRIG 0x0240
52#define JPGDEC_REG_FILE_BRP 0x0248
53#define JPGDEC_REG_FILE_TOTAL_SIZE 0x024C
54#define JPGDEC_REG_QT_ID 0x0270
55#define JPGDEC_REG_INTERRUPT_STATUS 0x0274
56#define JPGDEC_REG_STATUS 0x0278
57
58#endif /* _MTK_JPEG_REG_H */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 502877a4b1df..a60b538686ea 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -420,6 +420,11 @@ static void mtk_vdec_worker(struct work_struct *work)
420 dst_buf->index, 420 dst_buf->index,
421 ret, res_chg); 421 ret, res_chg);
422 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 422 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
423 if (ret == -EIO) {
424 mutex_lock(&ctx->lock);
425 src_buf_info->error = true;
426 mutex_unlock(&ctx->lock);
427 }
423 v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR); 428 v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
424 } else if (res_chg == false) { 429 } else if (res_chg == false) {
425 /* 430 /*
@@ -1170,8 +1175,16 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
1170 */ 1175 */
1171 1176
1172 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 1177 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
1173 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 1178 if (ret == -EIO) {
1174 VB2_BUF_STATE_DONE); 1179 mtk_v4l2_err("[%d] Unrecoverable error in vdec_if_decode.",
1180 ctx->id);
1181 ctx->state = MTK_STATE_ABORT;
1182 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf),
1183 VB2_BUF_STATE_ERROR);
1184 } else {
1185 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf),
1186 VB2_BUF_STATE_DONE);
1187 }
1175 mtk_v4l2_debug(ret ? 0 : 1, 1188 mtk_v4l2_debug(ret ? 0 : 1,
1176 "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", 1189 "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d",
1177 ctx->id, src_buf->index, 1190 ctx->id, src_buf->index,
@@ -1216,16 +1229,22 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
1216 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 1229 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1217 struct vb2_v4l2_buffer *vb2_v4l2; 1230 struct vb2_v4l2_buffer *vb2_v4l2;
1218 struct mtk_video_dec_buf *buf; 1231 struct mtk_video_dec_buf *buf;
1219 1232 bool buf_error;
1220 if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1221 return;
1222 1233
1223 vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); 1234 vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
1224 buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb); 1235 buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
1225 mutex_lock(&ctx->lock); 1236 mutex_lock(&ctx->lock);
1226 buf->queued_in_v4l2 = false; 1237 if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1227 buf->queued_in_vb2 = false; 1238 buf->queued_in_v4l2 = false;
1239 buf->queued_in_vb2 = false;
1240 }
1241 buf_error = buf->error;
1228 mutex_unlock(&ctx->lock); 1242 mutex_unlock(&ctx->lock);
1243
1244 if (buf_error) {
1245 mtk_v4l2_err("Unrecoverable error on buffer.");
1246 ctx->state = MTK_STATE_ABORT;
1247 }
1229} 1248}
1230 1249
1231static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) 1250static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 362f5a85762e..dc4fc1df63c5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -50,6 +50,7 @@ struct vdec_fb {
50 * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 50 * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2
51 * queue yet 51 * queue yet
52 * @lastframe: Intput buffer is last buffer - EOS 52 * @lastframe: Intput buffer is last buffer - EOS
53 * @error: An unrecoverable error occurs on this buffer.
53 * @frame_buffer: Decode status, and buffer information of Capture buffer 54 * @frame_buffer: Decode status, and buffer information of Capture buffer
54 * 55 *
55 * Note : These status information help us track and debug buffer state 56 * Note : These status information help us track and debug buffer state
@@ -63,6 +64,7 @@ struct mtk_video_dec_buf {
63 bool queued_in_vb2; 64 bool queued_in_vb2;
64 bool queued_in_v4l2; 65 bool queued_in_v4l2;
65 bool lastframe; 66 bool lastframe;
67 bool error;
66 struct vdec_fb frame_buffer; 68 struct vdec_fb frame_buffer;
67}; 69};
68 70
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index aa81f3ce9463..83f859e8509c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -269,11 +269,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
269 269
270 for (i = VENC_SYS, j = 0; i < NUM_MAX_VCODEC_REG_BASE; i++, j++) { 270 for (i = VENC_SYS, j = 0; i < NUM_MAX_VCODEC_REG_BASE; i++, j++) {
271 res = platform_get_resource(pdev, IORESOURCE_MEM, j); 271 res = platform_get_resource(pdev, IORESOURCE_MEM, j);
272 if (res == NULL) {
273 dev_err(&pdev->dev, "get memory resource failed.");
274 ret = -ENXIO;
275 goto err_res;
276 }
277 dev->reg_base[i] = devm_ioremap_resource(&pdev->dev, res); 272 dev->reg_base[i] = devm_ioremap_resource(&pdev->dev, res);
278 if (IS_ERR((__force void *)dev->reg_base[i])) { 273 if (IS_ERR((__force void *)dev->reg_base[i])) {
279 ret = PTR_ERR((__force void *)dev->reg_base[i]); 274 ret = PTR_ERR((__force void *)dev->reg_base[i]);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index 7d55975d3185..237e144c194f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -31,7 +31,6 @@ struct mtk_vcodec_dev;
31extern int mtk_v4l2_dbg_level; 31extern int mtk_v4l2_dbg_level;
32extern bool mtk_vcodec_dbg; 32extern bool mtk_vcodec_dbg;
33 33
34#define DEBUG 1
35 34
36#if defined(DEBUG) 35#if defined(DEBUG)
37 36
@@ -67,15 +66,15 @@ extern bool mtk_vcodec_dbg;
67 66
68#else 67#else
69 68
70#define mtk_v4l2_debug(level, fmt, args...) 69#define mtk_v4l2_debug(level, fmt, args...) {}
71#define mtk_v4l2_err(fmt, args...) 70#define mtk_v4l2_err(fmt, args...) {}
72#define mtk_v4l2_debug_enter() 71#define mtk_v4l2_debug_enter() {}
73#define mtk_v4l2_debug_leave() 72#define mtk_v4l2_debug_leave() {}
74 73
75#define mtk_vcodec_debug(h, fmt, args...) 74#define mtk_vcodec_debug(h, fmt, args...) {}
76#define mtk_vcodec_err(h, fmt, args...) 75#define mtk_vcodec_err(h, fmt, args...) {}
77#define mtk_vcodec_debug_enter(h) 76#define mtk_vcodec_debug_enter(h) {}
78#define mtk_vcodec_debug_leave(h) 77#define mtk_vcodec_debug_leave(h) {}
79 78
80#endif 79#endif
81 80
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index e91a3b425b0c..5539b1853f16 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -718,6 +718,26 @@ static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
718 *out_fb = fb; 718 *out_fb = fb;
719} 719}
720 720
721static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
722 struct vdec_vp9_vsi *vsi) {
723 if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) {
724 mtk_vcodec_err(inst, "Invalid vsi->sf_frm_idx=%u.",
725 vsi->sf_frm_idx);
726 return -EIO;
727 }
728 if (vsi->frm_to_show_idx >= VP9_MAX_FRM_BUF_NUM) {
729 mtk_vcodec_err(inst, "Invalid vsi->frm_to_show_idx=%u.",
730 vsi->frm_to_show_idx);
731 return -EIO;
732 }
733 if (vsi->new_fb_idx >= VP9_MAX_FRM_BUF_NUM) {
734 mtk_vcodec_err(inst, "Invalid vsi->new_fb_idx=%u.",
735 vsi->new_fb_idx);
736 return -EIO;
737 }
738 return 0;
739}
740
721static void vdec_vp9_deinit(unsigned long h_vdec) 741static void vdec_vp9_deinit(unsigned long h_vdec)
722{ 742{
723 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec; 743 struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
@@ -834,6 +854,12 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs,
834 goto DECODE_ERROR; 854 goto DECODE_ERROR;
835 } 855 }
836 856
857 ret = validate_vsi_array_indexes(inst, vsi);
858 if (ret) {
859 mtk_vcodec_err(inst, "Invalid values from VPU.");
860 goto DECODE_ERROR;
861 }
862
837 if (vsi->resolution_changed) { 863 if (vsi->resolution_changed) {
838 if (!vp9_alloc_work_buf(inst)) { 864 if (!vp9_alloc_work_buf(inst)) {
839 ret = -EINVAL; 865 ret = -EINVAL;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index db6b5205ffb1..ded1154481cd 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -85,6 +85,8 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx);
85 * @res_chg : [out] resolution change happens if current bs have different 85 * @res_chg : [out] resolution change happens if current bs have different
86 * picture width/height 86 * picture width/height
87 * Note: To flush the decoder when reaching EOF, set input bitstream as NULL. 87 * Note: To flush the decoder when reaching EOF, set input bitstream as NULL.
88 *
89 * Return: 0 on success. -EIO on unrecoverable error.
88 */ 90 */
89int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs, 91int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
90 struct vdec_fb *fb, bool *res_chg); 92 struct vdec_fb *fb, bool *res_chg);
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 a6fa145f2c54..acb639c4abd2 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -155,7 +155,7 @@ static void vp8_enc_free_work_buf(struct venc_vp8_inst *inst)
155 155
156 /* Buffers need to be freed by AP. */ 156 /* Buffers need to be freed by AP. */
157 for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) { 157 for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) {
158 if ((inst->work_bufs[i].size == 0)) 158 if (inst->work_bufs[i].size == 0)
159 continue; 159 continue;
160 mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]); 160 mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
161 } 161 }
@@ -172,7 +172,7 @@ static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst)
172 mtk_vcodec_debug_enter(inst); 172 mtk_vcodec_debug_enter(inst);
173 173
174 for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) { 174 for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) {
175 if ((wb[i].size == 0)) 175 if (wb[i].size == 0)
176 continue; 176 continue;
177 /* 177 /*
178 * This 'wb' structure is set by VPU side and shared to AP for 178 * This 'wb' structure is set by VPU side and shared to AP for
diff --git a/drivers/media/platform/s5p-cec/Makefile b/drivers/media/platform/s5p-cec/Makefile
new file mode 100644
index 000000000000..0e2cf457825a
--- /dev/null
+++ b/drivers/media/platform/s5p-cec/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_VIDEO_SAMSUNG_S5P_CEC) += s5p-cec.o
2s5p-cec-y += s5p_cec.o exynos_hdmi_cecctrl.o
diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h b/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
new file mode 100644
index 000000000000..7d9453505dce
--- /dev/null
+++ b/drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
@@ -0,0 +1,37 @@
1/* drivers/media/platform/s5p-cec/exynos_hdmi_cec.h
2 *
3 * Copyright (c) 2010, 2014 Samsung Electronics
4 * http://www.samsung.com/
5 *
6 * Header file for interface of Samsung Exynos hdmi cec hardware
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _EXYNOS_HDMI_CEC_H_
14#define _EXYNOS_HDMI_CEC_H_ __FILE__
15
16#include <linux/regmap.h>
17#include "s5p_cec.h"
18
19void s5p_cec_set_divider(struct s5p_cec_dev *cec);
20void s5p_cec_enable_rx(struct s5p_cec_dev *cec);
21void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec);
22void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec);
23void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec);
24void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec);
25void s5p_cec_reset(struct s5p_cec_dev *cec);
26void s5p_cec_tx_reset(struct s5p_cec_dev *cec);
27void s5p_cec_rx_reset(struct s5p_cec_dev *cec);
28void s5p_cec_threshold(struct s5p_cec_dev *cec);
29void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data,
30 size_t count, u8 retries);
31void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr);
32u32 s5p_cec_get_status(struct s5p_cec_dev *cec);
33void s5p_clr_pending_tx(struct s5p_cec_dev *cec);
34void s5p_clr_pending_rx(struct s5p_cec_dev *cec);
35void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer);
36
37#endif /* _EXYNOS_HDMI_CEC_H_ */
diff --git a/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
new file mode 100644
index 000000000000..1edf667d562a
--- /dev/null
+++ b/drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
@@ -0,0 +1,208 @@
1/* drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
2 *
3 * Copyright (c) 2009, 2014 Samsung Electronics
4 * http://www.samsung.com/
5 *
6 * cec ftn file for Samsung TVOUT driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/io.h>
14#include <linux/device.h>
15
16#include "exynos_hdmi_cec.h"
17#include "regs-cec.h"
18
19#define S5P_HDMI_FIN 24000000
20#define CEC_DIV_RATIO 320000
21
22#define CEC_MESSAGE_BROADCAST_MASK 0x0F
23#define CEC_MESSAGE_BROADCAST 0x0F
24#define CEC_FILTER_THRESHOLD 0x15
25
26void s5p_cec_set_divider(struct s5p_cec_dev *cec)
27{
28 u32 div_ratio, div_val;
29 unsigned int reg;
30
31 div_ratio = S5P_HDMI_FIN / CEC_DIV_RATIO - 1;
32
33 if (regmap_read(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, &reg)) {
34 dev_err(cec->dev, "failed to read phy control\n");
35 return;
36 }
37
38 reg = (reg & ~(0x3FF << 16)) | (div_ratio << 16);
39
40 if (regmap_write(cec->pmu, EXYNOS_HDMI_PHY_CONTROL, reg)) {
41 dev_err(cec->dev, "failed to write phy control\n");
42 return;
43 }
44
45 div_val = CEC_DIV_RATIO * 0.00005 - 1;
46
47 writeb(0x0, cec->reg + S5P_CEC_DIVISOR_3);
48 writeb(0x0, cec->reg + S5P_CEC_DIVISOR_2);
49 writeb(0x0, cec->reg + S5P_CEC_DIVISOR_1);
50 writeb(div_val, cec->reg + S5P_CEC_DIVISOR_0);
51}
52
53void s5p_cec_enable_rx(struct s5p_cec_dev *cec)
54{
55 u8 reg;
56
57 reg = readb(cec->reg + S5P_CEC_RX_CTRL);
58 reg |= S5P_CEC_RX_CTRL_ENABLE;
59 writeb(reg, cec->reg + S5P_CEC_RX_CTRL);
60}
61
62void s5p_cec_mask_rx_interrupts(struct s5p_cec_dev *cec)
63{
64 u8 reg;
65
66 reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
67 reg |= S5P_CEC_IRQ_RX_DONE;
68 reg |= S5P_CEC_IRQ_RX_ERROR;
69 writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
70}
71
72void s5p_cec_unmask_rx_interrupts(struct s5p_cec_dev *cec)
73{
74 u8 reg;
75
76 reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
77 reg &= ~S5P_CEC_IRQ_RX_DONE;
78 reg &= ~S5P_CEC_IRQ_RX_ERROR;
79 writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
80}
81
82void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec)
83{
84 u8 reg;
85
86 reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
87 reg |= S5P_CEC_IRQ_TX_DONE;
88 reg |= S5P_CEC_IRQ_TX_ERROR;
89 writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
90}
91
92void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec)
93{
94 u8 reg;
95
96 reg = readb(cec->reg + S5P_CEC_IRQ_MASK);
97 reg &= ~S5P_CEC_IRQ_TX_DONE;
98 reg &= ~S5P_CEC_IRQ_TX_ERROR;
99 writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
100}
101
102void s5p_cec_reset(struct s5p_cec_dev *cec)
103{
104 u8 reg;
105
106 writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL);
107 writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL);
108
109 reg = readb(cec->reg + 0xc4);
110 reg &= ~0x1;
111 writeb(reg, cec->reg + 0xc4);
112}
113
114void s5p_cec_tx_reset(struct s5p_cec_dev *cec)
115{
116 writeb(S5P_CEC_TX_CTRL_RESET, cec->reg + S5P_CEC_TX_CTRL);
117}
118
119void s5p_cec_rx_reset(struct s5p_cec_dev *cec)
120{
121 u8 reg;
122
123 writeb(S5P_CEC_RX_CTRL_RESET, cec->reg + S5P_CEC_RX_CTRL);
124
125 reg = readb(cec->reg + 0xc4);
126 reg &= ~0x1;
127 writeb(reg, cec->reg + 0xc4);
128}
129
130void s5p_cec_threshold(struct s5p_cec_dev *cec)
131{
132 writeb(CEC_FILTER_THRESHOLD, cec->reg + S5P_CEC_RX_FILTER_TH);
133 writeb(0, cec->reg + S5P_CEC_RX_FILTER_CTRL);
134}
135
136void s5p_cec_copy_packet(struct s5p_cec_dev *cec, char *data,
137 size_t count, u8 retries)
138{
139 int i = 0;
140 u8 reg;
141
142 while (i < count) {
143 writeb(data[i], cec->reg + (S5P_CEC_TX_BUFF0 + (i * 4)));
144 i++;
145 }
146
147 writeb(count, cec->reg + S5P_CEC_TX_BYTES);
148 reg = readb(cec->reg + S5P_CEC_TX_CTRL);
149 reg |= S5P_CEC_TX_CTRL_START;
150 reg &= ~0x70;
151 reg |= retries << 4;
152
153 if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST) {
154 dev_dbg(cec->dev, "Broadcast");
155 reg |= S5P_CEC_TX_CTRL_BCAST;
156 } else {
157 dev_dbg(cec->dev, "No Broadcast");
158 reg &= ~S5P_CEC_TX_CTRL_BCAST;
159 }
160
161 writeb(reg, cec->reg + S5P_CEC_TX_CTRL);
162 dev_dbg(cec->dev, "cec-tx: cec count (%zu): %*ph", count,
163 (int)count, data);
164}
165
166void s5p_cec_set_addr(struct s5p_cec_dev *cec, u32 addr)
167{
168 writeb(addr & 0x0F, cec->reg + S5P_CEC_LOGIC_ADDR);
169}
170
171u32 s5p_cec_get_status(struct s5p_cec_dev *cec)
172{
173 u32 status = 0;
174
175 status = readb(cec->reg + S5P_CEC_STATUS_0);
176 status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8;
177 status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16;
178 status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24;
179
180 dev_dbg(cec->dev, "status = 0x%x!\n", status);
181
182 return status;
183}
184
185void s5p_clr_pending_tx(struct s5p_cec_dev *cec)
186{
187 writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR,
188 cec->reg + S5P_CEC_IRQ_CLEAR);
189}
190
191void s5p_clr_pending_rx(struct s5p_cec_dev *cec)
192{
193 writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR,
194 cec->reg + S5P_CEC_IRQ_CLEAR);
195}
196
197void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer)
198{
199 u32 i = 0;
200 char debug[40];
201
202 while (i < size) {
203 buffer[i] = readb(cec->reg + S5P_CEC_RX_BUFF0 + (i * 4));
204 sprintf(debug + i * 2, "%02x ", buffer[i]);
205 i++;
206 }
207 dev_dbg(cec->dev, "cec-rx: cec size(%d): %s", size, debug);
208}
diff --git a/drivers/media/platform/s5p-cec/regs-cec.h b/drivers/media/platform/s5p-cec/regs-cec.h
new file mode 100644
index 000000000000..b2e7e129920e
--- /dev/null
+++ b/drivers/media/platform/s5p-cec/regs-cec.h
@@ -0,0 +1,96 @@
1/* drivers/media/platform/s5p-cec/regs-cec.h
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 * http://www.samsung.com/
5 *
6 * register header file for Samsung TVOUT driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __EXYNOS_REGS__H
14#define __EXYNOS_REGS__H
15
16/*
17 * Register part
18 */
19#define S5P_CEC_STATUS_0 (0x0000)
20#define S5P_CEC_STATUS_1 (0x0004)
21#define S5P_CEC_STATUS_2 (0x0008)
22#define S5P_CEC_STATUS_3 (0x000C)
23#define S5P_CEC_IRQ_MASK (0x0010)
24#define S5P_CEC_IRQ_CLEAR (0x0014)
25#define S5P_CEC_LOGIC_ADDR (0x0020)
26#define S5P_CEC_DIVISOR_0 (0x0030)
27#define S5P_CEC_DIVISOR_1 (0x0034)
28#define S5P_CEC_DIVISOR_2 (0x0038)
29#define S5P_CEC_DIVISOR_3 (0x003C)
30
31#define S5P_CEC_TX_CTRL (0x0040)
32#define S5P_CEC_TX_BYTES (0x0044)
33#define S5P_CEC_TX_STAT0 (0x0060)
34#define S5P_CEC_TX_STAT1 (0x0064)
35#define S5P_CEC_TX_BUFF0 (0x0080)
36#define S5P_CEC_TX_BUFF1 (0x0084)
37#define S5P_CEC_TX_BUFF2 (0x0088)
38#define S5P_CEC_TX_BUFF3 (0x008C)
39#define S5P_CEC_TX_BUFF4 (0x0090)
40#define S5P_CEC_TX_BUFF5 (0x0094)
41#define S5P_CEC_TX_BUFF6 (0x0098)
42#define S5P_CEC_TX_BUFF7 (0x009C)
43#define S5P_CEC_TX_BUFF8 (0x00A0)
44#define S5P_CEC_TX_BUFF9 (0x00A4)
45#define S5P_CEC_TX_BUFF10 (0x00A8)
46#define S5P_CEC_TX_BUFF11 (0x00AC)
47#define S5P_CEC_TX_BUFF12 (0x00B0)
48#define S5P_CEC_TX_BUFF13 (0x00B4)
49#define S5P_CEC_TX_BUFF14 (0x00B8)
50#define S5P_CEC_TX_BUFF15 (0x00BC)
51
52#define S5P_CEC_RX_CTRL (0x00C0)
53#define S5P_CEC_RX_STAT0 (0x00E0)
54#define S5P_CEC_RX_STAT1 (0x00E4)
55#define S5P_CEC_RX_BUFF0 (0x0100)
56#define S5P_CEC_RX_BUFF1 (0x0104)
57#define S5P_CEC_RX_BUFF2 (0x0108)
58#define S5P_CEC_RX_BUFF3 (0x010C)
59#define S5P_CEC_RX_BUFF4 (0x0110)
60#define S5P_CEC_RX_BUFF5 (0x0114)
61#define S5P_CEC_RX_BUFF6 (0x0118)
62#define S5P_CEC_RX_BUFF7 (0x011C)
63#define S5P_CEC_RX_BUFF8 (0x0120)
64#define S5P_CEC_RX_BUFF9 (0x0124)
65#define S5P_CEC_RX_BUFF10 (0x0128)
66#define S5P_CEC_RX_BUFF11 (0x012C)
67#define S5P_CEC_RX_BUFF12 (0x0130)
68#define S5P_CEC_RX_BUFF13 (0x0134)
69#define S5P_CEC_RX_BUFF14 (0x0138)
70#define S5P_CEC_RX_BUFF15 (0x013C)
71
72#define S5P_CEC_RX_FILTER_CTRL (0x0180)
73#define S5P_CEC_RX_FILTER_TH (0x0184)
74
75/*
76 * Bit definition part
77 */
78#define S5P_CEC_IRQ_TX_DONE (1<<0)
79#define S5P_CEC_IRQ_TX_ERROR (1<<1)
80#define S5P_CEC_IRQ_RX_DONE (1<<4)
81#define S5P_CEC_IRQ_RX_ERROR (1<<5)
82
83#define S5P_CEC_TX_CTRL_START (1<<0)
84#define S5P_CEC_TX_CTRL_BCAST (1<<1)
85#define S5P_CEC_TX_CTRL_RETRY (0x04<<4)
86#define S5P_CEC_TX_CTRL_RESET (1<<7)
87
88#define S5P_CEC_RX_CTRL_ENABLE (1<<0)
89#define S5P_CEC_RX_CTRL_RESET (1<<7)
90
91#define S5P_CEC_LOGIC_ADDR_MASK (0xF)
92
93/* PMU Registers for PHY */
94#define EXYNOS_HDMI_PHY_CONTROL 0x700
95
96#endif /* __EXYNOS_REGS__H */
diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c
new file mode 100644
index 000000000000..664937b61fa4
--- /dev/null
+++ b/drivers/media/platform/s5p-cec/s5p_cec.c
@@ -0,0 +1,304 @@
1/* drivers/media/platform/s5p-cec/s5p_cec.c
2 *
3 * Samsung S5P CEC driver
4 *
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This driver is based on the "cec interface driver for exynos soc" by
13 * SangPil Moon.
14 */
15
16#include <linux/clk.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/mfd/syscon.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_platform.h>
23#include <linux/platform_device.h>
24#include <linux/pm_runtime.h>
25#include <linux/timer.h>
26#include <linux/workqueue.h>
27#include <media/cec.h>
28#include <media/cec-notifier.h>
29
30#include "exynos_hdmi_cec.h"
31#include "regs-cec.h"
32#include "s5p_cec.h"
33
34#define CEC_NAME "s5p-cec"
35
36static int debug;
37module_param(debug, int, 0644);
38MODULE_PARM_DESC(debug, "debug level (0-2)");
39
40static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable)
41{
42 struct s5p_cec_dev *cec = cec_get_drvdata(adap);
43
44 if (enable) {
45 pm_runtime_get_sync(cec->dev);
46
47 s5p_cec_reset(cec);
48
49 s5p_cec_set_divider(cec);
50 s5p_cec_threshold(cec);
51
52 s5p_cec_unmask_tx_interrupts(cec);
53 s5p_cec_unmask_rx_interrupts(cec);
54 s5p_cec_enable_rx(cec);
55 } else {
56 s5p_cec_mask_tx_interrupts(cec);
57 s5p_cec_mask_rx_interrupts(cec);
58 pm_runtime_disable(cec->dev);
59 }
60
61 return 0;
62}
63
64static int s5p_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
65{
66 struct s5p_cec_dev *cec = cec_get_drvdata(adap);
67
68 s5p_cec_set_addr(cec, addr);
69 return 0;
70}
71
72static int s5p_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
73 u32 signal_free_time, struct cec_msg *msg)
74{
75 struct s5p_cec_dev *cec = cec_get_drvdata(adap);
76
77 /*
78 * Unclear if 0 retries are allowed by the hardware, so have 1 as
79 * the minimum.
80 */
81 s5p_cec_copy_packet(cec, msg->msg, msg->len, max(1, attempts - 1));
82 return 0;
83}
84
85static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
86{
87 struct s5p_cec_dev *cec = priv;
88 u32 status = 0;
89
90 status = s5p_cec_get_status(cec);
91
92 dev_dbg(cec->dev, "irq received\n");
93
94 if (status & CEC_STATUS_TX_DONE) {
95 if (status & CEC_STATUS_TX_ERROR) {
96 dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n");
97 cec->tx = STATE_ERROR;
98 } else {
99 dev_dbg(cec->dev, "CEC_STATUS_TX_DONE\n");
100 cec->tx = STATE_DONE;
101 }
102 s5p_clr_pending_tx(cec);
103 }
104
105 if (status & CEC_STATUS_RX_DONE) {
106 if (status & CEC_STATUS_RX_ERROR) {
107 dev_dbg(cec->dev, "CEC_STATUS_RX_ERROR set\n");
108 s5p_cec_rx_reset(cec);
109 s5p_cec_enable_rx(cec);
110 } else {
111 dev_dbg(cec->dev, "CEC_STATUS_RX_DONE set\n");
112 if (cec->rx != STATE_IDLE)
113 dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n");
114 cec->rx = STATE_BUSY;
115 cec->msg.len = status >> 24;
116 cec->msg.rx_status = CEC_RX_STATUS_OK;
117 s5p_cec_get_rx_buf(cec, cec->msg.len,
118 cec->msg.msg);
119 cec->rx = STATE_DONE;
120 s5p_cec_enable_rx(cec);
121 }
122 /* Clear interrupt pending bit */
123 s5p_clr_pending_rx(cec);
124 }
125 return IRQ_WAKE_THREAD;
126}
127
128static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv)
129{
130 struct s5p_cec_dev *cec = priv;
131
132 dev_dbg(cec->dev, "irq processing thread\n");
133 switch (cec->tx) {
134 case STATE_DONE:
135 cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
136 cec->tx = STATE_IDLE;
137 break;
138 case STATE_ERROR:
139 cec_transmit_done(cec->adap,
140 CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR,
141 0, 0, 0, 1);
142 cec->tx = STATE_IDLE;
143 break;
144 case STATE_BUSY:
145 dev_err(cec->dev, "state set to busy, this should not occur here\n");
146 break;
147 default:
148 break;
149 }
150
151 switch (cec->rx) {
152 case STATE_DONE:
153 cec_received_msg(cec->adap, &cec->msg);
154 cec->rx = STATE_IDLE;
155 break;
156 default:
157 break;
158 }
159
160 return IRQ_HANDLED;
161}
162
163static const struct cec_adap_ops s5p_cec_adap_ops = {
164 .adap_enable = s5p_cec_adap_enable,
165 .adap_log_addr = s5p_cec_adap_log_addr,
166 .adap_transmit = s5p_cec_adap_transmit,
167};
168
169static int s5p_cec_probe(struct platform_device *pdev)
170{
171 struct device *dev = &pdev->dev;
172 struct device_node *np;
173 struct platform_device *hdmi_dev;
174 struct resource *res;
175 struct s5p_cec_dev *cec;
176 int ret;
177
178 np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0);
179
180 if (!np) {
181 dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n");
182 return -ENODEV;
183 }
184 hdmi_dev = of_find_device_by_node(np);
185 if (hdmi_dev == NULL)
186 return -EPROBE_DEFER;
187
188 cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
189 if (!cec)
190 return -ENOMEM;
191
192 cec->dev = dev;
193
194 cec->irq = platform_get_irq(pdev, 0);
195 if (cec->irq < 0)
196 return cec->irq;
197
198 ret = devm_request_threaded_irq(dev, cec->irq, s5p_cec_irq_handler,
199 s5p_cec_irq_handler_thread, 0, pdev->name, cec);
200 if (ret)
201 return ret;
202
203 cec->clk = devm_clk_get(dev, "hdmicec");
204 if (IS_ERR(cec->clk))
205 return PTR_ERR(cec->clk);
206
207 cec->pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
208 "samsung,syscon-phandle");
209 if (IS_ERR(cec->pmu))
210 return -EPROBE_DEFER;
211
212 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
213 cec->reg = devm_ioremap_resource(dev, res);
214 if (IS_ERR(cec->reg))
215 return PTR_ERR(cec->reg);
216
217 cec->notifier = cec_notifier_get(&hdmi_dev->dev);
218 if (cec->notifier == NULL)
219 return -ENOMEM;
220
221 cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec,
222 CEC_NAME,
223 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
224 CEC_CAP_PASSTHROUGH | CEC_CAP_RC, 1);
225 ret = PTR_ERR_OR_ZERO(cec->adap);
226 if (ret)
227 return ret;
228
229 ret = cec_register_adapter(cec->adap, &pdev->dev);
230 if (ret)
231 goto err_delete_adapter;
232
233 cec_register_cec_notifier(cec->adap, cec->notifier);
234
235 platform_set_drvdata(pdev, cec);
236 pm_runtime_enable(dev);
237
238 dev_dbg(dev, "successfuly probed\n");
239 return 0;
240
241err_delete_adapter:
242 cec_delete_adapter(cec->adap);
243 return ret;
244}
245
246static int s5p_cec_remove(struct platform_device *pdev)
247{
248 struct s5p_cec_dev *cec = platform_get_drvdata(pdev);
249
250 cec_unregister_adapter(cec->adap);
251 cec_notifier_put(cec->notifier);
252 pm_runtime_disable(&pdev->dev);
253 return 0;
254}
255
256static int __maybe_unused s5p_cec_runtime_suspend(struct device *dev)
257{
258 struct s5p_cec_dev *cec = dev_get_drvdata(dev);
259
260 clk_disable_unprepare(cec->clk);
261 return 0;
262}
263
264static int __maybe_unused s5p_cec_runtime_resume(struct device *dev)
265{
266 struct s5p_cec_dev *cec = dev_get_drvdata(dev);
267 int ret;
268
269 ret = clk_prepare_enable(cec->clk);
270 if (ret < 0)
271 return ret;
272 return 0;
273}
274
275static const struct dev_pm_ops s5p_cec_pm_ops = {
276 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
277 pm_runtime_force_resume)
278 SET_RUNTIME_PM_OPS(s5p_cec_runtime_suspend, s5p_cec_runtime_resume,
279 NULL)
280};
281
282static const struct of_device_id s5p_cec_match[] = {
283 {
284 .compatible = "samsung,s5p-cec",
285 },
286 {},
287};
288MODULE_DEVICE_TABLE(of, s5p_cec_match);
289
290static struct platform_driver s5p_cec_pdrv = {
291 .probe = s5p_cec_probe,
292 .remove = s5p_cec_remove,
293 .driver = {
294 .name = CEC_NAME,
295 .of_match_table = s5p_cec_match,
296 .pm = &s5p_cec_pm_ops,
297 },
298};
299
300module_platform_driver(s5p_cec_pdrv);
301
302MODULE_AUTHOR("Kamil Debski <kamil@wypas.org>");
303MODULE_LICENSE("GPL");
304MODULE_DESCRIPTION("Samsung S5P CEC driver");
diff --git a/drivers/media/platform/s5p-cec/s5p_cec.h b/drivers/media/platform/s5p-cec/s5p_cec.h
new file mode 100644
index 000000000000..7015845c1caa
--- /dev/null
+++ b/drivers/media/platform/s5p-cec/s5p_cec.h
@@ -0,0 +1,79 @@
1/* drivers/media/platform/s5p-cec/s5p_cec.h
2 *
3 * Samsung S5P HDMI CEC driver
4 *
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef _S5P_CEC_H_
14#define _S5P_CEC_H_ __FILE__
15
16#include <linux/clk.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/mfd/syscon.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/timer.h>
25#include <linux/version.h>
26#include <linux/workqueue.h>
27#include <media/cec.h>
28
29#include "exynos_hdmi_cec.h"
30#include "regs-cec.h"
31#include "s5p_cec.h"
32
33#define CEC_NAME "s5p-cec"
34
35#define CEC_STATUS_TX_RUNNING (1 << 0)
36#define CEC_STATUS_TX_TRANSFERRING (1 << 1)
37#define CEC_STATUS_TX_DONE (1 << 2)
38#define CEC_STATUS_TX_ERROR (1 << 3)
39#define CEC_STATUS_TX_BYTES (0xFF << 8)
40#define CEC_STATUS_RX_RUNNING (1 << 16)
41#define CEC_STATUS_RX_RECEIVING (1 << 17)
42#define CEC_STATUS_RX_DONE (1 << 18)
43#define CEC_STATUS_RX_ERROR (1 << 19)
44#define CEC_STATUS_RX_BCAST (1 << 20)
45#define CEC_STATUS_RX_BYTES (0xFF << 24)
46
47#define CEC_WORKER_TX_DONE (1 << 0)
48#define CEC_WORKER_RX_MSG (1 << 1)
49
50/* CEC Rx buffer size */
51#define CEC_RX_BUFF_SIZE 16
52/* CEC Tx buffer size */
53#define CEC_TX_BUFF_SIZE 16
54
55enum cec_state {
56 STATE_IDLE,
57 STATE_BUSY,
58 STATE_DONE,
59 STATE_ERROR
60};
61
62struct cec_notifier;
63
64struct s5p_cec_dev {
65 struct cec_adapter *adap;
66 struct clk *clk;
67 struct device *dev;
68 struct mutex lock;
69 struct regmap *pmu;
70 struct cec_notifier *notifier;
71 int irq;
72 void __iomem *reg;
73
74 enum cec_state rx;
75 enum cec_state tx;
76 struct cec_msg msg;
77};
78
79#endif /* _S5P_CEC_H_ */
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 62c0dec30b59..81ed5cd5cd5d 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -679,7 +679,7 @@ static int g2d_probe(struct platform_device *pdev)
679 0, pdev->name, dev); 679 0, pdev->name, dev);
680 if (ret) { 680 if (ret) {
681 dev_err(&pdev->dev, "failed to install IRQ\n"); 681 dev_err(&pdev->dev, "failed to install IRQ\n");
682 goto put_clk_gate; 682 goto unprep_clk_gate;
683 } 683 }
684 684
685 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); 685 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
index d2cd35916dc5..c0166ee9a455 100644
--- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
+++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h
@@ -403,7 +403,7 @@
403#define MFC_OTHER_ENC_CTX_BUF_SIZE_V6 (12 * SZ_1K) /* 12KB */ 403#define MFC_OTHER_ENC_CTX_BUF_SIZE_V6 (12 * SZ_1K) /* 12KB */
404 404
405/* MFCv6 variant defines */ 405/* MFCv6 variant defines */
406#define MAX_FW_SIZE_V6 (SZ_1M) /* 1MB */ 406#define MAX_FW_SIZE_V6 (SZ_512K) /* 512KB */
407#define MAX_CPB_SIZE_V6 (3 * SZ_1M) /* 3MB */ 407#define MAX_CPB_SIZE_V6 (3 * SZ_1M) /* 3MB */
408#define MFC_VERSION_V6 0x61 408#define MFC_VERSION_V6 0x61
409#define MFC_NUM_PORTS_V6 1 409#define MFC_NUM_PORTS_V6 1
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/s5p-mfc/regs-mfc-v7.h
index 1a5c6fdf7846..9f220769d970 100644
--- a/drivers/media/platform/s5p-mfc/regs-mfc-v7.h
+++ b/drivers/media/platform/s5p-mfc/regs-mfc-v7.h
@@ -34,7 +34,7 @@
34#define S5P_FIMV_E_VP8_NUM_T_LAYER_V7 0xfdc4 34#define S5P_FIMV_E_VP8_NUM_T_LAYER_V7 0xfdc4
35 35
36/* MFCv7 variant defines */ 36/* MFCv7 variant defines */
37#define MAX_FW_SIZE_V7 (SZ_1M) /* 1MB */ 37#define MAX_FW_SIZE_V7 (SZ_512K) /* 512KB */
38#define MAX_CPB_SIZE_V7 (3 * SZ_1M) /* 3MB */ 38#define MAX_CPB_SIZE_V7 (3 * SZ_1M) /* 3MB */
39#define MFC_VERSION_V7 0x72 39#define MFC_VERSION_V7 0x72
40#define MFC_NUM_PORTS_V7 1 40#define MFC_NUM_PORTS_V7 1
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h
index 4d1c3750eb5e..75f5f7511d72 100644
--- a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h
+++ b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h
@@ -116,7 +116,7 @@
116#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V8 64 116#define S5P_FIMV_D_ALIGN_PLANE_SIZE_V8 64
117 117
118/* MFCv8 variant defines */ 118/* MFCv8 variant defines */
119#define MAX_FW_SIZE_V8 (SZ_1M) /* 1MB */ 119#define MAX_FW_SIZE_V8 (SZ_512K) /* 512KB */
120#define MAX_CPB_SIZE_V8 (3 * SZ_1M) /* 3MB */ 120#define MAX_CPB_SIZE_V8 (3 * SZ_1M) /* 3MB */
121#define MFC_VERSION_V8 0x80 121#define MFC_VERSION_V8 0x80
122#define MFC_NUM_PORTS_V8 1 122#define MFC_NUM_PORTS_V8 1
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index bb0a5887c9a9..1afde5021ca6 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,6 +22,7 @@
22#include <media/v4l2-event.h> 22#include <media/v4l2-event.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_device.h>
25#include <linux/of_reserved_mem.h> 26#include <linux/of_reserved_mem.h>
26#include <media/videobuf2-v4l2.h> 27#include <media/videobuf2-v4l2.h>
27#include "s5p_mfc_common.h" 28#include "s5p_mfc_common.h"
@@ -42,6 +43,10 @@ int mfc_debug_level;
42module_param_named(debug, mfc_debug_level, int, S_IRUGO | S_IWUSR); 43module_param_named(debug, mfc_debug_level, int, S_IRUGO | S_IWUSR);
43MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages"); 44MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages");
44 45
46static char *mfc_mem_size;
47module_param_named(mem, mfc_mem_size, charp, 0644);
48MODULE_PARM_DESC(mem, "Preallocated memory size for the firmware and context buffers");
49
45/* Helper functions for interrupt processing */ 50/* Helper functions for interrupt processing */
46 51
47/* Remove from hw execution round robin */ 52/* Remove from hw execution round robin */
@@ -206,6 +211,7 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work)
206 } 211 }
207 s5p_mfc_clock_on(); 212 s5p_mfc_clock_on();
208 ret = s5p_mfc_init_hw(dev); 213 ret = s5p_mfc_init_hw(dev);
214 s5p_mfc_clock_off();
209 if (ret) 215 if (ret)
210 mfc_err("Failed to reinit FW\n"); 216 mfc_err("Failed to reinit FW\n");
211 } 217 }
@@ -666,9 +672,9 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
666 break; 672 break;
667 } 673 }
668 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); 674 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
669 wake_up_ctx(ctx, reason, err);
670 WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); 675 WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
671 s5p_mfc_clock_off(); 676 s5p_mfc_clock_off();
677 wake_up_ctx(ctx, reason, err);
672 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); 678 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
673 } else { 679 } else {
674 s5p_mfc_handle_frame(ctx, reason, err); 680 s5p_mfc_handle_frame(ctx, reason, err);
@@ -682,15 +688,11 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
682 case S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET: 688 case S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET:
683 ctx->inst_no = s5p_mfc_hw_call(dev->mfc_ops, get_inst_no, dev); 689 ctx->inst_no = s5p_mfc_hw_call(dev->mfc_ops, get_inst_no, dev);
684 ctx->state = MFCINST_GOT_INST; 690 ctx->state = MFCINST_GOT_INST;
685 clear_work_bit(ctx);
686 wake_up(&ctx->queue);
687 goto irq_cleanup_hw; 691 goto irq_cleanup_hw;
688 692
689 case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET: 693 case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET:
690 clear_work_bit(ctx);
691 ctx->inst_no = MFC_NO_INSTANCE_SET; 694 ctx->inst_no = MFC_NO_INSTANCE_SET;
692 ctx->state = MFCINST_FREE; 695 ctx->state = MFCINST_FREE;
693 wake_up(&ctx->queue);
694 goto irq_cleanup_hw; 696 goto irq_cleanup_hw;
695 697
696 case S5P_MFC_R2H_CMD_SYS_INIT_RET: 698 case S5P_MFC_R2H_CMD_SYS_INIT_RET:
@@ -700,9 +702,9 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
700 if (ctx) 702 if (ctx)
701 clear_work_bit(ctx); 703 clear_work_bit(ctx);
702 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); 704 s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
703 wake_up_dev(dev, reason, err);
704 clear_bit(0, &dev->hw_lock); 705 clear_bit(0, &dev->hw_lock);
705 clear_bit(0, &dev->enter_suspend); 706 clear_bit(0, &dev->enter_suspend);
707 wake_up_dev(dev, reason, err);
706 break; 708 break;
707 709
708 case S5P_MFC_R2H_CMD_INIT_BUFFERS_RET: 710 case S5P_MFC_R2H_CMD_INIT_BUFFERS_RET:
@@ -717,9 +719,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
717 break; 719 break;
718 720
719 case S5P_MFC_R2H_CMD_DPB_FLUSH_RET: 721 case S5P_MFC_R2H_CMD_DPB_FLUSH_RET:
720 clear_work_bit(ctx);
721 ctx->state = MFCINST_RUNNING; 722 ctx->state = MFCINST_RUNNING;
722 wake_up(&ctx->queue);
723 goto irq_cleanup_hw; 723 goto irq_cleanup_hw;
724 724
725 default: 725 default:
@@ -738,6 +738,8 @@ irq_cleanup_hw:
738 mfc_err("Failed to unlock hw\n"); 738 mfc_err("Failed to unlock hw\n");
739 739
740 s5p_mfc_clock_off(); 740 s5p_mfc_clock_off();
741 clear_work_bit(ctx);
742 wake_up(&ctx->queue);
741 743
742 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); 744 s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
743 spin_unlock(&dev->irqlock); 745 spin_unlock(&dev->irqlock);
@@ -764,6 +766,7 @@ static int s5p_mfc_open(struct file *file)
764 ret = -ENOMEM; 766 ret = -ENOMEM;
765 goto err_alloc; 767 goto err_alloc;
766 } 768 }
769 init_waitqueue_head(&ctx->queue);
767 v4l2_fh_init(&ctx->fh, vdev); 770 v4l2_fh_init(&ctx->fh, vdev);
768 file->private_data = &ctx->fh; 771 file->private_data = &ctx->fh;
769 v4l2_fh_add(&ctx->fh); 772 v4l2_fh_add(&ctx->fh);
@@ -866,7 +869,6 @@ static int s5p_mfc_open(struct file *file)
866 /* Init videobuf2 queue for OUTPUT */ 869 /* Init videobuf2 queue for OUTPUT */
867 q = &ctx->vq_src; 870 q = &ctx->vq_src;
868 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 871 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
869 q->io_modes = VB2_MMAP;
870 q->drv_priv = &ctx->fh; 872 q->drv_priv = &ctx->fh;
871 q->lock = &dev->mfc_mutex; 873 q->lock = &dev->mfc_mutex;
872 if (vdev == dev->vfd_dec) { 874 if (vdev == dev->vfd_dec) {
@@ -899,7 +901,6 @@ static int s5p_mfc_open(struct file *file)
899 mfc_err("Failed to initialize videobuf2 queue(output)\n"); 901 mfc_err("Failed to initialize videobuf2 queue(output)\n");
900 goto err_queue_init; 902 goto err_queue_init;
901 } 903 }
902 init_waitqueue_head(&ctx->queue);
903 mutex_unlock(&dev->mfc_mutex); 904 mutex_unlock(&dev->mfc_mutex);
904 mfc_debug_leave(); 905 mfc_debug_leave();
905 return ret; 906 return ret;
@@ -1106,58 +1107,158 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev,
1106 return NULL; 1107 return NULL;
1107} 1108}
1108 1109
1109static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev) 1110static int s5p_mfc_configure_2port_memory(struct s5p_mfc_dev *mfc_dev)
1110{ 1111{
1111 struct device *dev = &mfc_dev->plat_dev->dev; 1112 struct device *dev = &mfc_dev->plat_dev->dev;
1112 1113 void *bank2_virt;
1113 /* 1114 dma_addr_t bank2_dma_addr;
1114 * When IOMMU is available, we cannot use the default configuration, 1115 unsigned long align_size = 1 << MFC_BASE_ALIGN_ORDER;
1115 * because of MFC firmware requirements: address space limited to 1116 int ret;
1116 * 256M and non-zero default start address.
1117 * This is still simplified, not optimal configuration, but for now
1118 * IOMMU core doesn't allow to configure device's IOMMUs channel
1119 * separately.
1120 */
1121 if (exynos_is_iommu_available(dev)) {
1122 int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE,
1123 S5P_MFC_IOMMU_DMA_SIZE);
1124 if (ret == 0)
1125 mfc_dev->mem_dev_l = mfc_dev->mem_dev_r = dev;
1126 return ret;
1127 }
1128 1117
1129 /* 1118 /*
1130 * Create and initialize virtual devices for accessing 1119 * Create and initialize virtual devices for accessing
1131 * reserved memory regions. 1120 * reserved memory regions.
1132 */ 1121 */
1133 mfc_dev->mem_dev_l = s5p_mfc_alloc_memdev(dev, "left", 1122 mfc_dev->mem_dev[BANK_L_CTX] = s5p_mfc_alloc_memdev(dev, "left",
1134 MFC_BANK1_ALLOC_CTX); 1123 BANK_L_CTX);
1135 if (!mfc_dev->mem_dev_l) 1124 if (!mfc_dev->mem_dev[BANK_L_CTX])
1136 return -ENODEV; 1125 return -ENODEV;
1137 mfc_dev->mem_dev_r = s5p_mfc_alloc_memdev(dev, "right", 1126 mfc_dev->mem_dev[BANK_R_CTX] = s5p_mfc_alloc_memdev(dev, "right",
1138 MFC_BANK2_ALLOC_CTX); 1127 BANK_R_CTX);
1139 if (!mfc_dev->mem_dev_r) { 1128 if (!mfc_dev->mem_dev[BANK_R_CTX]) {
1140 device_unregister(mfc_dev->mem_dev_l); 1129 device_unregister(mfc_dev->mem_dev[BANK_L_CTX]);
1141 return -ENODEV; 1130 return -ENODEV;
1142 } 1131 }
1143 1132
1133 /* Allocate memory for firmware and initialize both banks addresses */
1134 ret = s5p_mfc_alloc_firmware(mfc_dev);
1135 if (ret) {
1136 device_unregister(mfc_dev->mem_dev[BANK_R_CTX]);
1137 device_unregister(mfc_dev->mem_dev[BANK_L_CTX]);
1138 return ret;
1139 }
1140
1141 mfc_dev->dma_base[BANK_L_CTX] = mfc_dev->fw_buf.dma;
1142
1143 bank2_virt = dma_alloc_coherent(mfc_dev->mem_dev[BANK_R_CTX],
1144 align_size, &bank2_dma_addr, GFP_KERNEL);
1145 if (!bank2_virt) {
1146 mfc_err("Allocating bank2 base failed\n");
1147 s5p_mfc_release_firmware(mfc_dev);
1148 device_unregister(mfc_dev->mem_dev[BANK_R_CTX]);
1149 device_unregister(mfc_dev->mem_dev[BANK_L_CTX]);
1150 return -ENOMEM;
1151 }
1152
1153 /* Valid buffers passed to MFC encoder with LAST_FRAME command
1154 * should not have address of bank2 - MFC will treat it as a null frame.
1155 * To avoid such situation we set bank2 address below the pool address.
1156 */
1157 mfc_dev->dma_base[BANK_R_CTX] = bank2_dma_addr - align_size;
1158
1159 dma_free_coherent(mfc_dev->mem_dev[BANK_R_CTX], align_size, bank2_virt,
1160 bank2_dma_addr);
1161
1162 vb2_dma_contig_set_max_seg_size(mfc_dev->mem_dev[BANK_L_CTX],
1163 DMA_BIT_MASK(32));
1164 vb2_dma_contig_set_max_seg_size(mfc_dev->mem_dev[BANK_R_CTX],
1165 DMA_BIT_MASK(32));
1166
1144 return 0; 1167 return 0;
1145} 1168}
1146 1169
1147static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev) 1170static void s5p_mfc_unconfigure_2port_memory(struct s5p_mfc_dev *mfc_dev)
1171{
1172 device_unregister(mfc_dev->mem_dev[BANK_L_CTX]);
1173 device_unregister(mfc_dev->mem_dev[BANK_R_CTX]);
1174 vb2_dma_contig_clear_max_seg_size(mfc_dev->mem_dev[BANK_L_CTX]);
1175 vb2_dma_contig_clear_max_seg_size(mfc_dev->mem_dev[BANK_R_CTX]);
1176}
1177
1178static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev)
1148{ 1179{
1149 struct device *dev = &mfc_dev->plat_dev->dev; 1180 struct device *dev = &mfc_dev->plat_dev->dev;
1181 unsigned long mem_size = SZ_4M;
1182 unsigned int bitmap_size;
1150 1183
1151 if (exynos_is_iommu_available(dev)) { 1184 if (IS_ENABLED(CONFIG_DMA_CMA) || exynos_is_iommu_available(dev))
1152 exynos_unconfigure_iommu(dev); 1185 mem_size = SZ_8M;
1153 return; 1186
1187 if (mfc_mem_size)
1188 mem_size = memparse(mfc_mem_size, NULL);
1189
1190 bitmap_size = BITS_TO_LONGS(mem_size >> PAGE_SHIFT) * sizeof(long);
1191
1192 mfc_dev->mem_bitmap = kzalloc(bitmap_size, GFP_KERNEL);
1193 if (!mfc_dev->mem_bitmap)
1194 return -ENOMEM;
1195
1196 mfc_dev->mem_virt = dma_alloc_coherent(dev, mem_size,
1197 &mfc_dev->mem_base, GFP_KERNEL);
1198 if (!mfc_dev->mem_virt) {
1199 kfree(mfc_dev->mem_bitmap);
1200 dev_err(dev, "failed to preallocate %ld MiB for the firmware and context buffers\n",
1201 (mem_size / SZ_1M));
1202 return -ENOMEM;
1154 } 1203 }
1204 mfc_dev->mem_size = mem_size;
1205 mfc_dev->dma_base[BANK_L_CTX] = mfc_dev->mem_base;
1206 mfc_dev->dma_base[BANK_R_CTX] = mfc_dev->mem_base;
1207
1208 /*
1209 * MFC hardware cannot handle 0 as a base address, so mark first 128K
1210 * as used (to keep required base alignment) and adjust base address
1211 */
1212 if (mfc_dev->mem_base == (dma_addr_t)0) {
1213 unsigned int offset = 1 << MFC_BASE_ALIGN_ORDER;
1214
1215 bitmap_set(mfc_dev->mem_bitmap, 0, offset >> PAGE_SHIFT);
1216 mfc_dev->dma_base[BANK_L_CTX] += offset;
1217 mfc_dev->dma_base[BANK_R_CTX] += offset;
1218 }
1219
1220 /* Firmware allocation cannot fail in this case */
1221 s5p_mfc_alloc_firmware(mfc_dev);
1155 1222
1156 device_unregister(mfc_dev->mem_dev_l); 1223 mfc_dev->mem_dev[BANK_L_CTX] = mfc_dev->mem_dev[BANK_R_CTX] = dev;
1157 device_unregister(mfc_dev->mem_dev_r); 1224 vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
1225
1226 dev_info(dev, "preallocated %ld MiB buffer for the firmware and context buffers\n",
1227 (mem_size / SZ_1M));
1228
1229 return 0;
1230}
1231
1232static void s5p_mfc_unconfigure_common_memory(struct s5p_mfc_dev *mfc_dev)
1233{
1234 struct device *dev = &mfc_dev->plat_dev->dev;
1235
1236 dma_free_coherent(dev, mfc_dev->mem_size, mfc_dev->mem_virt,
1237 mfc_dev->mem_base);
1238 kfree(mfc_dev->mem_bitmap);
1239 vb2_dma_contig_clear_max_seg_size(dev);
1240}
1241
1242static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev)
1243{
1244 struct device *dev = &mfc_dev->plat_dev->dev;
1245
1246 if (exynos_is_iommu_available(dev) || !IS_TWOPORT(mfc_dev))
1247 return s5p_mfc_configure_common_memory(mfc_dev);
1248 else
1249 return s5p_mfc_configure_2port_memory(mfc_dev);
1158} 1250}
1159 1251
1160static void *mfc_get_drv_data(struct platform_device *pdev); 1252static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
1253{
1254 struct device *dev = &mfc_dev->plat_dev->dev;
1255
1256 s5p_mfc_release_firmware(mfc_dev);
1257 if (exynos_is_iommu_available(dev) || !IS_TWOPORT(mfc_dev))
1258 s5p_mfc_unconfigure_common_memory(mfc_dev);
1259 else
1260 s5p_mfc_unconfigure_2port_memory(mfc_dev);
1261}
1161 1262
1162/* MFC probe function */ 1263/* MFC probe function */
1163static int s5p_mfc_probe(struct platform_device *pdev) 1264static int s5p_mfc_probe(struct platform_device *pdev)
@@ -1182,7 +1283,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1182 return -ENODEV; 1283 return -ENODEV;
1183 } 1284 }
1184 1285
1185 dev->variant = mfc_get_drv_data(pdev); 1286 dev->variant = of_device_get_match_data(&pdev->dev);
1186 1287
1187 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1288 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1188 dev->regs_base = devm_ioremap_resource(&pdev->dev, res); 1289 dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
@@ -1214,19 +1315,18 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1214 goto err_dma; 1315 goto err_dma;
1215 } 1316 }
1216 1317
1217 vb2_dma_contig_set_max_seg_size(dev->mem_dev_l, DMA_BIT_MASK(32));
1218 vb2_dma_contig_set_max_seg_size(dev->mem_dev_r, DMA_BIT_MASK(32));
1219
1220 mutex_init(&dev->mfc_mutex); 1318 mutex_init(&dev->mfc_mutex);
1221 1319 init_waitqueue_head(&dev->queue);
1222 ret = s5p_mfc_alloc_firmware(dev); 1320 dev->hw_lock = 0;
1223 if (ret) 1321 INIT_WORK(&dev->watchdog_work, s5p_mfc_watchdog_worker);
1224 goto err_res; 1322 atomic_set(&dev->watchdog_cnt, 0);
1323 init_timer(&dev->watchdog_timer);
1324 dev->watchdog_timer.data = (unsigned long)dev;
1325 dev->watchdog_timer.function = s5p_mfc_watchdog;
1225 1326
1226 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); 1327 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
1227 if (ret) 1328 if (ret)
1228 goto err_v4l2_dev_reg; 1329 goto err_v4l2_dev_reg;
1229 init_waitqueue_head(&dev->queue);
1230 1330
1231 /* decoder */ 1331 /* decoder */
1232 vfd = video_device_alloc(); 1332 vfd = video_device_alloc();
@@ -1263,13 +1363,6 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1263 video_set_drvdata(vfd, dev); 1363 video_set_drvdata(vfd, dev);
1264 platform_set_drvdata(pdev, dev); 1364 platform_set_drvdata(pdev, dev);
1265 1365
1266 dev->hw_lock = 0;
1267 INIT_WORK(&dev->watchdog_work, s5p_mfc_watchdog_worker);
1268 atomic_set(&dev->watchdog_cnt, 0);
1269 init_timer(&dev->watchdog_timer);
1270 dev->watchdog_timer.data = (unsigned long)dev;
1271 dev->watchdog_timer.function = s5p_mfc_watchdog;
1272
1273 /* Initialize HW ops and commands based on MFC version */ 1366 /* Initialize HW ops and commands based on MFC version */
1274 s5p_mfc_init_hw_ops(dev); 1367 s5p_mfc_init_hw_ops(dev);
1275 s5p_mfc_init_hw_cmds(dev); 1368 s5p_mfc_init_hw_cmds(dev);
@@ -1305,8 +1398,6 @@ err_enc_alloc:
1305err_dec_alloc: 1398err_dec_alloc:
1306 v4l2_device_unregister(&dev->v4l2_dev); 1399 v4l2_device_unregister(&dev->v4l2_dev);
1307err_v4l2_dev_reg: 1400err_v4l2_dev_reg:
1308 s5p_mfc_release_firmware(dev);
1309err_res:
1310 s5p_mfc_final_pm(dev); 1401 s5p_mfc_final_pm(dev);
1311err_dma: 1402err_dma:
1312 s5p_mfc_unconfigure_dma_memory(dev); 1403 s5p_mfc_unconfigure_dma_memory(dev);
@@ -1348,10 +1439,7 @@ static int s5p_mfc_remove(struct platform_device *pdev)
1348 video_device_release(dev->vfd_enc); 1439 video_device_release(dev->vfd_enc);
1349 video_device_release(dev->vfd_dec); 1440 video_device_release(dev->vfd_dec);
1350 v4l2_device_unregister(&dev->v4l2_dev); 1441 v4l2_device_unregister(&dev->v4l2_dev);
1351 s5p_mfc_release_firmware(dev);
1352 s5p_mfc_unconfigure_dma_memory(dev); 1442 s5p_mfc_unconfigure_dma_memory(dev);
1353 vb2_dma_contig_clear_max_seg_size(dev->mem_dev_l);
1354 vb2_dma_contig_clear_max_seg_size(dev->mem_dev_r);
1355 1443
1356 s5p_mfc_final_pm(dev); 1444 s5p_mfc_final_pm(dev);
1357 return 0; 1445 return 0;
@@ -1423,16 +1511,11 @@ static struct s5p_mfc_buf_size buf_size_v5 = {
1423 .priv = &mfc_buf_size_v5, 1511 .priv = &mfc_buf_size_v5,
1424}; 1512};
1425 1513
1426static struct s5p_mfc_buf_align mfc_buf_align_v5 = {
1427 .base = MFC_BASE_ALIGN_ORDER,
1428};
1429
1430static struct s5p_mfc_variant mfc_drvdata_v5 = { 1514static struct s5p_mfc_variant mfc_drvdata_v5 = {
1431 .version = MFC_VERSION, 1515 .version = MFC_VERSION,
1432 .version_bit = MFC_V5_BIT, 1516 .version_bit = MFC_V5_BIT,
1433 .port_num = MFC_NUM_PORTS, 1517 .port_num = MFC_NUM_PORTS,
1434 .buf_size = &buf_size_v5, 1518 .buf_size = &buf_size_v5,
1435 .buf_align = &mfc_buf_align_v5,
1436 .fw_name[0] = "s5p-mfc.fw", 1519 .fw_name[0] = "s5p-mfc.fw",
1437 .clk_names = {"mfc", "sclk_mfc"}, 1520 .clk_names = {"mfc", "sclk_mfc"},
1438 .num_clocks = 2, 1521 .num_clocks = 2,
@@ -1453,16 +1536,11 @@ static struct s5p_mfc_buf_size buf_size_v6 = {
1453 .priv = &mfc_buf_size_v6, 1536 .priv = &mfc_buf_size_v6,
1454}; 1537};
1455 1538
1456static struct s5p_mfc_buf_align mfc_buf_align_v6 = {
1457 .base = 0,
1458};
1459
1460static struct s5p_mfc_variant mfc_drvdata_v6 = { 1539static struct s5p_mfc_variant mfc_drvdata_v6 = {
1461 .version = MFC_VERSION_V6, 1540 .version = MFC_VERSION_V6,
1462 .version_bit = MFC_V6_BIT, 1541 .version_bit = MFC_V6_BIT,
1463 .port_num = MFC_NUM_PORTS_V6, 1542 .port_num = MFC_NUM_PORTS_V6,
1464 .buf_size = &buf_size_v6, 1543 .buf_size = &buf_size_v6,
1465 .buf_align = &mfc_buf_align_v6,
1466 .fw_name[0] = "s5p-mfc-v6.fw", 1544 .fw_name[0] = "s5p-mfc-v6.fw",
1467 /* 1545 /*
1468 * v6-v2 firmware contains bug fixes and interface change 1546 * v6-v2 firmware contains bug fixes and interface change
@@ -1487,16 +1565,11 @@ static struct s5p_mfc_buf_size buf_size_v7 = {
1487 .priv = &mfc_buf_size_v7, 1565 .priv = &mfc_buf_size_v7,
1488}; 1566};
1489 1567
1490static struct s5p_mfc_buf_align mfc_buf_align_v7 = {
1491 .base = 0,
1492};
1493
1494static struct s5p_mfc_variant mfc_drvdata_v7 = { 1568static struct s5p_mfc_variant mfc_drvdata_v7 = {
1495 .version = MFC_VERSION_V7, 1569 .version = MFC_VERSION_V7,
1496 .version_bit = MFC_V7_BIT, 1570 .version_bit = MFC_V7_BIT,
1497 .port_num = MFC_NUM_PORTS_V7, 1571 .port_num = MFC_NUM_PORTS_V7,
1498 .buf_size = &buf_size_v7, 1572 .buf_size = &buf_size_v7,
1499 .buf_align = &mfc_buf_align_v7,
1500 .fw_name[0] = "s5p-mfc-v7.fw", 1573 .fw_name[0] = "s5p-mfc-v7.fw",
1501 .clk_names = {"mfc", "sclk_mfc"}, 1574 .clk_names = {"mfc", "sclk_mfc"},
1502 .num_clocks = 2, 1575 .num_clocks = 2,
@@ -1516,16 +1589,11 @@ static struct s5p_mfc_buf_size buf_size_v8 = {
1516 .priv = &mfc_buf_size_v8, 1589 .priv = &mfc_buf_size_v8,
1517}; 1590};
1518 1591
1519static struct s5p_mfc_buf_align mfc_buf_align_v8 = {
1520 .base = 0,
1521};
1522
1523static struct s5p_mfc_variant mfc_drvdata_v8 = { 1592static struct s5p_mfc_variant mfc_drvdata_v8 = {
1524 .version = MFC_VERSION_V8, 1593 .version = MFC_VERSION_V8,
1525 .version_bit = MFC_V8_BIT, 1594 .version_bit = MFC_V8_BIT,
1526 .port_num = MFC_NUM_PORTS_V8, 1595 .port_num = MFC_NUM_PORTS_V8,
1527 .buf_size = &buf_size_v8, 1596 .buf_size = &buf_size_v8,
1528 .buf_align = &mfc_buf_align_v8,
1529 .fw_name[0] = "s5p-mfc-v8.fw", 1597 .fw_name[0] = "s5p-mfc-v8.fw",
1530 .clk_names = {"mfc"}, 1598 .clk_names = {"mfc"},
1531 .num_clocks = 1, 1599 .num_clocks = 1,
@@ -1536,7 +1604,6 @@ static struct s5p_mfc_variant mfc_drvdata_v8_5433 = {
1536 .version_bit = MFC_V8_BIT, 1604 .version_bit = MFC_V8_BIT,
1537 .port_num = MFC_NUM_PORTS_V8, 1605 .port_num = MFC_NUM_PORTS_V8,
1538 .buf_size = &buf_size_v8, 1606 .buf_size = &buf_size_v8,
1539 .buf_align = &mfc_buf_align_v8,
1540 .fw_name[0] = "s5p-mfc-v8.fw", 1607 .fw_name[0] = "s5p-mfc-v8.fw",
1541 .clk_names = {"pclk", "aclk", "aclk_xiu"}, 1608 .clk_names = {"pclk", "aclk", "aclk_xiu"},
1542 .num_clocks = 3, 1609 .num_clocks = 3,
@@ -1563,18 +1630,6 @@ static const struct of_device_id exynos_mfc_match[] = {
1563}; 1630};
1564MODULE_DEVICE_TABLE(of, exynos_mfc_match); 1631MODULE_DEVICE_TABLE(of, exynos_mfc_match);
1565 1632
1566static void *mfc_get_drv_data(struct platform_device *pdev)
1567{
1568 struct s5p_mfc_variant *driver_data = NULL;
1569 const struct of_device_id *match;
1570
1571 match = of_match_node(exynos_mfc_match, pdev->dev.of_node);
1572 if (match)
1573 driver_data = (struct s5p_mfc_variant *)match->data;
1574
1575 return driver_data;
1576}
1577
1578static struct platform_driver s5p_mfc_driver = { 1633static struct platform_driver s5p_mfc_driver = {
1579 .probe = s5p_mfc_probe, 1634 .probe = s5p_mfc_probe,
1580 .remove = s5p_mfc_remove, 1635 .remove = s5p_mfc_remove,
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
index 8c4739ca16d6..4c80bb4243be 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
@@ -47,7 +47,7 @@ static int s5p_mfc_sys_init_cmd_v5(struct s5p_mfc_dev *dev)
47 struct s5p_mfc_cmd_args h2r_args; 47 struct s5p_mfc_cmd_args h2r_args;
48 48
49 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args)); 49 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
50 h2r_args.arg[0] = dev->fw_size; 50 h2r_args.arg[0] = dev->fw_buf.size;
51 return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SYS_INIT, 51 return s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_SYS_INIT,
52 &h2r_args); 52 &h2r_args);
53} 53}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index ab23236aa942..4220914529b2 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -33,8 +33,9 @@
33* while mmaping */ 33* while mmaping */
34#define DST_QUEUE_OFF_BASE (1 << 30) 34#define DST_QUEUE_OFF_BASE (1 << 30)
35 35
36#define MFC_BANK1_ALLOC_CTX 0 36#define BANK_L_CTX 0
37#define MFC_BANK2_ALLOC_CTX 1 37#define BANK_R_CTX 1
38#define BANK_CTX_NUM 2
38 39
39#define MFC_BANK1_ALIGN_ORDER 13 40#define MFC_BANK1_ALIGN_ORDER 13
40#define MFC_BANK2_ALIGN_ORDER 13 41#define MFC_BANK2_ALIGN_ORDER 13
@@ -44,14 +45,6 @@
44 45
45#include <media/videobuf2-dma-contig.h> 46#include <media/videobuf2-dma-contig.h>
46 47
47static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b)
48{
49 /* Same functionality as the vb2_dma_contig_plane_paddr */
50 dma_addr_t *paddr = vb2_dma_contig_memops.cookie(b);
51
52 return *paddr;
53}
54
55/* MFC definitions */ 48/* MFC definitions */
56#define MFC_MAX_EXTRA_DPB 5 49#define MFC_MAX_EXTRA_DPB 5
57#define MFC_MAX_BUFFERS 32 50#define MFC_MAX_BUFFERS 32
@@ -200,7 +193,7 @@ struct s5p_mfc_buf {
200 */ 193 */
201struct s5p_mfc_pm { 194struct s5p_mfc_pm {
202 struct clk *clock_gate; 195 struct clk *clock_gate;
203 const char **clk_names; 196 const char * const *clk_names;
204 struct clk *clocks[MFC_MAX_CLOCKS]; 197 struct clk *clocks[MFC_MAX_CLOCKS];
205 int num_clocks; 198 int num_clocks;
206 bool use_clock_gating; 199 bool use_clock_gating;
@@ -229,16 +222,11 @@ struct s5p_mfc_buf_size {
229 void *priv; 222 void *priv;
230}; 223};
231 224
232struct s5p_mfc_buf_align {
233 unsigned int base;
234};
235
236struct s5p_mfc_variant { 225struct s5p_mfc_variant {
237 unsigned int version; 226 unsigned int version;
238 unsigned int port_num; 227 unsigned int port_num;
239 u32 version_bit; 228 u32 version_bit;
240 struct s5p_mfc_buf_size *buf_size; 229 struct s5p_mfc_buf_size *buf_size;
241 struct s5p_mfc_buf_align *buf_align;
242 char *fw_name[MFC_FW_MAX_VERSIONS]; 230 char *fw_name[MFC_FW_MAX_VERSIONS];
243 const char *clk_names[MFC_MAX_CLOCKS]; 231 const char *clk_names[MFC_MAX_CLOCKS];
244 int num_clocks; 232 int num_clocks;
@@ -252,12 +240,14 @@ struct s5p_mfc_variant {
252 * buffer accessed by driver 240 * buffer accessed by driver
253 * @dma: DMA address, only valid when kernel DMA API used 241 * @dma: DMA address, only valid when kernel DMA API used
254 * @size: size of the buffer 242 * @size: size of the buffer
243 * @ctx: memory context (bank) used for this allocation
255 */ 244 */
256struct s5p_mfc_priv_buf { 245struct s5p_mfc_priv_buf {
257 unsigned long ofs; 246 unsigned long ofs;
258 void *virt; 247 void *virt;
259 dma_addr_t dma; 248 dma_addr_t dma;
260 size_t size; 249 size_t size;
250 unsigned int ctx;
261}; 251};
262 252
263/** 253/**
@@ -267,8 +257,7 @@ struct s5p_mfc_priv_buf {
267 * @vfd_dec: video device for decoding 257 * @vfd_dec: video device for decoding
268 * @vfd_enc: video device for encoding 258 * @vfd_enc: video device for encoding
269 * @plat_dev: platform device 259 * @plat_dev: platform device
270 * @mem_dev_l: child device of the left memory bank (0) 260 * @mem_dev[]: child devices of the memory banks
271 * @mem_dev_r: child device of the right memory bank (1)
272 * @regs_base: base address of the MFC hw registers 261 * @regs_base: base address of the MFC hw registers
273 * @irq: irq resource 262 * @irq: irq resource
274 * @dec_ctrl_handler: control framework handler for decoding 263 * @dec_ctrl_handler: control framework handler for decoding
@@ -286,8 +275,7 @@ struct s5p_mfc_priv_buf {
286 * @queue: waitqueue for waiting for completion of device commands 275 * @queue: waitqueue for waiting for completion of device commands
287 * @fw_size: size of firmware 276 * @fw_size: size of firmware
288 * @fw_virt_addr: virtual firmware address 277 * @fw_virt_addr: virtual firmware address
289 * @bank1: address of the beginning of bank 1 memory 278 * @dma_base[]: address of the beginning of memory banks
290 * @bank2: address of the beginning of bank 2 memory
291 * @hw_lock: used for hardware locking 279 * @hw_lock: used for hardware locking
292 * @ctx: array of driver contexts 280 * @ctx: array of driver contexts
293 * @curr_ctx: number of the currently running context 281 * @curr_ctx: number of the currently running context
@@ -310,14 +298,13 @@ struct s5p_mfc_dev {
310 struct video_device *vfd_dec; 298 struct video_device *vfd_dec;
311 struct video_device *vfd_enc; 299 struct video_device *vfd_enc;
312 struct platform_device *plat_dev; 300 struct platform_device *plat_dev;
313 struct device *mem_dev_l; 301 struct device *mem_dev[BANK_CTX_NUM];
314 struct device *mem_dev_r;
315 void __iomem *regs_base; 302 void __iomem *regs_base;
316 int irq; 303 int irq;
317 struct v4l2_ctrl_handler dec_ctrl_handler; 304 struct v4l2_ctrl_handler dec_ctrl_handler;
318 struct v4l2_ctrl_handler enc_ctrl_handler; 305 struct v4l2_ctrl_handler enc_ctrl_handler;
319 struct s5p_mfc_pm pm; 306 struct s5p_mfc_pm pm;
320 struct s5p_mfc_variant *variant; 307 const struct s5p_mfc_variant *variant;
321 int num_inst; 308 int num_inst;
322 spinlock_t irqlock; /* lock when operating on context */ 309 spinlock_t irqlock; /* lock when operating on context */
323 spinlock_t condlock; /* lock when changing/checking if a context is 310 spinlock_t condlock; /* lock when changing/checking if a context is
@@ -327,10 +314,12 @@ struct s5p_mfc_dev {
327 int int_type; 314 int int_type;
328 unsigned int int_err; 315 unsigned int int_err;
329 wait_queue_head_t queue; 316 wait_queue_head_t queue;
330 size_t fw_size; 317 struct s5p_mfc_priv_buf fw_buf;
331 void *fw_virt_addr; 318 size_t mem_size;
332 dma_addr_t bank1; 319 dma_addr_t mem_base;
333 dma_addr_t bank2; 320 unsigned long *mem_bitmap;
321 void *mem_virt;
322 dma_addr_t dma_base[BANK_CTX_NUM];
334 unsigned long hw_lock; 323 unsigned long hw_lock;
335 struct s5p_mfc_ctx *ctx[MFC_NUM_CONTEXTS]; 324 struct s5p_mfc_ctx *ctx[MFC_NUM_CONTEXTS];
336 int curr_ctx; 325 int curr_ctx;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index cc888713b3b6..69ef9c23a99a 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -26,51 +26,22 @@
26/* Allocate memory for firmware */ 26/* Allocate memory for firmware */
27int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev) 27int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
28{ 28{
29 void *bank2_virt; 29 struct s5p_mfc_priv_buf *fw_buf = &dev->fw_buf;
30 dma_addr_t bank2_dma_addr; 30 int err;
31 31
32 dev->fw_size = dev->variant->buf_size->fw; 32 fw_buf->size = dev->variant->buf_size->fw;
33 33
34 if (dev->fw_virt_addr) { 34 if (fw_buf->virt) {
35 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n"); 35 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
36 return -ENOMEM; 36 return -ENOMEM;
37 } 37 }
38 38
39 dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size, 39 err = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &dev->fw_buf);
40 &dev->bank1, GFP_KERNEL); 40 if (err) {
41
42 if (!dev->fw_virt_addr) {
43 mfc_err("Allocating bitprocessor buffer failed\n"); 41 mfc_err("Allocating bitprocessor buffer failed\n");
44 return -ENOMEM; 42 return err;
45 } 43 }
46 44
47 if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
48 bank2_virt = dma_alloc_coherent(dev->mem_dev_r, 1 << MFC_BASE_ALIGN_ORDER,
49 &bank2_dma_addr, GFP_KERNEL);
50
51 if (!bank2_virt) {
52 mfc_err("Allocating bank2 base failed\n");
53 dma_free_coherent(dev->mem_dev_l, dev->fw_size,
54 dev->fw_virt_addr, dev->bank1);
55 dev->fw_virt_addr = NULL;
56 return -ENOMEM;
57 }
58
59 /* Valid buffers passed to MFC encoder with LAST_FRAME command
60 * should not have address of bank2 - MFC will treat it as a null frame.
61 * To avoid such situation we set bank2 address below the pool address.
62 */
63 dev->bank2 = bank2_dma_addr - (1 << MFC_BASE_ALIGN_ORDER);
64
65 dma_free_coherent(dev->mem_dev_r, 1 << MFC_BASE_ALIGN_ORDER,
66 bank2_virt, bank2_dma_addr);
67
68 } else {
69 /* In this case bank2 can point to the same address as bank1.
70 * Firmware will always occupy the beginning of this area so it is
71 * impossible having a video frame buffer with zero address. */
72 dev->bank2 = dev->bank1;
73 }
74 return 0; 45 return 0;
75} 46}
76 47
@@ -99,17 +70,17 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
99 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 70 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
100 return -EINVAL; 71 return -EINVAL;
101 } 72 }
102 if (fw_blob->size > dev->fw_size) { 73 if (fw_blob->size > dev->fw_buf.size) {
103 mfc_err("MFC firmware is too big to be loaded\n"); 74 mfc_err("MFC firmware is too big to be loaded\n");
104 release_firmware(fw_blob); 75 release_firmware(fw_blob);
105 return -ENOMEM; 76 return -ENOMEM;
106 } 77 }
107 if (!dev->fw_virt_addr) { 78 if (!dev->fw_buf.virt) {
108 mfc_err("MFC firmware is not allocated\n"); 79 mfc_err("MFC firmware is not allocated\n");
109 release_firmware(fw_blob); 80 release_firmware(fw_blob);
110 return -EINVAL; 81 return -EINVAL;
111 } 82 }
112 memcpy(dev->fw_virt_addr, fw_blob->data, fw_blob->size); 83 memcpy(dev->fw_buf.virt, fw_blob->data, fw_blob->size);
113 wmb(); 84 wmb();
114 release_firmware(fw_blob); 85 release_firmware(fw_blob);
115 mfc_debug_leave(); 86 mfc_debug_leave();
@@ -121,11 +92,7 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
121{ 92{
122 /* Before calling this function one has to make sure 93 /* Before calling this function one has to make sure
123 * that MFC is no longer processing */ 94 * that MFC is no longer processing */
124 if (!dev->fw_virt_addr) 95 s5p_mfc_release_priv_buf(dev, &dev->fw_buf);
125 return -EINVAL;
126 dma_free_coherent(dev->mem_dev_l, dev->fw_size, dev->fw_virt_addr,
127 dev->bank1);
128 dev->fw_virt_addr = NULL;
129 return 0; 96 return 0;
130} 97}
131 98
@@ -210,13 +177,18 @@ int s5p_mfc_reset(struct s5p_mfc_dev *dev)
210static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev) 177static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
211{ 178{
212 if (IS_MFCV6_PLUS(dev)) { 179 if (IS_MFCV6_PLUS(dev)) {
213 mfc_write(dev, dev->bank1, S5P_FIMV_RISC_BASE_ADDRESS_V6); 180 mfc_write(dev, dev->dma_base[BANK_L_CTX],
214 mfc_debug(2, "Base Address : %pad\n", &dev->bank1); 181 S5P_FIMV_RISC_BASE_ADDRESS_V6);
182 mfc_debug(2, "Base Address : %pad\n",
183 &dev->dma_base[BANK_L_CTX]);
215 } else { 184 } else {
216 mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A); 185 mfc_write(dev, dev->dma_base[BANK_L_CTX],
217 mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B); 186 S5P_FIMV_MC_DRAMBASE_ADR_A);
187 mfc_write(dev, dev->dma_base[BANK_R_CTX],
188 S5P_FIMV_MC_DRAMBASE_ADR_B);
218 mfc_debug(2, "Bank1: %pad, Bank2: %pad\n", 189 mfc_debug(2, "Bank1: %pad, Bank2: %pad\n",
219 &dev->bank1, &dev->bank2); 190 &dev->dma_base[BANK_L_CTX],
191 &dev->dma_base[BANK_R_CTX]);
220 } 192 }
221} 193}
222 194
@@ -240,7 +212,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
240 int ret; 212 int ret;
241 213
242 mfc_debug_enter(); 214 mfc_debug_enter();
243 if (!dev->fw_virt_addr) { 215 if (!dev->fw_buf.virt) {
244 mfc_err("Firmware memory is not allocated.\n"); 216 mfc_err("Firmware memory is not allocated.\n");
245 return -EINVAL; 217 return -EINVAL;
246 } 218 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h
index 8e5df041edf7..45c807bf19cc 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h
@@ -18,7 +18,6 @@
18int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev); 18int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev);
19int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev); 19int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev);
20int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev); 20int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev);
21int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev);
22 21
23int s5p_mfc_init_hw(struct s5p_mfc_dev *dev); 22int s5p_mfc_init_hw(struct s5p_mfc_dev *dev);
24void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev); 23void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index 367ef8e8dbf0..8937b0af7cb3 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -931,14 +931,14 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
931 psize[1] = ctx->chroma_size; 931 psize[1] = ctx->chroma_size;
932 932
933 if (IS_MFCV6_PLUS(dev)) 933 if (IS_MFCV6_PLUS(dev))
934 alloc_devs[0] = ctx->dev->mem_dev_l; 934 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
935 else 935 else
936 alloc_devs[0] = ctx->dev->mem_dev_r; 936 alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
937 alloc_devs[1] = ctx->dev->mem_dev_l; 937 alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
938 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 938 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
939 ctx->state == MFCINST_INIT) { 939 ctx->state == MFCINST_INIT) {
940 psize[0] = ctx->dec_src_buf_size; 940 psize[0] = ctx->dec_src_buf_size;
941 alloc_devs[0] = ctx->dev->mem_dev_l; 941 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
942 } else { 942 } else {
943 mfc_err("This video node is dedicated to decoding. Decoding not initialized\n"); 943 mfc_err("This video node is dedicated to decoding. Decoding not initialized\n");
944 return -EINVAL; 944 return -EINVAL;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index e39d9e06e299..2a5fd7c42cd5 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -1832,7 +1832,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1832 if (*buf_count > MFC_MAX_BUFFERS) 1832 if (*buf_count > MFC_MAX_BUFFERS)
1833 *buf_count = MFC_MAX_BUFFERS; 1833 *buf_count = MFC_MAX_BUFFERS;
1834 psize[0] = ctx->enc_dst_buf_size; 1834 psize[0] = ctx->enc_dst_buf_size;
1835 alloc_devs[0] = ctx->dev->mem_dev_l; 1835 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
1836 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 1836 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1837 if (ctx->src_fmt) 1837 if (ctx->src_fmt)
1838 *plane_count = ctx->src_fmt->num_planes; 1838 *plane_count = ctx->src_fmt->num_planes;
@@ -1848,11 +1848,11 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1848 psize[1] = ctx->chroma_size; 1848 psize[1] = ctx->chroma_size;
1849 1849
1850 if (IS_MFCV6_PLUS(dev)) { 1850 if (IS_MFCV6_PLUS(dev)) {
1851 alloc_devs[0] = ctx->dev->mem_dev_l; 1851 alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX];
1852 alloc_devs[1] = ctx->dev->mem_dev_l; 1852 alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX];
1853 } else { 1853 } else {
1854 alloc_devs[0] = ctx->dev->mem_dev_r; 1854 alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX];
1855 alloc_devs[1] = ctx->dev->mem_dev_r; 1855 alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX];
1856 } 1856 }
1857 } else { 1857 } else {
1858 mfc_err("invalid queue type: %d\n", vq->type); 1858 mfc_err("invalid queue type: %d\n", vq->type);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
index 6962132ae8fa..76667924ee2a 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -11,54 +11,13 @@
11#ifndef S5P_MFC_IOMMU_H_ 11#ifndef S5P_MFC_IOMMU_H_
12#define S5P_MFC_IOMMU_H_ 12#define S5P_MFC_IOMMU_H_
13 13
14#define S5P_MFC_IOMMU_DMA_BASE 0x20000000lu 14#if defined(CONFIG_EXYNOS_IOMMU)
15#define S5P_MFC_IOMMU_DMA_SIZE SZ_256M
16
17#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
18
19#include <asm/dma-iommu.h>
20 15
21static inline bool exynos_is_iommu_available(struct device *dev) 16static inline bool exynos_is_iommu_available(struct device *dev)
22{ 17{
23 return dev->archdata.iommu != NULL; 18 return dev->archdata.iommu != NULL;
24} 19}
25 20
26static inline void exynos_unconfigure_iommu(struct device *dev)
27{
28 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
29
30 arm_iommu_detach_device(dev);
31 arm_iommu_release_mapping(mapping);
32}
33
34static inline int exynos_configure_iommu(struct device *dev,
35 unsigned int base, unsigned int size)
36{
37 struct dma_iommu_mapping *mapping = NULL;
38 int ret;
39
40 /* Disable the default mapping created by device core */
41 if (to_dma_iommu_mapping(dev))
42 exynos_unconfigure_iommu(dev);
43
44 mapping = arm_iommu_create_mapping(dev->bus, base, size);
45 if (IS_ERR(mapping)) {
46 pr_warn("Failed to create IOMMU mapping for device %s\n",
47 dev_name(dev));
48 return PTR_ERR(mapping);
49 }
50
51 ret = arm_iommu_attach_device(dev, mapping);
52 if (ret) {
53 pr_warn("Failed to attached device %s to IOMMU_mapping\n",
54 dev_name(dev));
55 arm_iommu_release_mapping(mapping);
56 return ret;
57 }
58
59 return 0;
60}
61
62#else 21#else
63 22
64static inline bool exynos_is_iommu_available(struct device *dev) 23static inline bool exynos_is_iommu_available(struct device *dev)
@@ -66,14 +25,6 @@ static inline bool exynos_is_iommu_available(struct device *dev)
66 return false; 25 return false;
67} 26}
68 27
69static inline int exynos_configure_iommu(struct device *dev,
70 unsigned int base, unsigned int size)
71{
72 return -ENOSYS;
73}
74
75static inline void exynos_unconfigure_iommu(struct device *dev) { }
76
77#endif 28#endif
78 29
79#endif /* S5P_MFC_IOMMU_H_ */ 30#endif /* S5P_MFC_IOMMU_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
index 99f65a92a6be..7f33cf23947f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c
@@ -37,38 +37,91 @@ void s5p_mfc_init_regs(struct s5p_mfc_dev *dev)
37 dev->mfc_regs = s5p_mfc_init_regs_v6_plus(dev); 37 dev->mfc_regs = s5p_mfc_init_regs_v6_plus(dev);
38} 38}
39 39
40int s5p_mfc_alloc_priv_buf(struct device *dev, dma_addr_t base, 40int s5p_mfc_alloc_priv_buf(struct s5p_mfc_dev *dev, unsigned int mem_ctx,
41 struct s5p_mfc_priv_buf *b) 41 struct s5p_mfc_priv_buf *b)
42{ 42{
43 unsigned int bits = dev->mem_size >> PAGE_SHIFT;
44 unsigned int count = b->size >> PAGE_SHIFT;
45 unsigned int align = (SZ_64K >> PAGE_SHIFT) - 1;
46 unsigned int start, offset;
47
43 mfc_debug(3, "Allocating priv: %zu\n", b->size); 48 mfc_debug(3, "Allocating priv: %zu\n", b->size);
44 49
45 b->virt = dma_alloc_coherent(dev, b->size, &b->dma, GFP_KERNEL); 50 if (dev->mem_virt) {
51 start = bitmap_find_next_zero_area(dev->mem_bitmap, bits, 0, count, align);
52 if (start > bits)
53 goto no_mem;
46 54
47 if (!b->virt) { 55 bitmap_set(dev->mem_bitmap, start, count);
48 mfc_err("Allocating private buffer of size %zu failed\n", 56 offset = start << PAGE_SHIFT;
49 b->size); 57 b->virt = dev->mem_virt + offset;
50 return -ENOMEM; 58 b->dma = dev->mem_base + offset;
51 } 59 } else {
60 struct device *mem_dev = dev->mem_dev[mem_ctx];
61 dma_addr_t base = dev->dma_base[mem_ctx];
52 62
53 if (b->dma < base) { 63 b->ctx = mem_ctx;
54 mfc_err("Invalid memory configuration - buffer (%pad) is below base memory address(%pad)\n", 64 b->virt = dma_alloc_coherent(mem_dev, b->size, &b->dma, GFP_KERNEL);
55 &b->dma, &base); 65 if (!b->virt)
56 dma_free_coherent(dev, b->size, b->virt, b->dma); 66 goto no_mem;
57 return -ENOMEM; 67 if (b->dma < base) {
68 mfc_err("Invalid memory configuration - buffer (%pad) is below base memory address(%pad)\n",
69 &b->dma, &base);
70 dma_free_coherent(mem_dev, b->size, b->virt, b->dma);
71 return -ENOMEM;
72 }
58 } 73 }
59 74
60 mfc_debug(3, "Allocated addr %p %pad\n", b->virt, &b->dma); 75 mfc_debug(3, "Allocated addr %p %pad\n", b->virt, &b->dma);
61 return 0; 76 return 0;
77no_mem:
78 mfc_err("Allocating private buffer of size %zu failed\n", b->size);
79 return -ENOMEM;
80}
81
82int s5p_mfc_alloc_generic_buf(struct s5p_mfc_dev *dev, unsigned int mem_ctx,
83 struct s5p_mfc_priv_buf *b)
84{
85 struct device *mem_dev = dev->mem_dev[mem_ctx];
86
87 mfc_debug(3, "Allocating generic buf: %zu\n", b->size);
88
89 b->ctx = mem_ctx;
90 b->virt = dma_alloc_coherent(mem_dev, b->size, &b->dma, GFP_KERNEL);
91 if (!b->virt)
92 goto no_mem;
93
94 mfc_debug(3, "Allocated addr %p %pad\n", b->virt, &b->dma);
95 return 0;
96no_mem:
97 mfc_err("Allocating generic buffer of size %zu failed\n", b->size);
98 return -ENOMEM;
62} 99}
63 100
64void s5p_mfc_release_priv_buf(struct device *dev, 101void s5p_mfc_release_priv_buf(struct s5p_mfc_dev *dev,
65 struct s5p_mfc_priv_buf *b) 102 struct s5p_mfc_priv_buf *b)
66{ 103{
67 if (b->virt) { 104 if (dev->mem_virt) {
68 dma_free_coherent(dev, b->size, b->virt, b->dma); 105 unsigned int start = (b->dma - dev->mem_base) >> PAGE_SHIFT;
69 b->virt = NULL; 106 unsigned int count = b->size >> PAGE_SHIFT;
70 b->dma = 0; 107
71 b->size = 0; 108 bitmap_clear(dev->mem_bitmap, start, count);
109 } else {
110 struct device *mem_dev = dev->mem_dev[b->ctx];
111
112 dma_free_coherent(mem_dev, b->size, b->virt, b->dma);
72 } 113 }
114 b->virt = NULL;
115 b->dma = 0;
116 b->size = 0;
73} 117}
74 118
119void s5p_mfc_release_generic_buf(struct s5p_mfc_dev *dev,
120 struct s5p_mfc_priv_buf *b)
121{
122 struct device *mem_dev = dev->mem_dev[b->ctx];
123 dma_free_coherent(mem_dev, b->size, b->virt, b->dma);
124 b->virt = NULL;
125 b->dma = 0;
126 b->size = 0;
127}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
index b6ac417ab63e..16d553fcff08 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h
@@ -315,10 +315,14 @@ struct s5p_mfc_hw_ops {
315 315
316void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); 316void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev);
317void s5p_mfc_init_regs(struct s5p_mfc_dev *dev); 317void s5p_mfc_init_regs(struct s5p_mfc_dev *dev);
318int s5p_mfc_alloc_priv_buf(struct device *dev, dma_addr_t base, 318int s5p_mfc_alloc_priv_buf(struct s5p_mfc_dev *dev, unsigned int mem_ctx,
319 struct s5p_mfc_priv_buf *b); 319 struct s5p_mfc_priv_buf *b);
320void s5p_mfc_release_priv_buf(struct device *dev, 320void s5p_mfc_release_priv_buf(struct s5p_mfc_dev *dev,
321 struct s5p_mfc_priv_buf *b); 321 struct s5p_mfc_priv_buf *b);
322int s5p_mfc_alloc_generic_buf(struct s5p_mfc_dev *dev, unsigned int mem_ctx,
323 struct s5p_mfc_priv_buf *b);
324void s5p_mfc_release_generic_buf(struct s5p_mfc_dev *dev,
325 struct s5p_mfc_priv_buf *b);
322 326
323 327
324#endif /* S5P_MFC_OPR_H_ */ 328#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
index f4301d5bbd32..b41ee608c171 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
@@ -30,8 +30,8 @@
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32 32
33#define OFFSETA(x) (((x) - dev->bank1) >> MFC_OFFSET_SHIFT) 33#define OFFSETA(x) (((x) - dev->dma_base[BANK_L_CTX]) >> MFC_OFFSET_SHIFT)
34#define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT) 34#define OFFSETB(x) (((x) - dev->dma_base[BANK_R_CTX]) >> MFC_OFFSET_SHIFT)
35 35
36/* Allocate temporary buffers for decoding */ 36/* Allocate temporary buffers for decoding */
37static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) 37static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)
@@ -41,7 +41,7 @@ static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)
41 int ret; 41 int ret;
42 42
43 ctx->dsc.size = buf_size->dsc; 43 ctx->dsc.size = buf_size->dsc;
44 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->dsc); 44 ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->dsc);
45 if (ret) { 45 if (ret) {
46 mfc_err("Failed to allocate temporary buffer\n"); 46 mfc_err("Failed to allocate temporary buffer\n");
47 return ret; 47 return ret;
@@ -57,7 +57,7 @@ static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)
57/* Release temporary buffers for decoding */ 57/* Release temporary buffers for decoding */
58static void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx) 58static void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx)
59{ 59{
60 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->dsc); 60 s5p_mfc_release_priv_buf(ctx->dev, &ctx->dsc);
61} 61}
62 62
63/* Allocate codec buffers */ 63/* Allocate codec buffers */
@@ -172,8 +172,7 @@ static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
172 /* Allocate only if memory from bank 1 is necessary */ 172 /* Allocate only if memory from bank 1 is necessary */
173 if (ctx->bank1.size > 0) { 173 if (ctx->bank1.size > 0) {
174 174
175 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, 175 ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->bank1);
176 &ctx->bank1);
177 if (ret) { 176 if (ret) {
178 mfc_err("Failed to allocate Bank1 temporary buffer\n"); 177 mfc_err("Failed to allocate Bank1 temporary buffer\n");
179 return ret; 178 return ret;
@@ -182,11 +181,10 @@ static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
182 } 181 }
183 /* Allocate only if memory from bank 2 is necessary */ 182 /* Allocate only if memory from bank 2 is necessary */
184 if (ctx->bank2.size > 0) { 183 if (ctx->bank2.size > 0) {
185 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_r, dev->bank2, 184 ret = s5p_mfc_alloc_priv_buf(dev, BANK_R_CTX, &ctx->bank2);
186 &ctx->bank2);
187 if (ret) { 185 if (ret) {
188 mfc_err("Failed to allocate Bank2 temporary buffer\n"); 186 mfc_err("Failed to allocate Bank2 temporary buffer\n");
189 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); 187 s5p_mfc_release_priv_buf(ctx->dev, &ctx->bank1);
190 return ret; 188 return ret;
191 } 189 }
192 BUG_ON(ctx->bank2.dma & ((1 << MFC_BANK2_ALIGN_ORDER) - 1)); 190 BUG_ON(ctx->bank2.dma & ((1 << MFC_BANK2_ALIGN_ORDER) - 1));
@@ -197,8 +195,8 @@ static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
197/* Release buffers allocated for codec */ 195/* Release buffers allocated for codec */
198static void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx) 196static void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
199{ 197{
200 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); 198 s5p_mfc_release_priv_buf(ctx->dev, &ctx->bank1);
201 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_r, &ctx->bank2); 199 s5p_mfc_release_priv_buf(ctx->dev, &ctx->bank2);
202} 200}
203 201
204/* Allocate memory for instance data buffer */ 202/* Allocate memory for instance data buffer */
@@ -214,7 +212,7 @@ static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
214 else 212 else
215 ctx->ctx.size = buf_size->non_h264_ctx; 213 ctx->ctx.size = buf_size->non_h264_ctx;
216 214
217 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->ctx); 215 ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->ctx);
218 if (ret) { 216 if (ret) {
219 mfc_err("Failed to allocate instance buffer\n"); 217 mfc_err("Failed to allocate instance buffer\n");
220 return ret; 218 return ret;
@@ -227,15 +225,15 @@ static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
227 225
228 /* Initialize shared memory */ 226 /* Initialize shared memory */
229 ctx->shm.size = buf_size->shm; 227 ctx->shm.size = buf_size->shm;
230 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->shm); 228 ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->shm);
231 if (ret) { 229 if (ret) {
232 mfc_err("Failed to allocate shared memory buffer\n"); 230 mfc_err("Failed to allocate shared memory buffer\n");
233 s5p_mfc_release_priv_buf(dev->mem_dev_l, &ctx->ctx); 231 s5p_mfc_release_priv_buf(dev, &ctx->ctx);
234 return ret; 232 return ret;
235 } 233 }
236 234
237 /* shared memory offset only keeps the offset from base (port a) */ 235 /* shared memory offset only keeps the offset from base (port a) */
238 ctx->shm.ofs = ctx->shm.dma - dev->bank1; 236 ctx->shm.ofs = ctx->shm.dma - dev->dma_base[BANK_L_CTX];
239 BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); 237 BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
240 238
241 memset(ctx->shm.virt, 0, buf_size->shm); 239 memset(ctx->shm.virt, 0, buf_size->shm);
@@ -246,8 +244,8 @@ static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
246/* Release instance buffer */ 244/* Release instance buffer */
247static void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx) 245static void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
248{ 246{
249 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->ctx); 247 s5p_mfc_release_priv_buf(ctx->dev, &ctx->ctx);
250 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->shm); 248 s5p_mfc_release_priv_buf(ctx->dev, &ctx->shm);
251} 249}
252 250
253static int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev) 251static int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev)
@@ -534,10 +532,10 @@ static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,
534{ 532{
535 struct s5p_mfc_dev *dev = ctx->dev; 533 struct s5p_mfc_dev *dev = ctx->dev;
536 534
537 *y_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR) 535 *y_addr = dev->dma_base[BANK_R_CTX] +
538 << MFC_OFFSET_SHIFT); 536 (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR) << MFC_OFFSET_SHIFT);
539 *c_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR) 537 *c_addr = dev->dma_base[BANK_R_CTX] +
540 << MFC_OFFSET_SHIFT); 538 (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR) << MFC_OFFSET_SHIFT);
541} 539}
542 540
543/* Set encoding ref & codec buffer */ 541/* Set encoding ref & codec buffer */
@@ -1214,7 +1212,8 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
1214 } 1212 }
1215 if (list_empty(&ctx->src_queue)) { 1213 if (list_empty(&ctx->src_queue)) {
1216 /* send null frame */ 1214 /* send null frame */
1217 s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2, dev->bank2); 1215 s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],
1216 dev->dma_base[BANK_R_CTX]);
1218 src_mb = NULL; 1217 src_mb = NULL;
1219 } else { 1218 } else {
1220 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, 1219 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
@@ -1222,8 +1221,9 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
1222 src_mb->flags |= MFC_BUF_FLAG_USED; 1221 src_mb->flags |= MFC_BUF_FLAG_USED;
1223 if (src_mb->b->vb2_buf.planes[0].bytesused == 0) { 1222 if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {
1224 /* send null frame */ 1223 /* send null frame */
1225 s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->bank2, 1224 s5p_mfc_set_enc_frame_buffer_v5(ctx,
1226 dev->bank2); 1225 dev->dma_base[BANK_R_CTX],
1226 dev->dma_base[BANK_R_CTX]);
1227 ctx->state = MFCINST_FINISHING; 1227 ctx->state = MFCINST_FINISHING;
1228 } else { 1228 } else {
1229 src_y_addr = vb2_dma_contig_plane_dma_addr( 1229 src_y_addr = vb2_dma_contig_plane_dma_addr(
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index d6f207e859ab..85880e9106be 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -239,8 +239,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
239 239
240 /* Allocate only if memory from bank 1 is necessary */ 240 /* Allocate only if memory from bank 1 is necessary */
241 if (ctx->bank1.size > 0) { 241 if (ctx->bank1.size > 0) {
242 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, 242 ret = s5p_mfc_alloc_generic_buf(dev, BANK_L_CTX, &ctx->bank1);
243 &ctx->bank1);
244 if (ret) { 243 if (ret) {
245 mfc_err("Failed to allocate Bank1 memory\n"); 244 mfc_err("Failed to allocate Bank1 memory\n");
246 return ret; 245 return ret;
@@ -253,7 +252,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
253/* Release buffers allocated for codec */ 252/* Release buffers allocated for codec */
254static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx) 253static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
255{ 254{
256 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); 255 s5p_mfc_release_generic_buf(ctx->dev, &ctx->bank1);
257} 256}
258 257
259/* Allocate memory for instance data buffer */ 258/* Allocate memory for instance data buffer */
@@ -292,7 +291,7 @@ static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
292 break; 291 break;
293 } 292 }
294 293
295 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->ctx); 294 ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->ctx);
296 if (ret) { 295 if (ret) {
297 mfc_err("Failed to allocate instance buffer\n"); 296 mfc_err("Failed to allocate instance buffer\n");
298 return ret; 297 return ret;
@@ -309,7 +308,7 @@ static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
309/* Release instance buffer */ 308/* Release instance buffer */
310static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx) 309static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
311{ 310{
312 s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->ctx); 311 s5p_mfc_release_priv_buf(ctx->dev, &ctx->ctx);
313} 312}
314 313
315/* Allocate context buffers for SYS_INIT */ 314/* Allocate context buffers for SYS_INIT */
@@ -321,8 +320,7 @@ static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
321 mfc_debug_enter(); 320 mfc_debug_enter();
322 321
323 dev->ctx_buf.size = buf_size->dev_ctx; 322 dev->ctx_buf.size = buf_size->dev_ctx;
324 ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, 323 ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &dev->ctx_buf);
325 &dev->ctx_buf);
326 if (ret) { 324 if (ret) {
327 mfc_err("Failed to allocate device context buffer\n"); 325 mfc_err("Failed to allocate device context buffer\n");
328 return ret; 326 return ret;
@@ -339,7 +337,7 @@ static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
339/* Release context buffers for SYS_INIT */ 337/* Release context buffers for SYS_INIT */
340static void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev) 338static void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
341{ 339{
342 s5p_mfc_release_priv_buf(dev->mem_dev_l, &dev->ctx_buf); 340 s5p_mfc_release_priv_buf(dev, &dev->ctx_buf);
343} 341}
344 342
345static int calc_plane(int width, int height) 343static int calc_plane(int width, int height)
@@ -497,7 +495,7 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx)
497 } 495 }
498 } 496 }
499 497
500 mfc_debug(2, "Buf1: %zu, buf_size1: %d (frames %d)\n", 498 mfc_debug(2, "Buf1: %zx, buf_size1: %d (frames %d)\n",
501 buf_addr1, buf_size1, ctx->total_dpb_count); 499 buf_addr1, buf_size1, ctx->total_dpb_count);
502 if (buf_size1 < 0) { 500 if (buf_size1 < 0) {
503 mfc_debug(2, "Not enough memory has been allocated.\n"); 501 mfc_debug(2, "Not enough memory has been allocated.\n");
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index ef2a519bcd4c..992d61a8b961 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -813,8 +813,8 @@ static u32 sh_vou_ntsc_mode(enum sh_vou_bus_fmt bus_fmt)
813{ 813{
814 switch (bus_fmt) { 814 switch (bus_fmt) {
815 default: 815 default:
816 pr_warning("%s(): Invalid bus-format code %d, using default 8-bit\n", 816 pr_warn("%s(): Invalid bus-format code %d, using default 8-bit\n",
817 __func__, bus_fmt); 817 __func__, bus_fmt);
818 case SH_VOU_BUS_8BIT: 818 case SH_VOU_BUS_8BIT:
819 return 1; 819 return 1;
820 case SH_VOU_BUS_16BIT: 820 case SH_VOU_BUS_16BIT:
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index 86d74788544f..f5979c12ad61 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -1,7 +1,6 @@
1config SOC_CAMERA 1config SOC_CAMERA
2 tristate "SoC camera support" 2 tristate "SoC camera support"
3 depends on VIDEO_V4L2 && HAS_DMA && I2C 3 depends on VIDEO_V4L2 && HAS_DMA && I2C
4 select VIDEOBUF_GEN
5 select VIDEOBUF2_CORE 4 select VIDEOBUF2_CORE
6 help 5 help
7 SoC Camera is a common API to several cameras, not connecting 6 SoC Camera is a common API to several cameras, not connecting
@@ -26,14 +25,3 @@ config VIDEO_SH_MOBILE_CEU
26 select SOC_CAMERA_SCALE_CROP 25 select SOC_CAMERA_SCALE_CROP
27 ---help--- 26 ---help---
28 This is a v4l2 driver for the SuperH Mobile CEU Interface 27 This is a v4l2 driver for the SuperH Mobile CEU Interface
29
30config VIDEO_ATMEL_ISI
31 tristate "ATMEL Image Sensor Interface (ISI) support"
32 depends on VIDEO_DEV && SOC_CAMERA
33 depends on ARCH_AT91 || COMPILE_TEST
34 depends on HAS_DMA
35 select VIDEOBUF2_DMA_CONTIG
36 ---help---
37 This module makes the ATMEL Image Sensor Interface available
38 as a v4l2 device.
39
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
index 7633a0f2f66f..07a451e8b228 100644
--- a/drivers/media/platform/soc_camera/Makefile
+++ b/drivers/media/platform/soc_camera/Makefile
@@ -6,5 +6,4 @@ obj-$(CONFIG_SOC_CAMERA_SCALE_CROP) += soc_scale_crop.o
6obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o 6obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
7 7
8# soc-camera host drivers have to be linked after camera drivers 8# soc-camera host drivers have to be linked after camera drivers
9obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
10obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 9obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
deleted file mode 100644
index 46de657c3e6d..000000000000
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ /dev/null
@@ -1,1167 +0,0 @@
1/*
2 * Copyright (c) 2011 Atmel Corporation
3 * Josh Wu, <josh.wu@atmel.com>
4 *
5 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
6 * and Sedji Gaouaou
7 * Based on the bttv driver for Bt848 with respective copyright holders
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/clk.h>
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/slab.h>
25
26#include <media/soc_camera.h>
27#include <media/drv-intf/soc_mediabus.h>
28#include <media/v4l2-of.h>
29#include <media/videobuf2-dma-contig.h>
30
31#include "atmel-isi.h"
32
33#define MAX_BUFFER_NUM 32
34#define MAX_SUPPORT_WIDTH 2048
35#define MAX_SUPPORT_HEIGHT 2048
36#define VID_LIMIT_BYTES (16 * 1024 * 1024)
37#define MIN_FRAME_RATE 15
38#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
39
40/* Frame buffer descriptor */
41struct fbd {
42 /* Physical address of the frame buffer */
43 u32 fb_address;
44 /* DMA Control Register(only in HISI2) */
45 u32 dma_ctrl;
46 /* Physical address of the next fbd */
47 u32 next_fbd_address;
48};
49
50static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
51{
52 fb_desc->dma_ctrl = ctrl;
53}
54
55struct isi_dma_desc {
56 struct list_head list;
57 struct fbd *p_fbd;
58 dma_addr_t fbd_phys;
59};
60
61/* Frame buffer data */
62struct frame_buffer {
63 struct vb2_v4l2_buffer vb;
64 struct isi_dma_desc *p_dma_desc;
65 struct list_head list;
66};
67
68struct atmel_isi {
69 /* Protects the access of variables shared with the ISR */
70 spinlock_t lock;
71 void __iomem *regs;
72
73 int sequence;
74
75 /* Allocate descriptors for dma buffer use */
76 struct fbd *p_fb_descriptors;
77 dma_addr_t fb_descriptors_phys;
78 struct list_head dma_desc_head;
79 struct isi_dma_desc dma_desc[MAX_BUFFER_NUM];
80 bool enable_preview_path;
81
82 struct completion complete;
83 /* ISI peripherial clock */
84 struct clk *pclk;
85 unsigned int irq;
86
87 struct isi_platform_data pdata;
88 u16 width_flags; /* max 12 bits */
89
90 struct list_head video_buffer_list;
91 struct frame_buffer *active;
92
93 struct soc_camera_host soc_host;
94};
95
96static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
97{
98 writel(val, isi->regs + reg);
99}
100static u32 isi_readl(struct atmel_isi *isi, u32 reg)
101{
102 return readl(isi->regs + reg);
103}
104
105static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi,
106 const struct soc_camera_format_xlate *xlate)
107{
108 if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) {
109 /* all convert to YUYV */
110 switch (xlate->code) {
111 case MEDIA_BUS_FMT_VYUY8_2X8:
112 return ISI_CFG2_YCC_SWAP_MODE_3;
113 case MEDIA_BUS_FMT_UYVY8_2X8:
114 return ISI_CFG2_YCC_SWAP_MODE_2;
115 case MEDIA_BUS_FMT_YVYU8_2X8:
116 return ISI_CFG2_YCC_SWAP_MODE_1;
117 }
118 } else if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_RGB565) {
119 /*
120 * Preview path is enabled, it will convert UYVY to RGB format.
121 * But if sensor output format is not UYVY, we need to set
122 * YCC_SWAP_MODE to convert it as UYVY.
123 */
124 switch (xlate->code) {
125 case MEDIA_BUS_FMT_VYUY8_2X8:
126 return ISI_CFG2_YCC_SWAP_MODE_1;
127 case MEDIA_BUS_FMT_YUYV8_2X8:
128 return ISI_CFG2_YCC_SWAP_MODE_2;
129 case MEDIA_BUS_FMT_YVYU8_2X8:
130 return ISI_CFG2_YCC_SWAP_MODE_3;
131 }
132 }
133
134 /*
135 * By default, no swap for the codec path of Atmel ISI. So codec
136 * output is same as sensor's output.
137 * For instance, if sensor's output is YUYV, then codec outputs YUYV.
138 * And if sensor's output is UYVY, then codec outputs UYVY.
139 */
140 return ISI_CFG2_YCC_SWAP_DEFAULT;
141}
142
143static void configure_geometry(struct atmel_isi *isi, u32 width,
144 u32 height, const struct soc_camera_format_xlate *xlate)
145{
146 u32 cfg2, psize;
147 u32 fourcc = xlate->host_fmt->fourcc;
148
149 isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
150 fourcc == V4L2_PIX_FMT_RGB32;
151
152 /* According to sensor's output format to set cfg2 */
153 switch (xlate->code) {
154 default:
155 /* Grey */
156 case MEDIA_BUS_FMT_Y8_1X8:
157 cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr;
158 break;
159 /* YUV */
160 case MEDIA_BUS_FMT_VYUY8_2X8:
161 case MEDIA_BUS_FMT_UYVY8_2X8:
162 case MEDIA_BUS_FMT_YVYU8_2X8:
163 case MEDIA_BUS_FMT_YUYV8_2X8:
164 cfg2 = ISI_CFG2_COL_SPACE_YCbCr |
165 setup_cfg2_yuv_swap(isi, xlate);
166 break;
167 /* RGB, TODO */
168 }
169
170 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
171 /* Set width */
172 cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
173 ISI_CFG2_IM_HSIZE_MASK;
174 /* Set height */
175 cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
176 & ISI_CFG2_IM_VSIZE_MASK;
177 isi_writel(isi, ISI_CFG2, cfg2);
178
179 /* No down sampling, preview size equal to sensor output size */
180 psize = ((width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) &
181 ISI_PSIZE_PREV_HSIZE_MASK;
182 psize |= ((height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) &
183 ISI_PSIZE_PREV_VSIZE_MASK;
184 isi_writel(isi, ISI_PSIZE, psize);
185 isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING);
186
187 return;
188}
189
190static bool is_supported(struct soc_camera_device *icd,
191 const u32 pixformat)
192{
193 switch (pixformat) {
194 /* YUV, including grey */
195 case V4L2_PIX_FMT_GREY:
196 case V4L2_PIX_FMT_YUYV:
197 case V4L2_PIX_FMT_UYVY:
198 case V4L2_PIX_FMT_YVYU:
199 case V4L2_PIX_FMT_VYUY:
200 /* RGB */
201 case V4L2_PIX_FMT_RGB565:
202 return true;
203 default:
204 return false;
205 }
206}
207
208static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
209{
210 if (isi->active) {
211 struct vb2_v4l2_buffer *vbuf = &isi->active->vb;
212 struct frame_buffer *buf = isi->active;
213
214 list_del_init(&buf->list);
215 vbuf->vb2_buf.timestamp = ktime_get_ns();
216 vbuf->sequence = isi->sequence++;
217 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
218 }
219
220 if (list_empty(&isi->video_buffer_list)) {
221 isi->active = NULL;
222 } else {
223 /* start next dma frame. */
224 isi->active = list_entry(isi->video_buffer_list.next,
225 struct frame_buffer, list);
226 if (!isi->enable_preview_path) {
227 isi_writel(isi, ISI_DMA_C_DSCR,
228 (u32)isi->active->p_dma_desc->fbd_phys);
229 isi_writel(isi, ISI_DMA_C_CTRL,
230 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
231 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
232 } else {
233 isi_writel(isi, ISI_DMA_P_DSCR,
234 (u32)isi->active->p_dma_desc->fbd_phys);
235 isi_writel(isi, ISI_DMA_P_CTRL,
236 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
237 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
238 }
239 }
240 return IRQ_HANDLED;
241}
242
243/* ISI interrupt service routine */
244static irqreturn_t isi_interrupt(int irq, void *dev_id)
245{
246 struct atmel_isi *isi = dev_id;
247 u32 status, mask, pending;
248 irqreturn_t ret = IRQ_NONE;
249
250 spin_lock(&isi->lock);
251
252 status = isi_readl(isi, ISI_STATUS);
253 mask = isi_readl(isi, ISI_INTMASK);
254 pending = status & mask;
255
256 if (pending & ISI_CTRL_SRST) {
257 complete(&isi->complete);
258 isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
259 ret = IRQ_HANDLED;
260 } else if (pending & ISI_CTRL_DIS) {
261 complete(&isi->complete);
262 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
263 ret = IRQ_HANDLED;
264 } else {
265 if (likely(pending & ISI_SR_CXFR_DONE) ||
266 likely(pending & ISI_SR_PXFR_DONE))
267 ret = atmel_isi_handle_streaming(isi);
268 }
269
270 spin_unlock(&isi->lock);
271 return ret;
272}
273
274#define WAIT_ISI_RESET 1
275#define WAIT_ISI_DISABLE 0
276static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
277{
278 unsigned long timeout;
279 /*
280 * The reset or disable will only succeed if we have a
281 * pixel clock from the camera.
282 */
283 init_completion(&isi->complete);
284
285 if (wait_reset) {
286 isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
287 isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
288 } else {
289 isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
290 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
291 }
292
293 timeout = wait_for_completion_timeout(&isi->complete,
294 msecs_to_jiffies(500));
295 if (timeout == 0)
296 return -ETIMEDOUT;
297
298 return 0;
299}
300
301/* ------------------------------------------------------------------
302 Videobuf operations
303 ------------------------------------------------------------------*/
304static int queue_setup(struct vb2_queue *vq,
305 unsigned int *nbuffers, unsigned int *nplanes,
306 unsigned int sizes[], struct device *alloc_devs[])
307{
308 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
309 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
310 struct atmel_isi *isi = ici->priv;
311 unsigned long size;
312
313 size = icd->sizeimage;
314
315 if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM)
316 *nbuffers = MAX_BUFFER_NUM;
317
318 if (size * *nbuffers > VID_LIMIT_BYTES)
319 *nbuffers = VID_LIMIT_BYTES / size;
320
321 *nplanes = 1;
322 sizes[0] = size;
323
324 isi->sequence = 0;
325 isi->active = NULL;
326
327 dev_dbg(icd->parent, "%s, count=%d, size=%ld\n", __func__,
328 *nbuffers, size);
329
330 return 0;
331}
332
333static int buffer_init(struct vb2_buffer *vb)
334{
335 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
336 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
337
338 buf->p_dma_desc = NULL;
339 INIT_LIST_HEAD(&buf->list);
340
341 return 0;
342}
343
344static int buffer_prepare(struct vb2_buffer *vb)
345{
346 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
347 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
348 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
349 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
350 struct atmel_isi *isi = ici->priv;
351 unsigned long size;
352 struct isi_dma_desc *desc;
353
354 size = icd->sizeimage;
355
356 if (vb2_plane_size(vb, 0) < size) {
357 dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n",
358 __func__, vb2_plane_size(vb, 0), size);
359 return -EINVAL;
360 }
361
362 vb2_set_plane_payload(vb, 0, size);
363
364 if (!buf->p_dma_desc) {
365 if (list_empty(&isi->dma_desc_head)) {
366 dev_err(icd->parent, "Not enough dma descriptors.\n");
367 return -EINVAL;
368 } else {
369 /* Get an available descriptor */
370 desc = list_entry(isi->dma_desc_head.next,
371 struct isi_dma_desc, list);
372 /* Delete the descriptor since now it is used */
373 list_del_init(&desc->list);
374
375 /* Initialize the dma descriptor */
376 desc->p_fbd->fb_address =
377 vb2_dma_contig_plane_dma_addr(vb, 0);
378 desc->p_fbd->next_fbd_address = 0;
379 set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
380
381 buf->p_dma_desc = desc;
382 }
383 }
384 return 0;
385}
386
387static void buffer_cleanup(struct vb2_buffer *vb)
388{
389 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
390 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
391 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
392 struct atmel_isi *isi = ici->priv;
393 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
394
395 /* This descriptor is available now and we add to head list */
396 if (buf->p_dma_desc)
397 list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
398}
399
400static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
401{
402 u32 ctrl, cfg1;
403
404 cfg1 = isi_readl(isi, ISI_CFG1);
405 /* Enable irq: cxfr for the codec path, pxfr for the preview path */
406 isi_writel(isi, ISI_INTEN,
407 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
408
409 /* Check if already in a frame */
410 if (!isi->enable_preview_path) {
411 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
412 dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
413 return;
414 }
415
416 isi_writel(isi, ISI_DMA_C_DSCR,
417 (u32)buffer->p_dma_desc->fbd_phys);
418 isi_writel(isi, ISI_DMA_C_CTRL,
419 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
420 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
421 } else {
422 isi_writel(isi, ISI_DMA_P_DSCR,
423 (u32)buffer->p_dma_desc->fbd_phys);
424 isi_writel(isi, ISI_DMA_P_CTRL,
425 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
426 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
427 }
428
429 cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
430 /* Enable linked list */
431 cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
432
433 /* Enable ISI */
434 ctrl = ISI_CTRL_EN;
435
436 if (!isi->enable_preview_path)
437 ctrl |= ISI_CTRL_CDC;
438
439 isi_writel(isi, ISI_CTRL, ctrl);
440 isi_writel(isi, ISI_CFG1, cfg1);
441}
442
443static void buffer_queue(struct vb2_buffer *vb)
444{
445 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
446 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
447 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
448 struct atmel_isi *isi = ici->priv;
449 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb);
450 unsigned long flags = 0;
451
452 spin_lock_irqsave(&isi->lock, flags);
453 list_add_tail(&buf->list, &isi->video_buffer_list);
454
455 if (isi->active == NULL) {
456 isi->active = buf;
457 if (vb2_is_streaming(vb->vb2_queue))
458 start_dma(isi, buf);
459 }
460 spin_unlock_irqrestore(&isi->lock, flags);
461}
462
463static int start_streaming(struct vb2_queue *vq, unsigned int count)
464{
465 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
466 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
467 struct atmel_isi *isi = ici->priv;
468 int ret;
469
470 pm_runtime_get_sync(ici->v4l2_dev.dev);
471
472 /* Reset ISI */
473 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
474 if (ret < 0) {
475 dev_err(icd->parent, "Reset ISI timed out\n");
476 pm_runtime_put(ici->v4l2_dev.dev);
477 return ret;
478 }
479 /* Disable all interrupts */
480 isi_writel(isi, ISI_INTDIS, (u32)~0UL);
481
482 configure_geometry(isi, icd->user_width, icd->user_height,
483 icd->current_fmt);
484
485 spin_lock_irq(&isi->lock);
486 /* Clear any pending interrupt */
487 isi_readl(isi, ISI_STATUS);
488
489 if (count)
490 start_dma(isi, isi->active);
491 spin_unlock_irq(&isi->lock);
492
493 return 0;
494}
495
496/* abort streaming and wait for last buffer */
497static void stop_streaming(struct vb2_queue *vq)
498{
499 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
500 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
501 struct atmel_isi *isi = ici->priv;
502 struct frame_buffer *buf, *node;
503 int ret = 0;
504 unsigned long timeout;
505
506 spin_lock_irq(&isi->lock);
507 isi->active = NULL;
508 /* Release all active buffers */
509 list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
510 list_del_init(&buf->list);
511 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
512 }
513 spin_unlock_irq(&isi->lock);
514
515 if (!isi->enable_preview_path) {
516 timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
517 /* Wait until the end of the current frame. */
518 while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
519 time_before(jiffies, timeout))
520 msleep(1);
521
522 if (time_after(jiffies, timeout))
523 dev_err(icd->parent,
524 "Timeout waiting for finishing codec request\n");
525 }
526
527 /* Disable interrupts */
528 isi_writel(isi, ISI_INTDIS,
529 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
530
531 /* Disable ISI and wait for it is done */
532 ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
533 if (ret < 0)
534 dev_err(icd->parent, "Disable ISI timed out\n");
535
536 pm_runtime_put(ici->v4l2_dev.dev);
537}
538
539static const struct vb2_ops isi_video_qops = {
540 .queue_setup = queue_setup,
541 .buf_init = buffer_init,
542 .buf_prepare = buffer_prepare,
543 .buf_cleanup = buffer_cleanup,
544 .buf_queue = buffer_queue,
545 .start_streaming = start_streaming,
546 .stop_streaming = stop_streaming,
547 .wait_prepare = vb2_ops_wait_prepare,
548 .wait_finish = vb2_ops_wait_finish,
549};
550
551/* ------------------------------------------------------------------
552 SOC camera operations for the device
553 ------------------------------------------------------------------*/
554static int isi_camera_init_videobuf(struct vb2_queue *q,
555 struct soc_camera_device *icd)
556{
557 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
558
559 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
560 q->io_modes = VB2_MMAP;
561 q->drv_priv = icd;
562 q->buf_struct_size = sizeof(struct frame_buffer);
563 q->ops = &isi_video_qops;
564 q->mem_ops = &vb2_dma_contig_memops;
565 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
566 q->lock = &ici->host_lock;
567 q->dev = ici->v4l2_dev.dev;
568
569 return vb2_queue_init(q);
570}
571
572static int isi_camera_set_fmt(struct soc_camera_device *icd,
573 struct v4l2_format *f)
574{
575 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
576 const struct soc_camera_format_xlate *xlate;
577 struct v4l2_pix_format *pix = &f->fmt.pix;
578 struct v4l2_subdev_format format = {
579 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
580 };
581 struct v4l2_mbus_framefmt *mf = &format.format;
582 int ret;
583
584 /* check with atmel-isi support format, if not support use YUYV */
585 if (!is_supported(icd, pix->pixelformat))
586 pix->pixelformat = V4L2_PIX_FMT_YUYV;
587
588 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
589 if (!xlate) {
590 dev_warn(icd->parent, "Format %x not found\n",
591 pix->pixelformat);
592 return -EINVAL;
593 }
594
595 dev_dbg(icd->parent, "Plan to set format %dx%d\n",
596 pix->width, pix->height);
597
598 mf->width = pix->width;
599 mf->height = pix->height;
600 mf->field = pix->field;
601 mf->colorspace = pix->colorspace;
602 mf->code = xlate->code;
603
604 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format);
605 if (ret < 0)
606 return ret;
607
608 if (mf->code != xlate->code)
609 return -EINVAL;
610
611 pix->width = mf->width;
612 pix->height = mf->height;
613 pix->field = mf->field;
614 pix->colorspace = mf->colorspace;
615 icd->current_fmt = xlate;
616
617 dev_dbg(icd->parent, "Finally set format %dx%d\n",
618 pix->width, pix->height);
619
620 return ret;
621}
622
623static int isi_camera_try_fmt(struct soc_camera_device *icd,
624 struct v4l2_format *f)
625{
626 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
627 const struct soc_camera_format_xlate *xlate;
628 struct v4l2_pix_format *pix = &f->fmt.pix;
629 struct v4l2_subdev_pad_config pad_cfg;
630 struct v4l2_subdev_format format = {
631 .which = V4L2_SUBDEV_FORMAT_TRY,
632 };
633 struct v4l2_mbus_framefmt *mf = &format.format;
634 u32 pixfmt = pix->pixelformat;
635 int ret;
636
637 /* check with atmel-isi support format, if not support use YUYV */
638 if (!is_supported(icd, pix->pixelformat))
639 pix->pixelformat = V4L2_PIX_FMT_YUYV;
640
641 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
642 if (pixfmt && !xlate) {
643 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
644 return -EINVAL;
645 }
646
647 /* limit to Atmel ISI hardware capabilities */
648 if (pix->height > MAX_SUPPORT_HEIGHT)
649 pix->height = MAX_SUPPORT_HEIGHT;
650 if (pix->width > MAX_SUPPORT_WIDTH)
651 pix->width = MAX_SUPPORT_WIDTH;
652
653 /* limit to sensor capabilities */
654 mf->width = pix->width;
655 mf->height = pix->height;
656 mf->field = pix->field;
657 mf->colorspace = pix->colorspace;
658 mf->code = xlate->code;
659
660 ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
661 if (ret < 0)
662 return ret;
663
664 pix->width = mf->width;
665 pix->height = mf->height;
666 pix->colorspace = mf->colorspace;
667
668 switch (mf->field) {
669 case V4L2_FIELD_ANY:
670 pix->field = V4L2_FIELD_NONE;
671 break;
672 case V4L2_FIELD_NONE:
673 break;
674 default:
675 dev_err(icd->parent, "Field type %d unsupported.\n",
676 mf->field);
677 ret = -EINVAL;
678 }
679
680 return ret;
681}
682
683static const struct soc_mbus_pixelfmt isi_camera_formats[] = {
684 {
685 .fourcc = V4L2_PIX_FMT_YUYV,
686 .name = "Packed YUV422 16 bit",
687 .bits_per_sample = 8,
688 .packing = SOC_MBUS_PACKING_2X8_PADHI,
689 .order = SOC_MBUS_ORDER_LE,
690 .layout = SOC_MBUS_LAYOUT_PACKED,
691 },
692 {
693 .fourcc = V4L2_PIX_FMT_RGB565,
694 .name = "RGB565",
695 .bits_per_sample = 8,
696 .packing = SOC_MBUS_PACKING_2X8_PADHI,
697 .order = SOC_MBUS_ORDER_LE,
698 .layout = SOC_MBUS_LAYOUT_PACKED,
699 },
700};
701
702/* This will be corrected as we get more formats */
703static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
704{
705 return fmt->packing == SOC_MBUS_PACKING_NONE ||
706 (fmt->bits_per_sample == 8 &&
707 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
708 (fmt->bits_per_sample > 8 &&
709 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
710}
711
712#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \
713 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
714 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
715 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
716 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
717 V4L2_MBUS_PCLK_SAMPLE_RISING | \
718 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
719 V4L2_MBUS_DATA_ACTIVE_HIGH)
720
721static int isi_camera_try_bus_param(struct soc_camera_device *icd,
722 unsigned char buswidth)
723{
724 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
725 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
726 struct atmel_isi *isi = ici->priv;
727 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
728 unsigned long common_flags;
729 int ret;
730
731 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
732 if (!ret) {
733 common_flags = soc_mbus_config_compatible(&cfg,
734 ISI_BUS_PARAM);
735 if (!common_flags) {
736 dev_warn(icd->parent,
737 "Flags incompatible: camera 0x%x, host 0x%x\n",
738 cfg.flags, ISI_BUS_PARAM);
739 return -EINVAL;
740 }
741 } else if (ret != -ENOIOCTLCMD) {
742 return ret;
743 }
744
745 if ((1 << (buswidth - 1)) & isi->width_flags)
746 return 0;
747 return -EINVAL;
748}
749
750
751static int isi_camera_get_formats(struct soc_camera_device *icd,
752 unsigned int idx,
753 struct soc_camera_format_xlate *xlate)
754{
755 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
756 int formats = 0, ret, i, n;
757 /* sensor format */
758 struct v4l2_subdev_mbus_code_enum code = {
759 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
760 .index = idx,
761 };
762 /* soc camera host format */
763 const struct soc_mbus_pixelfmt *fmt;
764
765 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
766 if (ret < 0)
767 /* No more formats */
768 return 0;
769
770 fmt = soc_mbus_get_fmtdesc(code.code);
771 if (!fmt) {
772 dev_err(icd->parent,
773 "Invalid format code #%u: %d\n", idx, code.code);
774 return 0;
775 }
776
777 /* This also checks support for the requested bits-per-sample */
778 ret = isi_camera_try_bus_param(icd, fmt->bits_per_sample);
779 if (ret < 0) {
780 dev_err(icd->parent,
781 "Fail to try the bus parameters.\n");
782 return 0;
783 }
784
785 switch (code.code) {
786 case MEDIA_BUS_FMT_UYVY8_2X8:
787 case MEDIA_BUS_FMT_VYUY8_2X8:
788 case MEDIA_BUS_FMT_YUYV8_2X8:
789 case MEDIA_BUS_FMT_YVYU8_2X8:
790 n = ARRAY_SIZE(isi_camera_formats);
791 formats += n;
792 for (i = 0; xlate && i < n; i++, xlate++) {
793 xlate->host_fmt = &isi_camera_formats[i];
794 xlate->code = code.code;
795 dev_dbg(icd->parent, "Providing format %s using code %d\n",
796 xlate->host_fmt->name, xlate->code);
797 }
798 break;
799 default:
800 if (!isi_camera_packing_supported(fmt))
801 return 0;
802 if (xlate)
803 dev_dbg(icd->parent,
804 "Providing format %s in pass-through mode\n",
805 fmt->name);
806 }
807
808 /* Generic pass-through */
809 formats++;
810 if (xlate) {
811 xlate->host_fmt = fmt;
812 xlate->code = code.code;
813 xlate++;
814 }
815
816 return formats;
817}
818
819static int isi_camera_add_device(struct soc_camera_device *icd)
820{
821 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
822 icd->devnum);
823
824 return 0;
825}
826
827static void isi_camera_remove_device(struct soc_camera_device *icd)
828{
829 dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
830 icd->devnum);
831}
832
833static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
834{
835 struct soc_camera_device *icd = file->private_data;
836
837 return vb2_poll(&icd->vb2_vidq, file, pt);
838}
839
840static int isi_camera_querycap(struct soc_camera_host *ici,
841 struct v4l2_capability *cap)
842{
843 strcpy(cap->driver, "atmel-isi");
844 strcpy(cap->card, "Atmel Image Sensor Interface");
845 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
846 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
847
848 return 0;
849}
850
851static int isi_camera_set_bus_param(struct soc_camera_device *icd)
852{
853 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
854 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
855 struct atmel_isi *isi = ici->priv;
856 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
857 unsigned long common_flags;
858 int ret;
859 u32 cfg1 = 0;
860
861 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
862 if (!ret) {
863 common_flags = soc_mbus_config_compatible(&cfg,
864 ISI_BUS_PARAM);
865 if (!common_flags) {
866 dev_warn(icd->parent,
867 "Flags incompatible: camera 0x%x, host 0x%x\n",
868 cfg.flags, ISI_BUS_PARAM);
869 return -EINVAL;
870 }
871 } else if (ret != -ENOIOCTLCMD) {
872 return ret;
873 } else {
874 common_flags = ISI_BUS_PARAM;
875 }
876 dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
877 cfg.flags, ISI_BUS_PARAM, common_flags);
878
879 /* Make choises, based on platform preferences */
880 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
881 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
882 if (isi->pdata.hsync_act_low)
883 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
884 else
885 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
886 }
887
888 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
889 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
890 if (isi->pdata.vsync_act_low)
891 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
892 else
893 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
894 }
895
896 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
897 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
898 if (isi->pdata.pclk_act_falling)
899 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
900 else
901 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
902 }
903
904 cfg.flags = common_flags;
905 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
906 if (ret < 0 && ret != -ENOIOCTLCMD) {
907 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
908 common_flags, ret);
909 return ret;
910 }
911
912 /* set bus param for ISI */
913 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
914 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
915 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
916 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
917 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
918 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
919
920 dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n",
921 common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
922 common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
923 common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
924
925 if (isi->pdata.has_emb_sync)
926 cfg1 |= ISI_CFG1_EMB_SYNC;
927 if (isi->pdata.full_mode)
928 cfg1 |= ISI_CFG1_FULL_MODE;
929
930 cfg1 |= ISI_CFG1_THMASK_BEATS_16;
931
932 /* Enable PM and peripheral clock before operate isi registers */
933 pm_runtime_get_sync(ici->v4l2_dev.dev);
934
935 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
936 isi_writel(isi, ISI_CFG1, cfg1);
937
938 pm_runtime_put(ici->v4l2_dev.dev);
939
940 return 0;
941}
942
943static struct soc_camera_host_ops isi_soc_camera_host_ops = {
944 .owner = THIS_MODULE,
945 .add = isi_camera_add_device,
946 .remove = isi_camera_remove_device,
947 .set_fmt = isi_camera_set_fmt,
948 .try_fmt = isi_camera_try_fmt,
949 .get_formats = isi_camera_get_formats,
950 .init_videobuf2 = isi_camera_init_videobuf,
951 .poll = isi_camera_poll,
952 .querycap = isi_camera_querycap,
953 .set_bus_param = isi_camera_set_bus_param,
954};
955
956/* -----------------------------------------------------------------------*/
957static int atmel_isi_remove(struct platform_device *pdev)
958{
959 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
960 struct atmel_isi *isi = container_of(soc_host,
961 struct atmel_isi, soc_host);
962
963 soc_camera_host_unregister(soc_host);
964 dma_free_coherent(&pdev->dev,
965 sizeof(struct fbd) * MAX_BUFFER_NUM,
966 isi->p_fb_descriptors,
967 isi->fb_descriptors_phys);
968 pm_runtime_disable(&pdev->dev);
969
970 return 0;
971}
972
973static int atmel_isi_parse_dt(struct atmel_isi *isi,
974 struct platform_device *pdev)
975{
976 struct device_node *np= pdev->dev.of_node;
977 struct v4l2_of_endpoint ep;
978 int err;
979
980 /* Default settings for ISI */
981 isi->pdata.full_mode = 1;
982 isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
983
984 np = of_graph_get_next_endpoint(np, NULL);
985 if (!np) {
986 dev_err(&pdev->dev, "Could not find the endpoint\n");
987 return -EINVAL;
988 }
989
990 err = v4l2_of_parse_endpoint(np, &ep);
991 of_node_put(np);
992 if (err) {
993 dev_err(&pdev->dev, "Could not parse the endpoint\n");
994 return err;
995 }
996
997 switch (ep.bus.parallel.bus_width) {
998 case 8:
999 isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
1000 break;
1001 case 10:
1002 isi->pdata.data_width_flags =
1003 ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
1004 break;
1005 default:
1006 dev_err(&pdev->dev, "Unsupported bus width: %d\n",
1007 ep.bus.parallel.bus_width);
1008 return -EINVAL;
1009 }
1010
1011 if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1012 isi->pdata.hsync_act_low = true;
1013 if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1014 isi->pdata.vsync_act_low = true;
1015 if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1016 isi->pdata.pclk_act_falling = true;
1017
1018 if (ep.bus_type == V4L2_MBUS_BT656)
1019 isi->pdata.has_emb_sync = true;
1020
1021 return 0;
1022}
1023
1024static int atmel_isi_probe(struct platform_device *pdev)
1025{
1026 int irq;
1027 struct atmel_isi *isi;
1028 struct resource *regs;
1029 int ret, i;
1030 struct soc_camera_host *soc_host;
1031
1032 isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL);
1033 if (!isi) {
1034 dev_err(&pdev->dev, "Can't allocate interface!\n");
1035 return -ENOMEM;
1036 }
1037
1038 isi->pclk = devm_clk_get(&pdev->dev, "isi_clk");
1039 if (IS_ERR(isi->pclk))
1040 return PTR_ERR(isi->pclk);
1041
1042 ret = atmel_isi_parse_dt(isi, pdev);
1043 if (ret)
1044 return ret;
1045
1046 isi->active = NULL;
1047 spin_lock_init(&isi->lock);
1048 INIT_LIST_HEAD(&isi->video_buffer_list);
1049 INIT_LIST_HEAD(&isi->dma_desc_head);
1050
1051 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
1052 sizeof(struct fbd) * MAX_BUFFER_NUM,
1053 &isi->fb_descriptors_phys,
1054 GFP_KERNEL);
1055 if (!isi->p_fb_descriptors) {
1056 dev_err(&pdev->dev, "Can't allocate descriptors!\n");
1057 return -ENOMEM;
1058 }
1059
1060 for (i = 0; i < MAX_BUFFER_NUM; i++) {
1061 isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
1062 isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
1063 i * sizeof(struct fbd);
1064 list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
1065 }
1066
1067 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1068 isi->regs = devm_ioremap_resource(&pdev->dev, regs);
1069 if (IS_ERR(isi->regs)) {
1070 ret = PTR_ERR(isi->regs);
1071 goto err_ioremap;
1072 }
1073
1074 if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
1075 isi->width_flags = 1 << 7;
1076 if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
1077 isi->width_flags |= 1 << 9;
1078
1079 irq = platform_get_irq(pdev, 0);
1080 if (irq < 0) {
1081 ret = irq;
1082 goto err_req_irq;
1083 }
1084
1085 ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi);
1086 if (ret) {
1087 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1088 goto err_req_irq;
1089 }
1090 isi->irq = irq;
1091
1092 soc_host = &isi->soc_host;
1093 soc_host->drv_name = "isi-camera";
1094 soc_host->ops = &isi_soc_camera_host_ops;
1095 soc_host->priv = isi;
1096 soc_host->v4l2_dev.dev = &pdev->dev;
1097 soc_host->nr = pdev->id;
1098
1099 pm_suspend_ignore_children(&pdev->dev, true);
1100 pm_runtime_enable(&pdev->dev);
1101
1102 ret = soc_camera_host_register(soc_host);
1103 if (ret) {
1104 dev_err(&pdev->dev, "Unable to register soc camera host\n");
1105 goto err_register_soc_camera_host;
1106 }
1107 return 0;
1108
1109err_register_soc_camera_host:
1110 pm_runtime_disable(&pdev->dev);
1111err_req_irq:
1112err_ioremap:
1113 dma_free_coherent(&pdev->dev,
1114 sizeof(struct fbd) * MAX_BUFFER_NUM,
1115 isi->p_fb_descriptors,
1116 isi->fb_descriptors_phys);
1117
1118 return ret;
1119}
1120
1121#ifdef CONFIG_PM
1122static int atmel_isi_runtime_suspend(struct device *dev)
1123{
1124 struct soc_camera_host *soc_host = to_soc_camera_host(dev);
1125 struct atmel_isi *isi = container_of(soc_host,
1126 struct atmel_isi, soc_host);
1127
1128 clk_disable_unprepare(isi->pclk);
1129
1130 return 0;
1131}
1132static int atmel_isi_runtime_resume(struct device *dev)
1133{
1134 struct soc_camera_host *soc_host = to_soc_camera_host(dev);
1135 struct atmel_isi *isi = container_of(soc_host,
1136 struct atmel_isi, soc_host);
1137
1138 return clk_prepare_enable(isi->pclk);
1139}
1140#endif /* CONFIG_PM */
1141
1142static const struct dev_pm_ops atmel_isi_dev_pm_ops = {
1143 SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend,
1144 atmel_isi_runtime_resume, NULL)
1145};
1146
1147static const struct of_device_id atmel_isi_of_match[] = {
1148 { .compatible = "atmel,at91sam9g45-isi" },
1149 { }
1150};
1151MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
1152
1153static struct platform_driver atmel_isi_driver = {
1154 .remove = atmel_isi_remove,
1155 .driver = {
1156 .name = "atmel_isi",
1157 .of_match_table = of_match_ptr(atmel_isi_of_match),
1158 .pm = &atmel_isi_dev_pm_ops,
1159 },
1160};
1161
1162module_platform_driver_probe(atmel_isi_driver, atmel_isi_probe);
1163
1164MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1165MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1166MODULE_LICENSE("GPL");
1167MODULE_SUPPORTED_DEVICE("video");
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index a15bfb5aea47..96dc01750bc0 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -1801,18 +1801,7 @@ static struct platform_driver sh_mobile_ceu_driver = {
1801 .remove = sh_mobile_ceu_remove, 1801 .remove = sh_mobile_ceu_remove,
1802}; 1802};
1803 1803
1804static int __init sh_mobile_ceu_init(void) 1804module_platform_driver(sh_mobile_ceu_driver);
1805{
1806 return platform_driver_register(&sh_mobile_ceu_driver);
1807}
1808
1809static void __exit sh_mobile_ceu_exit(void)
1810{
1811 platform_driver_unregister(&sh_mobile_ceu_driver);
1812}
1813
1814module_init(sh_mobile_ceu_init);
1815module_exit(sh_mobile_ceu_exit);
1816 1805
1817MODULE_DESCRIPTION("SuperH Mobile CEU driver"); 1806MODULE_DESCRIPTION("SuperH Mobile CEU driver");
1818MODULE_AUTHOR("Magnus Damm"); 1807MODULE_AUTHOR("Magnus Damm");
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index edd1c1de4e33..3c9421f4d8e3 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -37,18 +37,12 @@
37#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-dev.h> 38#include <media/v4l2-dev.h>
39#include <media/v4l2-of.h> 39#include <media/v4l2-of.h>
40#include <media/videobuf-core.h>
41#include <media/videobuf2-v4l2.h> 40#include <media/videobuf2-v4l2.h>
42 41
43/* Default to VGA resolution */ 42/* Default to VGA resolution */
44#define DEFAULT_WIDTH 640 43#define DEFAULT_WIDTH 640
45#define DEFAULT_HEIGHT 480 44#define DEFAULT_HEIGHT 480
46 45
47#define is_streaming(ici, icd) \
48 (((ici)->ops->init_videobuf) ? \
49 (icd)->vb_vidq.streaming : \
50 vb2_is_streaming(&(icd)->vb2_vidq))
51
52#define MAP_MAX_NUM 32 46#define MAP_MAX_NUM 32
53static DECLARE_BITMAP(device_map, MAP_MAX_NUM); 47static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
54static LIST_HEAD(hosts); 48static LIST_HEAD(hosts);
@@ -367,23 +361,13 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
367{ 361{
368 int ret; 362 int ret;
369 struct soc_camera_device *icd = file->private_data; 363 struct soc_camera_device *icd = file->private_data;
370 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
371 364
372 WARN_ON(priv != file->private_data); 365 WARN_ON(priv != file->private_data);
373 366
374 if (icd->streamer && icd->streamer != file) 367 if (icd->streamer && icd->streamer != file)
375 return -EBUSY; 368 return -EBUSY;
376 369
377 if (ici->ops->init_videobuf) { 370 ret = vb2_reqbufs(&icd->vb2_vidq, p);
378 ret = videobuf_reqbufs(&icd->vb_vidq, p);
379 if (ret < 0)
380 return ret;
381
382 ret = ici->ops->reqbufs(icd, p);
383 } else {
384 ret = vb2_reqbufs(&icd->vb2_vidq, p);
385 }
386
387 if (!ret) 371 if (!ret)
388 icd->streamer = p->count ? file : NULL; 372 icd->streamer = p->count ? file : NULL;
389 return ret; 373 return ret;
@@ -393,61 +377,44 @@ static int soc_camera_querybuf(struct file *file, void *priv,
393 struct v4l2_buffer *p) 377 struct v4l2_buffer *p)
394{ 378{
395 struct soc_camera_device *icd = file->private_data; 379 struct soc_camera_device *icd = file->private_data;
396 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
397 380
398 WARN_ON(priv != file->private_data); 381 WARN_ON(priv != file->private_data);
399 382
400 if (ici->ops->init_videobuf) 383 return vb2_querybuf(&icd->vb2_vidq, p);
401 return videobuf_querybuf(&icd->vb_vidq, p);
402 else
403 return vb2_querybuf(&icd->vb2_vidq, p);
404} 384}
405 385
406static int soc_camera_qbuf(struct file *file, void *priv, 386static int soc_camera_qbuf(struct file *file, void *priv,
407 struct v4l2_buffer *p) 387 struct v4l2_buffer *p)
408{ 388{
409 struct soc_camera_device *icd = file->private_data; 389 struct soc_camera_device *icd = file->private_data;
410 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
411 390
412 WARN_ON(priv != file->private_data); 391 WARN_ON(priv != file->private_data);
413 392
414 if (icd->streamer != file) 393 if (icd->streamer != file)
415 return -EBUSY; 394 return -EBUSY;
416 395
417 if (ici->ops->init_videobuf) 396 return vb2_qbuf(&icd->vb2_vidq, p);
418 return videobuf_qbuf(&icd->vb_vidq, p);
419 else
420 return vb2_qbuf(&icd->vb2_vidq, p);
421} 397}
422 398
423static int soc_camera_dqbuf(struct file *file, void *priv, 399static int soc_camera_dqbuf(struct file *file, void *priv,
424 struct v4l2_buffer *p) 400 struct v4l2_buffer *p)
425{ 401{
426 struct soc_camera_device *icd = file->private_data; 402 struct soc_camera_device *icd = file->private_data;
427 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
428 403
429 WARN_ON(priv != file->private_data); 404 WARN_ON(priv != file->private_data);
430 405
431 if (icd->streamer != file) 406 if (icd->streamer != file)
432 return -EBUSY; 407 return -EBUSY;
433 408
434 if (ici->ops->init_videobuf) 409 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
435 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
436 else
437 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
438} 410}
439 411
440static int soc_camera_create_bufs(struct file *file, void *priv, 412static int soc_camera_create_bufs(struct file *file, void *priv,
441 struct v4l2_create_buffers *create) 413 struct v4l2_create_buffers *create)
442{ 414{
443 struct soc_camera_device *icd = file->private_data; 415 struct soc_camera_device *icd = file->private_data;
444 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
445 int ret; 416 int ret;
446 417
447 /* videobuf2 only */
448 if (ici->ops->init_videobuf)
449 return -ENOTTY;
450
451 if (icd->streamer && icd->streamer != file) 418 if (icd->streamer && icd->streamer != file)
452 return -EBUSY; 419 return -EBUSY;
453 420
@@ -461,24 +428,14 @@ static int soc_camera_prepare_buf(struct file *file, void *priv,
461 struct v4l2_buffer *b) 428 struct v4l2_buffer *b)
462{ 429{
463 struct soc_camera_device *icd = file->private_data; 430 struct soc_camera_device *icd = file->private_data;
464 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
465 431
466 /* videobuf2 only */ 432 return vb2_prepare_buf(&icd->vb2_vidq, b);
467 if (ici->ops->init_videobuf)
468 return -EINVAL;
469 else
470 return vb2_prepare_buf(&icd->vb2_vidq, b);
471} 433}
472 434
473static int soc_camera_expbuf(struct file *file, void *priv, 435static int soc_camera_expbuf(struct file *file, void *priv,
474 struct v4l2_exportbuffer *p) 436 struct v4l2_exportbuffer *p)
475{ 437{
476 struct soc_camera_device *icd = file->private_data; 438 struct soc_camera_device *icd = file->private_data;
477 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
478
479 /* videobuf2 only */
480 if (ici->ops->init_videobuf)
481 return -ENOTTY;
482 439
483 if (icd->streamer && icd->streamer != file) 440 if (icd->streamer && icd->streamer != file)
484 return -EBUSY; 441 return -EBUSY;
@@ -602,8 +559,6 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
602 icd->sizeimage = pix->sizeimage; 559 icd->sizeimage = pix->sizeimage;
603 icd->colorspace = pix->colorspace; 560 icd->colorspace = pix->colorspace;
604 icd->field = pix->field; 561 icd->field = pix->field;
605 if (ici->ops->init_videobuf)
606 icd->vb_vidq.field = pix->field;
607 562
608 dev_dbg(icd->pdev, "set width: %d height: %d\n", 563 dev_dbg(icd->pdev, "set width: %d height: %d\n",
609 icd->user_width, icd->user_height); 564 icd->user_width, icd->user_height);
@@ -745,13 +700,9 @@ static int soc_camera_open(struct file *file)
745 if (ret < 0) 700 if (ret < 0)
746 goto esfmt; 701 goto esfmt;
747 702
748 if (ici->ops->init_videobuf) { 703 ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd);
749 ici->ops->init_videobuf(&icd->vb_vidq, icd); 704 if (ret < 0)
750 } else { 705 goto einitvb;
751 ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd);
752 if (ret < 0)
753 goto einitvb;
754 }
755 v4l2_ctrl_handler_setup(&icd->ctrl_handler); 706 v4l2_ctrl_handler_setup(&icd->ctrl_handler);
756 } 707 }
757 mutex_unlock(&ici->host_lock); 708 mutex_unlock(&ici->host_lock);
@@ -842,10 +793,7 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
842 793
843 if (mutex_lock_interruptible(&ici->host_lock)) 794 if (mutex_lock_interruptible(&ici->host_lock))
844 return -ERESTARTSYS; 795 return -ERESTARTSYS;
845 if (ici->ops->init_videobuf) 796 err = vb2_mmap(&icd->vb2_vidq, vma);
846 err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
847 else
848 err = vb2_mmap(&icd->vb2_vidq, vma);
849 mutex_unlock(&ici->host_lock); 797 mutex_unlock(&ici->host_lock);
850 798
851 dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n", 799 dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n",
@@ -866,10 +814,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
866 return POLLERR; 814 return POLLERR;
867 815
868 mutex_lock(&ici->host_lock); 816 mutex_lock(&ici->host_lock);
869 if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) 817 res = ici->ops->poll(file, pt);
870 dev_err(icd->pdev, "Trying to poll with no queued buffers!\n");
871 else
872 res = ici->ops->poll(file, pt);
873 mutex_unlock(&ici->host_lock); 818 mutex_unlock(&ici->host_lock);
874 return res; 819 return res;
875} 820}
@@ -900,7 +845,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
900 if (icd->streamer && icd->streamer != file) 845 if (icd->streamer && icd->streamer != file)
901 return -EBUSY; 846 return -EBUSY;
902 847
903 if (is_streaming(to_soc_camera_host(icd->parent), icd)) { 848 if (vb2_is_streaming(&icd->vb2_vidq)) {
904 dev_err(icd->pdev, "S_FMT denied: queue initialised\n"); 849 dev_err(icd->pdev, "S_FMT denied: queue initialised\n");
905 return -EBUSY; 850 return -EBUSY;
906 } 851 }
@@ -971,7 +916,6 @@ static int soc_camera_streamon(struct file *file, void *priv,
971 enum v4l2_buf_type i) 916 enum v4l2_buf_type i)
972{ 917{
973 struct soc_camera_device *icd = file->private_data; 918 struct soc_camera_device *icd = file->private_data;
974 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
975 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 919 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
976 int ret; 920 int ret;
977 921
@@ -983,12 +927,8 @@ static int soc_camera_streamon(struct file *file, void *priv,
983 if (icd->streamer != file) 927 if (icd->streamer != file)
984 return -EBUSY; 928 return -EBUSY;
985 929
986 /* This calls buf_queue from host driver's videobuf_queue_ops */ 930 /* This calls buf_queue from host driver's videobuf2_queue_ops */
987 if (ici->ops->init_videobuf) 931 ret = vb2_streamon(&icd->vb2_vidq, i);
988 ret = videobuf_streamon(&icd->vb_vidq);
989 else
990 ret = vb2_streamon(&icd->vb2_vidq, i);
991
992 if (!ret) 932 if (!ret)
993 v4l2_subdev_call(sd, video, s_stream, 1); 933 v4l2_subdev_call(sd, video, s_stream, 1);
994 934
@@ -1000,7 +940,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
1000{ 940{
1001 struct soc_camera_device *icd = file->private_data; 941 struct soc_camera_device *icd = file->private_data;
1002 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 942 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1003 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1004 int ret; 943 int ret;
1005 944
1006 WARN_ON(priv != file->private_data); 945 WARN_ON(priv != file->private_data);
@@ -1012,13 +951,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
1012 return -EBUSY; 951 return -EBUSY;
1013 952
1014 /* 953 /*
1015 * This calls buf_release from host driver's videobuf_queue_ops for all 954 * This calls buf_release from host driver's videobuf2_queue_ops for all
1016 * remaining buffers. When the last buffer is freed, stop capture 955 * remaining buffers. When the last buffer is freed, stop capture
1017 */ 956 */
1018 if (ici->ops->init_videobuf) 957 ret = vb2_streamoff(&icd->vb2_vidq, i);
1019 ret = videobuf_streamoff(&icd->vb_vidq);
1020 else
1021 ret = vb2_streamoff(&icd->vb2_vidq, i);
1022 958
1023 v4l2_subdev_call(sd, video, s_stream, 0); 959 v4l2_subdev_call(sd, video, s_stream, 0);
1024 960
@@ -1053,7 +989,7 @@ static int soc_camera_s_selection(struct file *file, void *fh,
1053 989
1054 if (s->target == V4L2_SEL_TGT_COMPOSE) { 990 if (s->target == V4L2_SEL_TGT_COMPOSE) {
1055 /* No output size change during a running capture! */ 991 /* No output size change during a running capture! */
1056 if (is_streaming(ici, icd) && 992 if (vb2_is_streaming(&icd->vb2_vidq) &&
1057 (icd->user_width != s->r.width || 993 (icd->user_width != s->r.width ||
1058 icd->user_height != s->r.height)) 994 icd->user_height != s->r.height))
1059 return -EBUSY; 995 return -EBUSY;
@@ -1066,7 +1002,8 @@ static int soc_camera_s_selection(struct file *file, void *fh,
1066 return -EBUSY; 1002 return -EBUSY;
1067 } 1003 }
1068 1004
1069 if (s->target == V4L2_SEL_TGT_CROP && is_streaming(ici, icd) && 1005 if (s->target == V4L2_SEL_TGT_CROP &&
1006 vb2_is_streaming(&icd->vb2_vidq) &&
1070 ici->ops->set_liveselection) 1007 ici->ops->set_liveselection)
1071 ret = ici->ops->set_liveselection(icd, s); 1008 ret = ici->ops->set_liveselection(icd, s);
1072 else 1009 else
@@ -1910,9 +1847,7 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1910 !ici->ops->set_fmt || 1847 !ici->ops->set_fmt ||
1911 !ici->ops->set_bus_param || 1848 !ici->ops->set_bus_param ||
1912 !ici->ops->querycap || 1849 !ici->ops->querycap ||
1913 ((!ici->ops->init_videobuf || 1850 !ici->ops->init_videobuf2 ||
1914 !ici->ops->reqbufs) &&
1915 !ici->ops->init_videobuf2) ||
1916 !ici->ops->poll || 1851 !ici->ops->poll ||
1917 !ici->v4l2_dev.dev) 1852 !ici->v4l2_dev.dev)
1918 return -EINVAL; 1853 return -EINVAL;
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
index f77252d6ccd3..0116097c0c0f 100644
--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -62,7 +62,8 @@ int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
62EXPORT_SYMBOL(soc_camera_client_g_rect); 62EXPORT_SYMBOL(soc_camera_client_g_rect);
63 63
64/* Client crop has changed, update our sub-rectangle to remain within the area */ 64/* Client crop has changed, update our sub-rectangle to remain within the area */
65static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect) 65static void move_and_crop_subrect(struct v4l2_rect *rect,
66 struct v4l2_rect *subrect)
66{ 67{
67 if (rect->width < subrect->width) 68 if (rect->width < subrect->width)
68 subrect->width = rect->width; 69 subrect->width = rect->width;
@@ -72,14 +73,14 @@ static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect)
72 73
73 if (rect->left > subrect->left) 74 if (rect->left > subrect->left)
74 subrect->left = rect->left; 75 subrect->left = rect->left;
75 else if (rect->left + rect->width > 76 else if (rect->left + rect->width <
76 subrect->left + subrect->width) 77 subrect->left + subrect->width)
77 subrect->left = rect->left + rect->width - 78 subrect->left = rect->left + rect->width -
78 subrect->width; 79 subrect->width;
79 80
80 if (rect->top > subrect->top) 81 if (rect->top > subrect->top)
81 subrect->top = rect->top; 82 subrect->top = rect->top;
82 else if (rect->top + rect->height > 83 else if (rect->top + rect->height <
83 subrect->top + subrect->height) 84 subrect->top + subrect->height)
84 subrect->top = rect->top + rect->height - 85 subrect->top = rect->top + rect->height -
85 subrect->height; 86 subrect->height;
@@ -216,7 +217,7 @@ int soc_camera_client_s_selection(struct v4l2_subdev *sd,
216 217
217 if (!ret) { 218 if (!ret) {
218 *target_rect = *cam_rect; 219 *target_rect = *cam_rect;
219 update_subrect(target_rect, subrect); 220 move_and_crop_subrect(target_rect, subrect);
220 } 221 }
221 222
222 return ret; 223 return ret;
@@ -299,7 +300,7 @@ update_cache:
299 if (host_1to1) 300 if (host_1to1)
300 *subrect = *rect; 301 *subrect = *rect;
301 else 302 else
302 update_subrect(rect, subrect); 303 move_and_crop_subrect(rect, subrect);
303 304
304 return 0; 305 return 0;
305} 306}
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 7652ce2ec1dc..59280ac31937 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -865,9 +865,8 @@ static int c8sectpfe_probe(struct platform_device *pdev)
865 } 865 }
866 866
867 /* Setup timer interrupt */ 867 /* Setup timer interrupt */
868 init_timer(&fei->timer); 868 setup_timer(&fei->timer, c8sectpfe_timer_interrupt,
869 fei->timer.function = c8sectpfe_timer_interrupt; 869 (unsigned long)fei);
870 fei->timer.data = (unsigned long)fei;
871 870
872 mutex_init(&fei->lock); 871 mutex_init(&fei->lock);
873 872
diff --git a/drivers/media/platform/sti/cec/Makefile b/drivers/media/platform/sti/cec/Makefile
new file mode 100644
index 000000000000..f07905e1448a
--- /dev/null
+++ b/drivers/media/platform/sti/cec/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += stih-cec.o
diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c
new file mode 100644
index 000000000000..39ff55145a82
--- /dev/null
+++ b/drivers/media/platform/sti/cec/stih-cec.c
@@ -0,0 +1,404 @@
1/*
2 * STIH4xx CEC driver
3 * Copyright (C) STMicroelectronic SA 2016
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10#include <linux/clk.h>
11#include <linux/interrupt.h>
12#include <linux/kernel.h>
13#include <linux/mfd/syscon.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/of_platform.h>
17#include <linux/platform_device.h>
18
19#include <media/cec.h>
20#include <media/cec-notifier.h>
21
22#define CEC_NAME "stih-cec"
23
24/* CEC registers */
25#define CEC_CLK_DIV 0x0
26#define CEC_CTRL 0x4
27#define CEC_IRQ_CTRL 0x8
28#define CEC_STATUS 0xC
29#define CEC_EXT_STATUS 0x10
30#define CEC_TX_CTRL 0x14
31#define CEC_FREE_TIME_THRESH 0x18
32#define CEC_BIT_TOUT_THRESH 0x1C
33#define CEC_BIT_PULSE_THRESH 0x20
34#define CEC_DATA 0x24
35#define CEC_TX_ARRAY_CTRL 0x28
36#define CEC_CTRL2 0x2C
37#define CEC_TX_ERROR_STS 0x30
38#define CEC_ADDR_TABLE 0x34
39#define CEC_DATA_ARRAY_CTRL 0x38
40#define CEC_DATA_ARRAY_STATUS 0x3C
41#define CEC_TX_DATA_BASE 0x40
42#define CEC_TX_DATA_TOP 0x50
43#define CEC_TX_DATA_SIZE 0x1
44#define CEC_RX_DATA_BASE 0x54
45#define CEC_RX_DATA_TOP 0x64
46#define CEC_RX_DATA_SIZE 0x1
47
48/* CEC_CTRL2 */
49#define CEC_LINE_INACTIVE_EN BIT(0)
50#define CEC_AUTO_BUS_ERR_EN BIT(1)
51#define CEC_STOP_ON_ARB_ERR_EN BIT(2)
52#define CEC_TX_REQ_WAIT_EN BIT(3)
53
54/* CEC_DATA_ARRAY_CTRL */
55#define CEC_TX_ARRAY_EN BIT(0)
56#define CEC_RX_ARRAY_EN BIT(1)
57#define CEC_TX_ARRAY_RESET BIT(2)
58#define CEC_RX_ARRAY_RESET BIT(3)
59#define CEC_TX_N_OF_BYTES_IRQ_EN BIT(4)
60#define CEC_TX_STOP_ON_NACK BIT(7)
61
62/* CEC_TX_ARRAY_CTRL */
63#define CEC_TX_N_OF_BYTES 0x1F
64#define CEC_TX_START BIT(5)
65#define CEC_TX_AUTO_SOM_EN BIT(6)
66#define CEC_TX_AUTO_EOM_EN BIT(7)
67
68/* CEC_IRQ_CTRL */
69#define CEC_TX_DONE_IRQ_EN BIT(0)
70#define CEC_ERROR_IRQ_EN BIT(2)
71#define CEC_RX_DONE_IRQ_EN BIT(3)
72#define CEC_RX_SOM_IRQ_EN BIT(4)
73#define CEC_RX_EOM_IRQ_EN BIT(5)
74#define CEC_FREE_TIME_IRQ_EN BIT(6)
75#define CEC_PIN_STS_IRQ_EN BIT(7)
76
77/* CEC_CTRL */
78#define CEC_IN_FILTER_EN BIT(0)
79#define CEC_PWR_SAVE_EN BIT(1)
80#define CEC_EN BIT(4)
81#define CEC_ACK_CTRL BIT(5)
82#define CEC_RX_RESET_EN BIT(6)
83#define CEC_IGNORE_RX_ERROR BIT(7)
84
85/* CEC_STATUS */
86#define CEC_TX_DONE_STS BIT(0)
87#define CEC_TX_ACK_GET_STS BIT(1)
88#define CEC_ERROR_STS BIT(2)
89#define CEC_RX_DONE_STS BIT(3)
90#define CEC_RX_SOM_STS BIT(4)
91#define CEC_RX_EOM_STS BIT(5)
92#define CEC_FREE_TIME_IRQ_STS BIT(6)
93#define CEC_PIN_STS BIT(7)
94#define CEC_SBIT_TOUT_STS BIT(8)
95#define CEC_DBIT_TOUT_STS BIT(9)
96#define CEC_LPULSE_ERROR_STS BIT(10)
97#define CEC_HPULSE_ERROR_STS BIT(11)
98#define CEC_TX_ERROR BIT(12)
99#define CEC_TX_ARB_ERROR BIT(13)
100#define CEC_RX_ERROR_MIN BIT(14)
101#define CEC_RX_ERROR_MAX BIT(15)
102
103/* Signal free time in bit periods (2.4ms) */
104#define CEC_PRESENT_INIT_SFT 7
105#define CEC_NEW_INIT_SFT 5
106#define CEC_RETRANSMIT_SFT 3
107
108/* Constants for CEC_BIT_TOUT_THRESH register */
109#define CEC_SBIT_TOUT_47MS BIT(1)
110#define CEC_SBIT_TOUT_48MS (BIT(0) | BIT(1))
111#define CEC_SBIT_TOUT_50MS BIT(2)
112#define CEC_DBIT_TOUT_27MS BIT(0)
113#define CEC_DBIT_TOUT_28MS BIT(1)
114#define CEC_DBIT_TOUT_29MS (BIT(0) | BIT(1))
115
116/* Constants for CEC_BIT_PULSE_THRESH register */
117#define CEC_BIT_LPULSE_03MS BIT(1)
118#define CEC_BIT_HPULSE_03MS BIT(3)
119
120/* Constants for CEC_DATA_ARRAY_STATUS register */
121#define CEC_RX_N_OF_BYTES 0x1F
122#define CEC_TX_N_OF_BYTES_SENT BIT(5)
123#define CEC_RX_OVERRUN BIT(6)
124
125struct stih_cec {
126 struct cec_adapter *adap;
127 struct device *dev;
128 struct clk *clk;
129 void __iomem *regs;
130 int irq;
131 u32 irq_status;
132 struct cec_notifier *notifier;
133};
134
135static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable)
136{
137 struct stih_cec *cec = cec_get_drvdata(adap);
138
139 if (enable) {
140 /* The doc says (input TCLK_PERIOD * CEC_CLK_DIV) = 0.1ms */
141 unsigned long clk_freq = clk_get_rate(cec->clk);
142 u32 cec_clk_div = clk_freq / 10000;
143
144 writel(cec_clk_div, cec->regs + CEC_CLK_DIV);
145
146 /* Configuration of the durations activating a timeout */
147 writel(CEC_SBIT_TOUT_47MS | (CEC_DBIT_TOUT_28MS << 4),
148 cec->regs + CEC_BIT_TOUT_THRESH);
149
150 /* Configuration of the smallest allowed duration for pulses */
151 writel(CEC_BIT_LPULSE_03MS | CEC_BIT_HPULSE_03MS,
152 cec->regs + CEC_BIT_PULSE_THRESH);
153
154 /* Minimum received bit period threshold */
155 writel(BIT(5) | BIT(7), cec->regs + CEC_TX_CTRL);
156
157 /* Configuration of transceiver data arrays */
158 writel(CEC_TX_ARRAY_EN | CEC_RX_ARRAY_EN | CEC_TX_STOP_ON_NACK,
159 cec->regs + CEC_DATA_ARRAY_CTRL);
160
161 /* Configuration of the control bits for CEC Transceiver */
162 writel(CEC_IN_FILTER_EN | CEC_EN | CEC_RX_RESET_EN,
163 cec->regs + CEC_CTRL);
164
165 /* Clear logical addresses */
166 writel(0, cec->regs + CEC_ADDR_TABLE);
167
168 /* Clear the status register */
169 writel(0x0, cec->regs + CEC_STATUS);
170
171 /* Enable the interrupts */
172 writel(CEC_TX_DONE_IRQ_EN | CEC_RX_DONE_IRQ_EN |
173 CEC_RX_SOM_IRQ_EN | CEC_RX_EOM_IRQ_EN |
174 CEC_ERROR_IRQ_EN,
175 cec->regs + CEC_IRQ_CTRL);
176
177 } else {
178 /* Clear logical addresses */
179 writel(0, cec->regs + CEC_ADDR_TABLE);
180
181 /* Clear the status register */
182 writel(0x0, cec->regs + CEC_STATUS);
183
184 /* Disable the interrupts */
185 writel(0, cec->regs + CEC_IRQ_CTRL);
186 }
187
188 return 0;
189}
190
191static int stih_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
192{
193 struct stih_cec *cec = cec_get_drvdata(adap);
194 u32 reg = readl(cec->regs + CEC_ADDR_TABLE);
195
196 reg |= 1 << logical_addr;
197
198 if (logical_addr == CEC_LOG_ADDR_INVALID)
199 reg = 0;
200
201 writel(reg, cec->regs + CEC_ADDR_TABLE);
202
203 return 0;
204}
205
206static int stih_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
207 u32 signal_free_time, struct cec_msg *msg)
208{
209 struct stih_cec *cec = cec_get_drvdata(adap);
210 int i;
211
212 /* Copy message into registers */
213 for (i = 0; i < msg->len; i++)
214 writeb(msg->msg[i], cec->regs + CEC_TX_DATA_BASE + i);
215
216 /* Start transmission, configure hardware to add start and stop bits
217 * Signal free time is handled by the hardware
218 */
219 writel(CEC_TX_AUTO_SOM_EN | CEC_TX_AUTO_EOM_EN | CEC_TX_START |
220 msg->len, cec->regs + CEC_TX_ARRAY_CTRL);
221
222 return 0;
223}
224
225static void stih_tx_done(struct stih_cec *cec, u32 status)
226{
227 if (status & CEC_TX_ERROR) {
228 cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR, 0, 0, 0, 1);
229 return;
230 }
231
232 if (status & CEC_TX_ARB_ERROR) {
233 cec_transmit_done(cec->adap,
234 CEC_TX_STATUS_ARB_LOST, 1, 0, 0, 0);
235 return;
236 }
237
238 if (!(status & CEC_TX_ACK_GET_STS)) {
239 cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK, 0, 1, 0, 0);
240 return;
241 }
242
243 cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
244}
245
246static void stih_rx_done(struct stih_cec *cec, u32 status)
247{
248 struct cec_msg msg = {};
249 u8 i;
250
251 if (status & CEC_RX_ERROR_MIN)
252 return;
253
254 if (status & CEC_RX_ERROR_MAX)
255 return;
256
257 msg.len = readl(cec->regs + CEC_DATA_ARRAY_STATUS) & 0x1f;
258
259 if (!msg.len)
260 return;
261
262 if (msg.len > 16)
263 msg.len = 16;
264
265 for (i = 0; i < msg.len; i++)
266 msg.msg[i] = readl(cec->regs + CEC_RX_DATA_BASE + i);
267
268 cec_received_msg(cec->adap, &msg);
269}
270
271static irqreturn_t stih_cec_irq_handler_thread(int irq, void *priv)
272{
273 struct stih_cec *cec = priv;
274
275 if (cec->irq_status & CEC_TX_DONE_STS)
276 stih_tx_done(cec, cec->irq_status);
277
278 if (cec->irq_status & CEC_RX_DONE_STS)
279 stih_rx_done(cec, cec->irq_status);
280
281 cec->irq_status = 0;
282
283 return IRQ_HANDLED;
284}
285
286static irqreturn_t stih_cec_irq_handler(int irq, void *priv)
287{
288 struct stih_cec *cec = priv;
289
290 cec->irq_status = readl(cec->regs + CEC_STATUS);
291 writel(cec->irq_status, cec->regs + CEC_STATUS);
292
293 return IRQ_WAKE_THREAD;
294}
295
296static const struct cec_adap_ops sti_cec_adap_ops = {
297 .adap_enable = stih_cec_adap_enable,
298 .adap_log_addr = stih_cec_adap_log_addr,
299 .adap_transmit = stih_cec_adap_transmit,
300};
301
302static int stih_cec_probe(struct platform_device *pdev)
303{
304 struct device *dev = &pdev->dev;
305 struct resource *res;
306 struct stih_cec *cec;
307 struct device_node *np;
308 struct platform_device *hdmi_dev;
309 int ret;
310
311 cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
312 if (!cec)
313 return -ENOMEM;
314
315 np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0);
316
317 if (!np) {
318 dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n");
319 return -ENODEV;
320 }
321
322 hdmi_dev = of_find_device_by_node(np);
323 if (!hdmi_dev)
324 return -EPROBE_DEFER;
325
326 cec->notifier = cec_notifier_get(&hdmi_dev->dev);
327 if (!cec->notifier)
328 return -ENOMEM;
329
330 cec->dev = dev;
331
332 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
333 cec->regs = devm_ioremap_resource(dev, res);
334 if (IS_ERR(cec->regs))
335 return PTR_ERR(cec->regs);
336
337 cec->irq = platform_get_irq(pdev, 0);
338 if (cec->irq < 0)
339 return cec->irq;
340
341 ret = devm_request_threaded_irq(dev, cec->irq, stih_cec_irq_handler,
342 stih_cec_irq_handler_thread, 0,
343 pdev->name, cec);
344 if (ret)
345 return ret;
346
347 cec->clk = devm_clk_get(dev, "cec-clk");
348 if (IS_ERR(cec->clk)) {
349 dev_err(dev, "Cannot get cec clock\n");
350 return PTR_ERR(cec->clk);
351 }
352
353 cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec,
354 CEC_NAME,
355 CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH |
356 CEC_CAP_TRANSMIT, 1);
357 ret = PTR_ERR_OR_ZERO(cec->adap);
358 if (ret)
359 return ret;
360
361 ret = cec_register_adapter(cec->adap, &pdev->dev);
362 if (ret) {
363 cec_delete_adapter(cec->adap);
364 return ret;
365 }
366
367 cec_register_cec_notifier(cec->adap, cec->notifier);
368
369 platform_set_drvdata(pdev, cec);
370 return 0;
371}
372
373static int stih_cec_remove(struct platform_device *pdev)
374{
375 struct stih_cec *cec = platform_get_drvdata(pdev);
376
377 cec_unregister_adapter(cec->adap);
378 cec_notifier_put(cec->notifier);
379
380 return 0;
381}
382
383static const struct of_device_id stih_cec_match[] = {
384 {
385 .compatible = "st,stih-cec",
386 },
387 {},
388};
389MODULE_DEVICE_TABLE(of, stih_cec_match);
390
391static struct platform_driver stih_cec_pdrv = {
392 .probe = stih_cec_probe,
393 .remove = stih_cec_remove,
394 .driver = {
395 .name = CEC_NAME,
396 .of_match_table = stih_cec_match,
397 },
398};
399
400module_platform_driver(stih_cec_pdrv);
401
402MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@linaro.org>");
403MODULE_LICENSE("GPL");
404MODULE_DESCRIPTION("STIH4xx CEC driver");
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
index e79bdc611432..84ea43c0eb46 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
@@ -375,7 +375,7 @@ static int delta_mjpeg_decode(struct delta_ctx *pctx, struct delta_au *pau)
375 struct delta_mjpeg_ctx *ctx = to_ctx(pctx); 375 struct delta_mjpeg_ctx *ctx = to_ctx(pctx);
376 int ret; 376 int ret;
377 struct delta_au au = *pau; 377 struct delta_au au = *pau;
378 unsigned int data_offset; 378 unsigned int data_offset = 0;
379 struct mjpeg_header *header = &ctx->header_struct; 379 struct mjpeg_header *header = &ctx->header_struct;
380 380
381 if (!ctx->header) { 381 if (!ctx->header) {
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 23472e3784ff..e2cf2b90e500 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -801,17 +801,17 @@ static void dump_dtd(struct vpdma_dtd *dtd)
801 * flags: VPDMA flags to configure some descriptor fileds 801 * flags: VPDMA flags to configure some descriptor fileds
802 */ 802 */
803void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, 803void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
804 const struct v4l2_rect *c_rect, 804 int stride, const struct v4l2_rect *c_rect,
805 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 805 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
806 int max_w, int max_h, enum vpdma_channel chan, u32 flags) 806 int max_w, int max_h, enum vpdma_channel chan, u32 flags)
807{ 807{
808 vpdma_rawchan_add_out_dtd(list, width, c_rect, fmt, dma_addr, 808 vpdma_rawchan_add_out_dtd(list, width, stride, c_rect, fmt, dma_addr,
809 max_w, max_h, chan_info[chan].num, flags); 809 max_w, max_h, chan_info[chan].num, flags);
810} 810}
811EXPORT_SYMBOL(vpdma_add_out_dtd); 811EXPORT_SYMBOL(vpdma_add_out_dtd);
812 812
813void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, 813void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
814 const struct v4l2_rect *c_rect, 814 int stride, const struct v4l2_rect *c_rect,
815 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 815 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
816 int max_w, int max_h, int raw_vpdma_chan, u32 flags) 816 int max_w, int max_h, int raw_vpdma_chan, u32 flags)
817{ 817{
@@ -821,7 +821,6 @@ void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
821 int channel, next_chan; 821 int channel, next_chan;
822 struct v4l2_rect rect = *c_rect; 822 struct v4l2_rect rect = *c_rect;
823 int depth = fmt->depth; 823 int depth = fmt->depth;
824 int stride;
825 struct vpdma_dtd *dtd; 824 struct vpdma_dtd *dtd;
826 825
827 channel = next_chan = raw_vpdma_chan; 826 channel = next_chan = raw_vpdma_chan;
@@ -833,8 +832,6 @@ void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
833 depth = 8; 832 depth = 8;
834 } 833 }
835 834
836 stride = ALIGN((depth * width) >> 3, VPDMA_STRIDE_ALIGN);
837
838 dma_addr += rect.top * stride + (rect.left * depth >> 3); 835 dma_addr += rect.top * stride + (rect.left * depth >> 3);
839 836
840 dtd = list->next; 837 dtd = list->next;
@@ -882,7 +879,7 @@ EXPORT_SYMBOL(vpdma_rawchan_add_out_dtd);
882 * contribute to the client) 879 * contribute to the client)
883 */ 880 */
884void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, 881void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
885 const struct v4l2_rect *c_rect, 882 int stride, const struct v4l2_rect *c_rect,
886 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 883 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
887 enum vpdma_channel chan, int field, u32 flags, int frame_width, 884 enum vpdma_channel chan, int field, u32 flags, int frame_width,
888 int frame_height, int start_h, int start_v) 885 int frame_height, int start_h, int start_v)
@@ -892,7 +889,6 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
892 int depth = fmt->depth; 889 int depth = fmt->depth;
893 int channel, next_chan; 890 int channel, next_chan;
894 struct v4l2_rect rect = *c_rect; 891 struct v4l2_rect rect = *c_rect;
895 int stride;
896 struct vpdma_dtd *dtd; 892 struct vpdma_dtd *dtd;
897 893
898 channel = next_chan = chan_info[chan].num; 894 channel = next_chan = chan_info[chan].num;
@@ -904,8 +900,6 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
904 depth = 8; 900 depth = 8;
905 } 901 }
906 902
907 stride = ALIGN((depth * width) >> 3, VPDMA_STRIDE_ALIGN);
908
909 dma_addr += rect.top * stride + (rect.left * depth >> 3); 903 dma_addr += rect.top * stride + (rect.left * depth >> 3);
910 904
911 dtd = list->next; 905 dtd = list->next;
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index 131700c112b2..7e611501c291 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -242,16 +242,16 @@ void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
242void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list, 242void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
243 int chan_num); 243 int chan_num);
244void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, 244void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
245 const struct v4l2_rect *c_rect, 245 int stride, const struct v4l2_rect *c_rect,
246 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 246 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
247 int max_w, int max_h, enum vpdma_channel chan, u32 flags); 247 int max_w, int max_h, enum vpdma_channel chan, u32 flags);
248void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width, 248void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
249 const struct v4l2_rect *c_rect, 249 int stride, const struct v4l2_rect *c_rect,
250 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 250 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
251 int max_w, int max_h, int raw_vpdma_chan, u32 flags); 251 int max_w, int max_h, int raw_vpdma_chan, u32 flags);
252 252
253void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, 253void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
254 const struct v4l2_rect *c_rect, 254 int stride, const struct v4l2_rect *c_rect,
255 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 255 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
256 enum vpdma_channel chan, int field, u32 flags, int frame_width, 256 enum vpdma_channel chan, int field, u32 flags, int frame_width,
257 int frame_height, int start_h, int start_v); 257 int frame_height, int start_h, int start_v);
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index f0156b7759e9..c47151495b6f 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -1085,7 +1085,8 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
1085 vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1, 1085 vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1,
1086 MAX_W, MAX_H); 1086 MAX_W, MAX_H);
1087 1087
1088 vpdma_add_out_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect, 1088 vpdma_add_out_dtd(&ctx->desc_list, q_data->width,
1089 q_data->bytesperline[VPE_LUMA], &q_data->c_rect,
1089 vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1, 1090 vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1,
1090 MAX_OUT_HEIGHT_REG1, p_data->channel, flags); 1091 MAX_OUT_HEIGHT_REG1, p_data->channel, flags);
1091} 1092}
@@ -1169,7 +1170,8 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
1169 if (p_data->vb_part && fmt->fourcc == V4L2_PIX_FMT_NV12) 1170 if (p_data->vb_part && fmt->fourcc == V4L2_PIX_FMT_NV12)
1170 frame_height /= 2; 1171 frame_height /= 2;
1171 1172
1172 vpdma_add_in_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect, 1173 vpdma_add_in_dtd(&ctx->desc_list, q_data->width,
1174 q_data->bytesperline[VPE_LUMA], &q_data->c_rect,
1173 vpdma_fmt, dma_addr, p_data->channel, field, flags, frame_width, 1175 vpdma_fmt, dma_addr, p_data->channel, field, flags, frame_width,
1174 frame_height, 0, 0); 1176 frame_height, 0, 0);
1175} 1177}
@@ -1595,6 +1597,7 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1595 struct v4l2_plane_pix_format *plane_fmt; 1597 struct v4l2_plane_pix_format *plane_fmt;
1596 unsigned int w_align; 1598 unsigned int w_align;
1597 int i, depth, depth_bytes, height; 1599 int i, depth, depth_bytes, height;
1600 unsigned int stride = 0;
1598 1601
1599 if (!fmt || !(fmt->types & type)) { 1602 if (!fmt || !(fmt->types & type)) {
1600 vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", 1603 vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
@@ -1681,16 +1684,27 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1681 plane_fmt = &pix->plane_fmt[i]; 1684 plane_fmt = &pix->plane_fmt[i];
1682 depth = fmt->vpdma_fmt[i]->depth; 1685 depth = fmt->vpdma_fmt[i]->depth;
1683 1686
1684 if (i == VPE_LUMA) 1687 stride = (pix->width * fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
1685 plane_fmt->bytesperline = (pix->width * depth) >> 3; 1688 if (stride > plane_fmt->bytesperline)
1686 else 1689 plane_fmt->bytesperline = stride;
1687 plane_fmt->bytesperline = pix->width; 1690
1691 plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline,
1692 VPDMA_STRIDE_ALIGN);
1688 1693
1689 if (pix->num_planes == 1 && fmt->coplanar) 1694 if (i == VPE_LUMA) {
1690 depth += fmt->vpdma_fmt[VPE_CHROMA]->depth; 1695 plane_fmt->sizeimage = pix->height *
1691 plane_fmt->sizeimage = 1696 plane_fmt->bytesperline;
1692 (pix->height * pix->width * depth) >> 3;
1693 1697
1698 if (pix->num_planes == 1 && fmt->coplanar)
1699 plane_fmt->sizeimage += pix->height *
1700 plane_fmt->bytesperline *
1701 fmt->vpdma_fmt[VPE_CHROMA]->depth >> 3;
1702
1703 } else { /* i == VIP_CHROMA */
1704 plane_fmt->sizeimage = (pix->height *
1705 plane_fmt->bytesperline *
1706 depth) >> 3;
1707 }
1694 memset(plane_fmt->reserved, 0, sizeof(plane_fmt->reserved)); 1708 memset(plane_fmt->reserved, 0, sizeof(plane_fmt->reserved));
1695 } 1709 }
1696 1710
diff --git a/drivers/media/platform/vimc/Kconfig b/drivers/media/platform/vimc/Kconfig
new file mode 100644
index 000000000000..a18f6352c422
--- /dev/null
+++ b/drivers/media/platform/vimc/Kconfig
@@ -0,0 +1,14 @@
1config VIDEO_VIMC
2 tristate "Virtual Media Controller Driver (VIMC)"
3 depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
4 select VIDEOBUF2_VMALLOC
5 default n
6 ---help---
7 Skeleton driver for Virtual Media Controller
8
9 This driver can be compared to the vivid driver for emulating
10 a media node that exposes a complex media topology. The topology
11 is hard coded for now but is meant to be highly configurable in
12 the future.
13
14 When in doubt, say N.
diff --git a/drivers/media/platform/vimc/Makefile b/drivers/media/platform/vimc/Makefile
new file mode 100644
index 000000000000..c45195e5e05c
--- /dev/null
+++ b/drivers/media/platform/vimc/Makefile
@@ -0,0 +1,3 @@
1vimc-objs := vimc-core.o vimc-capture.o vimc-sensor.o
2
3obj-$(CONFIG_VIDEO_VIMC) += vimc.o
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
new file mode 100644
index 000000000000..9adb06d7e13d
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -0,0 +1,498 @@
1/*
2 * vimc-capture.c Virtual Media Controller Driver
3 *
4 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <media/v4l2-ioctl.h>
19#include <media/videobuf2-core.h>
20#include <media/videobuf2-vmalloc.h>
21
22#include "vimc-capture.h"
23
24struct vimc_cap_device {
25 struct vimc_ent_device ved;
26 struct video_device vdev;
27 struct v4l2_pix_format format;
28 struct vb2_queue queue;
29 struct list_head buf_list;
30 /*
31 * NOTE: in a real driver, a spin lock must be used to access the
32 * queue because the frames are generated from a hardware interruption
33 * and the isr is not allowed to sleep.
34 * Even if it is not necessary a spinlock in the vimc driver, we
35 * use it here as a code reference
36 */
37 spinlock_t qlock;
38 struct mutex lock;
39 u32 sequence;
40 struct media_pipeline pipe;
41};
42
43struct vimc_cap_buffer {
44 /*
45 * struct vb2_v4l2_buffer must be the first element
46 * the videobuf2 framework will allocate this struct based on
47 * buf_struct_size and use the first sizeof(struct vb2_buffer) bytes of
48 * memory as a vb2_buffer
49 */
50 struct vb2_v4l2_buffer vb2;
51 struct list_head list;
52};
53
54static int vimc_cap_querycap(struct file *file, void *priv,
55 struct v4l2_capability *cap)
56{
57 struct vimc_cap_device *vcap = video_drvdata(file);
58
59 strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
60 strlcpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
61 snprintf(cap->bus_info, sizeof(cap->bus_info),
62 "platform:%s", vcap->vdev.v4l2_dev->name);
63
64 return 0;
65}
66
67static int vimc_cap_fmt_vid_cap(struct file *file, void *priv,
68 struct v4l2_format *f)
69{
70 struct vimc_cap_device *vcap = video_drvdata(file);
71
72 f->fmt.pix = vcap->format;
73
74 return 0;
75}
76
77static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
78 struct v4l2_fmtdesc *f)
79{
80 struct vimc_cap_device *vcap = video_drvdata(file);
81
82 if (f->index > 0)
83 return -EINVAL;
84
85 /* We only support one format for now */
86 f->pixelformat = vcap->format.pixelformat;
87
88 return 0;
89}
90
91static const struct v4l2_file_operations vimc_cap_fops = {
92 .owner = THIS_MODULE,
93 .open = v4l2_fh_open,
94 .release = vb2_fop_release,
95 .read = vb2_fop_read,
96 .poll = vb2_fop_poll,
97 .unlocked_ioctl = video_ioctl2,
98 .mmap = vb2_fop_mmap,
99};
100
101static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
102 .vidioc_querycap = vimc_cap_querycap,
103
104 .vidioc_g_fmt_vid_cap = vimc_cap_fmt_vid_cap,
105 .vidioc_s_fmt_vid_cap = vimc_cap_fmt_vid_cap,
106 .vidioc_try_fmt_vid_cap = vimc_cap_fmt_vid_cap,
107 .vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
108
109 .vidioc_reqbufs = vb2_ioctl_reqbufs,
110 .vidioc_create_bufs = vb2_ioctl_create_bufs,
111 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
112 .vidioc_querybuf = vb2_ioctl_querybuf,
113 .vidioc_qbuf = vb2_ioctl_qbuf,
114 .vidioc_dqbuf = vb2_ioctl_dqbuf,
115 .vidioc_expbuf = vb2_ioctl_expbuf,
116 .vidioc_streamon = vb2_ioctl_streamon,
117 .vidioc_streamoff = vb2_ioctl_streamoff,
118};
119
120static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap,
121 enum vb2_buffer_state state)
122{
123 struct vimc_cap_buffer *vbuf, *node;
124
125 spin_lock(&vcap->qlock);
126
127 list_for_each_entry_safe(vbuf, node, &vcap->buf_list, list) {
128 list_del(&vbuf->list);
129 vb2_buffer_done(&vbuf->vb2.vb2_buf, state);
130 }
131
132 spin_unlock(&vcap->qlock);
133}
134
135static int vimc_cap_pipeline_s_stream(struct vimc_cap_device *vcap, int enable)
136{
137 struct v4l2_subdev *sd;
138 struct media_pad *pad;
139 int ret;
140
141 /* Start the stream in the subdevice direct connected */
142 pad = media_entity_remote_pad(&vcap->vdev.entity.pads[0]);
143
144 /*
145 * if it is a raw node from vimc-core, there is nothing to activate
146 * TODO: remove this when there are no more raw nodes in the
147 * core and return error instead
148 */
149 if (pad->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
150 return 0;
151
152 sd = media_entity_to_v4l2_subdev(pad->entity);
153 ret = v4l2_subdev_call(sd, video, s_stream, enable);
154 if (ret && ret != -ENOIOCTLCMD)
155 return ret;
156
157 return 0;
158}
159
160static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
161{
162 struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
163 struct media_entity *entity = &vcap->vdev.entity;
164 int ret;
165
166 vcap->sequence = 0;
167
168 /* Start the media pipeline */
169 ret = media_pipeline_start(entity, &vcap->pipe);
170 if (ret) {
171 vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
172 return ret;
173 }
174
175 /* Enable streaming from the pipe */
176 ret = vimc_cap_pipeline_s_stream(vcap, 1);
177 if (ret) {
178 media_pipeline_stop(entity);
179 vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
180 return ret;
181 }
182
183 return 0;
184}
185
186/*
187 * Stop the stream engine. Any remaining buffers in the stream queue are
188 * dequeued and passed on to the vb2 framework marked as STATE_ERROR.
189 */
190static void vimc_cap_stop_streaming(struct vb2_queue *vq)
191{
192 struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
193
194 /* Disable streaming from the pipe */
195 vimc_cap_pipeline_s_stream(vcap, 0);
196
197 /* Stop the media pipeline */
198 media_pipeline_stop(&vcap->vdev.entity);
199
200 /* Release all active buffers */
201 vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_ERROR);
202}
203
204static void vimc_cap_buf_queue(struct vb2_buffer *vb2_buf)
205{
206 struct vimc_cap_device *vcap = vb2_get_drv_priv(vb2_buf->vb2_queue);
207 struct vimc_cap_buffer *buf = container_of(vb2_buf,
208 struct vimc_cap_buffer,
209 vb2.vb2_buf);
210
211 spin_lock(&vcap->qlock);
212 list_add_tail(&buf->list, &vcap->buf_list);
213 spin_unlock(&vcap->qlock);
214}
215
216static int vimc_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
217 unsigned int *nplanes, unsigned int sizes[],
218 struct device *alloc_devs[])
219{
220 struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
221
222 if (*nplanes)
223 return sizes[0] < vcap->format.sizeimage ? -EINVAL : 0;
224 /* We don't support multiplanes for now */
225 *nplanes = 1;
226 sizes[0] = vcap->format.sizeimage;
227
228 return 0;
229}
230
231static int vimc_cap_buffer_prepare(struct vb2_buffer *vb)
232{
233 struct vimc_cap_device *vcap = vb2_get_drv_priv(vb->vb2_queue);
234 unsigned long size = vcap->format.sizeimage;
235
236 if (vb2_plane_size(vb, 0) < size) {
237 dev_err(vcap->vdev.v4l2_dev->dev,
238 "%s: buffer too small (%lu < %lu)\n",
239 vcap->vdev.name, vb2_plane_size(vb, 0), size);
240 return -EINVAL;
241 }
242 return 0;
243}
244
245static const struct vb2_ops vimc_cap_qops = {
246 .start_streaming = vimc_cap_start_streaming,
247 .stop_streaming = vimc_cap_stop_streaming,
248 .buf_queue = vimc_cap_buf_queue,
249 .queue_setup = vimc_cap_queue_setup,
250 .buf_prepare = vimc_cap_buffer_prepare,
251 /*
252 * Since q->lock is set we can use the standard
253 * vb2_ops_wait_prepare/finish helper functions.
254 */
255 .wait_prepare = vb2_ops_wait_prepare,
256 .wait_finish = vb2_ops_wait_finish,
257};
258
259/*
260 * NOTE: this function is a copy of v4l2_subdev_link_validate_get_format
261 * maybe the v4l2 function should be public
262 */
263static int vimc_cap_v4l2_subdev_link_validate_get_format(struct media_pad *pad,
264 struct v4l2_subdev_format *fmt)
265{
266 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(pad->entity);
267
268 fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
269 fmt->pad = pad->index;
270
271 return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
272}
273
274static int vimc_cap_link_validate(struct media_link *link)
275{
276 struct v4l2_subdev_format source_fmt;
277 const struct vimc_pix_map *vpix;
278 struct vimc_cap_device *vcap = container_of(link->sink->entity,
279 struct vimc_cap_device,
280 vdev.entity);
281 struct v4l2_pix_format *sink_fmt = &vcap->format;
282 int ret;
283
284 /*
285 * if it is a raw node from vimc-core, ignore the link for now
286 * TODO: remove this when there are no more raw nodes in the
287 * core and return error instead
288 */
289 if (link->source->entity->obj_type == MEDIA_ENTITY_TYPE_BASE)
290 return 0;
291
292 /* Get the the format of the subdev */
293 ret = vimc_cap_v4l2_subdev_link_validate_get_format(link->source,
294 &source_fmt);
295 if (ret)
296 return ret;
297
298 dev_dbg(vcap->vdev.v4l2_dev->dev,
299 "%s: link validate formats src:%dx%d %d sink:%dx%d %d\n",
300 vcap->vdev.name,
301 source_fmt.format.width, source_fmt.format.height,
302 source_fmt.format.code,
303 sink_fmt->width, sink_fmt->height,
304 sink_fmt->pixelformat);
305
306 /* The width, height and code must match. */
307 vpix = vimc_pix_map_by_pixelformat(sink_fmt->pixelformat);
308 if (source_fmt.format.width != sink_fmt->width
309 || source_fmt.format.height != sink_fmt->height
310 || vpix->code != source_fmt.format.code)
311 return -EPIPE;
312
313 /*
314 * The field order must match, or the sink field order must be NONE
315 * to support interlaced hardware connected to bridges that support
316 * progressive formats only.
317 */
318 if (source_fmt.format.field != sink_fmt->field &&
319 sink_fmt->field != V4L2_FIELD_NONE)
320 return -EPIPE;
321
322 return 0;
323}
324
325static const struct media_entity_operations vimc_cap_mops = {
326 .link_validate = vimc_cap_link_validate,
327};
328
329static void vimc_cap_destroy(struct vimc_ent_device *ved)
330{
331 struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
332 ved);
333
334 vb2_queue_release(&vcap->queue);
335 media_entity_cleanup(ved->ent);
336 video_unregister_device(&vcap->vdev);
337 vimc_pads_cleanup(vcap->ved.pads);
338 kfree(vcap);
339}
340
341static void vimc_cap_process_frame(struct vimc_ent_device *ved,
342 struct media_pad *sink, const void *frame)
343{
344 struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
345 ved);
346 struct vimc_cap_buffer *vimc_buf;
347 void *vbuf;
348
349 spin_lock(&vcap->qlock);
350
351 /* Get the first entry of the list */
352 vimc_buf = list_first_entry_or_null(&vcap->buf_list,
353 typeof(*vimc_buf), list);
354 if (!vimc_buf) {
355 spin_unlock(&vcap->qlock);
356 return;
357 }
358
359 /* Remove this entry from the list */
360 list_del(&vimc_buf->list);
361
362 spin_unlock(&vcap->qlock);
363
364 /* Fill the buffer */
365 vimc_buf->vb2.vb2_buf.timestamp = ktime_get_ns();
366 vimc_buf->vb2.sequence = vcap->sequence++;
367 vimc_buf->vb2.field = vcap->format.field;
368
369 vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
370
371 memcpy(vbuf, frame, vcap->format.sizeimage);
372
373 /* Set it as ready */
374 vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
375 vcap->format.sizeimage);
376 vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE);
377}
378
379struct vimc_ent_device *vimc_cap_create(struct v4l2_device *v4l2_dev,
380 const char *const name,
381 u16 num_pads,
382 const unsigned long *pads_flag)
383{
384 const struct vimc_pix_map *vpix;
385 struct vimc_cap_device *vcap;
386 struct video_device *vdev;
387 struct vb2_queue *q;
388 int ret;
389
390 /*
391 * Check entity configuration params
392 * NOTE: we only support a single sink pad
393 */
394 if (!name || num_pads != 1 || !pads_flag ||
395 !(pads_flag[0] & MEDIA_PAD_FL_SINK))
396 return ERR_PTR(-EINVAL);
397
398 /* Allocate the vimc_cap_device struct */
399 vcap = kzalloc(sizeof(*vcap), GFP_KERNEL);
400 if (!vcap)
401 return ERR_PTR(-ENOMEM);
402
403 /* Allocate the pads */
404 vcap->ved.pads = vimc_pads_init(num_pads, pads_flag);
405 if (IS_ERR(vcap->ved.pads)) {
406 ret = PTR_ERR(vcap->ved.pads);
407 goto err_free_vcap;
408 }
409
410 /* Initialize the media entity */
411 vcap->vdev.entity.name = name;
412 vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
413 ret = media_entity_pads_init(&vcap->vdev.entity,
414 num_pads, vcap->ved.pads);
415 if (ret)
416 goto err_clean_pads;
417
418 /* Initialize the lock */
419 mutex_init(&vcap->lock);
420
421 /* Initialize the vb2 queue */
422 q = &vcap->queue;
423 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
424 q->io_modes = VB2_MMAP | VB2_DMABUF;
425 q->drv_priv = vcap;
426 q->buf_struct_size = sizeof(struct vimc_cap_buffer);
427 q->ops = &vimc_cap_qops;
428 q->mem_ops = &vb2_vmalloc_memops;
429 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
430 q->min_buffers_needed = 2;
431 q->lock = &vcap->lock;
432
433 ret = vb2_queue_init(q);
434 if (ret) {
435 dev_err(vcap->vdev.v4l2_dev->dev,
436 "%s: vb2 queue init failed (err=%d)\n",
437 vcap->vdev.name, ret);
438 goto err_clean_m_ent;
439 }
440
441 /* Initialize buffer list and its lock */
442 INIT_LIST_HEAD(&vcap->buf_list);
443 spin_lock_init(&vcap->qlock);
444
445 /* Set the frame format (this is hardcoded for now) */
446 vcap->format.width = 640;
447 vcap->format.height = 480;
448 vcap->format.pixelformat = V4L2_PIX_FMT_RGB24;
449 vcap->format.field = V4L2_FIELD_NONE;
450 vcap->format.colorspace = V4L2_COLORSPACE_SRGB;
451
452 vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat);
453
454 vcap->format.bytesperline = vcap->format.width * vpix->bpp;
455 vcap->format.sizeimage = vcap->format.bytesperline *
456 vcap->format.height;
457
458 /* Fill the vimc_ent_device struct */
459 vcap->ved.destroy = vimc_cap_destroy;
460 vcap->ved.ent = &vcap->vdev.entity;
461 vcap->ved.process_frame = vimc_cap_process_frame;
462
463 /* Initialize the video_device struct */
464 vdev = &vcap->vdev;
465 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
466 vdev->entity.ops = &vimc_cap_mops;
467 vdev->release = video_device_release_empty;
468 vdev->fops = &vimc_cap_fops;
469 vdev->ioctl_ops = &vimc_cap_ioctl_ops;
470 vdev->lock = &vcap->lock;
471 vdev->queue = q;
472 vdev->v4l2_dev = v4l2_dev;
473 vdev->vfl_dir = VFL_DIR_RX;
474 strlcpy(vdev->name, name, sizeof(vdev->name));
475 video_set_drvdata(vdev, &vcap->ved);
476
477 /* Register the video_device with the v4l2 and the media framework */
478 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
479 if (ret) {
480 dev_err(vcap->vdev.v4l2_dev->dev,
481 "%s: video register failed (err=%d)\n",
482 vcap->vdev.name, ret);
483 goto err_release_queue;
484 }
485
486 return &vcap->ved;
487
488err_release_queue:
489 vb2_queue_release(q);
490err_clean_m_ent:
491 media_entity_cleanup(&vcap->vdev.entity);
492err_clean_pads:
493 vimc_pads_cleanup(vcap->ved.pads);
494err_free_vcap:
495 kfree(vcap);
496
497 return ERR_PTR(ret);
498}
diff --git a/drivers/media/platform/vimc/vimc-capture.h b/drivers/media/platform/vimc/vimc-capture.h
new file mode 100644
index 000000000000..581a813abdf1
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-capture.h
@@ -0,0 +1,28 @@
1/*
2 * vimc-capture.h Virtual Media Controller Driver
3 *
4 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef _VIMC_CAPTURE_H_
19#define _VIMC_CAPTURE_H_
20
21#include "vimc-core.h"
22
23struct vimc_ent_device *vimc_cap_create(struct v4l2_device *v4l2_dev,
24 const char *const name,
25 u16 num_pads,
26 const unsigned long *pads_flag);
27
28#endif
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
new file mode 100644
index 000000000000..bc107da8fbd5
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-core.c
@@ -0,0 +1,695 @@
1/*
2 * vimc-core.c Virtual Media Controller Driver
3 *
4 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <media/media-device.h>
22#include <media/v4l2-device.h>
23
24#include "vimc-capture.h"
25#include "vimc-core.h"
26#include "vimc-sensor.h"
27
28#define VIMC_PDEV_NAME "vimc"
29#define VIMC_MDEV_MODEL_NAME "VIMC MDEV"
30
31#define VIMC_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) { \
32 .src_ent = src, \
33 .src_pad = srcpad, \
34 .sink_ent = sink, \
35 .sink_pad = sinkpad, \
36 .flags = link_flags, \
37}
38
39struct vimc_device {
40 /*
41 * The pipeline configuration
42 * (filled before calling vimc_device_register)
43 */
44 const struct vimc_pipeline_config *pipe_cfg;
45
46 /* The Associated media_device parent */
47 struct media_device mdev;
48
49 /* Internal v4l2 parent device*/
50 struct v4l2_device v4l2_dev;
51
52 /* Internal topology */
53 struct vimc_ent_device **ved;
54};
55
56/**
57 * enum vimc_ent_node - Select the functionality of a node in the topology
58 * @VIMC_ENT_NODE_SENSOR: A node of type SENSOR simulates a camera sensor
59 * generating internal images in bayer format and
60 * propagating those images through the pipeline
61 * @VIMC_ENT_NODE_CAPTURE: A node of type CAPTURE is a v4l2 video_device
62 * that exposes the received image from the
63 * pipeline to the user space
64 * @VIMC_ENT_NODE_INPUT: A node of type INPUT is a v4l2 video_device that
65 * receives images from the user space and
66 * propagates them through the pipeline
67 * @VIMC_ENT_NODE_DEBAYER: A node type DEBAYER expects to receive a frame
68 * in bayer format converts it to RGB
69 * @VIMC_ENT_NODE_SCALER: A node of type SCALER scales the received image
70 * by a given multiplier
71 *
72 * This enum is used in the entity configuration struct to allow the definition
73 * of a custom topology specifying the role of each node on it.
74 */
75enum vimc_ent_node {
76 VIMC_ENT_NODE_SENSOR,
77 VIMC_ENT_NODE_CAPTURE,
78 VIMC_ENT_NODE_INPUT,
79 VIMC_ENT_NODE_DEBAYER,
80 VIMC_ENT_NODE_SCALER,
81};
82
83/* Structure which describes individual configuration for each entity */
84struct vimc_ent_config {
85 const char *name;
86 size_t pads_qty;
87 const unsigned long *pads_flag;
88 enum vimc_ent_node node;
89};
90
91/* Structure which describes links between entities */
92struct vimc_ent_link {
93 unsigned int src_ent;
94 u16 src_pad;
95 unsigned int sink_ent;
96 u16 sink_pad;
97 u32 flags;
98};
99
100/* Structure which describes the whole topology */
101struct vimc_pipeline_config {
102 const struct vimc_ent_config *ents;
103 size_t num_ents;
104 const struct vimc_ent_link *links;
105 size_t num_links;
106};
107
108/* --------------------------------------------------------------------------
109 * Topology Configuration
110 */
111
112static const struct vimc_ent_config ent_config[] = {
113 {
114 .name = "Sensor A",
115 .pads_qty = 1,
116 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SOURCE},
117 .node = VIMC_ENT_NODE_SENSOR,
118 },
119 {
120 .name = "Sensor B",
121 .pads_qty = 1,
122 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SOURCE},
123 .node = VIMC_ENT_NODE_SENSOR,
124 },
125 {
126 .name = "Debayer A",
127 .pads_qty = 2,
128 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SINK,
129 MEDIA_PAD_FL_SOURCE},
130 .node = VIMC_ENT_NODE_DEBAYER,
131 },
132 {
133 .name = "Debayer B",
134 .pads_qty = 2,
135 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SINK,
136 MEDIA_PAD_FL_SOURCE},
137 .node = VIMC_ENT_NODE_DEBAYER,
138 },
139 {
140 .name = "Raw Capture 0",
141 .pads_qty = 1,
142 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SINK},
143 .node = VIMC_ENT_NODE_CAPTURE,
144 },
145 {
146 .name = "Raw Capture 1",
147 .pads_qty = 1,
148 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SINK},
149 .node = VIMC_ENT_NODE_CAPTURE,
150 },
151 {
152 .name = "RGB/YUV Input",
153 .pads_qty = 1,
154 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SOURCE},
155 .node = VIMC_ENT_NODE_INPUT,
156 },
157 {
158 .name = "Scaler",
159 .pads_qty = 2,
160 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SINK,
161 MEDIA_PAD_FL_SOURCE},
162 .node = VIMC_ENT_NODE_SCALER,
163 },
164 {
165 .name = "RGB/YUV Capture",
166 .pads_qty = 1,
167 .pads_flag = (const unsigned long[]){MEDIA_PAD_FL_SINK},
168 .node = VIMC_ENT_NODE_CAPTURE,
169 },
170};
171
172static const struct vimc_ent_link ent_links[] = {
173 /* Link: Sensor A (Pad 0)->(Pad 0) Debayer A */
174 VIMC_ENT_LINK(0, 0, 2, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
175 /* Link: Sensor A (Pad 0)->(Pad 0) Raw Capture 0 */
176 VIMC_ENT_LINK(0, 0, 4, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
177 /* Link: Sensor B (Pad 0)->(Pad 0) Debayer B */
178 VIMC_ENT_LINK(1, 0, 3, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
179 /* Link: Sensor B (Pad 0)->(Pad 0) Raw Capture 1 */
180 VIMC_ENT_LINK(1, 0, 5, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
181 /* Link: Debayer A (Pad 1)->(Pad 0) Scaler */
182 VIMC_ENT_LINK(2, 1, 7, 0, MEDIA_LNK_FL_ENABLED),
183 /* Link: Debayer B (Pad 1)->(Pad 0) Scaler */
184 VIMC_ENT_LINK(3, 1, 7, 0, 0),
185 /* Link: RGB/YUV Input (Pad 0)->(Pad 0) Scaler */
186 VIMC_ENT_LINK(6, 0, 7, 0, 0),
187 /* Link: Scaler (Pad 1)->(Pad 0) RGB/YUV Capture */
188 VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
189};
190
191static const struct vimc_pipeline_config pipe_cfg = {
192 .ents = ent_config,
193 .num_ents = ARRAY_SIZE(ent_config),
194 .links = ent_links,
195 .num_links = ARRAY_SIZE(ent_links)
196};
197
198/* -------------------------------------------------------------------------- */
199
200static const struct vimc_pix_map vimc_pix_map_list[] = {
201 /* TODO: add all missing formats */
202
203 /* RGB formats */
204 {
205 .code = MEDIA_BUS_FMT_BGR888_1X24,
206 .pixelformat = V4L2_PIX_FMT_BGR24,
207 .bpp = 3,
208 },
209 {
210 .code = MEDIA_BUS_FMT_RGB888_1X24,
211 .pixelformat = V4L2_PIX_FMT_RGB24,
212 .bpp = 3,
213 },
214 {
215 .code = MEDIA_BUS_FMT_ARGB8888_1X32,
216 .pixelformat = V4L2_PIX_FMT_ARGB32,
217 .bpp = 4,
218 },
219
220 /* Bayer formats */
221 {
222 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
223 .pixelformat = V4L2_PIX_FMT_SBGGR8,
224 .bpp = 1,
225 },
226 {
227 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
228 .pixelformat = V4L2_PIX_FMT_SGBRG8,
229 .bpp = 1,
230 },
231 {
232 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
233 .pixelformat = V4L2_PIX_FMT_SGRBG8,
234 .bpp = 1,
235 },
236 {
237 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
238 .pixelformat = V4L2_PIX_FMT_SRGGB8,
239 .bpp = 1,
240 },
241 {
242 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
243 .pixelformat = V4L2_PIX_FMT_SBGGR10,
244 .bpp = 2,
245 },
246 {
247 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
248 .pixelformat = V4L2_PIX_FMT_SGBRG10,
249 .bpp = 2,
250 },
251 {
252 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
253 .pixelformat = V4L2_PIX_FMT_SGRBG10,
254 .bpp = 2,
255 },
256 {
257 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
258 .pixelformat = V4L2_PIX_FMT_SRGGB10,
259 .bpp = 2,
260 },
261
262 /* 10bit raw bayer a-law compressed to 8 bits */
263 {
264 .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
265 .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
266 .bpp = 1,
267 },
268 {
269 .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
270 .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
271 .bpp = 1,
272 },
273 {
274 .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
275 .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
276 .bpp = 1,
277 },
278 {
279 .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
280 .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
281 .bpp = 1,
282 },
283
284 /* 10bit raw bayer DPCM compressed to 8 bits */
285 {
286 .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
287 .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
288 .bpp = 1,
289 },
290 {
291 .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
292 .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
293 .bpp = 1,
294 },
295 {
296 .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
297 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
298 .bpp = 1,
299 },
300 {
301 .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
302 .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
303 .bpp = 1,
304 },
305 {
306 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
307 .pixelformat = V4L2_PIX_FMT_SBGGR12,
308 .bpp = 2,
309 },
310 {
311 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
312 .pixelformat = V4L2_PIX_FMT_SGBRG12,
313 .bpp = 2,
314 },
315 {
316 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
317 .pixelformat = V4L2_PIX_FMT_SGRBG12,
318 .bpp = 2,
319 },
320 {
321 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
322 .pixelformat = V4L2_PIX_FMT_SRGGB12,
323 .bpp = 2,
324 },
325};
326
327const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
328{
329 unsigned int i;
330
331 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
332 if (vimc_pix_map_list[i].code == code)
333 return &vimc_pix_map_list[i];
334 }
335 return NULL;
336}
337
338const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
339{
340 unsigned int i;
341
342 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
343 if (vimc_pix_map_list[i].pixelformat == pixelformat)
344 return &vimc_pix_map_list[i];
345 }
346 return NULL;
347}
348
349int vimc_propagate_frame(struct media_pad *src, const void *frame)
350{
351 struct media_link *link;
352
353 if (!(src->flags & MEDIA_PAD_FL_SOURCE))
354 return -EINVAL;
355
356 /* Send this frame to all sink pads that are direct linked */
357 list_for_each_entry(link, &src->entity->links, list) {
358 if (link->source == src &&
359 (link->flags & MEDIA_LNK_FL_ENABLED)) {
360 struct vimc_ent_device *ved = NULL;
361 struct media_entity *entity = link->sink->entity;
362
363 if (is_media_entity_v4l2_subdev(entity)) {
364 struct v4l2_subdev *sd =
365 container_of(entity, struct v4l2_subdev,
366 entity);
367 ved = v4l2_get_subdevdata(sd);
368 } else if (is_media_entity_v4l2_video_device(entity)) {
369 struct video_device *vdev =
370 container_of(entity,
371 struct video_device,
372 entity);
373 ved = video_get_drvdata(vdev);
374 }
375 if (ved && ved->process_frame)
376 ved->process_frame(ved, link->sink, frame);
377 }
378 }
379
380 return 0;
381}
382
383static void vimc_device_unregister(struct vimc_device *vimc)
384{
385 unsigned int i;
386
387 media_device_unregister(&vimc->mdev);
388 /* Cleanup (only initialized) entities */
389 for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
390 if (vimc->ved[i] && vimc->ved[i]->destroy)
391 vimc->ved[i]->destroy(vimc->ved[i]);
392
393 vimc->ved[i] = NULL;
394 }
395 v4l2_device_unregister(&vimc->v4l2_dev);
396 media_device_cleanup(&vimc->mdev);
397}
398
399/* Helper function to allocate and initialize pads */
400struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
401{
402 struct media_pad *pads;
403 unsigned int i;
404
405 /* Allocate memory for the pads */
406 pads = kcalloc(num_pads, sizeof(*pads), GFP_KERNEL);
407 if (!pads)
408 return ERR_PTR(-ENOMEM);
409
410 /* Initialize the pads */
411 for (i = 0; i < num_pads; i++) {
412 pads[i].index = i;
413 pads[i].flags = pads_flag[i];
414 }
415
416 return pads;
417}
418
419/*
420 * TODO: remove this function when all the
421 * entities specific code are implemented
422 */
423static void vimc_raw_destroy(struct vimc_ent_device *ved)
424{
425 media_device_unregister_entity(ved->ent);
426
427 media_entity_cleanup(ved->ent);
428
429 vimc_pads_cleanup(ved->pads);
430
431 kfree(ved->ent);
432
433 kfree(ved);
434}
435
436/*
437 * TODO: remove this function when all the
438 * entities specific code are implemented
439 */
440static struct vimc_ent_device *vimc_raw_create(struct v4l2_device *v4l2_dev,
441 const char *const name,
442 u16 num_pads,
443 const unsigned long *pads_flag)
444{
445 struct vimc_ent_device *ved;
446 int ret;
447
448 /* Allocate the main ved struct */
449 ved = kzalloc(sizeof(*ved), GFP_KERNEL);
450 if (!ved)
451 return ERR_PTR(-ENOMEM);
452
453 /* Allocate the media entity */
454 ved->ent = kzalloc(sizeof(*ved->ent), GFP_KERNEL);
455 if (!ved->ent) {
456 ret = -ENOMEM;
457 goto err_free_ved;
458 }
459
460 /* Allocate the pads */
461 ved->pads = vimc_pads_init(num_pads, pads_flag);
462 if (IS_ERR(ved->pads)) {
463 ret = PTR_ERR(ved->pads);
464 goto err_free_ent;
465 }
466
467 /* Initialize the media entity */
468 ved->ent->name = name;
469 ved->ent->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
470 ret = media_entity_pads_init(ved->ent, num_pads, ved->pads);
471 if (ret)
472 goto err_cleanup_pads;
473
474 /* Register the media entity */
475 ret = media_device_register_entity(v4l2_dev->mdev, ved->ent);
476 if (ret)
477 goto err_cleanup_entity;
478
479 /* Fill out the destroy function and return */
480 ved->destroy = vimc_raw_destroy;
481 return ved;
482
483err_cleanup_entity:
484 media_entity_cleanup(ved->ent);
485err_cleanup_pads:
486 vimc_pads_cleanup(ved->pads);
487err_free_ent:
488 kfree(ved->ent);
489err_free_ved:
490 kfree(ved);
491
492 return ERR_PTR(ret);
493}
494
495static int vimc_device_register(struct vimc_device *vimc)
496{
497 unsigned int i;
498 int ret;
499
500 /* Allocate memory for the vimc_ent_devices pointers */
501 vimc->ved = devm_kcalloc(vimc->mdev.dev, vimc->pipe_cfg->num_ents,
502 sizeof(*vimc->ved), GFP_KERNEL);
503 if (!vimc->ved)
504 return -ENOMEM;
505
506 /* Link the media device within the v4l2_device */
507 vimc->v4l2_dev.mdev = &vimc->mdev;
508
509 /* Register the v4l2 struct */
510 ret = v4l2_device_register(vimc->mdev.dev, &vimc->v4l2_dev);
511 if (ret) {
512 dev_err(vimc->mdev.dev,
513 "v4l2 device register failed (err=%d)\n", ret);
514 return ret;
515 }
516
517 /* Initialize entities */
518 for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
519 struct vimc_ent_device *(*create_func)(struct v4l2_device *,
520 const char *const,
521 u16,
522 const unsigned long *);
523
524 /* Register the specific node */
525 switch (vimc->pipe_cfg->ents[i].node) {
526 case VIMC_ENT_NODE_SENSOR:
527 create_func = vimc_sen_create;
528 break;
529
530 case VIMC_ENT_NODE_CAPTURE:
531 create_func = vimc_cap_create;
532 break;
533
534 /* TODO: Instantiate the specific topology node */
535 case VIMC_ENT_NODE_INPUT:
536 case VIMC_ENT_NODE_DEBAYER:
537 case VIMC_ENT_NODE_SCALER:
538 default:
539 /*
540 * TODO: remove this when all the entities specific
541 * code are implemented
542 */
543 create_func = vimc_raw_create;
544 break;
545 }
546
547 vimc->ved[i] = create_func(&vimc->v4l2_dev,
548 vimc->pipe_cfg->ents[i].name,
549 vimc->pipe_cfg->ents[i].pads_qty,
550 vimc->pipe_cfg->ents[i].pads_flag);
551 if (IS_ERR(vimc->ved[i])) {
552 ret = PTR_ERR(vimc->ved[i]);
553 vimc->ved[i] = NULL;
554 goto err;
555 }
556 }
557
558 /* Initialize the links between entities */
559 for (i = 0; i < vimc->pipe_cfg->num_links; i++) {
560 const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i];
561
562 ret = media_create_pad_link(vimc->ved[link->src_ent]->ent,
563 link->src_pad,
564 vimc->ved[link->sink_ent]->ent,
565 link->sink_pad,
566 link->flags);
567 if (ret)
568 goto err;
569 }
570
571 /* Register the media device */
572 ret = media_device_register(&vimc->mdev);
573 if (ret) {
574 dev_err(vimc->mdev.dev,
575 "media device register failed (err=%d)\n", ret);
576 return ret;
577 }
578
579 /* Expose all subdev's nodes*/
580 ret = v4l2_device_register_subdev_nodes(&vimc->v4l2_dev);
581 if (ret) {
582 dev_err(vimc->mdev.dev,
583 "vimc subdev nodes registration failed (err=%d)\n",
584 ret);
585 goto err;
586 }
587
588 return 0;
589
590err:
591 /* Destroy the so far created topology */
592 vimc_device_unregister(vimc);
593
594 return ret;
595}
596
597static int vimc_probe(struct platform_device *pdev)
598{
599 struct vimc_device *vimc;
600 int ret;
601
602 /* Prepare the vimc topology structure */
603
604 /* Allocate memory for the vimc structure */
605 vimc = kzalloc(sizeof(*vimc), GFP_KERNEL);
606 if (!vimc)
607 return -ENOMEM;
608
609 /* Set the pipeline configuration struct */
610 vimc->pipe_cfg = &pipe_cfg;
611
612 /* Initialize media device */
613 strlcpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
614 sizeof(vimc->mdev.model));
615 vimc->mdev.dev = &pdev->dev;
616 media_device_init(&vimc->mdev);
617
618 /* Create vimc topology */
619 ret = vimc_device_register(vimc);
620 if (ret) {
621 dev_err(vimc->mdev.dev,
622 "vimc device registration failed (err=%d)\n", ret);
623 kfree(vimc);
624 return ret;
625 }
626
627 /* Link the topology object with the platform device object */
628 platform_set_drvdata(pdev, vimc);
629
630 return 0;
631}
632
633static int vimc_remove(struct platform_device *pdev)
634{
635 struct vimc_device *vimc = platform_get_drvdata(pdev);
636
637 /* Destroy all the topology */
638 vimc_device_unregister(vimc);
639 kfree(vimc);
640
641 return 0;
642}
643
644static void vimc_dev_release(struct device *dev)
645{
646}
647
648static struct platform_device vimc_pdev = {
649 .name = VIMC_PDEV_NAME,
650 .dev.release = vimc_dev_release,
651};
652
653static struct platform_driver vimc_pdrv = {
654 .probe = vimc_probe,
655 .remove = vimc_remove,
656 .driver = {
657 .name = VIMC_PDEV_NAME,
658 },
659};
660
661static int __init vimc_init(void)
662{
663 int ret;
664
665 ret = platform_device_register(&vimc_pdev);
666 if (ret) {
667 dev_err(&vimc_pdev.dev,
668 "platform device registration failed (err=%d)\n", ret);
669 return ret;
670 }
671
672 ret = platform_driver_register(&vimc_pdrv);
673 if (ret) {
674 dev_err(&vimc_pdev.dev,
675 "platform driver registration failed (err=%d)\n", ret);
676
677 platform_device_unregister(&vimc_pdev);
678 }
679
680 return ret;
681}
682
683static void __exit vimc_exit(void)
684{
685 platform_driver_unregister(&vimc_pdrv);
686
687 platform_device_unregister(&vimc_pdev);
688}
689
690module_init(vimc_init);
691module_exit(vimc_exit);
692
693MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC)");
694MODULE_AUTHOR("Helen Fornazier <helen.fornazier@gmail.com>");
695MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-core.h b/drivers/media/platform/vimc/vimc-core.h
new file mode 100644
index 000000000000..4525d23211ca
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-core.h
@@ -0,0 +1,112 @@
1/*
2 * vimc-core.h Virtual Media Controller Driver
3 *
4 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef _VIMC_CORE_H_
19#define _VIMC_CORE_H_
20
21#include <linux/slab.h>
22#include <media/v4l2-device.h>
23
24/**
25 * struct vimc_pix_map - maps media bus code with v4l2 pixel format
26 *
27 * @code: media bus format code defined by MEDIA_BUS_FMT_* macros
28 * @bbp: number of bytes each pixel occupies
29 * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros
30 *
31 * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding
32 * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp)
33 */
34struct vimc_pix_map {
35 unsigned int code;
36 unsigned int bpp;
37 u32 pixelformat;
38};
39
40/**
41 * struct vimc_ent_device - core struct that represents a node in the topology
42 *
43 * @ent: the pointer to struct media_entity for the node
44 * @pads: the list of pads of the node
45 * @destroy: callback to destroy the node
46 * @process_frame: callback send a frame to that node
47 *
48 * Each node of the topology must create a vimc_ent_device struct. Depending on
49 * the node it will be of an instance of v4l2_subdev or video_device struct
50 * where both contains a struct media_entity.
51 * Those structures should embedded the vimc_ent_device struct through
52 * v4l2_set_subdevdata() and video_set_drvdata() respectivaly, allowing the
53 * vimc_ent_device struct to be retrieved from the corresponding struct
54 * media_entity
55 */
56struct vimc_ent_device {
57 struct media_entity *ent;
58 struct media_pad *pads;
59 void (*destroy)(struct vimc_ent_device *);
60 void (*process_frame)(struct vimc_ent_device *ved,
61 struct media_pad *sink, const void *frame);
62};
63
64/**
65 * vimc_propagate_frame - propagate a frame through the topology
66 *
67 * @src: the source pad where the frame is being originated
68 * @frame: the frame to be propagated
69 *
70 * This function will call the process_frame callback from the vimc_ent_device
71 * struct of the nodes directly connected to the @src pad
72 */
73int vimc_propagate_frame(struct media_pad *src, const void *frame);
74
75/**
76 * vimc_pads_init - initialize pads
77 *
78 * @num_pads: number of pads to initialize
79 * @pads_flags: flags to use in each pad
80 *
81 * Helper functions to allocate/initialize pads
82 */
83struct media_pad *vimc_pads_init(u16 num_pads,
84 const unsigned long *pads_flag);
85
86/**
87 * vimc_pads_cleanup - free pads
88 *
89 * @pads: pointer to the pads
90 *
91 * Helper function to free the pads initialized with vimc_pads_init
92 */
93static inline void vimc_pads_cleanup(struct media_pad *pads)
94{
95 kfree(pads);
96}
97
98/**
99 * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
100 *
101 * @code: media bus format code defined by MEDIA_BUS_FMT_* macros
102 */
103const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
104
105/**
106 * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format
107 *
108 * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros
109 */
110const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
111
112#endif
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
new file mode 100644
index 000000000000..591f6a4f8bd3
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -0,0 +1,276 @@
1/*
2 * vimc-sensor.c Virtual Media Controller Driver
3 *
4 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/freezer.h>
19#include <linux/kthread.h>
20#include <linux/v4l2-mediabus.h>
21#include <linux/vmalloc.h>
22#include <media/v4l2-subdev.h>
23
24#include "vimc-sensor.h"
25
26struct vimc_sen_device {
27 struct vimc_ent_device ved;
28 struct v4l2_subdev sd;
29 struct task_struct *kthread_sen;
30 u8 *frame;
31 /* The active format */
32 struct v4l2_mbus_framefmt mbus_format;
33 int frame_size;
34};
35
36static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
37 struct v4l2_subdev_pad_config *cfg,
38 struct v4l2_subdev_mbus_code_enum *code)
39{
40 struct vimc_sen_device *vsen =
41 container_of(sd, struct vimc_sen_device, sd);
42
43 /* TODO: Add support for other codes */
44 if (code->index)
45 return -EINVAL;
46
47 code->code = vsen->mbus_format.code;
48
49 return 0;
50}
51
52static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
53 struct v4l2_subdev_pad_config *cfg,
54 struct v4l2_subdev_frame_size_enum *fse)
55{
56 struct vimc_sen_device *vsen =
57 container_of(sd, struct vimc_sen_device, sd);
58
59 /* TODO: Add support to other formats */
60 if (fse->index)
61 return -EINVAL;
62
63 /* TODO: Add support for other codes */
64 if (fse->code != vsen->mbus_format.code)
65 return -EINVAL;
66
67 fse->min_width = vsen->mbus_format.width;
68 fse->max_width = vsen->mbus_format.width;
69 fse->min_height = vsen->mbus_format.height;
70 fse->max_height = vsen->mbus_format.height;
71
72 return 0;
73}
74
75static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
76 struct v4l2_subdev_pad_config *cfg,
77 struct v4l2_subdev_format *format)
78{
79 struct vimc_sen_device *vsen =
80 container_of(sd, struct vimc_sen_device, sd);
81
82 format->format = vsen->mbus_format;
83
84 return 0;
85}
86
87static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
88 .enum_mbus_code = vimc_sen_enum_mbus_code,
89 .enum_frame_size = vimc_sen_enum_frame_size,
90 .get_fmt = vimc_sen_get_fmt,
91 /* TODO: Add support to other formats */
92 .set_fmt = vimc_sen_get_fmt,
93};
94
95/* media operations */
96static const struct media_entity_operations vimc_sen_mops = {
97 .link_validate = v4l2_subdev_link_validate,
98};
99
100static int vimc_thread_sen(void *data)
101{
102 struct vimc_sen_device *vsen = data;
103 unsigned int i;
104
105 set_freezable();
106 set_current_state(TASK_UNINTERRUPTIBLE);
107
108 for (;;) {
109 try_to_freeze();
110 if (kthread_should_stop())
111 break;
112
113 memset(vsen->frame, 100, vsen->frame_size);
114
115 /* Send the frame to all source pads */
116 for (i = 0; i < vsen->sd.entity.num_pads; i++)
117 vimc_propagate_frame(&vsen->sd.entity.pads[i],
118 vsen->frame);
119
120 /* 60 frames per second */
121 schedule_timeout(HZ/60);
122 }
123
124 return 0;
125}
126
127static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
128{
129 struct vimc_sen_device *vsen =
130 container_of(sd, struct vimc_sen_device, sd);
131 int ret;
132
133 if (enable) {
134 const struct vimc_pix_map *vpix;
135
136 if (vsen->kthread_sen)
137 return -EINVAL;
138
139 /* Calculate the frame size */
140 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
141 vsen->frame_size = vsen->mbus_format.width * vpix->bpp *
142 vsen->mbus_format.height;
143
144 /*
145 * Allocate the frame buffer. Use vmalloc to be able to
146 * allocate a large amount of memory
147 */
148 vsen->frame = vmalloc(vsen->frame_size);
149 if (!vsen->frame)
150 return -ENOMEM;
151
152 /* Initialize the image generator thread */
153 vsen->kthread_sen = kthread_run(vimc_thread_sen, vsen, "%s-sen",
154 vsen->sd.v4l2_dev->name);
155 if (IS_ERR(vsen->kthread_sen)) {
156 dev_err(vsen->sd.v4l2_dev->dev,
157 "%s: kernel_thread() failed\n", vsen->sd.name);
158 vfree(vsen->frame);
159 vsen->frame = NULL;
160 return PTR_ERR(vsen->kthread_sen);
161 }
162 } else {
163 if (!vsen->kthread_sen)
164 return -EINVAL;
165
166 /* Stop image generator */
167 ret = kthread_stop(vsen->kthread_sen);
168 vsen->kthread_sen = NULL;
169
170 vfree(vsen->frame);
171 vsen->frame = NULL;
172 return ret;
173 }
174
175 return 0;
176}
177
178struct v4l2_subdev_video_ops vimc_sen_video_ops = {
179 .s_stream = vimc_sen_s_stream,
180};
181
182static const struct v4l2_subdev_ops vimc_sen_ops = {
183 .pad = &vimc_sen_pad_ops,
184 .video = &vimc_sen_video_ops,
185};
186
187static void vimc_sen_destroy(struct vimc_ent_device *ved)
188{
189 struct vimc_sen_device *vsen =
190 container_of(ved, struct vimc_sen_device, ved);
191
192 v4l2_device_unregister_subdev(&vsen->sd);
193 media_entity_cleanup(ved->ent);
194 kfree(vsen);
195}
196
197struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev,
198 const char *const name,
199 u16 num_pads,
200 const unsigned long *pads_flag)
201{
202 struct vimc_sen_device *vsen;
203 unsigned int i;
204 int ret;
205
206 /* NOTE: a sensor node may be created with more then one pad */
207 if (!name || !num_pads || !pads_flag)
208 return ERR_PTR(-EINVAL);
209
210 /* check if all pads are sources */
211 for (i = 0; i < num_pads; i++)
212 if (!(pads_flag[i] & MEDIA_PAD_FL_SOURCE))
213 return ERR_PTR(-EINVAL);
214
215 /* Allocate the vsen struct */
216 vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
217 if (!vsen)
218 return ERR_PTR(-ENOMEM);
219
220 /* Allocate the pads */
221 vsen->ved.pads = vimc_pads_init(num_pads, pads_flag);
222 if (IS_ERR(vsen->ved.pads)) {
223 ret = PTR_ERR(vsen->ved.pads);
224 goto err_free_vsen;
225 }
226
227 /* Fill the vimc_ent_device struct */
228 vsen->ved.destroy = vimc_sen_destroy;
229 vsen->ved.ent = &vsen->sd.entity;
230
231 /* Initialize the subdev */
232 v4l2_subdev_init(&vsen->sd, &vimc_sen_ops);
233 vsen->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
234 vsen->sd.entity.ops = &vimc_sen_mops;
235 vsen->sd.owner = THIS_MODULE;
236 strlcpy(vsen->sd.name, name, sizeof(vsen->sd.name));
237 v4l2_set_subdevdata(&vsen->sd, &vsen->ved);
238
239 /* Expose this subdev to user space */
240 vsen->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
241
242 /* Initialize the media entity */
243 ret = media_entity_pads_init(&vsen->sd.entity,
244 num_pads, vsen->ved.pads);
245 if (ret)
246 goto err_clean_pads;
247
248 /* Set the active frame format (this is hardcoded for now) */
249 vsen->mbus_format.width = 640;
250 vsen->mbus_format.height = 480;
251 vsen->mbus_format.code = MEDIA_BUS_FMT_RGB888_1X24;
252 vsen->mbus_format.field = V4L2_FIELD_NONE;
253 vsen->mbus_format.colorspace = V4L2_COLORSPACE_SRGB;
254 vsen->mbus_format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
255 vsen->mbus_format.xfer_func = V4L2_XFER_FUNC_SRGB;
256
257 /* Register the subdev with the v4l2 and the media framework */
258 ret = v4l2_device_register_subdev(v4l2_dev, &vsen->sd);
259 if (ret) {
260 dev_err(vsen->sd.v4l2_dev->dev,
261 "%s: subdev register failed (err=%d)\n",
262 vsen->sd.name, ret);
263 goto err_clean_m_ent;
264 }
265
266 return &vsen->ved;
267
268err_clean_m_ent:
269 media_entity_cleanup(&vsen->sd.entity);
270err_clean_pads:
271 vimc_pads_cleanup(vsen->ved.pads);
272err_free_vsen:
273 kfree(vsen);
274
275 return ERR_PTR(ret);
276}
diff --git a/drivers/media/platform/vimc/vimc-sensor.h b/drivers/media/platform/vimc/vimc-sensor.h
new file mode 100644
index 000000000000..505310e8aeb7
--- /dev/null
+++ b/drivers/media/platform/vimc/vimc-sensor.h
@@ -0,0 +1,28 @@
1/*
2 * vimc-sensor.h Virtual Media Controller Driver
3 *
4 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef _VIMC_SENSOR_H_
19#define _VIMC_SENSOR_H_
20
21#include "vimc-core.h"
22
23struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev,
24 const char *const name,
25 u16 num_pads,
26 const unsigned long *pads_flag);
27
28#endif
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index db0dd19d227a..b36ac19dc6e4 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -1,13 +1,14 @@
1config VIDEO_VIVID 1config VIDEO_VIVID
2 tristate "Virtual Video Test Driver" 2 tristate "Virtual Video Test Driver"
3 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB 3 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB
4 depends on HAS_DMA
4 select FONT_SUPPORT 5 select FONT_SUPPORT
5 select FONT_8x16 6 select FONT_8x16
6 select FB_CFB_FILLRECT 7 select FB_CFB_FILLRECT
7 select FB_CFB_COPYAREA 8 select FB_CFB_COPYAREA
8 select FB_CFB_IMAGEBLIT 9 select FB_CFB_IMAGEBLIT
9 select MEDIA_CEC_EDID
10 select VIDEOBUF2_VMALLOC 10 select VIDEOBUF2_VMALLOC
11 select VIDEOBUF2_DMA_CONTIG
11 select VIDEO_V4L2_TPG 12 select VIDEO_V4L2_TPG
12 default n 13 default n
13 ---help--- 14 ---help---
@@ -25,7 +26,7 @@ config VIDEO_VIVID
25 26
26config VIDEO_VIVID_CEC 27config VIDEO_VIVID_CEC
27 bool "Enable CEC emulation support" 28 bool "Enable CEC emulation support"
28 depends on VIDEO_VIVID && MEDIA_CEC_SUPPORT 29 depends on VIDEO_VIVID && CEC_CORE
29 ---help--- 30 ---help---
30 When selected the vivid module will emulate the optional 31 When selected the vivid module will emulate the optional
31 HDMI CEC feature. 32 HDMI CEC feature.
diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c
index cb4933592a3c..653f4099f737 100644
--- a/drivers/media/platform/vivid/vivid-cec.c
+++ b/drivers/media/platform/vivid/vivid-cec.c
@@ -135,7 +135,7 @@ static int vivid_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
135static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 135static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
136 u32 signal_free_time, struct cec_msg *msg) 136 u32 signal_free_time, struct cec_msg *msg)
137{ 137{
138 struct vivid_dev *dev = adap->priv; 138 struct vivid_dev *dev = cec_get_drvdata(adap);
139 struct vivid_cec_work *cw = kzalloc(sizeof(*cw), GFP_KERNEL); 139 struct vivid_cec_work *cw = kzalloc(sizeof(*cw), GFP_KERNEL);
140 long delta_jiffies = 0; 140 long delta_jiffies = 0;
141 141
@@ -166,7 +166,7 @@ static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
166 166
167static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) 167static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg)
168{ 168{
169 struct vivid_dev *dev = adap->priv; 169 struct vivid_dev *dev = cec_get_drvdata(adap);
170 struct cec_msg reply; 170 struct cec_msg reply;
171 u8 dest = cec_msg_destination(msg); 171 u8 dest = cec_msg_destination(msg);
172 u8 disp_ctl; 172 u8 disp_ctl;
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index 51e37812ec98..ef344b9a48af 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -30,6 +30,7 @@
30#include <linux/videodev2.h> 30#include <linux/videodev2.h>
31#include <linux/v4l2-dv-timings.h> 31#include <linux/v4l2-dv-timings.h>
32#include <media/videobuf2-vmalloc.h> 32#include <media/videobuf2-vmalloc.h>
33#include <media/videobuf2-dma-contig.h>
33#include <media/v4l2-dv-timings.h> 34#include <media/v4l2-dv-timings.h>
34#include <media/v4l2-ioctl.h> 35#include <media/v4l2-ioctl.h>
35#include <media/v4l2-fh.h> 36#include <media/v4l2-fh.h>
@@ -151,6 +152,12 @@ static bool no_error_inj;
151module_param(no_error_inj, bool, 0444); 152module_param(no_error_inj, bool, 0444);
152MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls"); 153MODULE_PARM_DESC(no_error_inj, " if set disable the error injecting controls");
153 154
155static unsigned int allocators[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 0 };
156module_param_array(allocators, uint, NULL, 0444);
157MODULE_PARM_DESC(allocators, " memory allocator selection, default is 0.\n"
158 "\t\t 0 == vmalloc\n"
159 "\t\t 1 == dma-contig");
160
154static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS]; 161static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS];
155 162
156const struct v4l2_rect vivid_min_rect = { 163const struct v4l2_rect vivid_min_rect = {
@@ -636,6 +643,10 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
636{ 643{
637 static const struct v4l2_dv_timings def_dv_timings = 644 static const struct v4l2_dv_timings def_dv_timings =
638 V4L2_DV_BT_CEA_1280X720P60; 645 V4L2_DV_BT_CEA_1280X720P60;
646 static const struct vb2_mem_ops * const vivid_mem_ops[2] = {
647 &vb2_vmalloc_memops,
648 &vb2_dma_contig_memops,
649 };
639 unsigned in_type_counter[4] = { 0, 0, 0, 0 }; 650 unsigned in_type_counter[4] = { 0, 0, 0, 0 };
640 unsigned out_type_counter[4] = { 0, 0, 0, 0 }; 651 unsigned out_type_counter[4] = { 0, 0, 0, 0 };
641 int ccs_cap = ccs_cap_mode[inst]; 652 int ccs_cap = ccs_cap_mode[inst];
@@ -646,6 +657,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
646 struct video_device *vfd; 657 struct video_device *vfd;
647 struct vb2_queue *q; 658 struct vb2_queue *q;
648 unsigned node_type = node_types[inst]; 659 unsigned node_type = node_types[inst];
660 unsigned int allocator = allocators[inst];
649 v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0; 661 v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
650 int ret; 662 int ret;
651 int i; 663 int i;
@@ -1039,6 +1051,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
1039 goto unreg_dev; 1051 goto unreg_dev;
1040 } 1052 }
1041 1053
1054 if (allocator == 1)
1055 dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1056 else if (allocator >= ARRAY_SIZE(vivid_mem_ops))
1057 allocator = 0;
1058
1042 /* start creating the vb2 queues */ 1059 /* start creating the vb2 queues */
1043 if (dev->has_vid_cap) { 1060 if (dev->has_vid_cap) {
1044 /* initialize vid_cap queue */ 1061 /* initialize vid_cap queue */
@@ -1049,10 +1066,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
1049 q->drv_priv = dev; 1066 q->drv_priv = dev;
1050 q->buf_struct_size = sizeof(struct vivid_buffer); 1067 q->buf_struct_size = sizeof(struct vivid_buffer);
1051 q->ops = &vivid_vid_cap_qops; 1068 q->ops = &vivid_vid_cap_qops;
1052 q->mem_ops = &vb2_vmalloc_memops; 1069 q->mem_ops = vivid_mem_ops[allocator];
1053 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1070 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1054 q->min_buffers_needed = 2; 1071 q->min_buffers_needed = 2;
1055 q->lock = &dev->mutex; 1072 q->lock = &dev->mutex;
1073 q->dev = dev->v4l2_dev.dev;
1056 1074
1057 ret = vb2_queue_init(q); 1075 ret = vb2_queue_init(q);
1058 if (ret) 1076 if (ret)
@@ -1068,10 +1086,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
1068 q->drv_priv = dev; 1086 q->drv_priv = dev;
1069 q->buf_struct_size = sizeof(struct vivid_buffer); 1087 q->buf_struct_size = sizeof(struct vivid_buffer);
1070 q->ops = &vivid_vid_out_qops; 1088 q->ops = &vivid_vid_out_qops;
1071 q->mem_ops = &vb2_vmalloc_memops; 1089 q->mem_ops = vivid_mem_ops[allocator];
1072 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1090 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1073 q->min_buffers_needed = 2; 1091 q->min_buffers_needed = 2;
1074 q->lock = &dev->mutex; 1092 q->lock = &dev->mutex;
1093 q->dev = dev->v4l2_dev.dev;
1075 1094
1076 ret = vb2_queue_init(q); 1095 ret = vb2_queue_init(q);
1077 if (ret) 1096 if (ret)
@@ -1087,10 +1106,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
1087 q->drv_priv = dev; 1106 q->drv_priv = dev;
1088 q->buf_struct_size = sizeof(struct vivid_buffer); 1107 q->buf_struct_size = sizeof(struct vivid_buffer);
1089 q->ops = &vivid_vbi_cap_qops; 1108 q->ops = &vivid_vbi_cap_qops;
1090 q->mem_ops = &vb2_vmalloc_memops; 1109 q->mem_ops = vivid_mem_ops[allocator];
1091 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1110 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1092 q->min_buffers_needed = 2; 1111 q->min_buffers_needed = 2;
1093 q->lock = &dev->mutex; 1112 q->lock = &dev->mutex;
1113 q->dev = dev->v4l2_dev.dev;
1094 1114
1095 ret = vb2_queue_init(q); 1115 ret = vb2_queue_init(q);
1096 if (ret) 1116 if (ret)
@@ -1106,10 +1126,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
1106 q->drv_priv = dev; 1126 q->drv_priv = dev;
1107 q->buf_struct_size = sizeof(struct vivid_buffer); 1127 q->buf_struct_size = sizeof(struct vivid_buffer);
1108 q->ops = &vivid_vbi_out_qops; 1128 q->ops = &vivid_vbi_out_qops;
1109 q->mem_ops = &vb2_vmalloc_memops; 1129 q->mem_ops = vivid_mem_ops[allocator];
1110 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1130 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1111 q->min_buffers_needed = 2; 1131 q->min_buffers_needed = 2;
1112 q->lock = &dev->mutex; 1132 q->lock = &dev->mutex;
1133 q->dev = dev->v4l2_dev.dev;
1113 1134
1114 ret = vb2_queue_init(q); 1135 ret = vb2_queue_init(q);
1115 if (ret) 1136 if (ret)
@@ -1124,10 +1145,11 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
1124 q->drv_priv = dev; 1145 q->drv_priv = dev;
1125 q->buf_struct_size = sizeof(struct vivid_buffer); 1146 q->buf_struct_size = sizeof(struct vivid_buffer);
1126 q->ops = &vivid_sdr_cap_qops; 1147 q->ops = &vivid_sdr_cap_qops;
1127 q->mem_ops = &vb2_vmalloc_memops; 1148 q->mem_ops = vivid_mem_ops[allocator];
1128 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1149 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1129 q->min_buffers_needed = 8; 1150 q->min_buffers_needed = 8;
1130 q->lock = &dev->mutex; 1151 q->lock = &dev->mutex;
1152 q->dev = dev->v4l2_dev.dev;
1131 1153
1132 ret = vb2_queue_init(q); 1154 ret = vb2_queue_init(q);
1133 if (ret) 1155 if (ret)
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index a18e6fec219b..01419455e545 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -616,7 +616,7 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
616 /* This driver supports custom bytesperline values */ 616 /* This driver supports custom bytesperline values */
617 617
618 mp->num_planes = fmt->buffers; 618 mp->num_planes = fmt->buffers;
619 for (p = 0; p < mp->num_planes; p++) { 619 for (p = 0; p < fmt->buffers; p++) {
620 /* Calculate the minimum supported bytesperline value */ 620 /* Calculate the minimum supported bytesperline value */
621 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3; 621 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
622 /* Calculate the maximum supported bytesperline value */ 622 /* Calculate the maximum supported bytesperline value */
@@ -626,10 +626,17 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
626 pfmt[p].bytesperline = max_bpl; 626 pfmt[p].bytesperline = max_bpl;
627 if (pfmt[p].bytesperline < bytesperline) 627 if (pfmt[p].bytesperline < bytesperline)
628 pfmt[p].bytesperline = bytesperline; 628 pfmt[p].bytesperline = bytesperline;
629 pfmt[p].sizeimage = tpg_calc_line_width(&dev->tpg, p, pfmt[p].bytesperline) * 629
630 mp->height + fmt->data_offset[p]; 630 pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /
631 fmt->vdownsampling[p] + fmt->data_offset[p];
632
631 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 633 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
632 } 634 }
635 for (p = fmt->buffers; p < fmt->planes; p++)
636 pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *
637 (fmt->bit_depth[p] / fmt->vdownsampling[p])) /
638 (fmt->bit_depth[0] / fmt->vdownsampling[0]);
639
633 mp->colorspace = vivid_colorspace_cap(dev); 640 mp->colorspace = vivid_colorspace_cap(dev);
634 if (fmt->color_enc == TGP_COLOR_ENC_HSV) 641 if (fmt->color_enc == TGP_COLOR_ENC_HSV)
635 mp->hsv_enc = vivid_hsv_enc_cap(dev); 642 mp->hsv_enc = vivid_hsv_enc_cap(dev);
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index 5fc010f6ce67..f0f423c7ca41 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -858,7 +858,7 @@ int vidioc_g_edid(struct file *file, void *_fh,
858 return -EINVAL; 858 return -EINVAL;
859 if (edid->start_block + edid->blocks > dev->edid_blocks) 859 if (edid->start_block + edid->blocks > dev->edid_blocks)
860 edid->blocks = dev->edid_blocks - edid->start_block; 860 edid->blocks = dev->edid_blocks - edid->start_block;
861 memcpy(edid->edid, dev->edid, edid->blocks * 128); 861 cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
862 cec_set_edid_phys_addr(edid->edid, edid->blocks * 128, adap->phys_addr); 862 memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
863 return 0; 863 return 0;
864} 864}
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
index 7ba52ee98371..0b1b6218ede8 100644
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
@@ -390,22 +390,28 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
390 390
391 /* This driver supports custom bytesperline values */ 391 /* This driver supports custom bytesperline values */
392 392
393 /* Calculate the minimum supported bytesperline value */
394 bytesperline = (mp->width * fmt->bit_depth[0]) >> 3;
395 /* Calculate the maximum supported bytesperline value */
396 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3;
397 mp->num_planes = fmt->buffers; 393 mp->num_planes = fmt->buffers;
398 for (p = 0; p < mp->num_planes; p++) { 394 for (p = 0; p < fmt->buffers; p++) {
395 /* Calculate the minimum supported bytesperline value */
396 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
397 /* Calculate the maximum supported bytesperline value */
398 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
399
399 if (pfmt[p].bytesperline > max_bpl) 400 if (pfmt[p].bytesperline > max_bpl)
400 pfmt[p].bytesperline = max_bpl; 401 pfmt[p].bytesperline = max_bpl;
401 if (pfmt[p].bytesperline < bytesperline) 402 if (pfmt[p].bytesperline < bytesperline)
402 pfmt[p].bytesperline = bytesperline; 403 pfmt[p].bytesperline = bytesperline;
403 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; 404
405 pfmt[p].sizeimage = (pfmt[p].bytesperline * mp->height) /
406 fmt->vdownsampling[p];
407
404 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 408 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
405 } 409 }
406 for (p = fmt->buffers; p < fmt->planes; p++) 410 for (p = fmt->buffers; p < fmt->planes; p++)
407 pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) / 411 pfmt[0].sizeimage += (pfmt[0].bytesperline * mp->height *
408 (fmt->bit_depth[0] * fmt->vdownsampling[p]); 412 (fmt->bit_depth[p] / fmt->vdownsampling[p])) /
413 (fmt->bit_depth[0] / fmt->vdownsampling[0]);
414
409 mp->xfer_func = V4L2_XFER_FUNC_DEFAULT; 415 mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
410 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 416 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
411 mp->quantization = V4L2_QUANTIZATION_DEFAULT; 417 mp->quantization = V4L2_QUANTIZATION_DEFAULT;
@@ -1172,14 +1178,12 @@ int vidioc_subscribe_event(struct v4l2_fh *fh,
1172 const struct v4l2_event_subscription *sub) 1178 const struct v4l2_event_subscription *sub)
1173{ 1179{
1174 switch (sub->type) { 1180 switch (sub->type) {
1175 case V4L2_EVENT_CTRL:
1176 return v4l2_ctrl_subscribe_event(fh, sub);
1177 case V4L2_EVENT_SOURCE_CHANGE: 1181 case V4L2_EVENT_SOURCE_CHANGE:
1178 if (fh->vdev->vfl_dir == VFL_DIR_RX) 1182 if (fh->vdev->vfl_dir == VFL_DIR_RX)
1179 return v4l2_src_change_event_subscribe(fh, sub); 1183 return v4l2_src_change_event_subscribe(fh, sub);
1180 break; 1184 break;
1181 default: 1185 default:
1182 break; 1186 return v4l2_ctrl_subscribe_event(fh, sub);
1183 } 1187 }
1184 return -EINVAL; 1188 return -EINVAL;
1185} 1189}
diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 1328e1bd2143..a33afc385a48 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -3,6 +3,7 @@ vsp1-y += vsp1_dl.o vsp1_drm.o vsp1_video.o
3vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o 3vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
4vsp1-y += vsp1_clu.o vsp1_hsit.o vsp1_lut.o 4vsp1-y += vsp1_clu.o vsp1_hsit.o vsp1_lut.o
5vsp1-y += vsp1_bru.o vsp1_sru.o vsp1_uds.o 5vsp1-y += vsp1_bru.o vsp1_sru.o vsp1_uds.o
6vsp1-y += vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
6vsp1-y += vsp1_lif.o 7vsp1-y += vsp1_lif.o
7 8
8obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o 9obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index b23fa879a9aa..85387a64179a 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -32,6 +32,8 @@ struct vsp1_entity;
32struct vsp1_platform_data; 32struct vsp1_platform_data;
33struct vsp1_bru; 33struct vsp1_bru;
34struct vsp1_clu; 34struct vsp1_clu;
35struct vsp1_hgo;
36struct vsp1_hgt;
35struct vsp1_hsit; 37struct vsp1_hsit;
36struct vsp1_lif; 38struct vsp1_lif;
37struct vsp1_lut; 39struct vsp1_lut;
@@ -50,6 +52,8 @@ struct vsp1_uds;
50#define VSP1_HAS_CLU (1 << 4) 52#define VSP1_HAS_CLU (1 << 4)
51#define VSP1_HAS_WPF_VFLIP (1 << 5) 53#define VSP1_HAS_WPF_VFLIP (1 << 5)
52#define VSP1_HAS_WPF_HFLIP (1 << 6) 54#define VSP1_HAS_WPF_HFLIP (1 << 6)
55#define VSP1_HAS_HGO (1 << 7)
56#define VSP1_HAS_HGT (1 << 8)
53 57
54struct vsp1_device_info { 58struct vsp1_device_info {
55 u32 version; 59 u32 version;
@@ -73,6 +77,8 @@ struct vsp1_device {
73 77
74 struct vsp1_bru *bru; 78 struct vsp1_bru *bru;
75 struct vsp1_clu *clu; 79 struct vsp1_clu *clu;
80 struct vsp1_hgo *hgo;
81 struct vsp1_hgt *hgt;
76 struct vsp1_hsit *hsi; 82 struct vsp1_hsit *hsi;
77 struct vsp1_hsit *hst; 83 struct vsp1_hsit *hst;
78 struct vsp1_lif *lif; 84 struct vsp1_lif *lif;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index ee8355c28f94..85362c5ef57a 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -251,7 +251,8 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
251 sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); 251 sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
252 sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); 252 sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
253 253
254 /* Scaling isn't supported, the compose rectangle size must be identical 254 /*
255 * Scaling isn't supported, the compose rectangle size must be identical
255 * to the sink format size. 256 * to the sink format size.
256 */ 257 */
257 format = vsp1_entity_get_pad_format(&bru->entity, config, sel->pad); 258 format = vsp1_entity_get_pad_format(&bru->entity, config, sel->pad);
@@ -300,13 +301,15 @@ static void bru_configure(struct vsp1_entity *entity,
300 format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config, 301 format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config,
301 bru->entity.source_pad); 302 bru->entity.source_pad);
302 303
303 /* The hardware is extremely flexible but we have no userspace API to 304 /*
305 * The hardware is extremely flexible but we have no userspace API to
304 * expose all the parameters, nor is it clear whether we would have use 306 * expose all the parameters, nor is it clear whether we would have use
305 * cases for all the supported modes. Let's just harcode the parameters 307 * cases for all the supported modes. Let's just harcode the parameters
306 * to sane default values for now. 308 * to sane default values for now.
307 */ 309 */
308 310
309 /* Disable dithering and enable color data normalization unless the 311 /*
312 * Disable dithering and enable color data normalization unless the
310 * format at the pipeline output is premultiplied. 313 * format at the pipeline output is premultiplied.
311 */ 314 */
312 flags = pipe->output ? pipe->output->format.flags : 0; 315 flags = pipe->output ? pipe->output->format.flags : 0;
@@ -314,7 +317,8 @@ static void bru_configure(struct vsp1_entity *entity,
314 flags & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA ? 317 flags & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA ?
315 0 : VI6_BRU_INCTRL_NRM); 318 0 : VI6_BRU_INCTRL_NRM);
316 319
317 /* Set the background position to cover the whole output image and 320 /*
321 * Set the background position to cover the whole output image and
318 * configure its color. 322 * configure its color.
319 */ 323 */
320 vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_SIZE, 324 vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_SIZE,
@@ -325,7 +329,8 @@ static void bru_configure(struct vsp1_entity *entity,
325 vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_COL, bru->bgcolor | 329 vsp1_bru_write(bru, dl, VI6_BRU_VIRRPF_COL, bru->bgcolor |
326 (0xff << VI6_BRU_VIRRPF_COL_A_SHIFT)); 330 (0xff << VI6_BRU_VIRRPF_COL_A_SHIFT));
327 331
328 /* Route BRU input 1 as SRC input to the ROP unit and configure the ROP 332 /*
333 * Route BRU input 1 as SRC input to the ROP unit and configure the ROP
329 * unit with a NOP operation to make BRU input 1 available as the 334 * unit with a NOP operation to make BRU input 1 available as the
330 * Blend/ROP unit B SRC input. 335 * Blend/ROP unit B SRC input.
331 */ 336 */
@@ -337,7 +342,8 @@ static void bru_configure(struct vsp1_entity *entity,
337 bool premultiplied = false; 342 bool premultiplied = false;
338 u32 ctrl = 0; 343 u32 ctrl = 0;
339 344
340 /* Configure all Blend/ROP units corresponding to an enabled BRU 345 /*
346 * Configure all Blend/ROP units corresponding to an enabled BRU
341 * input for alpha blending. Blend/ROP units corresponding to 347 * input for alpha blending. Blend/ROP units corresponding to
342 * disabled BRU inputs are used in ROP NOP mode to ignore the 348 * disabled BRU inputs are used in ROP NOP mode to ignore the
343 * SRC input. 349 * SRC input.
@@ -352,13 +358,15 @@ static void bru_configure(struct vsp1_entity *entity,
352 | VI6_BRU_CTRL_AROP(VI6_ROP_NOP); 358 | VI6_BRU_CTRL_AROP(VI6_ROP_NOP);
353 } 359 }
354 360
355 /* Select the virtual RPF as the Blend/ROP unit A DST input to 361 /*
362 * Select the virtual RPF as the Blend/ROP unit A DST input to
356 * serve as a background color. 363 * serve as a background color.
357 */ 364 */
358 if (i == 0) 365 if (i == 0)
359 ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF; 366 ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF;
360 367
361 /* Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to 368 /*
369 * Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to
362 * D in that order. The Blend/ROP unit B SRC is hardwired to the 370 * D in that order. The Blend/ROP unit B SRC is hardwired to the
363 * ROP unit output, the corresponding register bits must be set 371 * ROP unit output, the corresponding register bits must be set
364 * to 0. 372 * to 0.
@@ -368,7 +376,8 @@ static void bru_configure(struct vsp1_entity *entity,
368 376
369 vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl); 377 vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
370 378
371 /* Harcode the blending formula to 379 /*
380 * Harcode the blending formula to
372 * 381 *
373 * DSTc = DSTc * (1 - SRCa) + SRCc * SRCa 382 * DSTc = DSTc * (1 - SRCa) + SRCc * SRCa
374 * DSTa = DSTa * (1 - SRCa) + SRCa 383 * DSTa = DSTa * (1 - SRCa) + SRCa
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index ad545aff4e35..7d8f37772b56 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -240,7 +240,8 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
240 INIT_LIST_HEAD(&dl->fragments); 240 INIT_LIST_HEAD(&dl->fragments);
241 dl->dlm = dlm; 241 dl->dlm = dlm;
242 242
243 /* Initialize the display list body and allocate DMA memory for the body 243 /*
244 * Initialize the display list body and allocate DMA memory for the body
244 * and the optional header. Both are allocated together to avoid memory 245 * and the optional header. Both are allocated together to avoid memory
245 * fragmentation, with the header located right after the body in 246 * fragmentation, with the header located right after the body in
246 * memory. 247 * memory.
@@ -511,7 +512,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
511 goto done; 512 goto done;
512 } 513 }
513 514
514 /* Once the UPD bit has been set the hardware can start processing the 515 /*
516 * Once the UPD bit has been set the hardware can start processing the
515 * display list at any time and we can't touch the address and size 517 * display list at any time and we can't touch the address and size
516 * registers. In that case mark the update as pending, it will be 518 * registers. In that case mark the update as pending, it will be
517 * queued up to the hardware by the frame end interrupt handler. 519 * queued up to the hardware by the frame end interrupt handler.
@@ -523,7 +525,8 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
523 goto done; 525 goto done;
524 } 526 }
525 527
526 /* Program the hardware with the display list body address and size. 528 /*
529 * Program the hardware with the display list body address and size.
527 * The UPD bit will be cleared by the device when the display list is 530 * The UPD bit will be cleared by the device when the display list is
528 * processed. 531 * processed.
529 */ 532 */
@@ -547,7 +550,8 @@ void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm)
547{ 550{
548 spin_lock(&dlm->lock); 551 spin_lock(&dlm->lock);
549 552
550 /* The display start interrupt signals the end of the display list 553 /*
554 * The display start interrupt signals the end of the display list
551 * processing by the device. The active display list, if any, won't be 555 * processing by the device. The active display list, if any, won't be
552 * accessed anymore and can be reused. 556 * accessed anymore and can be reused.
553 */ 557 */
@@ -566,14 +570,16 @@ void vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
566 __vsp1_dl_list_put(dlm->active); 570 __vsp1_dl_list_put(dlm->active);
567 dlm->active = NULL; 571 dlm->active = NULL;
568 572
569 /* Header mode is used for mem-to-mem pipelines only. We don't need to 573 /*
574 * Header mode is used for mem-to-mem pipelines only. We don't need to
570 * perform any operation as there can't be any new display list queued 575 * perform any operation as there can't be any new display list queued
571 * in that case. 576 * in that case.
572 */ 577 */
573 if (dlm->mode == VSP1_DL_MODE_HEADER) 578 if (dlm->mode == VSP1_DL_MODE_HEADER)
574 goto done; 579 goto done;
575 580
576 /* The UPD bit set indicates that the commit operation raced with the 581 /*
582 * The UPD bit set indicates that the commit operation raced with the
577 * interrupt and occurred after the frame end event and UPD clear but 583 * interrupt and occurred after the frame end event and UPD clear but
578 * before interrupt processing. The hardware hasn't taken the update 584 * before interrupt processing. The hardware hasn't taken the update
579 * into account yet, we'll thus skip one frame and retry. 585 * into account yet, we'll thus skip one frame and retry.
@@ -581,7 +587,8 @@ void vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
581 if (vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD) 587 if (vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD)
582 goto done; 588 goto done;
583 589
584 /* The device starts processing the queued display list right after the 590 /*
591 * The device starts processing the queued display list right after the
585 * frame end interrupt. The display list thus becomes active. 592 * frame end interrupt. The display list thus becomes active.
586 */ 593 */
587 if (dlm->queued) { 594 if (dlm->queued) {
@@ -589,7 +596,8 @@ void vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
589 dlm->queued = NULL; 596 dlm->queued = NULL;
590 } 597 }
591 598
592 /* Now that the UPD bit has been cleared we can queue the next display 599 /*
600 * Now that the UPD bit has been cleared we can queue the next display
593 * list to the hardware if one has been prepared. 601 * list to the hardware if one has been prepared.
594 */ 602 */
595 if (dlm->pending) { 603 if (dlm->pending) {
@@ -615,7 +623,8 @@ void vsp1_dlm_setup(struct vsp1_device *vsp1)
615 | VI6_DL_CTRL_DC2 | VI6_DL_CTRL_DC1 | VI6_DL_CTRL_DC0 623 | VI6_DL_CTRL_DC2 | VI6_DL_CTRL_DC1 | VI6_DL_CTRL_DC0
616 | VI6_DL_CTRL_DLE; 624 | VI6_DL_CTRL_DLE;
617 625
618 /* The DRM pipeline operates with display lists in Continuous Frame 626 /*
627 * The DRM pipeline operates with display lists in Continuous Frame
619 * Mode, all other pipelines use manual start. 628 * Mode, all other pipelines use manual start.
620 */ 629 */
621 if (vsp1->drm) 630 if (vsp1->drm)
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index b4c0f10fc3b0..9d235e830f5a 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -78,7 +78,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
78 int ret; 78 int ret;
79 79
80 if (!cfg) { 80 if (!cfg) {
81 /* NULL configuration means the CRTC is being disabled, stop 81 /*
82 * NULL configuration means the CRTC is being disabled, stop
82 * the pipeline and turn the light off. 83 * the pipeline and turn the light off.
83 */ 84 */
84 ret = vsp1_pipeline_stop(pipe); 85 ret = vsp1_pipeline_stop(pipe);
@@ -106,7 +107,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
106 dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n", 107 dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
107 __func__, cfg->width, cfg->height); 108 __func__, cfg->width, cfg->height);
108 109
109 /* Configure the format at the BRU sinks and propagate it through the 110 /*
111 * Configure the format at the BRU sinks and propagate it through the
110 * pipeline. 112 * pipeline.
111 */ 113 */
112 memset(&format, 0, sizeof(format)); 114 memset(&format, 0, sizeof(format));
@@ -175,7 +177,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
175 __func__, format.format.width, format.format.height, 177 __func__, format.format.width, format.format.height,
176 format.format.code); 178 format.format.code);
177 179
178 /* Verify that the format at the output of the pipeline matches the 180 /*
181 * Verify that the format at the output of the pipeline matches the
179 * requested frame size and media bus code. 182 * requested frame size and media bus code.
180 */ 183 */
181 if (format.format.width != cfg->width || 184 if (format.format.width != cfg->width ||
@@ -185,7 +188,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
185 return -EPIPE; 188 return -EPIPE;
186 } 189 }
187 190
188 /* Mark the pipeline as streaming and enable the VSP1. This will store 191 /*
192 * Mark the pipeline as streaming and enable the VSP1. This will store
189 * the pipeline pointer in all entities, which the s_stream handlers 193 * the pipeline pointer in all entities, which the s_stream handlers
190 * will need. We don't start the entities themselves right at this point 194 * will need. We don't start the entities themselves right at this point
191 * as there's no plane configured yet, so we can't start processing 195 * as there's no plane configured yet, so we can't start processing
@@ -219,9 +223,6 @@ void vsp1_du_atomic_begin(struct device *dev)
219 struct vsp1_pipeline *pipe = &vsp1->drm->pipe; 223 struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
220 224
221 vsp1->drm->num_inputs = pipe->num_inputs; 225 vsp1->drm->num_inputs = pipe->num_inputs;
222
223 /* Prepare the display list. */
224 pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
225} 226}
226EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin); 227EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
227 228
@@ -320,7 +321,8 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
320 const struct v4l2_rect *crop; 321 const struct v4l2_rect *crop;
321 int ret; 322 int ret;
322 323
323 /* Configure the format on the RPF sink pad and propagate it up to the 324 /*
325 * Configure the format on the RPF sink pad and propagate it up to the
324 * BRU sink pad. 326 * BRU sink pad.
325 */ 327 */
326 crop = &vsp1->drm->inputs[rpf->entity.index].crop; 328 crop = &vsp1->drm->inputs[rpf->entity.index].crop;
@@ -359,7 +361,8 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
359 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, 361 __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height,
360 rpf->entity.index); 362 rpf->entity.index);
361 363
362 /* RPF source, hardcode the format to ARGB8888 to turn on format 364 /*
365 * RPF source, hardcode the format to ARGB8888 to turn on format
363 * conversion if needed. 366 * conversion if needed.
364 */ 367 */
365 format.pad = RWPF_PAD_SOURCE; 368 format.pad = RWPF_PAD_SOURCE;
@@ -425,10 +428,14 @@ void vsp1_du_atomic_flush(struct device *dev)
425 struct vsp1_pipeline *pipe = &vsp1->drm->pipe; 428 struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
426 struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, }; 429 struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
427 struct vsp1_entity *entity; 430 struct vsp1_entity *entity;
431 struct vsp1_dl_list *dl;
428 unsigned long flags; 432 unsigned long flags;
429 unsigned int i; 433 unsigned int i;
430 int ret; 434 int ret;
431 435
436 /* Prepare the display list. */
437 dl = vsp1_dl_list_get(pipe->output->dlm);
438
432 /* Count the number of enabled inputs and sort them by Z-order. */ 439 /* Count the number of enabled inputs and sort them by Z-order. */
433 pipe->num_inputs = 0; 440 pipe->num_inputs = 0;
434 441
@@ -483,26 +490,25 @@ void vsp1_du_atomic_flush(struct device *dev)
483 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); 490 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
484 491
485 if (!pipe->inputs[rpf->entity.index]) { 492 if (!pipe->inputs[rpf->entity.index]) {
486 vsp1_dl_list_write(pipe->dl, entity->route->reg, 493 vsp1_dl_list_write(dl, entity->route->reg,
487 VI6_DPR_NODE_UNUSED); 494 VI6_DPR_NODE_UNUSED);
488 continue; 495 continue;
489 } 496 }
490 } 497 }
491 498
492 vsp1_entity_route_setup(entity, pipe->dl); 499 vsp1_entity_route_setup(entity, pipe, dl);
493 500
494 if (entity->ops->configure) { 501 if (entity->ops->configure) {
495 entity->ops->configure(entity, pipe, pipe->dl, 502 entity->ops->configure(entity, pipe, dl,
496 VSP1_ENTITY_PARAMS_INIT); 503 VSP1_ENTITY_PARAMS_INIT);
497 entity->ops->configure(entity, pipe, pipe->dl, 504 entity->ops->configure(entity, pipe, dl,
498 VSP1_ENTITY_PARAMS_RUNTIME); 505 VSP1_ENTITY_PARAMS_RUNTIME);
499 entity->ops->configure(entity, pipe, pipe->dl, 506 entity->ops->configure(entity, pipe, dl,
500 VSP1_ENTITY_PARAMS_PARTITION); 507 VSP1_ENTITY_PARAMS_PARTITION);
501 } 508 }
502 } 509 }
503 510
504 vsp1_dl_list_commit(pipe->dl); 511 vsp1_dl_list_commit(dl);
505 pipe->dl = NULL;
506 512
507 /* Start or stop the pipeline if needed. */ 513 /* Start or stop the pipeline if needed. */
508 if (!vsp1->drm->num_inputs && pipe->num_inputs) { 514 if (!vsp1->drm->num_inputs && pipe->num_inputs) {
@@ -528,7 +534,8 @@ int vsp1_drm_create_links(struct vsp1_device *vsp1)
528 unsigned int i; 534 unsigned int i;
529 int ret; 535 int ret;
530 536
531 /* VSPD instances require a BRU to perform composition and a LIF to 537 /*
538 * VSPD instances require a BRU to perform composition and a LIF to
532 * output to the DU. 539 * output to the DU.
533 */ 540 */
534 if (!vsp1->bru || !vsp1->lif) 541 if (!vsp1->bru || !vsp1->lif)
@@ -595,6 +602,7 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
595 pipe->bru = &vsp1->bru->entity; 602 pipe->bru = &vsp1->bru->entity;
596 pipe->lif = &vsp1->lif->entity; 603 pipe->lif = &vsp1->lif->entity;
597 pipe->output = vsp1->wpf[0]; 604 pipe->output = vsp1->wpf[0];
605 pipe->output->pipe = pipe;
598 606
599 return 0; 607 return 0;
600} 608}
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index 9e28ab9254ba..c8d2f88fc483 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -21,7 +21,7 @@
21 * vsp1_drm - State for the API exposed to the DRM driver 21 * vsp1_drm - State for the API exposed to the DRM driver
22 * @pipe: the VSP1 pipeline used for display 22 * @pipe: the VSP1 pipeline used for display
23 * @num_inputs: number of active pipeline inputs at the beginning of an update 23 * @num_inputs: number of active pipeline inputs at the beginning of an update
24 * @planes: source crop rectangle, destination compose rectangle and z-order 24 * @inputs: source crop rectangle, destination compose rectangle and z-order
25 * position for every input 25 * position for every input
26 */ 26 */
27struct vsp1_drm { 27struct vsp1_drm {
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index aa237b48ad55..048446af5ae7 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -30,6 +30,8 @@
30#include "vsp1_clu.h" 30#include "vsp1_clu.h"
31#include "vsp1_dl.h" 31#include "vsp1_dl.h"
32#include "vsp1_drm.h" 32#include "vsp1_drm.h"
33#include "vsp1_hgo.h"
34#include "vsp1_hgt.h"
33#include "vsp1_hsit.h" 35#include "vsp1_hsit.h"
34#include "vsp1_lif.h" 36#include "vsp1_lif.h"
35#include "vsp1_lut.h" 37#include "vsp1_lut.h"
@@ -105,7 +107,9 @@ static int vsp1_create_sink_links(struct vsp1_device *vsp1,
105 if (source->type == sink->type) 107 if (source->type == sink->type)
106 continue; 108 continue;
107 109
108 if (source->type == VSP1_ENTITY_LIF || 110 if (source->type == VSP1_ENTITY_HGO ||
111 source->type == VSP1_ENTITY_HGT ||
112 source->type == VSP1_ENTITY_LIF ||
109 source->type == VSP1_ENTITY_WPF) 113 source->type == VSP1_ENTITY_WPF)
110 continue; 114 continue;
111 115
@@ -148,6 +152,26 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
148 return ret; 152 return ret;
149 } 153 }
150 154
155 if (vsp1->hgo) {
156 ret = media_create_pad_link(&vsp1->hgo->histo.entity.subdev.entity,
157 HISTO_PAD_SOURCE,
158 &vsp1->hgo->histo.video.entity, 0,
159 MEDIA_LNK_FL_ENABLED |
160 MEDIA_LNK_FL_IMMUTABLE);
161 if (ret < 0)
162 return ret;
163 }
164
165 if (vsp1->hgt) {
166 ret = media_create_pad_link(&vsp1->hgt->histo.entity.subdev.entity,
167 HISTO_PAD_SOURCE,
168 &vsp1->hgt->histo.video.entity, 0,
169 MEDIA_LNK_FL_ENABLED |
170 MEDIA_LNK_FL_IMMUTABLE);
171 if (ret < 0)
172 return ret;
173 }
174
151 if (vsp1->lif) { 175 if (vsp1->lif) {
152 ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity, 176 ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
153 RWPF_PAD_SOURCE, 177 RWPF_PAD_SOURCE,
@@ -170,7 +194,8 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
170 } 194 }
171 195
172 for (i = 0; i < vsp1->info->wpf_count; ++i) { 196 for (i = 0; i < vsp1->info->wpf_count; ++i) {
173 /* Connect the video device to the WPF. All connections are 197 /*
198 * Connect the video device to the WPF. All connections are
174 * immutable. 199 * immutable.
175 */ 200 */
176 struct vsp1_rwpf *wpf = vsp1->wpf[i]; 201 struct vsp1_rwpf *wpf = vsp1->wpf[i];
@@ -227,7 +252,8 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
227 media_device_init(mdev); 252 media_device_init(mdev);
228 253
229 vsp1->media_ops.link_setup = vsp1_entity_link_setup; 254 vsp1->media_ops.link_setup = vsp1_entity_link_setup;
230 /* Don't perform link validation when the userspace API is disabled as 255 /*
256 * Don't perform link validation when the userspace API is disabled as
231 * the pipeline is configured internally by the driver in that case, and 257 * the pipeline is configured internally by the driver in that case, and
232 * its configuration can thus be trusted. 258 * its configuration can thus be trusted.
233 */ 259 */
@@ -279,7 +305,30 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
279 305
280 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities); 306 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities);
281 307
282 /* The LIF is only supported when used in conjunction with the DU, in 308 if (vsp1->info->features & VSP1_HAS_HGO && vsp1->info->uapi) {
309 vsp1->hgo = vsp1_hgo_create(vsp1);
310 if (IS_ERR(vsp1->hgo)) {
311 ret = PTR_ERR(vsp1->hgo);
312 goto done;
313 }
314
315 list_add_tail(&vsp1->hgo->histo.entity.list_dev,
316 &vsp1->entities);
317 }
318
319 if (vsp1->info->features & VSP1_HAS_HGT && vsp1->info->uapi) {
320 vsp1->hgt = vsp1_hgt_create(vsp1);
321 if (IS_ERR(vsp1->hgt)) {
322 ret = PTR_ERR(vsp1->hgt);
323 goto done;
324 }
325
326 list_add_tail(&vsp1->hgt->histo.entity.list_dev,
327 &vsp1->entities);
328 }
329
330 /*
331 * The LIF is only supported when used in conjunction with the DU, in
283 * which case the userspace API is disabled. If the userspace API is 332 * which case the userspace API is disabled. If the userspace API is
284 * enabled skip the LIF, even when present. 333 * enabled skip the LIF, even when present.
285 */ 334 */
@@ -391,7 +440,8 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
391 if (ret < 0) 440 if (ret < 0)
392 goto done; 441 goto done;
393 442
394 /* Register subdev nodes if the userspace API is enabled or initialize 443 /*
444 * Register subdev nodes if the userspace API is enabled or initialize
395 * the DRM pipeline otherwise. 445 * the DRM pipeline otherwise.
396 */ 446 */
397 if (vsp1->info->uapi) { 447 if (vsp1->info->uapi) {
@@ -562,8 +612,9 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
562 .version = VI6_IP_VERSION_MODEL_VSPS_H2, 612 .version = VI6_IP_VERSION_MODEL_VSPS_H2,
563 .model = "VSP1-S", 613 .model = "VSP1-S",
564 .gen = 2, 614 .gen = 2,
565 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT 615 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
566 | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP, 616 | VSP1_HAS_HGT | VSP1_HAS_LUT | VSP1_HAS_SRU
617 | VSP1_HAS_WPF_VFLIP,
567 .rpf_count = 5, 618 .rpf_count = 5,
568 .uds_count = 3, 619 .uds_count = 3,
569 .wpf_count = 4, 620 .wpf_count = 4,
@@ -583,7 +634,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
583 .version = VI6_IP_VERSION_MODEL_VSPD_GEN2, 634 .version = VI6_IP_VERSION_MODEL_VSPD_GEN2,
584 .model = "VSP1-D", 635 .model = "VSP1-D",
585 .gen = 2, 636 .gen = 2,
586 .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_LUT, 637 .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LIF
638 | VSP1_HAS_LUT,
587 .rpf_count = 4, 639 .rpf_count = 4,
588 .uds_count = 1, 640 .uds_count = 1,
589 .wpf_count = 1, 641 .wpf_count = 1,
@@ -593,8 +645,9 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
593 .version = VI6_IP_VERSION_MODEL_VSPS_M2, 645 .version = VI6_IP_VERSION_MODEL_VSPS_M2,
594 .model = "VSP1-S", 646 .model = "VSP1-S",
595 .gen = 2, 647 .gen = 2,
596 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT 648 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
597 | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP, 649 | VSP1_HAS_HGT | VSP1_HAS_LUT | VSP1_HAS_SRU
650 | VSP1_HAS_WPF_VFLIP,
598 .rpf_count = 5, 651 .rpf_count = 5,
599 .uds_count = 1, 652 .uds_count = 1,
600 .wpf_count = 4, 653 .wpf_count = 4,
@@ -626,8 +679,9 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
626 .version = VI6_IP_VERSION_MODEL_VSPI_GEN3, 679 .version = VI6_IP_VERSION_MODEL_VSPI_GEN3,
627 .model = "VSP2-I", 680 .model = "VSP2-I",
628 .gen = 3, 681 .gen = 3,
629 .features = VSP1_HAS_CLU | VSP1_HAS_LUT | VSP1_HAS_SRU 682 .features = VSP1_HAS_CLU | VSP1_HAS_HGO | VSP1_HAS_HGT
630 | VSP1_HAS_WPF_HFLIP | VSP1_HAS_WPF_VFLIP, 683 | VSP1_HAS_LUT | VSP1_HAS_SRU | VSP1_HAS_WPF_HFLIP
684 | VSP1_HAS_WPF_VFLIP,
631 .rpf_count = 1, 685 .rpf_count = 1,
632 .uds_count = 1, 686 .uds_count = 1,
633 .wpf_count = 1, 687 .wpf_count = 1,
@@ -645,8 +699,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
645 .version = VI6_IP_VERSION_MODEL_VSPBC_GEN3, 699 .version = VI6_IP_VERSION_MODEL_VSPBC_GEN3,
646 .model = "VSP2-BC", 700 .model = "VSP2-BC",
647 .gen = 3, 701 .gen = 3,
648 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT 702 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_HGO
649 | VSP1_HAS_WPF_VFLIP, 703 | VSP1_HAS_LUT | VSP1_HAS_WPF_VFLIP,
650 .rpf_count = 5, 704 .rpf_count = 5,
651 .wpf_count = 1, 705 .wpf_count = 1,
652 .num_bru_inputs = 5, 706 .num_bru_inputs = 5,
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index da673495c222..4bdb3b141611 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -21,6 +21,8 @@
21#include "vsp1.h" 21#include "vsp1.h"
22#include "vsp1_dl.h" 22#include "vsp1_dl.h"
23#include "vsp1_entity.h" 23#include "vsp1_entity.h"
24#include "vsp1_pipe.h"
25#include "vsp1_rwpf.h"
24 26
25static inline struct vsp1_entity * 27static inline struct vsp1_entity *
26media_entity_to_vsp1_entity(struct media_entity *entity) 28media_entity_to_vsp1_entity(struct media_entity *entity)
@@ -28,11 +30,42 @@ media_entity_to_vsp1_entity(struct media_entity *entity)
28 return container_of(entity, struct vsp1_entity, subdev.entity); 30 return container_of(entity, struct vsp1_entity, subdev.entity);
29} 31}
30 32
31void vsp1_entity_route_setup(struct vsp1_entity *source, 33void vsp1_entity_route_setup(struct vsp1_entity *entity,
34 struct vsp1_pipeline *pipe,
32 struct vsp1_dl_list *dl) 35 struct vsp1_dl_list *dl)
33{ 36{
37 struct vsp1_entity *source;
34 struct vsp1_entity *sink; 38 struct vsp1_entity *sink;
35 39
40 if (entity->type == VSP1_ENTITY_HGO) {
41 u32 smppt;
42
43 /*
44 * The HGO is a special case, its routing is configured on the
45 * sink pad.
46 */
47 source = media_entity_to_vsp1_entity(entity->sources[0]);
48 smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
49 | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
50
51 vsp1_dl_list_write(dl, VI6_DPR_HGO_SMPPT, smppt);
52 return;
53 } else if (entity->type == VSP1_ENTITY_HGT) {
54 u32 smppt;
55
56 /*
57 * The HGT is a special case, its routing is configured on the
58 * sink pad.
59 */
60 source = media_entity_to_vsp1_entity(entity->sources[0]);
61 smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
62 | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
63
64 vsp1_dl_list_write(dl, VI6_DPR_HGT_SMPPT, smppt);
65 return;
66 }
67
68 source = entity;
36 if (source->route->reg == 0) 69 if (source->route->reg == 0)
37 return; 70 return;
38 71
@@ -199,7 +232,8 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
199 struct v4l2_subdev_pad_config *config; 232 struct v4l2_subdev_pad_config *config;
200 struct v4l2_mbus_framefmt *format; 233 struct v4l2_mbus_framefmt *format;
201 234
202 /* The entity can't perform format conversion, the sink format 235 /*
236 * The entity can't perform format conversion, the sink format
203 * is always identical to the source format. 237 * is always identical to the source format.
204 */ 238 */
205 if (code->index) 239 if (code->index)
@@ -263,7 +297,8 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
263 fse->min_height = min_height; 297 fse->min_height = min_height;
264 fse->max_height = max_height; 298 fse->max_height = max_height;
265 } else { 299 } else {
266 /* The size on the source pad are fixed and always identical to 300 /*
301 * The size on the source pad are fixed and always identical to
267 * the size on the sink pad. 302 * the size on the sink pad.
268 */ 303 */
269 fse->min_width = format->width; 304 fse->min_width = format->width;
@@ -281,25 +316,32 @@ done:
281 * Media Operations 316 * Media Operations
282 */ 317 */
283 318
284int vsp1_entity_link_setup(struct media_entity *entity, 319static int vsp1_entity_link_setup_source(const struct media_pad *source_pad,
285 const struct media_pad *local, 320 const struct media_pad *sink_pad,
286 const struct media_pad *remote, u32 flags) 321 u32 flags)
287{ 322{
288 struct vsp1_entity *source; 323 struct vsp1_entity *source;
289 324
290 if (!(local->flags & MEDIA_PAD_FL_SOURCE)) 325 source = media_entity_to_vsp1_entity(source_pad->entity);
291 return 0;
292
293 source = media_entity_to_vsp1_entity(local->entity);
294 326
295 if (!source->route) 327 if (!source->route)
296 return 0; 328 return 0;
297 329
298 if (flags & MEDIA_LNK_FL_ENABLED) { 330 if (flags & MEDIA_LNK_FL_ENABLED) {
299 if (source->sink) 331 struct vsp1_entity *sink
300 return -EBUSY; 332 = media_entity_to_vsp1_entity(sink_pad->entity);
301 source->sink = remote->entity; 333
302 source->sink_pad = remote->index; 334 /*
335 * Fan-out is limited to one for the normal data path plus
336 * optional HGO and HGT. We ignore the HGO and HGT here.
337 */
338 if (sink->type != VSP1_ENTITY_HGO &&
339 sink->type != VSP1_ENTITY_HGT) {
340 if (source->sink)
341 return -EBUSY;
342 source->sink = sink_pad->entity;
343 source->sink_pad = sink_pad->index;
344 }
303 } else { 345 } else {
304 source->sink = NULL; 346 source->sink = NULL;
305 source->sink_pad = 0; 347 source->sink_pad = 0;
@@ -308,6 +350,85 @@ int vsp1_entity_link_setup(struct media_entity *entity,
308 return 0; 350 return 0;
309} 351}
310 352
353static int vsp1_entity_link_setup_sink(const struct media_pad *source_pad,
354 const struct media_pad *sink_pad,
355 u32 flags)
356{
357 struct vsp1_entity *sink;
358
359 sink = media_entity_to_vsp1_entity(sink_pad->entity);
360
361 if (flags & MEDIA_LNK_FL_ENABLED) {
362 /* Fan-in is limited to one. */
363 if (sink->sources[sink_pad->index])
364 return -EBUSY;
365
366 sink->sources[sink_pad->index] = source_pad->entity;
367 } else {
368 sink->sources[sink_pad->index] = NULL;
369 }
370
371 return 0;
372}
373
374int vsp1_entity_link_setup(struct media_entity *entity,
375 const struct media_pad *local,
376 const struct media_pad *remote, u32 flags)
377{
378 if (local->flags & MEDIA_PAD_FL_SOURCE)
379 return vsp1_entity_link_setup_source(local, remote, flags);
380 else
381 return vsp1_entity_link_setup_sink(remote, local, flags);
382}
383
384/**
385 * vsp1_entity_remote_pad - Find the pad at the remote end of a link
386 * @pad: Pad at the local end of the link
387 *
388 * Search for a remote pad connected to the given pad by iterating over all
389 * links originating or terminating at that pad until an enabled link is found.
390 *
391 * Our link setup implementation guarantees that the output fan-out will not be
392 * higher than one for the data pipelines, except for the links to the HGO and
393 * HGT that can be enabled in addition to a regular data link. When traversing
394 * outgoing links this function ignores HGO and HGT entities and should thus be
395 * used in place of the generic media_entity_remote_pad() function to traverse
396 * data pipelines.
397 *
398 * Return a pointer to the pad at the remote end of the first found enabled
399 * link, or NULL if no enabled link has been found.
400 */
401struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
402{
403 struct media_link *link;
404
405 list_for_each_entry(link, &pad->entity->links, list) {
406 struct vsp1_entity *entity;
407
408 if (!(link->flags & MEDIA_LNK_FL_ENABLED))
409 continue;
410
411 /* If we're the sink the source will never be an HGO or HGT. */
412 if (link->sink == pad)
413 return link->source;
414
415 if (link->source != pad)
416 continue;
417
418 /* If the sink isn't a subdevice it can't be an HGO or HGT. */
419 if (!is_media_entity_v4l2_subdev(link->sink->entity))
420 return link->sink;
421
422 entity = media_entity_to_vsp1_entity(link->sink->entity);
423 if (entity->type != VSP1_ENTITY_HGO &&
424 entity->type != VSP1_ENTITY_HGT)
425 return link->sink;
426 }
427
428 return NULL;
429
430}
431
311/* ----------------------------------------------------------------------------- 432/* -----------------------------------------------------------------------------
312 * Initialization 433 * Initialization
313 */ 434 */
@@ -334,6 +455,8 @@ static const struct vsp1_route vsp1_routes[] = {
334 VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), 455 VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
335 VI6_DPR_NODE_BRU_IN(4) }, VI6_DPR_NODE_BRU_OUT }, 456 VI6_DPR_NODE_BRU_IN(4) }, VI6_DPR_NODE_BRU_OUT },
336 VSP1_ENTITY_ROUTE(CLU), 457 VSP1_ENTITY_ROUTE(CLU),
458 { VSP1_ENTITY_HGO, 0, 0, { 0, }, 0 },
459 { VSP1_ENTITY_HGT, 0, 0, { 0, }, 0 },
337 VSP1_ENTITY_ROUTE(HSI), 460 VSP1_ENTITY_ROUTE(HSI),
338 VSP1_ENTITY_ROUTE(HST), 461 VSP1_ENTITY_ROUTE(HST),
339 { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, }, VI6_DPR_NODE_LIF }, 462 { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, }, VI6_DPR_NODE_LIF },
@@ -386,7 +509,14 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
386 for (i = 0; i < num_pads - 1; ++i) 509 for (i = 0; i < num_pads - 1; ++i)
387 entity->pads[i].flags = MEDIA_PAD_FL_SINK; 510 entity->pads[i].flags = MEDIA_PAD_FL_SINK;
388 511
389 entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE; 512 entity->sources = devm_kcalloc(vsp1->dev, max(num_pads - 1, 1U),
513 sizeof(*entity->sources), GFP_KERNEL);
514 if (entity->sources == NULL)
515 return -ENOMEM;
516
517 /* Single-pad entities only have a sink. */
518 entity->pads[num_pads - 1].flags = num_pads > 1 ? MEDIA_PAD_FL_SOURCE
519 : MEDIA_PAD_FL_SINK;
390 520
391 /* Initialize the media entity. */ 521 /* Initialize the media entity. */
392 ret = media_entity_pads_init(&entity->subdev.entity, num_pads, 522 ret = media_entity_pads_init(&entity->subdev.entity, num_pads,
@@ -407,7 +537,8 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
407 537
408 vsp1_entity_init_cfg(subdev, NULL); 538 vsp1_entity_init_cfg(subdev, NULL);
409 539
410 /* Allocate the pad configuration to store formats and selection 540 /*
541 * Allocate the pad configuration to store formats and selection
411 * rectangles. 542 * rectangles.
412 */ 543 */
413 entity->config = v4l2_subdev_alloc_pad_config(&entity->subdev); 544 entity->config = v4l2_subdev_alloc_pad_config(&entity->subdev);
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 901146f807b9..c169a060b6d2 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -25,6 +25,8 @@ struct vsp1_pipeline;
25enum vsp1_entity_type { 25enum vsp1_entity_type {
26 VSP1_ENTITY_BRU, 26 VSP1_ENTITY_BRU,
27 VSP1_ENTITY_CLU, 27 VSP1_ENTITY_CLU,
28 VSP1_ENTITY_HGO,
29 VSP1_ENTITY_HGT,
28 VSP1_ENTITY_HSI, 30 VSP1_ENTITY_HSI,
29 VSP1_ENTITY_HST, 31 VSP1_ENTITY_HST,
30 VSP1_ENTITY_LIF, 32 VSP1_ENTITY_LIF,
@@ -102,6 +104,7 @@ struct vsp1_entity {
102 struct media_pad *pads; 104 struct media_pad *pads;
103 unsigned int source_pad; 105 unsigned int source_pad;
104 106
107 struct media_entity **sources;
105 struct media_entity *sink; 108 struct media_entity *sink;
106 unsigned int sink_pad; 109 unsigned int sink_pad;
107 110
@@ -142,9 +145,12 @@ vsp1_entity_get_pad_selection(struct vsp1_entity *entity,
142int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, 145int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
143 struct v4l2_subdev_pad_config *cfg); 146 struct v4l2_subdev_pad_config *cfg);
144 147
145void vsp1_entity_route_setup(struct vsp1_entity *source, 148void vsp1_entity_route_setup(struct vsp1_entity *entity,
149 struct vsp1_pipeline *pipe,
146 struct vsp1_dl_list *dl); 150 struct vsp1_dl_list *dl);
147 151
152struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
153
148int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, 154int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
149 struct v4l2_subdev_pad_config *cfg, 155 struct v4l2_subdev_pad_config *cfg,
150 struct v4l2_subdev_format *fmt); 156 struct v4l2_subdev_format *fmt);
diff --git a/drivers/media/platform/vsp1/vsp1_hgo.c b/drivers/media/platform/vsp1/vsp1_hgo.c
new file mode 100644
index 000000000000..50309c053b78
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_hgo.c
@@ -0,0 +1,230 @@
1/*
2 * vsp1_hgo.c -- R-Car VSP1 Histogram Generator 1D
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/gfp.h>
16
17#include <media/v4l2-subdev.h>
18#include <media/videobuf2-vmalloc.h>
19
20#include "vsp1.h"
21#include "vsp1_dl.h"
22#include "vsp1_hgo.h"
23
24#define HGO_DATA_SIZE ((2 + 256) * 4)
25
26/* -----------------------------------------------------------------------------
27 * Device Access
28 */
29
30static inline u32 vsp1_hgo_read(struct vsp1_hgo *hgo, u32 reg)
31{
32 return vsp1_read(hgo->histo.entity.vsp1, reg);
33}
34
35static inline void vsp1_hgo_write(struct vsp1_hgo *hgo, struct vsp1_dl_list *dl,
36 u32 reg, u32 data)
37{
38 vsp1_dl_list_write(dl, reg, data);
39}
40
41/* -----------------------------------------------------------------------------
42 * Frame End Handler
43 */
44
45void vsp1_hgo_frame_end(struct vsp1_entity *entity)
46{
47 struct vsp1_hgo *hgo = to_hgo(&entity->subdev);
48 struct vsp1_histogram_buffer *buf;
49 unsigned int i;
50 size_t size;
51 u32 *data;
52
53 buf = vsp1_histogram_buffer_get(&hgo->histo);
54 if (!buf)
55 return;
56
57 data = buf->addr;
58
59 if (hgo->num_bins == 256) {
60 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_MAXMIN);
61 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_SUM);
62
63 for (i = 0; i < 256; ++i) {
64 vsp1_write(hgo->histo.entity.vsp1,
65 VI6_HGO_EXT_HIST_ADDR, i);
66 *data++ = vsp1_hgo_read(hgo, VI6_HGO_EXT_HIST_DATA);
67 }
68
69 size = (2 + 256) * sizeof(u32);
70 } else if (hgo->max_rgb) {
71 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_MAXMIN);
72 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_SUM);
73
74 for (i = 0; i < 64; ++i)
75 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_HISTO(i));
76
77 size = (2 + 64) * sizeof(u32);
78 } else {
79 *data++ = vsp1_hgo_read(hgo, VI6_HGO_R_MAXMIN);
80 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_MAXMIN);
81 *data++ = vsp1_hgo_read(hgo, VI6_HGO_B_MAXMIN);
82
83 *data++ = vsp1_hgo_read(hgo, VI6_HGO_R_SUM);
84 *data++ = vsp1_hgo_read(hgo, VI6_HGO_G_SUM);
85 *data++ = vsp1_hgo_read(hgo, VI6_HGO_B_SUM);
86
87 for (i = 0; i < 64; ++i) {
88 data[i] = vsp1_hgo_read(hgo, VI6_HGO_R_HISTO(i));
89 data[i+64] = vsp1_hgo_read(hgo, VI6_HGO_G_HISTO(i));
90 data[i+128] = vsp1_hgo_read(hgo, VI6_HGO_B_HISTO(i));
91 }
92
93 size = (6 + 64 * 3) * sizeof(u32);
94 }
95
96 vsp1_histogram_buffer_complete(&hgo->histo, buf, size);
97}
98
99/* -----------------------------------------------------------------------------
100 * Controls
101 */
102
103#define V4L2_CID_VSP1_HGO_MAX_RGB (V4L2_CID_USER_BASE | 0x1001)
104#define V4L2_CID_VSP1_HGO_NUM_BINS (V4L2_CID_USER_BASE | 0x1002)
105
106static const struct v4l2_ctrl_config hgo_max_rgb_control = {
107 .id = V4L2_CID_VSP1_HGO_MAX_RGB,
108 .name = "Maximum RGB Mode",
109 .type = V4L2_CTRL_TYPE_BOOLEAN,
110 .min = 0,
111 .max = 1,
112 .def = 0,
113 .step = 1,
114 .flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
115};
116
117static const s64 hgo_num_bins[] = {
118 64, 256,
119};
120
121static const struct v4l2_ctrl_config hgo_num_bins_control = {
122 .id = V4L2_CID_VSP1_HGO_NUM_BINS,
123 .name = "Number of Bins",
124 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
125 .min = 0,
126 .max = 1,
127 .def = 0,
128 .qmenu_int = hgo_num_bins,
129 .flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
130};
131
132/* -----------------------------------------------------------------------------
133 * VSP1 Entity Operations
134 */
135
136static void hgo_configure(struct vsp1_entity *entity,
137 struct vsp1_pipeline *pipe,
138 struct vsp1_dl_list *dl,
139 enum vsp1_entity_params params)
140{
141 struct vsp1_hgo *hgo = to_hgo(&entity->subdev);
142 struct v4l2_rect *compose;
143 struct v4l2_rect *crop;
144 unsigned int hratio;
145 unsigned int vratio;
146
147 if (params != VSP1_ENTITY_PARAMS_INIT)
148 return;
149
150 crop = vsp1_entity_get_pad_selection(entity, entity->config,
151 HISTO_PAD_SINK, V4L2_SEL_TGT_CROP);
152 compose = vsp1_entity_get_pad_selection(entity, entity->config,
153 HISTO_PAD_SINK,
154 V4L2_SEL_TGT_COMPOSE);
155
156 vsp1_hgo_write(hgo, dl, VI6_HGO_REGRST, VI6_HGO_REGRST_RCLEA);
157
158 vsp1_hgo_write(hgo, dl, VI6_HGO_OFFSET,
159 (crop->left << VI6_HGO_OFFSET_HOFFSET_SHIFT) |
160 (crop->top << VI6_HGO_OFFSET_VOFFSET_SHIFT));
161 vsp1_hgo_write(hgo, dl, VI6_HGO_SIZE,
162 (crop->width << VI6_HGO_SIZE_HSIZE_SHIFT) |
163 (crop->height << VI6_HGO_SIZE_VSIZE_SHIFT));
164
165 mutex_lock(hgo->ctrls.handler.lock);
166 hgo->max_rgb = hgo->ctrls.max_rgb->cur.val;
167 if (hgo->ctrls.num_bins)
168 hgo->num_bins = hgo_num_bins[hgo->ctrls.num_bins->cur.val];
169 mutex_unlock(hgo->ctrls.handler.lock);
170
171 hratio = crop->width * 2 / compose->width / 3;
172 vratio = crop->height * 2 / compose->height / 3;
173 vsp1_hgo_write(hgo, dl, VI6_HGO_MODE,
174 (hgo->num_bins == 256 ? VI6_HGO_MODE_STEP : 0) |
175 (hgo->max_rgb ? VI6_HGO_MODE_MAXRGB : 0) |
176 (hratio << VI6_HGO_MODE_HRATIO_SHIFT) |
177 (vratio << VI6_HGO_MODE_VRATIO_SHIFT));
178}
179
180static const struct vsp1_entity_operations hgo_entity_ops = {
181 .configure = hgo_configure,
182 .destroy = vsp1_histogram_destroy,
183};
184
185/* -----------------------------------------------------------------------------
186 * Initialization and Cleanup
187 */
188
189static const unsigned int hgo_mbus_formats[] = {
190 MEDIA_BUS_FMT_AYUV8_1X32,
191 MEDIA_BUS_FMT_ARGB8888_1X32,
192 MEDIA_BUS_FMT_AHSV8888_1X32,
193};
194
195struct vsp1_hgo *vsp1_hgo_create(struct vsp1_device *vsp1)
196{
197 struct vsp1_hgo *hgo;
198 int ret;
199
200 hgo = devm_kzalloc(vsp1->dev, sizeof(*hgo), GFP_KERNEL);
201 if (hgo == NULL)
202 return ERR_PTR(-ENOMEM);
203
204 /* Initialize the control handler. */
205 v4l2_ctrl_handler_init(&hgo->ctrls.handler,
206 vsp1->info->gen == 3 ? 2 : 1);
207 hgo->ctrls.max_rgb = v4l2_ctrl_new_custom(&hgo->ctrls.handler,
208 &hgo_max_rgb_control, NULL);
209 if (vsp1->info->gen == 3)
210 hgo->ctrls.num_bins =
211 v4l2_ctrl_new_custom(&hgo->ctrls.handler,
212 &hgo_num_bins_control, NULL);
213
214 hgo->max_rgb = false;
215 hgo->num_bins = 64;
216
217 hgo->histo.entity.subdev.ctrl_handler = &hgo->ctrls.handler;
218
219 /* Initialize the video device and queue for statistics data. */
220 ret = vsp1_histogram_init(vsp1, &hgo->histo, VSP1_ENTITY_HGO, "hgo",
221 &hgo_entity_ops, hgo_mbus_formats,
222 ARRAY_SIZE(hgo_mbus_formats),
223 HGO_DATA_SIZE, V4L2_META_FMT_VSP1_HGO);
224 if (ret < 0) {
225 vsp1_entity_destroy(&hgo->histo.entity);
226 return ERR_PTR(ret);
227 }
228
229 return hgo;
230}
diff --git a/drivers/media/platform/vsp1/vsp1_hgo.h b/drivers/media/platform/vsp1/vsp1_hgo.h
new file mode 100644
index 000000000000..c6c0b7a80e0c
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_hgo.h
@@ -0,0 +1,45 @@
1/*
2 * vsp1_hgo.h -- R-Car VSP1 Histogram Generator 1D
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#ifndef __VSP1_HGO_H__
14#define __VSP1_HGO_H__
15
16#include <media/media-entity.h>
17#include <media/v4l2-ctrls.h>
18#include <media/v4l2-subdev.h>
19
20#include "vsp1_histo.h"
21
22struct vsp1_device;
23
24struct vsp1_hgo {
25 struct vsp1_histogram histo;
26
27 struct {
28 struct v4l2_ctrl_handler handler;
29 struct v4l2_ctrl *max_rgb;
30 struct v4l2_ctrl *num_bins;
31 } ctrls;
32
33 bool max_rgb;
34 unsigned int num_bins;
35};
36
37static inline struct vsp1_hgo *to_hgo(struct v4l2_subdev *subdev)
38{
39 return container_of(subdev, struct vsp1_hgo, histo.entity.subdev);
40}
41
42struct vsp1_hgo *vsp1_hgo_create(struct vsp1_device *vsp1);
43void vsp1_hgo_frame_end(struct vsp1_entity *hgo);
44
45#endif /* __VSP1_HGO_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_hgt.c b/drivers/media/platform/vsp1/vsp1_hgt.c
new file mode 100644
index 000000000000..b5ce305e3e6f
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_hgt.c
@@ -0,0 +1,222 @@
1/*
2 * vsp1_hgt.c -- R-Car VSP1 Histogram Generator 2D
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 *
6 * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/gfp.h>
16
17#include <media/v4l2-subdev.h>
18#include <media/videobuf2-vmalloc.h>
19
20#include "vsp1.h"
21#include "vsp1_dl.h"
22#include "vsp1_hgt.h"
23
24#define HGT_DATA_SIZE ((2 + 6 * 32) * 4)
25
26/* -----------------------------------------------------------------------------
27 * Device Access
28 */
29
30static inline u32 vsp1_hgt_read(struct vsp1_hgt *hgt, u32 reg)
31{
32 return vsp1_read(hgt->histo.entity.vsp1, reg);
33}
34
35static inline void vsp1_hgt_write(struct vsp1_hgt *hgt, struct vsp1_dl_list *dl,
36 u32 reg, u32 data)
37{
38 vsp1_dl_list_write(dl, reg, data);
39}
40
41/* -----------------------------------------------------------------------------
42 * Frame End Handler
43 */
44
45void vsp1_hgt_frame_end(struct vsp1_entity *entity)
46{
47 struct vsp1_hgt *hgt = to_hgt(&entity->subdev);
48 struct vsp1_histogram_buffer *buf;
49 unsigned int m;
50 unsigned int n;
51 u32 *data;
52
53 buf = vsp1_histogram_buffer_get(&hgt->histo);
54 if (!buf)
55 return;
56
57 data = buf->addr;
58
59 *data++ = vsp1_hgt_read(hgt, VI6_HGT_MAXMIN);
60 *data++ = vsp1_hgt_read(hgt, VI6_HGT_SUM);
61
62 for (m = 0; m < 6; ++m)
63 for (n = 0; n < 32; ++n)
64 *data++ = vsp1_hgt_read(hgt, VI6_HGT_HISTO(m, n));
65
66 vsp1_histogram_buffer_complete(&hgt->histo, buf, HGT_DATA_SIZE);
67}
68
69/* -----------------------------------------------------------------------------
70 * Controls
71 */
72
73#define V4L2_CID_VSP1_HGT_HUE_AREAS (V4L2_CID_USER_BASE | 0x1001)
74
75static int hgt_hue_areas_try_ctrl(struct v4l2_ctrl *ctrl)
76{
77 const u8 *values = ctrl->p_new.p_u8;
78 unsigned int i;
79
80 /*
81 * The hardware has constraints on the hue area boundaries beyond the
82 * control min, max and step. The values must match one of the following
83 * expressions.
84 *
85 * 0L <= 0U <= 1L <= 1U <= 2L <= 2U <= 3L <= 3U <= 4L <= 4U <= 5L <= 5U
86 * 0U <= 1L <= 1U <= 2L <= 2U <= 3L <= 3U <= 4L <= 4U <= 5L <= 5U <= 0L
87 *
88 * Start by verifying the common part...
89 */
90 for (i = 1; i < (HGT_NUM_HUE_AREAS * 2) - 1; ++i) {
91 if (values[i] > values[i+1])
92 return -EINVAL;
93 }
94
95 /* ... and handle 0L separately. */
96 if (values[0] > values[1] && values[11] > values[0])
97 return -EINVAL;
98
99 return 0;
100}
101
102static int hgt_hue_areas_s_ctrl(struct v4l2_ctrl *ctrl)
103{
104 struct vsp1_hgt *hgt = container_of(ctrl->handler, struct vsp1_hgt,
105 ctrls);
106
107 memcpy(hgt->hue_areas, ctrl->p_new.p_u8, sizeof(hgt->hue_areas));
108 return 0;
109}
110
111static const struct v4l2_ctrl_ops hgt_hue_areas_ctrl_ops = {
112 .try_ctrl = hgt_hue_areas_try_ctrl,
113 .s_ctrl = hgt_hue_areas_s_ctrl,
114};
115
116static const struct v4l2_ctrl_config hgt_hue_areas = {
117 .ops = &hgt_hue_areas_ctrl_ops,
118 .id = V4L2_CID_VSP1_HGT_HUE_AREAS,
119 .name = "Boundary Values for Hue Area",
120 .type = V4L2_CTRL_TYPE_U8,
121 .min = 0,
122 .max = 255,
123 .def = 0,
124 .step = 1,
125 .dims = { 12 },
126};
127
128/* -----------------------------------------------------------------------------
129 * VSP1 Entity Operations
130 */
131
132static void hgt_configure(struct vsp1_entity *entity,
133 struct vsp1_pipeline *pipe,
134 struct vsp1_dl_list *dl,
135 enum vsp1_entity_params params)
136{
137 struct vsp1_hgt *hgt = to_hgt(&entity->subdev);
138 struct v4l2_rect *compose;
139 struct v4l2_rect *crop;
140 unsigned int hratio;
141 unsigned int vratio;
142 u8 lower;
143 u8 upper;
144 unsigned int i;
145
146 if (params != VSP1_ENTITY_PARAMS_INIT)
147 return;
148
149 crop = vsp1_entity_get_pad_selection(entity, entity->config,
150 HISTO_PAD_SINK, V4L2_SEL_TGT_CROP);
151 compose = vsp1_entity_get_pad_selection(entity, entity->config,
152 HISTO_PAD_SINK,
153 V4L2_SEL_TGT_COMPOSE);
154
155 vsp1_hgt_write(hgt, dl, VI6_HGT_REGRST, VI6_HGT_REGRST_RCLEA);
156
157 vsp1_hgt_write(hgt, dl, VI6_HGT_OFFSET,
158 (crop->left << VI6_HGT_OFFSET_HOFFSET_SHIFT) |
159 (crop->top << VI6_HGT_OFFSET_VOFFSET_SHIFT));
160 vsp1_hgt_write(hgt, dl, VI6_HGT_SIZE,
161 (crop->width << VI6_HGT_SIZE_HSIZE_SHIFT) |
162 (crop->height << VI6_HGT_SIZE_VSIZE_SHIFT));
163
164 mutex_lock(hgt->ctrls.lock);
165 for (i = 0; i < HGT_NUM_HUE_AREAS; ++i) {
166 lower = hgt->hue_areas[i*2 + 0];
167 upper = hgt->hue_areas[i*2 + 1];
168 vsp1_hgt_write(hgt, dl, VI6_HGT_HUE_AREA(i),
169 (lower << VI6_HGT_HUE_AREA_LOWER_SHIFT) |
170 (upper << VI6_HGT_HUE_AREA_UPPER_SHIFT));
171 }
172 mutex_unlock(hgt->ctrls.lock);
173
174 hratio = crop->width * 2 / compose->width / 3;
175 vratio = crop->height * 2 / compose->height / 3;
176 vsp1_hgt_write(hgt, dl, VI6_HGT_MODE,
177 (hratio << VI6_HGT_MODE_HRATIO_SHIFT) |
178 (vratio << VI6_HGT_MODE_VRATIO_SHIFT));
179}
180
181static const struct vsp1_entity_operations hgt_entity_ops = {
182 .configure = hgt_configure,
183 .destroy = vsp1_histogram_destroy,
184};
185
186/* -----------------------------------------------------------------------------
187 * Initialization and Cleanup
188 */
189
190static const unsigned int hgt_mbus_formats[] = {
191 MEDIA_BUS_FMT_AHSV8888_1X32,
192};
193
194struct vsp1_hgt *vsp1_hgt_create(struct vsp1_device *vsp1)
195{
196 struct vsp1_hgt *hgt;
197 int ret;
198
199 hgt = devm_kzalloc(vsp1->dev, sizeof(*hgt), GFP_KERNEL);
200 if (hgt == NULL)
201 return ERR_PTR(-ENOMEM);
202
203 /* Initialize the control handler. */
204 v4l2_ctrl_handler_init(&hgt->ctrls, 1);
205 v4l2_ctrl_new_custom(&hgt->ctrls, &hgt_hue_areas, NULL);
206
207 hgt->histo.entity.subdev.ctrl_handler = &hgt->ctrls;
208
209 /* Initialize the video device and queue for statistics data. */
210 ret = vsp1_histogram_init(vsp1, &hgt->histo, VSP1_ENTITY_HGT, "hgt",
211 &hgt_entity_ops, hgt_mbus_formats,
212 ARRAY_SIZE(hgt_mbus_formats),
213 HGT_DATA_SIZE, V4L2_META_FMT_VSP1_HGT);
214 if (ret < 0) {
215 vsp1_entity_destroy(&hgt->histo.entity);
216 return ERR_PTR(ret);
217 }
218
219 v4l2_ctrl_handler_setup(&hgt->ctrls);
220
221 return hgt;
222}
diff --git a/drivers/media/platform/vsp1/vsp1_hgt.h b/drivers/media/platform/vsp1/vsp1_hgt.h
new file mode 100644
index 000000000000..83f2e130942a
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_hgt.h
@@ -0,0 +1,42 @@
1/*
2 * vsp1_hgt.h -- R-Car VSP1 Histogram Generator 2D
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 *
6 * Contact: Niklas Söderlund (niklas.soderlund@ragnatech.se)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#ifndef __VSP1_HGT_H__
14#define __VSP1_HGT_H__
15
16#include <media/media-entity.h>
17#include <media/v4l2-ctrls.h>
18#include <media/v4l2-subdev.h>
19
20#include "vsp1_histo.h"
21
22struct vsp1_device;
23
24#define HGT_NUM_HUE_AREAS 6
25
26struct vsp1_hgt {
27 struct vsp1_histogram histo;
28
29 struct v4l2_ctrl_handler ctrls;
30
31 u8 hue_areas[HGT_NUM_HUE_AREAS * 2];
32};
33
34static inline struct vsp1_hgt *to_hgt(struct v4l2_subdev *subdev)
35{
36 return container_of(subdev, struct vsp1_hgt, histo.entity.subdev);
37}
38
39struct vsp1_hgt *vsp1_hgt_create(struct vsp1_device *vsp1);
40void vsp1_hgt_frame_end(struct vsp1_entity *hgt);
41
42#endif /* __VSP1_HGT_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
new file mode 100644
index 000000000000..afab77cf4fa5
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_histo.c
@@ -0,0 +1,646 @@
1/*
2 * vsp1_histo.c -- R-Car VSP1 Histogram API
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 * Copyright (C) 2016 Laurent Pinchart
6 *
7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#include <linux/device.h>
16#include <linux/gfp.h>
17
18#include <media/v4l2-ioctl.h>
19#include <media/v4l2-subdev.h>
20#include <media/videobuf2-vmalloc.h>
21
22#include "vsp1.h"
23#include "vsp1_histo.h"
24#include "vsp1_pipe.h"
25
26#define HISTO_MIN_SIZE 4U
27#define HISTO_MAX_SIZE 8192U
28
29/* -----------------------------------------------------------------------------
30 * Buffer Operations
31 */
32
33static inline struct vsp1_histogram_buffer *
34to_vsp1_histogram_buffer(struct vb2_v4l2_buffer *vbuf)
35{
36 return container_of(vbuf, struct vsp1_histogram_buffer, buf);
37}
38
39struct vsp1_histogram_buffer *
40vsp1_histogram_buffer_get(struct vsp1_histogram *histo)
41{
42 struct vsp1_histogram_buffer *buf = NULL;
43 unsigned long flags;
44
45 spin_lock_irqsave(&histo->irqlock, flags);
46
47 if (list_empty(&histo->irqqueue))
48 goto done;
49
50 buf = list_first_entry(&histo->irqqueue, struct vsp1_histogram_buffer,
51 queue);
52 list_del(&buf->queue);
53 histo->readout = true;
54
55done:
56 spin_unlock_irqrestore(&histo->irqlock, flags);
57 return buf;
58}
59
60void vsp1_histogram_buffer_complete(struct vsp1_histogram *histo,
61 struct vsp1_histogram_buffer *buf,
62 size_t size)
63{
64 struct vsp1_pipeline *pipe = histo->pipe;
65 unsigned long flags;
66
67 /*
68 * The pipeline pointer is guaranteed to be valid as this function is
69 * called from the frame completion interrupt handler, which can only
70 * occur when video streaming is active.
71 */
72 buf->buf.sequence = pipe->sequence;
73 buf->buf.vb2_buf.timestamp = ktime_get_ns();
74 vb2_set_plane_payload(&buf->buf.vb2_buf, 0, size);
75 vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
76
77 spin_lock_irqsave(&histo->irqlock, flags);
78 histo->readout = false;
79 wake_up(&histo->wait_queue);
80 spin_unlock_irqrestore(&histo->irqlock, flags);
81}
82
83/* -----------------------------------------------------------------------------
84 * videobuf2 Queue Operations
85 */
86
87static int histo_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
88 unsigned int *nplanes, unsigned int sizes[],
89 struct device *alloc_devs[])
90{
91 struct vsp1_histogram *histo = vb2_get_drv_priv(vq);
92
93 if (*nplanes) {
94 if (*nplanes != 1)
95 return -EINVAL;
96
97 if (sizes[0] < histo->data_size)
98 return -EINVAL;
99
100 return 0;
101 }
102
103 *nplanes = 1;
104 sizes[0] = histo->data_size;
105
106 return 0;
107}
108
109static int histo_buffer_prepare(struct vb2_buffer *vb)
110{
111 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
112 struct vsp1_histogram *histo = vb2_get_drv_priv(vb->vb2_queue);
113 struct vsp1_histogram_buffer *buf = to_vsp1_histogram_buffer(vbuf);
114
115 if (vb->num_planes != 1)
116 return -EINVAL;
117
118 if (vb2_plane_size(vb, 0) < histo->data_size)
119 return -EINVAL;
120
121 buf->addr = vb2_plane_vaddr(vb, 0);
122
123 return 0;
124}
125
126static void histo_buffer_queue(struct vb2_buffer *vb)
127{
128 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
129 struct vsp1_histogram *histo = vb2_get_drv_priv(vb->vb2_queue);
130 struct vsp1_histogram_buffer *buf = to_vsp1_histogram_buffer(vbuf);
131 unsigned long flags;
132
133 spin_lock_irqsave(&histo->irqlock, flags);
134 list_add_tail(&buf->queue, &histo->irqqueue);
135 spin_unlock_irqrestore(&histo->irqlock, flags);
136}
137
138static int histo_start_streaming(struct vb2_queue *vq, unsigned int count)
139{
140 return 0;
141}
142
143static void histo_stop_streaming(struct vb2_queue *vq)
144{
145 struct vsp1_histogram *histo = vb2_get_drv_priv(vq);
146 struct vsp1_histogram_buffer *buffer;
147 unsigned long flags;
148
149 spin_lock_irqsave(&histo->irqlock, flags);
150
151 /* Remove all buffers from the IRQ queue. */
152 list_for_each_entry(buffer, &histo->irqqueue, queue)
153 vb2_buffer_done(&buffer->buf.vb2_buf, VB2_BUF_STATE_ERROR);
154 INIT_LIST_HEAD(&histo->irqqueue);
155
156 /* Wait for the buffer being read out (if any) to complete. */
157 wait_event_lock_irq(histo->wait_queue, !histo->readout, histo->irqlock);
158
159 spin_unlock_irqrestore(&histo->irqlock, flags);
160}
161
162static const struct vb2_ops histo_video_queue_qops = {
163 .queue_setup = histo_queue_setup,
164 .buf_prepare = histo_buffer_prepare,
165 .buf_queue = histo_buffer_queue,
166 .wait_prepare = vb2_ops_wait_prepare,
167 .wait_finish = vb2_ops_wait_finish,
168 .start_streaming = histo_start_streaming,
169 .stop_streaming = histo_stop_streaming,
170};
171
172/* -----------------------------------------------------------------------------
173 * V4L2 Subdevice Operations
174 */
175
176static int histo_enum_mbus_code(struct v4l2_subdev *subdev,
177 struct v4l2_subdev_pad_config *cfg,
178 struct v4l2_subdev_mbus_code_enum *code)
179{
180 struct vsp1_histogram *histo = subdev_to_histo(subdev);
181
182 if (code->pad == HISTO_PAD_SOURCE) {
183 code->code = MEDIA_BUS_FMT_FIXED;
184 return 0;
185 }
186
187 return vsp1_subdev_enum_mbus_code(subdev, cfg, code, histo->formats,
188 histo->num_formats);
189}
190
191static int histo_enum_frame_size(struct v4l2_subdev *subdev,
192 struct v4l2_subdev_pad_config *cfg,
193 struct v4l2_subdev_frame_size_enum *fse)
194{
195 if (fse->pad != HISTO_PAD_SINK)
196 return -EINVAL;
197
198 return vsp1_subdev_enum_frame_size(subdev, cfg, fse, HISTO_MIN_SIZE,
199 HISTO_MIN_SIZE, HISTO_MAX_SIZE,
200 HISTO_MAX_SIZE);
201}
202
203static int histo_get_selection(struct v4l2_subdev *subdev,
204 struct v4l2_subdev_pad_config *cfg,
205 struct v4l2_subdev_selection *sel)
206{
207 struct vsp1_histogram *histo = subdev_to_histo(subdev);
208 struct v4l2_subdev_pad_config *config;
209 struct v4l2_mbus_framefmt *format;
210 struct v4l2_rect *crop;
211 int ret = 0;
212
213 if (sel->pad != HISTO_PAD_SINK)
214 return -EINVAL;
215
216 mutex_lock(&histo->entity.lock);
217
218 config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which);
219 if (!config) {
220 ret = -EINVAL;
221 goto done;
222 }
223
224 switch (sel->target) {
225 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
226 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
227 crop = vsp1_entity_get_pad_selection(&histo->entity, config,
228 HISTO_PAD_SINK,
229 V4L2_SEL_TGT_CROP);
230 sel->r.left = 0;
231 sel->r.top = 0;
232 sel->r.width = crop->width;
233 sel->r.height = crop->height;
234 break;
235
236 case V4L2_SEL_TGT_CROP_BOUNDS:
237 case V4L2_SEL_TGT_CROP_DEFAULT:
238 format = vsp1_entity_get_pad_format(&histo->entity, config,
239 HISTO_PAD_SINK);
240 sel->r.left = 0;
241 sel->r.top = 0;
242 sel->r.width = format->width;
243 sel->r.height = format->height;
244 break;
245
246 case V4L2_SEL_TGT_COMPOSE:
247 case V4L2_SEL_TGT_CROP:
248 sel->r = *vsp1_entity_get_pad_selection(&histo->entity, config,
249 sel->pad, sel->target);
250 break;
251
252 default:
253 ret = -EINVAL;
254 break;
255 }
256
257done:
258 mutex_unlock(&histo->entity.lock);
259 return ret;
260}
261
262static int histo_set_crop(struct v4l2_subdev *subdev,
263 struct v4l2_subdev_pad_config *config,
264 struct v4l2_subdev_selection *sel)
265{
266 struct vsp1_histogram *histo = subdev_to_histo(subdev);
267 struct v4l2_mbus_framefmt *format;
268 struct v4l2_rect *selection;
269
270 /* The crop rectangle must be inside the input frame. */
271 format = vsp1_entity_get_pad_format(&histo->entity, config,
272 HISTO_PAD_SINK);
273 sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
274 sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
275 sel->r.width = clamp_t(unsigned int, sel->r.width, HISTO_MIN_SIZE,
276 format->width - sel->r.left);
277 sel->r.height = clamp_t(unsigned int, sel->r.height, HISTO_MIN_SIZE,
278 format->height - sel->r.top);
279
280 /* Set the crop rectangle and reset the compose rectangle. */
281 selection = vsp1_entity_get_pad_selection(&histo->entity, config,
282 sel->pad, V4L2_SEL_TGT_CROP);
283 *selection = sel->r;
284
285 selection = vsp1_entity_get_pad_selection(&histo->entity, config,
286 sel->pad,
287 V4L2_SEL_TGT_COMPOSE);
288 *selection = sel->r;
289
290 return 0;
291}
292
293static int histo_set_compose(struct v4l2_subdev *subdev,
294 struct v4l2_subdev_pad_config *config,
295 struct v4l2_subdev_selection *sel)
296{
297 struct vsp1_histogram *histo = subdev_to_histo(subdev);
298 struct v4l2_rect *compose;
299 struct v4l2_rect *crop;
300 unsigned int ratio;
301
302 /*
303 * The compose rectangle is used to configure downscaling, the top left
304 * corner is fixed to (0,0) and the size to 1/2 or 1/4 of the crop
305 * rectangle.
306 */
307 sel->r.left = 0;
308 sel->r.top = 0;
309
310 crop = vsp1_entity_get_pad_selection(&histo->entity, config, sel->pad,
311 V4L2_SEL_TGT_CROP);
312
313 /*
314 * Clamp the width and height to acceptable values first and then
315 * compute the closest rounded dividing ratio.
316 *
317 * Ratio Rounded ratio
318 * --------------------------
319 * [1.0 1.5[ 1
320 * [1.5 3.0[ 2
321 * [3.0 4.0] 4
322 *
323 * The rounded ratio can be computed using
324 *
325 * 1 << (ceil(ratio * 2) / 3)
326 */
327 sel->r.width = clamp(sel->r.width, crop->width / 4, crop->width);
328 ratio = 1 << (crop->width * 2 / sel->r.width / 3);
329 sel->r.width = crop->width / ratio;
330
331
332 sel->r.height = clamp(sel->r.height, crop->height / 4, crop->height);
333 ratio = 1 << (crop->height * 2 / sel->r.height / 3);
334 sel->r.height = crop->height / ratio;
335
336 compose = vsp1_entity_get_pad_selection(&histo->entity, config,
337 sel->pad,
338 V4L2_SEL_TGT_COMPOSE);
339 *compose = sel->r;
340
341 return 0;
342}
343
344static int histo_set_selection(struct v4l2_subdev *subdev,
345 struct v4l2_subdev_pad_config *cfg,
346 struct v4l2_subdev_selection *sel)
347{
348 struct vsp1_histogram *histo = subdev_to_histo(subdev);
349 struct v4l2_subdev_pad_config *config;
350 int ret;
351
352 if (sel->pad != HISTO_PAD_SINK)
353 return -EINVAL;
354
355 mutex_lock(&histo->entity.lock);
356
357 config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which);
358 if (!config) {
359 ret = -EINVAL;
360 goto done;
361 }
362
363 if (sel->target == V4L2_SEL_TGT_CROP)
364 ret = histo_set_crop(subdev, config, sel);
365 else if (sel->target == V4L2_SEL_TGT_COMPOSE)
366 ret = histo_set_compose(subdev, config, sel);
367 else
368 ret = -EINVAL;
369
370done:
371 mutex_unlock(&histo->entity.lock);
372 return ret;
373}
374
375static int histo_get_format(struct v4l2_subdev *subdev,
376 struct v4l2_subdev_pad_config *cfg,
377 struct v4l2_subdev_format *fmt)
378{
379 if (fmt->pad == HISTO_PAD_SOURCE) {
380 fmt->format.code = MEDIA_BUS_FMT_FIXED;
381 fmt->format.width = 0;
382 fmt->format.height = 0;
383 fmt->format.field = V4L2_FIELD_NONE;
384 fmt->format.colorspace = V4L2_COLORSPACE_RAW;
385 return 0;
386 }
387
388 return vsp1_subdev_get_pad_format(subdev, cfg, fmt);
389}
390
391static int histo_set_format(struct v4l2_subdev *subdev,
392 struct v4l2_subdev_pad_config *cfg,
393 struct v4l2_subdev_format *fmt)
394{
395 struct vsp1_histogram *histo = subdev_to_histo(subdev);
396 struct v4l2_subdev_pad_config *config;
397 struct v4l2_mbus_framefmt *format;
398 struct v4l2_rect *selection;
399 unsigned int i;
400 int ret = 0;
401
402 if (fmt->pad != HISTO_PAD_SINK)
403 return histo_get_format(subdev, cfg, fmt);
404
405 mutex_lock(&histo->entity.lock);
406
407 config = vsp1_entity_get_pad_config(&histo->entity, cfg, fmt->which);
408 if (!config) {
409 ret = -EINVAL;
410 goto done;
411 }
412
413 /*
414 * Default to the first format if the requested format is not
415 * supported.
416 */
417 for (i = 0; i < histo->num_formats; ++i) {
418 if (fmt->format.code == histo->formats[i])
419 break;
420 }
421 if (i == histo->num_formats)
422 fmt->format.code = histo->formats[0];
423
424 format = vsp1_entity_get_pad_format(&histo->entity, config, fmt->pad);
425
426 format->code = fmt->format.code;
427 format->width = clamp_t(unsigned int, fmt->format.width,
428 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
429 format->height = clamp_t(unsigned int, fmt->format.height,
430 HISTO_MIN_SIZE, HISTO_MAX_SIZE);
431 format->field = V4L2_FIELD_NONE;
432 format->colorspace = V4L2_COLORSPACE_SRGB;
433
434 fmt->format = *format;
435
436 /* Reset the crop and compose rectangles */
437 selection = vsp1_entity_get_pad_selection(&histo->entity, config,
438 fmt->pad, V4L2_SEL_TGT_CROP);
439 selection->left = 0;
440 selection->top = 0;
441 selection->width = format->width;
442 selection->height = format->height;
443
444 selection = vsp1_entity_get_pad_selection(&histo->entity, config,
445 fmt->pad,
446 V4L2_SEL_TGT_COMPOSE);
447 selection->left = 0;
448 selection->top = 0;
449 selection->width = format->width;
450 selection->height = format->height;
451
452done:
453 mutex_unlock(&histo->entity.lock);
454 return ret;
455}
456
457static const struct v4l2_subdev_pad_ops histo_pad_ops = {
458 .enum_mbus_code = histo_enum_mbus_code,
459 .enum_frame_size = histo_enum_frame_size,
460 .get_fmt = histo_get_format,
461 .set_fmt = histo_set_format,
462 .get_selection = histo_get_selection,
463 .set_selection = histo_set_selection,
464};
465
466static const struct v4l2_subdev_ops histo_ops = {
467 .pad = &histo_pad_ops,
468};
469
470/* -----------------------------------------------------------------------------
471 * V4L2 ioctls
472 */
473
474static int histo_v4l2_querycap(struct file *file, void *fh,
475 struct v4l2_capability *cap)
476{
477 struct v4l2_fh *vfh = file->private_data;
478 struct vsp1_histogram *histo = vdev_to_histo(vfh->vdev);
479
480 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
481 | V4L2_CAP_VIDEO_CAPTURE_MPLANE
482 | V4L2_CAP_VIDEO_OUTPUT_MPLANE
483 | V4L2_CAP_META_CAPTURE;
484 cap->device_caps = V4L2_CAP_META_CAPTURE
485 | V4L2_CAP_STREAMING;
486
487 strlcpy(cap->driver, "vsp1", sizeof(cap->driver));
488 strlcpy(cap->card, histo->video.name, sizeof(cap->card));
489 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
490 dev_name(histo->entity.vsp1->dev));
491
492 return 0;
493}
494
495static int histo_v4l2_enum_format(struct file *file, void *fh,
496 struct v4l2_fmtdesc *f)
497{
498 struct v4l2_fh *vfh = file->private_data;
499 struct vsp1_histogram *histo = vdev_to_histo(vfh->vdev);
500
501 if (f->index > 0 || f->type != histo->queue.type)
502 return -EINVAL;
503
504 f->pixelformat = histo->meta_format;
505
506 return 0;
507}
508
509static int histo_v4l2_get_format(struct file *file, void *fh,
510 struct v4l2_format *format)
511{
512 struct v4l2_fh *vfh = file->private_data;
513 struct vsp1_histogram *histo = vdev_to_histo(vfh->vdev);
514 struct v4l2_meta_format *meta = &format->fmt.meta;
515
516 if (format->type != histo->queue.type)
517 return -EINVAL;
518
519 memset(meta, 0, sizeof(*meta));
520
521 meta->dataformat = histo->meta_format;
522 meta->buffersize = histo->data_size;
523
524 return 0;
525}
526
527static const struct v4l2_ioctl_ops histo_v4l2_ioctl_ops = {
528 .vidioc_querycap = histo_v4l2_querycap,
529 .vidioc_enum_fmt_meta_cap = histo_v4l2_enum_format,
530 .vidioc_g_fmt_meta_cap = histo_v4l2_get_format,
531 .vidioc_s_fmt_meta_cap = histo_v4l2_get_format,
532 .vidioc_try_fmt_meta_cap = histo_v4l2_get_format,
533 .vidioc_reqbufs = vb2_ioctl_reqbufs,
534 .vidioc_querybuf = vb2_ioctl_querybuf,
535 .vidioc_qbuf = vb2_ioctl_qbuf,
536 .vidioc_dqbuf = vb2_ioctl_dqbuf,
537 .vidioc_create_bufs = vb2_ioctl_create_bufs,
538 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
539 .vidioc_streamon = vb2_ioctl_streamon,
540 .vidioc_streamoff = vb2_ioctl_streamoff,
541};
542
543/* -----------------------------------------------------------------------------
544 * V4L2 File Operations
545 */
546
547static const struct v4l2_file_operations histo_v4l2_fops = {
548 .owner = THIS_MODULE,
549 .unlocked_ioctl = video_ioctl2,
550 .open = v4l2_fh_open,
551 .release = vb2_fop_release,
552 .poll = vb2_fop_poll,
553 .mmap = vb2_fop_mmap,
554};
555
556static void vsp1_histogram_cleanup(struct vsp1_histogram *histo)
557{
558 if (video_is_registered(&histo->video))
559 video_unregister_device(&histo->video);
560
561 media_entity_cleanup(&histo->video.entity);
562}
563
564void vsp1_histogram_destroy(struct vsp1_entity *entity)
565{
566 struct vsp1_histogram *histo = subdev_to_histo(&entity->subdev);
567
568 vsp1_histogram_cleanup(histo);
569}
570
571int vsp1_histogram_init(struct vsp1_device *vsp1, struct vsp1_histogram *histo,
572 enum vsp1_entity_type type, const char *name,
573 const struct vsp1_entity_operations *ops,
574 const unsigned int *formats, unsigned int num_formats,
575 size_t data_size, u32 meta_format)
576{
577 int ret;
578
579 histo->formats = formats;
580 histo->num_formats = num_formats;
581 histo->data_size = data_size;
582 histo->meta_format = meta_format;
583
584 histo->pad.flags = MEDIA_PAD_FL_SINK;
585 histo->video.vfl_dir = VFL_DIR_RX;
586
587 mutex_init(&histo->lock);
588 spin_lock_init(&histo->irqlock);
589 INIT_LIST_HEAD(&histo->irqqueue);
590 init_waitqueue_head(&histo->wait_queue);
591
592 /* Initialize the VSP entity... */
593 histo->entity.ops = ops;
594 histo->entity.type = type;
595
596 ret = vsp1_entity_init(vsp1, &histo->entity, name, 2, &histo_ops,
597 MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
598 if (ret < 0)
599 return ret;
600
601 /* ... and the media entity... */
602 ret = media_entity_pads_init(&histo->video.entity, 1, &histo->pad);
603 if (ret < 0)
604 return ret;
605
606 /* ... and the video node... */
607 histo->video.v4l2_dev = &vsp1->v4l2_dev;
608 histo->video.fops = &histo_v4l2_fops;
609 snprintf(histo->video.name, sizeof(histo->video.name),
610 "%s histo", histo->entity.subdev.name);
611 histo->video.vfl_type = VFL_TYPE_GRABBER;
612 histo->video.release = video_device_release_empty;
613 histo->video.ioctl_ops = &histo_v4l2_ioctl_ops;
614
615 video_set_drvdata(&histo->video, histo);
616
617 /* ... and the buffers queue... */
618 histo->queue.type = V4L2_BUF_TYPE_META_CAPTURE;
619 histo->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
620 histo->queue.lock = &histo->lock;
621 histo->queue.drv_priv = histo;
622 histo->queue.buf_struct_size = sizeof(struct vsp1_histogram_buffer);
623 histo->queue.ops = &histo_video_queue_qops;
624 histo->queue.mem_ops = &vb2_vmalloc_memops;
625 histo->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
626 histo->queue.dev = vsp1->dev;
627 ret = vb2_queue_init(&histo->queue);
628 if (ret < 0) {
629 dev_err(vsp1->dev, "failed to initialize vb2 queue\n");
630 goto error;
631 }
632
633 /* ... and register the video device. */
634 histo->video.queue = &histo->queue;
635 ret = video_register_device(&histo->video, VFL_TYPE_GRABBER, -1);
636 if (ret < 0) {
637 dev_err(vsp1->dev, "failed to register video device\n");
638 goto error;
639 }
640
641 return 0;
642
643error:
644 vsp1_histogram_cleanup(histo);
645 return ret;
646}
diff --git a/drivers/media/platform/vsp1/vsp1_histo.h b/drivers/media/platform/vsp1/vsp1_histo.h
new file mode 100644
index 000000000000..af2874f6031d
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_histo.h
@@ -0,0 +1,84 @@
1/*
2 * vsp1_histo.h -- R-Car VSP1 Histogram API
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 * Copyright (C) 2016 Laurent Pinchart
6 *
7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14#ifndef __VSP1_HISTO_H__
15#define __VSP1_HISTO_H__
16
17#include <linux/list.h>
18#include <linux/mutex.h>
19#include <linux/spinlock.h>
20
21#include <media/media-entity.h>
22#include <media/v4l2-dev.h>
23#include <media/videobuf2-v4l2.h>
24
25#include "vsp1_entity.h"
26
27struct vsp1_device;
28struct vsp1_pipeline;
29
30#define HISTO_PAD_SINK 0
31#define HISTO_PAD_SOURCE 1
32
33struct vsp1_histogram_buffer {
34 struct vb2_v4l2_buffer buf;
35 struct list_head queue;
36 void *addr;
37};
38
39struct vsp1_histogram {
40 struct vsp1_pipeline *pipe;
41
42 struct vsp1_entity entity;
43 struct video_device video;
44 struct media_pad pad;
45
46 const u32 *formats;
47 unsigned int num_formats;
48 size_t data_size;
49 u32 meta_format;
50
51 struct mutex lock;
52 struct vb2_queue queue;
53
54 spinlock_t irqlock;
55 struct list_head irqqueue;
56
57 wait_queue_head_t wait_queue;
58 bool readout;
59};
60
61static inline struct vsp1_histogram *vdev_to_histo(struct video_device *vdev)
62{
63 return container_of(vdev, struct vsp1_histogram, video);
64}
65
66static inline struct vsp1_histogram *subdev_to_histo(struct v4l2_subdev *subdev)
67{
68 return container_of(subdev, struct vsp1_histogram, entity.subdev);
69}
70
71int vsp1_histogram_init(struct vsp1_device *vsp1, struct vsp1_histogram *histo,
72 enum vsp1_entity_type type, const char *name,
73 const struct vsp1_entity_operations *ops,
74 const unsigned int *formats, unsigned int num_formats,
75 size_t data_size, u32 meta_format);
76void vsp1_histogram_destroy(struct vsp1_entity *entity);
77
78struct vsp1_histogram_buffer *
79vsp1_histogram_buffer_get(struct vsp1_histogram *histo);
80void vsp1_histogram_buffer_complete(struct vsp1_histogram *histo,
81 struct vsp1_histogram_buffer *buf,
82 size_t size);
83
84#endif /* __VSP1_HISTO_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 94316afc54ff..764d405345ee 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -84,7 +84,8 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
84 format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad); 84 format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad);
85 85
86 if (fmt->pad == HSIT_PAD_SOURCE) { 86 if (fmt->pad == HSIT_PAD_SOURCE) {
87 /* The HST and HSI output format code and resolution can't be 87 /*
88 * The HST and HSI output format code and resolution can't be
88 * modified. 89 * modified.
89 */ 90 */
90 fmt->format = *format; 91 fmt->format = *format;
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index e32acae1fc6e..702487f895b3 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -84,7 +84,8 @@ static int lif_set_format(struct v4l2_subdev *subdev,
84 format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad); 84 format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
85 85
86 if (fmt->pad == LIF_PAD_SOURCE) { 86 if (fmt->pad == LIF_PAD_SOURCE) {
87 /* The LIF source format is always identical to its sink 87 /*
88 * The LIF source format is always identical to its sink
88 * format. 89 * format.
89 */ 90 */
90 fmt->format = *format; 91 fmt->format = *format;
@@ -176,7 +177,8 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
176 lif->entity.ops = &lif_entity_ops; 177 lif->entity.ops = &lif_entity_ops;
177 lif->entity.type = VSP1_ENTITY_LIF; 178 lif->entity.type = VSP1_ENTITY_LIF;
178 179
179 /* The LIF is never exposed to userspace, but media entity registration 180 /*
181 * The LIF is never exposed to userspace, but media entity registration
180 * requires a function to be set. Use PROC_VIDEO_PIXEL_FORMATTER just to 182 * requires a function to be set. Use PROC_VIDEO_PIXEL_FORMATTER just to
181 * avoid triggering a WARN_ON(), the value won't be seen anywhere. 183 * avoid triggering a WARN_ON(), the value won't be seen anywhere.
182 */ 184 */
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 280ba0804699..edebf3fa926f 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -23,6 +23,8 @@
23#include "vsp1_bru.h" 23#include "vsp1_bru.h"
24#include "vsp1_dl.h" 24#include "vsp1_dl.h"
25#include "vsp1_entity.h" 25#include "vsp1_entity.h"
26#include "vsp1_hgo.h"
27#include "vsp1_hgt.h"
26#include "vsp1_pipe.h" 28#include "vsp1_pipe.h"
27#include "vsp1_rwpf.h" 29#include "vsp1_rwpf.h"
28#include "vsp1_uds.h" 30#include "vsp1_uds.h"
@@ -157,9 +159,15 @@ const struct vsp1_format_info *vsp1_get_format_info(struct vsp1_device *vsp1,
157{ 159{
158 unsigned int i; 160 unsigned int i;
159 161
160 /* Special case, the VYUY format is supported on Gen2 only. */ 162 /* Special case, the VYUY and HSV formats are supported on Gen2 only. */
161 if (vsp1->info->gen != 2 && fourcc == V4L2_PIX_FMT_VYUY) 163 if (vsp1->info->gen != 2) {
162 return NULL; 164 switch (fourcc) {
165 case V4L2_PIX_FMT_VYUY:
166 case V4L2_PIX_FMT_HSV24:
167 case V4L2_PIX_FMT_HSV32:
168 return NULL;
169 }
170 }
163 171
164 for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) { 172 for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) {
165 const struct vsp1_format_info *info = &vsp1_video_formats[i]; 173 const struct vsp1_format_info *info = &vsp1_video_formats[i];
@@ -198,11 +206,25 @@ void vsp1_pipeline_reset(struct vsp1_pipeline *pipe)
198 pipe->output = NULL; 206 pipe->output = NULL;
199 } 207 }
200 208
209 if (pipe->hgo) {
210 struct vsp1_hgo *hgo = to_hgo(&pipe->hgo->subdev);
211
212 hgo->histo.pipe = NULL;
213 }
214
215 if (pipe->hgt) {
216 struct vsp1_hgt *hgt = to_hgt(&pipe->hgt->subdev);
217
218 hgt->histo.pipe = NULL;
219 }
220
201 INIT_LIST_HEAD(&pipe->entities); 221 INIT_LIST_HEAD(&pipe->entities);
202 pipe->state = VSP1_PIPELINE_STOPPED; 222 pipe->state = VSP1_PIPELINE_STOPPED;
203 pipe->buffers_ready = 0; 223 pipe->buffers_ready = 0;
204 pipe->num_inputs = 0; 224 pipe->num_inputs = 0;
205 pipe->bru = NULL; 225 pipe->bru = NULL;
226 pipe->hgo = NULL;
227 pipe->hgt = NULL;
206 pipe->lif = NULL; 228 pipe->lif = NULL;
207 pipe->uds = NULL; 229 pipe->uds = NULL;
208} 230}
@@ -246,16 +268,17 @@ bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe)
246 268
247int vsp1_pipeline_stop(struct vsp1_pipeline *pipe) 269int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
248{ 270{
271 struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
249 struct vsp1_entity *entity; 272 struct vsp1_entity *entity;
250 unsigned long flags; 273 unsigned long flags;
251 int ret; 274 int ret;
252 275
253 if (pipe->lif) { 276 if (pipe->lif) {
254 /* When using display lists in continuous frame mode the only 277 /*
278 * When using display lists in continuous frame mode the only
255 * way to stop the pipeline is to reset the hardware. 279 * way to stop the pipeline is to reset the hardware.
256 */ 280 */
257 ret = vsp1_reset_wpf(pipe->output->entity.vsp1, 281 ret = vsp1_reset_wpf(vsp1, pipe->output->entity.index);
258 pipe->output->entity.index);
259 if (ret == 0) { 282 if (ret == 0) {
260 spin_lock_irqsave(&pipe->irqlock, flags); 283 spin_lock_irqsave(&pipe->irqlock, flags);
261 pipe->state = VSP1_PIPELINE_STOPPED; 284 pipe->state = VSP1_PIPELINE_STOPPED;
@@ -275,10 +298,20 @@ int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
275 298
276 list_for_each_entry(entity, &pipe->entities, list_pipe) { 299 list_for_each_entry(entity, &pipe->entities, list_pipe) {
277 if (entity->route && entity->route->reg) 300 if (entity->route && entity->route->reg)
278 vsp1_write(entity->vsp1, entity->route->reg, 301 vsp1_write(vsp1, entity->route->reg,
279 VI6_DPR_NODE_UNUSED); 302 VI6_DPR_NODE_UNUSED);
280 } 303 }
281 304
305 if (pipe->hgo)
306 vsp1_write(vsp1, VI6_DPR_HGO_SMPPT,
307 (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
308 (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
309
310 if (pipe->hgt)
311 vsp1_write(vsp1, VI6_DPR_HGT_SMPPT,
312 (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
313 (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
314
282 v4l2_subdev_call(&pipe->output->entity.subdev, video, s_stream, 0); 315 v4l2_subdev_call(&pipe->output->entity.subdev, video, s_stream, 0);
283 316
284 return ret; 317 return ret;
@@ -302,6 +335,12 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
302 335
303 vsp1_dlm_irq_frame_end(pipe->output->dlm); 336 vsp1_dlm_irq_frame_end(pipe->output->dlm);
304 337
338 if (pipe->hgo)
339 vsp1_hgo_frame_end(pipe->hgo);
340
341 if (pipe->hgt)
342 vsp1_hgt_frame_end(pipe->hgt);
343
305 if (pipe->frame_end) 344 if (pipe->frame_end)
306 pipe->frame_end(pipe); 345 pipe->frame_end(pipe);
307 346
@@ -322,7 +361,8 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
322 if (!pipe->uds) 361 if (!pipe->uds)
323 return; 362 return;
324 363
325 /* The BRU background color has a fixed alpha value set to 255, the 364 /*
365 * The BRU background color has a fixed alpha value set to 255, the
326 * output alpha value is thus always equal to 255. 366 * output alpha value is thus always equal to 255.
327 */ 367 */
328 if (pipe->uds_input->type == VSP1_ENTITY_BRU) 368 if (pipe->uds_input->type == VSP1_ENTITY_BRU)
@@ -337,7 +377,8 @@ void vsp1_pipelines_suspend(struct vsp1_device *vsp1)
337 unsigned int i; 377 unsigned int i;
338 int ret; 378 int ret;
339 379
340 /* To avoid increasing the system suspend time needlessly, loop over the 380 /*
381 * To avoid increasing the system suspend time needlessly, loop over the
341 * pipelines twice, first to set them all to the stopping state, and 382 * pipelines twice, first to set them all to the stopping state, and
342 * then to wait for the stop to complete. 383 * then to wait for the stop to complete.
343 */ 384 */
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index ac4ad2655551..91a784a13422 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -25,11 +25,12 @@ struct vsp1_rwpf;
25 25
26/* 26/*
27 * struct vsp1_format_info - VSP1 video format description 27 * struct vsp1_format_info - VSP1 video format description
28 * @mbus: media bus format code
29 * @fourcc: V4L2 pixel format FCC identifier 28 * @fourcc: V4L2 pixel format FCC identifier
29 * @mbus: media bus format code
30 * @hwfmt: VSP1 hardware format
31 * @swap: swap register control
30 * @planes: number of planes 32 * @planes: number of planes
31 * @bpp: bits per pixel 33 * @bpp: bits per pixel
32 * @hwfmt: VSP1 hardware format
33 * @swap_yc: the Y and C components are swapped (Y comes before C) 34 * @swap_yc: the Y and C components are swapped (Y comes before C)
34 * @swap_uv: the U and V components are swapped (V comes before U) 35 * @swap_uv: the U and V components are swapped (V comes before U)
35 * @hsub: horizontal subsampling factor 36 * @hsub: horizontal subsampling factor
@@ -72,6 +73,8 @@ enum vsp1_pipeline_state {
72 * @inputs: array of RPFs in the pipeline (indexed by RPF index) 73 * @inputs: array of RPFs in the pipeline (indexed by RPF index)
73 * @output: WPF at the output of the pipeline 74 * @output: WPF at the output of the pipeline
74 * @bru: BRU entity, if present 75 * @bru: BRU entity, if present
76 * @hgo: HGO entity, if present
77 * @hgt: HGT entity, if present
75 * @lif: LIF entity, if present 78 * @lif: LIF entity, if present
76 * @uds: UDS entity, if present 79 * @uds: UDS entity, if present
77 * @uds_input: entity at the input of the UDS, if the UDS is present 80 * @uds_input: entity at the input of the UDS, if the UDS is present
@@ -100,6 +103,8 @@ struct vsp1_pipeline {
100 struct vsp1_rwpf *inputs[VSP1_MAX_RPF]; 103 struct vsp1_rwpf *inputs[VSP1_MAX_RPF];
101 struct vsp1_rwpf *output; 104 struct vsp1_rwpf *output;
102 struct vsp1_entity *bru; 105 struct vsp1_entity *bru;
106 struct vsp1_entity *hgo;
107 struct vsp1_entity *hgt;
103 struct vsp1_entity *lif; 108 struct vsp1_entity *lif;
104 struct vsp1_entity *uds; 109 struct vsp1_entity *uds;
105 struct vsp1_entity *uds_input; 110 struct vsp1_entity *uds_input;
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 47b1dee044fb..cd3e32af6e3b 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -328,8 +328,8 @@
328#define VI6_DPR_ROUTE_RT_MASK (0x3f << 0) 328#define VI6_DPR_ROUTE_RT_MASK (0x3f << 0)
329#define VI6_DPR_ROUTE_RT_SHIFT 0 329#define VI6_DPR_ROUTE_RT_SHIFT 0
330 330
331#define VI6_DPR_HGO_SMPPT 0x2050 331#define VI6_DPR_HGO_SMPPT 0x2054
332#define VI6_DPR_HGT_SMPPT 0x2054 332#define VI6_DPR_HGT_SMPPT 0x2058
333#define VI6_DPR_SMPPT_TGW_MASK (7 << 8) 333#define VI6_DPR_SMPPT_TGW_MASK (7 << 8)
334#define VI6_DPR_SMPPT_TGW_SHIFT 8 334#define VI6_DPR_SMPPT_TGW_SHIFT 8
335#define VI6_DPR_SMPPT_PT_MASK (0x3f << 0) 335#define VI6_DPR_SMPPT_PT_MASK (0x3f << 0)
@@ -590,33 +590,55 @@
590 */ 590 */
591 591
592#define VI6_HGO_OFFSET 0x3000 592#define VI6_HGO_OFFSET 0x3000
593#define VI6_HGO_OFFSET_HOFFSET_SHIFT 16
594#define VI6_HGO_OFFSET_VOFFSET_SHIFT 0
593#define VI6_HGO_SIZE 0x3004 595#define VI6_HGO_SIZE 0x3004
596#define VI6_HGO_SIZE_HSIZE_SHIFT 16
597#define VI6_HGO_SIZE_VSIZE_SHIFT 0
594#define VI6_HGO_MODE 0x3008 598#define VI6_HGO_MODE 0x3008
599#define VI6_HGO_MODE_STEP (1 << 10)
600#define VI6_HGO_MODE_MAXRGB (1 << 7)
601#define VI6_HGO_MODE_OFSB_R (1 << 6)
602#define VI6_HGO_MODE_OFSB_G (1 << 5)
603#define VI6_HGO_MODE_OFSB_B (1 << 4)
604#define VI6_HGO_MODE_HRATIO_SHIFT 2
605#define VI6_HGO_MODE_VRATIO_SHIFT 0
595#define VI6_HGO_LB_TH 0x300c 606#define VI6_HGO_LB_TH 0x300c
596#define VI6_HGO_LBn_H(n) (0x3010 + (n) * 8) 607#define VI6_HGO_LBn_H(n) (0x3010 + (n) * 8)
597#define VI6_HGO_LBn_V(n) (0x3014 + (n) * 8) 608#define VI6_HGO_LBn_V(n) (0x3014 + (n) * 8)
598#define VI6_HGO_R_HISTO 0x3030 609#define VI6_HGO_R_HISTO(n) (0x3030 + (n) * 4)
599#define VI6_HGO_R_MAXMIN 0x3130 610#define VI6_HGO_R_MAXMIN 0x3130
600#define VI6_HGO_R_SUM 0x3134 611#define VI6_HGO_R_SUM 0x3134
601#define VI6_HGO_R_LB_DET 0x3138 612#define VI6_HGO_R_LB_DET 0x3138
602#define VI6_HGO_G_HISTO 0x3140 613#define VI6_HGO_G_HISTO(n) (0x3140 + (n) * 4)
603#define VI6_HGO_G_MAXMIN 0x3240 614#define VI6_HGO_G_MAXMIN 0x3240
604#define VI6_HGO_G_SUM 0x3244 615#define VI6_HGO_G_SUM 0x3244
605#define VI6_HGO_G_LB_DET 0x3248 616#define VI6_HGO_G_LB_DET 0x3248
606#define VI6_HGO_B_HISTO 0x3250 617#define VI6_HGO_B_HISTO(n) (0x3250 + (n) * 4)
607#define VI6_HGO_B_MAXMIN 0x3350 618#define VI6_HGO_B_MAXMIN 0x3350
608#define VI6_HGO_B_SUM 0x3354 619#define VI6_HGO_B_SUM 0x3354
609#define VI6_HGO_B_LB_DET 0x3358 620#define VI6_HGO_B_LB_DET 0x3358
621#define VI6_HGO_EXT_HIST_ADDR 0x335c
622#define VI6_HGO_EXT_HIST_DATA 0x3360
610#define VI6_HGO_REGRST 0x33fc 623#define VI6_HGO_REGRST 0x33fc
624#define VI6_HGO_REGRST_RCLEA (1 << 0)
611 625
612/* ----------------------------------------------------------------------------- 626/* -----------------------------------------------------------------------------
613 * HGT Control Registers 627 * HGT Control Registers
614 */ 628 */
615 629
616#define VI6_HGT_OFFSET 0x3400 630#define VI6_HGT_OFFSET 0x3400
631#define VI6_HGT_OFFSET_HOFFSET_SHIFT 16
632#define VI6_HGT_OFFSET_VOFFSET_SHIFT 0
617#define VI6_HGT_SIZE 0x3404 633#define VI6_HGT_SIZE 0x3404
634#define VI6_HGT_SIZE_HSIZE_SHIFT 16
635#define VI6_HGT_SIZE_VSIZE_SHIFT 0
618#define VI6_HGT_MODE 0x3408 636#define VI6_HGT_MODE 0x3408
637#define VI6_HGT_MODE_HRATIO_SHIFT 2
638#define VI6_HGT_MODE_VRATIO_SHIFT 0
619#define VI6_HGT_HUE_AREA(n) (0x340c + (n) * 4) 639#define VI6_HGT_HUE_AREA(n) (0x340c + (n) * 4)
640#define VI6_HGT_HUE_AREA_LOWER_SHIFT 16
641#define VI6_HGT_HUE_AREA_UPPER_SHIFT 0
620#define VI6_HGT_LB_TH 0x3424 642#define VI6_HGT_LB_TH 0x3424
621#define VI6_HGT_LBn_H(n) (0x3438 + (n) * 8) 643#define VI6_HGT_LBn_H(n) (0x3438 + (n) * 8)
622#define VI6_HGT_LBn_V(n) (0x342c + (n) * 8) 644#define VI6_HGT_LBn_V(n) (0x342c + (n) * 8)
@@ -625,6 +647,7 @@
625#define VI6_HGT_SUM 0x3754 647#define VI6_HGT_SUM 0x3754
626#define VI6_HGT_LB_DET 0x3758 648#define VI6_HGT_LB_DET 0x3758
627#define VI6_HGT_REGRST 0x37fc 649#define VI6_HGT_REGRST 0x37fc
650#define VI6_HGT_REGRST_RCLEA (1 << 0)
628 651
629/* ----------------------------------------------------------------------------- 652/* -----------------------------------------------------------------------------
630 * LIF Control Registers 653 * LIF Control Registers
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index b2e34a800ffa..8feddd59cf8d 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -72,7 +72,8 @@ static void rpf_configure(struct vsp1_entity *entity,
72 } 72 }
73 73
74 if (params == VSP1_ENTITY_PARAMS_PARTITION) { 74 if (params == VSP1_ENTITY_PARAMS_PARTITION) {
75 unsigned int offsets[2]; 75 struct vsp1_device *vsp1 = rpf->entity.vsp1;
76 struct vsp1_rwpf_memory mem = rpf->mem;
76 struct v4l2_rect crop; 77 struct v4l2_rect crop;
77 78
78 /* 79 /*
@@ -105,7 +106,7 @@ static void rpf_configure(struct vsp1_entity *entity,
105 * of the pipeline. 106 * of the pipeline.
106 */ 107 */
107 output = vsp1_entity_get_pad_format(wpf, wpf->config, 108 output = vsp1_entity_get_pad_format(wpf, wpf->config,
108 RWPF_PAD_SOURCE); 109 RWPF_PAD_SINK);
109 110
110 crop.width = pipe->partition.width * input_width 111 crop.width = pipe->partition.width * input_width
111 / output->width; 112 / output->width;
@@ -120,22 +121,30 @@ static void rpf_configure(struct vsp1_entity *entity,
120 (crop.width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) | 121 (crop.width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) |
121 (crop.height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT)); 122 (crop.height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT));
122 123
123 offsets[0] = crop.top * format->plane_fmt[0].bytesperline 124 mem.addr[0] += crop.top * format->plane_fmt[0].bytesperline
124 + crop.left * fmtinfo->bpp[0] / 8; 125 + crop.left * fmtinfo->bpp[0] / 8;
125 126
126 if (format->num_planes > 1) 127 if (format->num_planes > 1) {
127 offsets[1] = crop.top * format->plane_fmt[1].bytesperline 128 unsigned int offset;
128 + crop.left / fmtinfo->hsub 129
129 * fmtinfo->bpp[1] / 8; 130 offset = crop.top * format->plane_fmt[1].bytesperline
130 else 131 + crop.left / fmtinfo->hsub
131 offsets[1] = 0; 132 * fmtinfo->bpp[1] / 8;
132 133 mem.addr[1] += offset;
133 vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_Y, 134 mem.addr[2] += offset;
134 rpf->mem.addr[0] + offsets[0]); 135 }
135 vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C0, 136
136 rpf->mem.addr[1] + offsets[1]); 137 /*
137 vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C1, 138 * On Gen3 hardware the SPUVS bit has no effect on 3-planar
138 rpf->mem.addr[2] + offsets[1]); 139 * formats. Swap the U and V planes manually in that case.
140 */
141 if (vsp1->info->gen == 3 && format->num_planes == 3 &&
142 fmtinfo->swap_uv)
143 swap(mem.addr[1], mem.addr[2]);
144
145 vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_Y, mem.addr[0]);
146 vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C0, mem.addr[1]);
147 vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_C1, mem.addr[2]);
139 return; 148 return;
140 } 149 }
141 150
@@ -186,7 +195,8 @@ static void rpf_configure(struct vsp1_entity *entity,
186 (left << VI6_RPF_LOC_HCOORD_SHIFT) | 195 (left << VI6_RPF_LOC_HCOORD_SHIFT) |
187 (top << VI6_RPF_LOC_VCOORD_SHIFT)); 196 (top << VI6_RPF_LOC_VCOORD_SHIFT));
188 197
189 /* On Gen2 use the alpha channel (extended to 8 bits) when available or 198 /*
199 * On Gen2 use the alpha channel (extended to 8 bits) when available or
190 * a fixed alpha value set through the V4L2_CID_ALPHA_COMPONENT control 200 * a fixed alpha value set through the V4L2_CID_ALPHA_COMPONENT control
191 * otherwise. 201 * otherwise.
192 * 202 *
@@ -216,7 +226,8 @@ static void rpf_configure(struct vsp1_entity *entity,
216 u32 mult; 226 u32 mult;
217 227
218 if (fmtinfo->alpha) { 228 if (fmtinfo->alpha) {
219 /* When the input contains an alpha channel enable the 229 /*
230 * When the input contains an alpha channel enable the
220 * alpha multiplier. If the input is premultiplied we 231 * alpha multiplier. If the input is premultiplied we
221 * need to multiply both the alpha channel and the pixel 232 * need to multiply both the alpha channel and the pixel
222 * components by the global alpha value to keep them 233 * components by the global alpha value to keep them
@@ -231,7 +242,8 @@ static void rpf_configure(struct vsp1_entity *entity,
231 VI6_RPF_MULT_ALPHA_P_MMD_RATIO : 242 VI6_RPF_MULT_ALPHA_P_MMD_RATIO :
232 VI6_RPF_MULT_ALPHA_P_MMD_NONE); 243 VI6_RPF_MULT_ALPHA_P_MMD_NONE);
233 } else { 244 } else {
234 /* When the input doesn't contain an alpha channel the 245 /*
246 * When the input doesn't contain an alpha channel the
235 * global alpha value is applied in the unpacking unit, 247 * global alpha value is applied in the unpacking unit,
236 * the alpha multiplier isn't needed and must be 248 * the alpha multiplier isn't needed and must be
237 * disabled. 249 * disabled.
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index 04104ef28fb5..cfd8f1904fa6 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -86,7 +86,8 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
86 format = vsp1_entity_get_pad_format(&rwpf->entity, config, fmt->pad); 86 format = vsp1_entity_get_pad_format(&rwpf->entity, config, fmt->pad);
87 87
88 if (fmt->pad == RWPF_PAD_SOURCE) { 88 if (fmt->pad == RWPF_PAD_SOURCE) {
89 /* The RWPF performs format conversion but can't scale, only the 89 /*
90 * The RWPF performs format conversion but can't scale, only the
90 * format code can be changed on the source pad. 91 * format code can be changed on the source pad.
91 */ 92 */
92 format->code = fmt->format.code; 93 format->code = fmt->format.code;
@@ -120,6 +121,11 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
120 RWPF_PAD_SOURCE); 121 RWPF_PAD_SOURCE);
121 *format = fmt->format; 122 *format = fmt->format;
122 123
124 if (rwpf->flip.rotate) {
125 format->width = fmt->format.height;
126 format->height = fmt->format.width;
127 }
128
123done: 129done:
124 mutex_unlock(&rwpf->entity.lock); 130 mutex_unlock(&rwpf->entity.lock);
125 return ret; 131 return ret;
@@ -205,7 +211,8 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
205 format = vsp1_entity_get_pad_format(&rwpf->entity, config, 211 format = vsp1_entity_get_pad_format(&rwpf->entity, config,
206 RWPF_PAD_SINK); 212 RWPF_PAD_SINK);
207 213
208 /* Restrict the crop rectangle coordinates to multiples of 2 to avoid 214 /*
215 * Restrict the crop rectangle coordinates to multiples of 2 to avoid
209 * shifting the color plane. 216 * shifting the color plane.
210 */ 217 */
211 if (format->code == MEDIA_BUS_FMT_AYUV8_1X32) { 218 if (format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 1c98aff3da5d..58215a7ab631 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -56,9 +56,14 @@ struct vsp1_rwpf {
56 56
57 struct { 57 struct {
58 spinlock_t lock; 58 spinlock_t lock;
59 struct v4l2_ctrl *ctrls[2]; 59 struct {
60 struct v4l2_ctrl *vflip;
61 struct v4l2_ctrl *hflip;
62 struct v4l2_ctrl *rotate;
63 } ctrls;
60 unsigned int pending; 64 unsigned int pending;
61 unsigned int active; 65 unsigned int active;
66 bool rotate;
62 } flip; 67 } flip;
63 68
64 struct vsp1_rwpf_memory mem; 69 struct vsp1_rwpf_memory mem;
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index b4e568a3b4ed..30142793dfcd 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -191,7 +191,8 @@ static void sru_try_format(struct vsp1_sru *sru,
191 SRU_PAD_SINK); 191 SRU_PAD_SINK);
192 fmt->code = format->code; 192 fmt->code = format->code;
193 193
194 /* We can upscale by 2 in both direction, but not independently. 194 /*
195 * We can upscale by 2 in both direction, but not independently.
195 * Compare the input and output rectangles areas (avoiding 196 * Compare the input and output rectangles areas (avoiding
196 * integer overflows on the output): if the requested output 197 * integer overflows on the output): if the requested output
197 * area is larger than 1.5^2 the input area upscale by two, 198 * area is larger than 1.5^2 the input area upscale by two,
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index da8f89a31ea4..4226403ad235 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -293,7 +293,8 @@ static void uds_configure(struct vsp1_entity *entity,
293 293
294 dev_dbg(uds->entity.vsp1->dev, "hscale %u vscale %u\n", hscale, vscale); 294 dev_dbg(uds->entity.vsp1->dev, "hscale %u vscale %u\n", hscale, vscale);
295 295
296 /* Multi-tap scaling can't be enabled along with alpha scaling when 296 /*
297 * Multi-tap scaling can't be enabled along with alpha scaling when
297 * scaling down with a factor lower than or equal to 1/2 in either 298 * scaling down with a factor lower than or equal to 1/2 in either
298 * direction. 299 * direction.
299 */ 300 */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3eaadbf7a876..eab3c3ea85d7 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -31,6 +31,8 @@
31#include "vsp1_bru.h" 31#include "vsp1_bru.h"
32#include "vsp1_dl.h" 32#include "vsp1_dl.h"
33#include "vsp1_entity.h" 33#include "vsp1_entity.h"
34#include "vsp1_hgo.h"
35#include "vsp1_hgt.h"
34#include "vsp1_pipe.h" 36#include "vsp1_pipe.h"
35#include "vsp1_rwpf.h" 37#include "vsp1_rwpf.h"
36#include "vsp1_uds.h" 38#include "vsp1_uds.h"
@@ -103,7 +105,8 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
103 unsigned int height = pix->height; 105 unsigned int height = pix->height;
104 unsigned int i; 106 unsigned int i;
105 107
106 /* Backward compatibility: replace deprecated RGB formats by their XRGB 108 /*
109 * Backward compatibility: replace deprecated RGB formats by their XRGB
107 * equivalent. This selects the format older userspace applications want 110 * equivalent. This selects the format older userspace applications want
108 * while still exposing the new format. 111 * while still exposing the new format.
109 */ 112 */
@@ -114,7 +117,8 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
114 } 117 }
115 } 118 }
116 119
117 /* Retrieve format information and select the default format if the 120 /*
121 * Retrieve format information and select the default format if the
118 * requested format isn't supported. 122 * requested format isn't supported.
119 */ 123 */
120 info = vsp1_get_format_info(video->vsp1, pix->pixelformat); 124 info = vsp1_get_format_info(video->vsp1, pix->pixelformat);
@@ -140,7 +144,8 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
140 pix->height = clamp(height, VSP1_VIDEO_MIN_HEIGHT, 144 pix->height = clamp(height, VSP1_VIDEO_MIN_HEIGHT,
141 VSP1_VIDEO_MAX_HEIGHT); 145 VSP1_VIDEO_MAX_HEIGHT);
142 146
143 /* Compute and clamp the stride and image size. While not documented in 147 /*
148 * Compute and clamp the stride and image size. While not documented in
144 * the datasheet, strides not aligned to a multiple of 128 bytes result 149 * the datasheet, strides not aligned to a multiple of 128 bytes result
145 * in image corruption. 150 * in image corruption.
146 */ 151 */
@@ -184,9 +189,13 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe)
184 struct vsp1_entity *entity; 189 struct vsp1_entity *entity;
185 unsigned int div_size; 190 unsigned int div_size;
186 191
192 /*
193 * Partitions are computed on the size before rotation, use the format
194 * at the WPF sink.
195 */
187 format = vsp1_entity_get_pad_format(&pipe->output->entity, 196 format = vsp1_entity_get_pad_format(&pipe->output->entity,
188 pipe->output->entity.config, 197 pipe->output->entity.config,
189 RWPF_PAD_SOURCE); 198 RWPF_PAD_SINK);
190 div_size = format->width; 199 div_size = format->width;
191 200
192 /* Gen2 hardware doesn't require image partitioning. */ 201 /* Gen2 hardware doesn't require image partitioning. */
@@ -226,9 +235,13 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe,
226 struct v4l2_rect partition; 235 struct v4l2_rect partition;
227 unsigned int modulus; 236 unsigned int modulus;
228 237
238 /*
239 * Partitions are computed on the size before rotation, use the format
240 * at the WPF sink.
241 */
229 format = vsp1_entity_get_pad_format(&pipe->output->entity, 242 format = vsp1_entity_get_pad_format(&pipe->output->entity,
230 pipe->output->entity.config, 243 pipe->output->entity.config,
231 RWPF_PAD_SOURCE); 244 RWPF_PAD_SINK);
232 245
233 /* A single partition simply processes the output size in full. */ 246 /* A single partition simply processes the output size in full. */
234 if (pipe->partitions <= 1) { 247 if (pipe->partitions <= 1) {
@@ -449,7 +462,8 @@ static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe)
449 state = pipe->state; 462 state = pipe->state;
450 pipe->state = VSP1_PIPELINE_STOPPED; 463 pipe->state = VSP1_PIPELINE_STOPPED;
451 464
452 /* If a stop has been requested, mark the pipeline as stopped and 465 /*
466 * If a stop has been requested, mark the pipeline as stopped and
453 * return. Otherwise restart the pipeline if ready. 467 * return. Otherwise restart the pipeline if ready.
454 */ 468 */
455 if (state == VSP1_PIPELINE_STOPPING) 469 if (state == VSP1_PIPELINE_STOPPING)
@@ -474,7 +488,12 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
474 if (ret < 0) 488 if (ret < 0)
475 return ret; 489 return ret;
476 490
477 pad = media_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]); 491 /*
492 * The main data path doesn't include the HGO or HGT, use
493 * vsp1_entity_remote_pad() to traverse the graph.
494 */
495
496 pad = vsp1_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]);
478 497
479 while (1) { 498 while (1) {
480 if (pad == NULL) { 499 if (pad == NULL) {
@@ -491,7 +510,8 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
491 entity = to_vsp1_entity( 510 entity = to_vsp1_entity(
492 media_entity_to_v4l2_subdev(pad->entity)); 511 media_entity_to_v4l2_subdev(pad->entity));
493 512
494 /* A BRU is present in the pipeline, store the BRU input pad 513 /*
514 * A BRU is present in the pipeline, store the BRU input pad
495 * number in the input RPF for use when configuring the RPF. 515 * number in the input RPF for use when configuring the RPF.
496 */ 516 */
497 if (entity->type == VSP1_ENTITY_BRU) { 517 if (entity->type == VSP1_ENTITY_BRU) {
@@ -526,13 +546,9 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
526 : &input->entity; 546 : &input->entity;
527 } 547 }
528 548
529 /* Follow the source link. The link setup operations ensure 549 /* Follow the source link, ignoring any HGO or HGT. */
530 * that the output fan-out can't be more than one, there is thus
531 * no need to verify here that only a single source link is
532 * activated.
533 */
534 pad = &entity->pads[entity->source_pad]; 550 pad = &entity->pads[entity->source_pad];
535 pad = media_entity_remote_pad(pad); 551 pad = vsp1_entity_remote_pad(pad);
536 } 552 }
537 553
538 /* The last entity must be the output WPF. */ 554 /* The last entity must be the output WPF. */
@@ -587,6 +603,16 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
587 pipe->lif = e; 603 pipe->lif = e;
588 } else if (e->type == VSP1_ENTITY_BRU) { 604 } else if (e->type == VSP1_ENTITY_BRU) {
589 pipe->bru = e; 605 pipe->bru = e;
606 } else if (e->type == VSP1_ENTITY_HGO) {
607 struct vsp1_hgo *hgo = to_hgo(subdev);
608
609 pipe->hgo = e;
610 hgo->histo.pipe = pipe;
611 } else if (e->type == VSP1_ENTITY_HGT) {
612 struct vsp1_hgt *hgt = to_hgt(subdev);
613
614 pipe->hgt = e;
615 hgt->histo.pipe = pipe;
590 } 616 }
591 } 617 }
592 618
@@ -596,7 +622,8 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
596 if (pipe->num_inputs == 0 || !pipe->output) 622 if (pipe->num_inputs == 0 || !pipe->output)
597 return -EPIPE; 623 return -EPIPE;
598 624
599 /* Follow links downstream for each input and make sure the graph 625 /*
626 * Follow links downstream for each input and make sure the graph
600 * contains no loop and that all branches end at the output WPF. 627 * contains no loop and that all branches end at the output WPF.
601 */ 628 */
602 for (i = 0; i < video->vsp1->info->rpf_count; ++i) { 629 for (i = 0; i < video->vsp1->info->rpf_count; ++i) {
@@ -627,7 +654,8 @@ static struct vsp1_pipeline *vsp1_video_pipeline_get(struct vsp1_video *video)
627 struct vsp1_pipeline *pipe; 654 struct vsp1_pipeline *pipe;
628 int ret; 655 int ret;
629 656
630 /* Get a pipeline object for the video node. If a pipeline has already 657 /*
658 * Get a pipeline object for the video node. If a pipeline has already
631 * been allocated just increment its reference count and return it. 659 * been allocated just increment its reference count and return it.
632 * Otherwise allocate a new pipeline and initialize it, it will be freed 660 * Otherwise allocate a new pipeline and initialize it, it will be freed
633 * when the last reference is released. 661 * when the last reference is released.
@@ -767,7 +795,8 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
767 if (pipe->uds) { 795 if (pipe->uds) {
768 struct vsp1_uds *uds = to_uds(&pipe->uds->subdev); 796 struct vsp1_uds *uds = to_uds(&pipe->uds->subdev);
769 797
770 /* If a BRU is present in the pipeline before the UDS, the alpha 798 /*
799 * If a BRU is present in the pipeline before the UDS, the alpha
771 * component doesn't need to be scaled as the BRU output alpha 800 * component doesn't need to be scaled as the BRU output alpha
772 * value is fixed to 255. Otherwise we need to scale the alpha 801 * value is fixed to 255. Otherwise we need to scale the alpha
773 * component only when available at the input RPF. 802 * component only when available at the input RPF.
@@ -783,7 +812,7 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
783 } 812 }
784 813
785 list_for_each_entry(entity, &pipe->entities, list_pipe) { 814 list_for_each_entry(entity, &pipe->entities, list_pipe) {
786 vsp1_entity_route_setup(entity, pipe->dl); 815 vsp1_entity_route_setup(entity, pipe, pipe->dl);
787 816
788 if (entity->ops->configure) 817 if (entity->ops->configure)
789 entity->ops->configure(entity, pipe, pipe->dl, 818 entity->ops->configure(entity, pipe, pipe->dl,
@@ -797,6 +826,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
797{ 826{
798 struct vsp1_video *video = vb2_get_drv_priv(vq); 827 struct vsp1_video *video = vb2_get_drv_priv(vq);
799 struct vsp1_pipeline *pipe = video->rwpf->pipe; 828 struct vsp1_pipeline *pipe = video->rwpf->pipe;
829 bool start_pipeline = false;
800 unsigned long flags; 830 unsigned long flags;
801 int ret; 831 int ret;
802 832
@@ -807,11 +837,23 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
807 mutex_unlock(&pipe->lock); 837 mutex_unlock(&pipe->lock);
808 return ret; 838 return ret;
809 } 839 }
840
841 start_pipeline = true;
810 } 842 }
811 843
812 pipe->stream_count++; 844 pipe->stream_count++;
813 mutex_unlock(&pipe->lock); 845 mutex_unlock(&pipe->lock);
814 846
847 /*
848 * vsp1_pipeline_ready() is not sufficient to establish that all streams
849 * are prepared and the pipeline is configured, as multiple streams
850 * can race through streamon with buffers already queued; Therefore we
851 * don't even attempt to start the pipeline until the last stream has
852 * called through here.
853 */
854 if (!start_pipeline)
855 return 0;
856
815 spin_lock_irqsave(&pipe->irqlock, flags); 857 spin_lock_irqsave(&pipe->irqlock, flags);
816 if (vsp1_pipeline_ready(pipe)) 858 if (vsp1_pipeline_ready(pipe))
817 vsp1_video_pipeline_run(pipe); 859 vsp1_video_pipeline_run(pipe);
@@ -968,7 +1010,8 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
968 if (video->queue.owner && video->queue.owner != file->private_data) 1010 if (video->queue.owner && video->queue.owner != file->private_data)
969 return -EBUSY; 1011 return -EBUSY;
970 1012
971 /* Get a pipeline for the video node and start streaming on it. No link 1013 /*
1014 * Get a pipeline for the video node and start streaming on it. No link
972 * touching an entity in the pipeline can be activated or deactivated 1015 * touching an entity in the pipeline can be activated or deactivated
973 * once streaming is started. 1016 * once streaming is started.
974 */ 1017 */
@@ -988,7 +1031,8 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
988 1031
989 mutex_unlock(&mdev->graph_mutex); 1032 mutex_unlock(&mdev->graph_mutex);
990 1033
991 /* Verify that the configured format matches the output of the connected 1034 /*
1035 * Verify that the configured format matches the output of the connected
992 * subdev. 1036 * subdev.
993 */ 1037 */
994 ret = vsp1_video_verify_format(video); 1038 ret = vsp1_video_verify_format(video);
@@ -1050,6 +1094,7 @@ static int vsp1_video_open(struct file *file)
1050 ret = vsp1_device_get(video->vsp1); 1094 ret = vsp1_device_get(video->vsp1);
1051 if (ret < 0) { 1095 if (ret < 0) {
1052 v4l2_fh_del(vfh); 1096 v4l2_fh_del(vfh);
1097 v4l2_fh_exit(vfh);
1053 kfree(vfh); 1098 kfree(vfh);
1054 } 1099 }
1055 1100
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 7c48f81cd5c1..32df109b119f 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -43,32 +43,90 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf,
43enum wpf_flip_ctrl { 43enum wpf_flip_ctrl {
44 WPF_CTRL_VFLIP = 0, 44 WPF_CTRL_VFLIP = 0,
45 WPF_CTRL_HFLIP = 1, 45 WPF_CTRL_HFLIP = 1,
46 WPF_CTRL_MAX,
47}; 46};
48 47
48static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
49{
50 struct vsp1_video *video = wpf->video;
51 struct v4l2_mbus_framefmt *sink_format;
52 struct v4l2_mbus_framefmt *source_format;
53 bool rotate;
54 int ret = 0;
55
56 /*
57 * Only consider the 0°/180° from/to 90°/270° modifications, the rest
58 * is taken care of by the flipping configuration.
59 */
60 rotate = rotation == 90 || rotation == 270;
61 if (rotate == wpf->flip.rotate)
62 return 0;
63
64 /* Changing rotation isn't allowed when buffers are allocated. */
65 mutex_lock(&video->lock);
66
67 if (vb2_is_busy(&video->queue)) {
68 ret = -EBUSY;
69 goto done;
70 }
71
72 sink_format = vsp1_entity_get_pad_format(&wpf->entity,
73 wpf->entity.config,
74 RWPF_PAD_SINK);
75 source_format = vsp1_entity_get_pad_format(&wpf->entity,
76 wpf->entity.config,
77 RWPF_PAD_SOURCE);
78
79 mutex_lock(&wpf->entity.lock);
80
81 if (rotate) {
82 source_format->width = sink_format->height;
83 source_format->height = sink_format->width;
84 } else {
85 source_format->width = sink_format->width;
86 source_format->height = sink_format->height;
87 }
88
89 wpf->flip.rotate = rotate;
90
91 mutex_unlock(&wpf->entity.lock);
92
93done:
94 mutex_unlock(&video->lock);
95 return ret;
96}
97
49static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl) 98static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
50{ 99{
51 struct vsp1_rwpf *wpf = 100 struct vsp1_rwpf *wpf =
52 container_of(ctrl->handler, struct vsp1_rwpf, ctrls); 101 container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
53 unsigned int i; 102 unsigned int rotation;
54 u32 flip = 0; 103 u32 flip = 0;
104 int ret;
55 105
56 switch (ctrl->id) { 106 /* Update the rotation. */
57 case V4L2_CID_HFLIP: 107 rotation = wpf->flip.ctrls.rotate ? wpf->flip.ctrls.rotate->val : 0;
58 case V4L2_CID_VFLIP: 108 ret = vsp1_wpf_set_rotation(wpf, rotation);
59 for (i = 0; i < WPF_CTRL_MAX; ++i) { 109 if (ret < 0)
60 if (wpf->flip.ctrls[i]) 110 return ret;
61 flip |= wpf->flip.ctrls[i]->val ? BIT(i) : 0;
62 }
63 111
64 spin_lock_irq(&wpf->flip.lock); 112 /*
65 wpf->flip.pending = flip; 113 * Compute the flip value resulting from all three controls, with
66 spin_unlock_irq(&wpf->flip.lock); 114 * rotation by 180° flipping the image in both directions. Store the
67 break; 115 * result in the pending flip field for the next frame that will be
116 * processed.
117 */
118 if (wpf->flip.ctrls.vflip->val)
119 flip |= BIT(WPF_CTRL_VFLIP);
68 120
69 default: 121 if (wpf->flip.ctrls.hflip && wpf->flip.ctrls.hflip->val)
70 return -EINVAL; 122 flip |= BIT(WPF_CTRL_HFLIP);
71 } 123
124 if (rotation == 180 || rotation == 270)
125 flip ^= BIT(WPF_CTRL_VFLIP) | BIT(WPF_CTRL_HFLIP);
126
127 spin_lock_irq(&wpf->flip.lock);
128 wpf->flip.pending = flip;
129 spin_unlock_irq(&wpf->flip.lock);
72 130
73 return 0; 131 return 0;
74} 132}
@@ -88,12 +146,14 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf)
88 /* Only WPF0 supports flipping. */ 146 /* Only WPF0 supports flipping. */
89 num_flip_ctrls = 0; 147 num_flip_ctrls = 0;
90 } else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) { 148 } else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
91 /* When horizontal flip is supported the WPF implements two 149 /*
92 * controls (horizontal flip and vertical flip). 150 * When horizontal flip is supported the WPF implements three
151 * controls (horizontal flip, vertical flip and rotation).
93 */ 152 */
94 num_flip_ctrls = 2; 153 num_flip_ctrls = 3;
95 } else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) { 154 } else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
96 /* When only vertical flip is supported the WPF implements a 155 /*
156 * When only vertical flip is supported the WPF implements a
97 * single control (vertical flip). 157 * single control (vertical flip).
98 */ 158 */
99 num_flip_ctrls = 1; 159 num_flip_ctrls = 1;
@@ -105,17 +165,19 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf)
105 vsp1_rwpf_init_ctrls(wpf, num_flip_ctrls); 165 vsp1_rwpf_init_ctrls(wpf, num_flip_ctrls);
106 166
107 if (num_flip_ctrls >= 1) { 167 if (num_flip_ctrls >= 1) {
108 wpf->flip.ctrls[WPF_CTRL_VFLIP] = 168 wpf->flip.ctrls.vflip =
109 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops, 169 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
110 V4L2_CID_VFLIP, 0, 1, 1, 0); 170 V4L2_CID_VFLIP, 0, 1, 1, 0);
111 } 171 }
112 172
113 if (num_flip_ctrls == 2) { 173 if (num_flip_ctrls == 3) {
114 wpf->flip.ctrls[WPF_CTRL_HFLIP] = 174 wpf->flip.ctrls.hflip =
115 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops, 175 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
116 V4L2_CID_HFLIP, 0, 1, 1, 0); 176 V4L2_CID_HFLIP, 0, 1, 1, 0);
117 177 wpf->flip.ctrls.rotate =
118 v4l2_ctrl_cluster(2, wpf->flip.ctrls); 178 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
179 V4L2_CID_ROTATE, 0, 270, 90, 0);
180 v4l2_ctrl_cluster(3, &wpf->flip.ctrls.vflip);
119 } 181 }
120 182
121 if (wpf->ctrls.error) { 183 if (wpf->ctrls.error) {
@@ -139,7 +201,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
139 if (enable) 201 if (enable)
140 return 0; 202 return 0;
141 203
142 /* Write to registers directly when stopping the stream as there will be 204 /*
205 * Write to registers directly when stopping the stream as there will be
143 * no pipeline run to apply the display list. 206 * no pipeline run to apply the display list.
144 */ 207 */
145 vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0); 208 vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
@@ -216,10 +279,11 @@ static void wpf_configure(struct vsp1_entity *entity,
216 279
217 if (params == VSP1_ENTITY_PARAMS_PARTITION) { 280 if (params == VSP1_ENTITY_PARAMS_PARTITION) {
218 const struct v4l2_pix_format_mplane *format = &wpf->format; 281 const struct v4l2_pix_format_mplane *format = &wpf->format;
282 const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
219 struct vsp1_rwpf_memory mem = wpf->mem; 283 struct vsp1_rwpf_memory mem = wpf->mem;
220 unsigned int flip = wpf->flip.active; 284 unsigned int flip = wpf->flip.active;
221 unsigned int width = source_format->width; 285 unsigned int width = sink_format->width;
222 unsigned int height = source_format->height; 286 unsigned int height = sink_format->height;
223 unsigned int offset; 287 unsigned int offset;
224 288
225 /* 289 /*
@@ -242,45 +306,86 @@ static void wpf_configure(struct vsp1_entity *entity,
242 /* 306 /*
243 * Update the memory offsets based on flipping configuration. 307 * Update the memory offsets based on flipping configuration.
244 * The destination addresses point to the locations where the 308 * The destination addresses point to the locations where the
245 * VSP starts writing to memory, which can be different corners 309 * VSP starts writing to memory, which can be any corner of the
246 * of the image depending on vertical flipping. 310 * image depending on the combination of flipping and rotation.
247 */ 311 */
248 if (pipe->partitions > 1) {
249 const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
250 312
251 /* 313 /*
252 * Horizontal flipping is handled through a line buffer 314 * First take the partition left coordinate into account.
253 * and doesn't modify the start address, but still needs 315 * Compute the offset to order the partitions correctly on the
254 * to be handled when image partitioning is in effect to 316 * output based on whether flipping is enabled. Consider
255 * order the partitions correctly. 317 * horizontal flipping when rotation is disabled but vertical
256 */ 318 * flipping when rotation is enabled, as rotating the image
257 if (flip & BIT(WPF_CTRL_HFLIP)) 319 * switches the horizontal and vertical directions. The offset
258 offset = format->width - pipe->partition.left 320 * is applied horizontally or vertically accordingly.
259 - pipe->partition.width; 321 */
322 if (flip & BIT(WPF_CTRL_HFLIP) && !wpf->flip.rotate)
323 offset = format->width - pipe->partition.left
324 - pipe->partition.width;
325 else if (flip & BIT(WPF_CTRL_VFLIP) && wpf->flip.rotate)
326 offset = format->height - pipe->partition.left
327 - pipe->partition.width;
328 else
329 offset = pipe->partition.left;
330
331 for (i = 0; i < format->num_planes; ++i) {
332 unsigned int hsub = i > 0 ? fmtinfo->hsub : 1;
333 unsigned int vsub = i > 0 ? fmtinfo->vsub : 1;
334
335 if (wpf->flip.rotate)
336 mem.addr[i] += offset / vsub
337 * format->plane_fmt[i].bytesperline;
260 else 338 else
261 offset = pipe->partition.left; 339 mem.addr[i] += offset / hsub
262 340 * fmtinfo->bpp[i] / 8;
263 mem.addr[0] += offset * fmtinfo->bpp[0] / 8;
264 if (format->num_planes > 1) {
265 mem.addr[1] += offset / fmtinfo->hsub
266 * fmtinfo->bpp[1] / 8;
267 mem.addr[2] += offset / fmtinfo->hsub
268 * fmtinfo->bpp[2] / 8;
269 }
270 } 341 }
271 342
272 if (flip & BIT(WPF_CTRL_VFLIP)) { 343 if (flip & BIT(WPF_CTRL_VFLIP)) {
273 mem.addr[0] += (format->height - 1) 344 /*
345 * When rotating the output (after rotation) image
346 * height is equal to the partition width (before
347 * rotation). Otherwise it is equal to the output
348 * image height.
349 */
350 if (wpf->flip.rotate)
351 height = pipe->partition.width;
352 else
353 height = format->height;
354
355 mem.addr[0] += (height - 1)
274 * format->plane_fmt[0].bytesperline; 356 * format->plane_fmt[0].bytesperline;
275 357
276 if (format->num_planes > 1) { 358 if (format->num_planes > 1) {
277 offset = (format->height / wpf->fmtinfo->vsub - 1) 359 offset = (height / fmtinfo->vsub - 1)
278 * format->plane_fmt[1].bytesperline; 360 * format->plane_fmt[1].bytesperline;
279 mem.addr[1] += offset; 361 mem.addr[1] += offset;
280 mem.addr[2] += offset; 362 mem.addr[2] += offset;
281 } 363 }
282 } 364 }
283 365
366 if (wpf->flip.rotate && !(flip & BIT(WPF_CTRL_HFLIP))) {
367 unsigned int hoffset = max(0, (int)format->width - 16);
368
369 /*
370 * Compute the output coordinate. The partition
371 * horizontal (left) offset becomes a vertical offset.
372 */
373 for (i = 0; i < format->num_planes; ++i) {
374 unsigned int hsub = i > 0 ? fmtinfo->hsub : 1;
375
376 mem.addr[i] += hoffset / hsub
377 * fmtinfo->bpp[i] / 8;
378 }
379 }
380
381 /*
382 * On Gen3 hardware the SPUVS bit has no effect on 3-planar
383 * formats. Swap the U and V planes manually in that case.
384 */
385 if (vsp1->info->gen == 3 && format->num_planes == 3 &&
386 fmtinfo->swap_uv)
387 swap(mem.addr[1], mem.addr[2]);
388
284 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]); 389 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]);
285 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]); 390 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]);
286 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]); 391 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]);
@@ -294,6 +399,9 @@ static void wpf_configure(struct vsp1_entity *entity,
294 399
295 outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT; 400 outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;
296 401
402 if (wpf->flip.rotate)
403 outfmt |= VI6_WPF_OUTFMT_ROT;
404
297 if (fmtinfo->alpha) 405 if (fmtinfo->alpha)
298 outfmt |= VI6_WPF_OUTFMT_PXA; 406 outfmt |= VI6_WPF_OUTFMT_PXA;
299 if (fmtinfo->swap_yc) 407 if (fmtinfo->swap_yc)
@@ -327,7 +435,8 @@ static void wpf_configure(struct vsp1_entity *entity,
327 435
328 vsp1_dl_list_write(dl, VI6_WPF_WRBCK_CTRL, 0); 436 vsp1_dl_list_write(dl, VI6_WPF_WRBCK_CTRL, 0);
329 437
330 /* Sources. If the pipeline has a single input and BRU is not used, 438 /*
439 * Sources. If the pipeline has a single input and BRU is not used,
331 * configure it as the master layer. Otherwise configure all 440 * configure it as the master layer. Otherwise configure all
332 * inputs as sub-layers and select the virtual RPF as the master 441 * inputs as sub-layers and select the virtual RPF as the master
333 * layer. 442 * layer.
@@ -354,9 +463,18 @@ static void wpf_configure(struct vsp1_entity *entity,
354 VI6_WFP_IRQ_ENB_DFEE); 463 VI6_WFP_IRQ_ENB_DFEE);
355} 464}
356 465
466static unsigned int wpf_max_width(struct vsp1_entity *entity,
467 struct vsp1_pipeline *pipe)
468{
469 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
470
471 return wpf->flip.rotate ? 256 : wpf->max_width;
472}
473
357static const struct vsp1_entity_operations wpf_entity_ops = { 474static const struct vsp1_entity_operations wpf_entity_ops = {
358 .destroy = vsp1_wpf_destroy, 475 .destroy = vsp1_wpf_destroy,
359 .configure = wpf_configure, 476 .configure = wpf_configure,
477 .max_width = wpf_max_width,
360}; 478};
361 479
362/* ----------------------------------------------------------------------------- 480/* -----------------------------------------------------------------------------
diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c
index 60f026a58076..f4a53f1e856e 100644
--- a/drivers/media/radio/si4713/si4713.c
+++ b/drivers/media/radio/si4713/si4713.c
@@ -1656,9 +1656,18 @@ static const struct i2c_device_id si4713_id[] = {
1656}; 1656};
1657MODULE_DEVICE_TABLE(i2c, si4713_id); 1657MODULE_DEVICE_TABLE(i2c, si4713_id);
1658 1658
1659#if IS_ENABLED(CONFIG_OF)
1660static const struct of_device_id si4713_of_match[] = {
1661 { .compatible = "silabs,si4713" },
1662 { },
1663};
1664MODULE_DEVICE_TABLE(of, si4713_of_match);
1665#endif
1666
1659static struct i2c_driver si4713_i2c_driver = { 1667static struct i2c_driver si4713_i2c_driver = {
1660 .driver = { 1668 .driver = {
1661 .name = "si4713", 1669 .name = "si4713",
1670 .of_match_table = of_match_ptr(si4713_of_match),
1662 }, 1671 },
1663 .probe = si4713_probe, 1672 .probe = si4713_probe,
1664 .remove = si4713_remove, 1673 .remove = si4713_remove,
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index 74a1b3ecb30a..588e2d61c3b4 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -1550,9 +1550,8 @@ int fmc_prepare(struct fmdev *fmdev)
1550 atomic_set(&fmdev->tx_cnt, 1); 1550 atomic_set(&fmdev->tx_cnt, 1);
1551 fmdev->resp_comp = NULL; 1551 fmdev->resp_comp = NULL;
1552 1552
1553 init_timer(&fmdev->irq_info.timer); 1553 setup_timer(&fmdev->irq_info.timer, &int_timeout_handler,
1554 fmdev->irq_info.timer.function = &int_timeout_handler; 1554 (unsigned long)fmdev);
1555 fmdev->irq_info.timer.data = (unsigned long)fmdev;
1556 /*TODO: add FM_STIC_EVENT later */ 1555 /*TODO: add FM_STIC_EVENT later */
1557 fmdev->irq_info.mask = FM_MAL_EVENT; 1556 fmdev->irq_info.mask = FM_MAL_EVENT;
1558 1557
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index d1d3fd00ed89..e422f3d56f76 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -426,4 +426,13 @@ config IR_SERIAL_TRANSMITTER
426 ---help--- 426 ---help---
427 Serial Port Transmitter support 427 Serial Port Transmitter support
428 428
429config IR_SIR
430 tristate "Built-in SIR IrDA port"
431 depends on RC_CORE
432 ---help---
433 Say Y if you want to use a IrDA SIR port Transceivers.
434
435 To compile this driver as a module, choose M here: the module will
436 be called sir-ir.
437
429endif #RC_DEVICES 438endif #RC_DEVICES
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 679aa0af85cd..245e2c2d0b22 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -39,4 +39,5 @@ obj-$(CONFIG_RC_ST) += st_rc.o
39obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o 39obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
40obj-$(CONFIG_IR_IMG) += img-ir/ 40obj-$(CONFIG_IR_IMG) += img-ir/
41obj-$(CONFIG_IR_SERIAL) += serial_ir.o 41obj-$(CONFIG_IR_SERIAL) += serial_ir.o
42obj-$(CONFIG_IR_SIR) += sir_ir.o
42obj-$(CONFIG_IR_MTK) += mtk-cir.o 43obj-$(CONFIG_IR_MTK) += mtk-cir.o
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 4a4895e4d599..b4f773b9dc1d 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -158,7 +158,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
158 rcdev->input_id.version = 0x0100; 158 rcdev->input_id.version = 0x0100;
159 rcdev->dev.parent = &pdev->dev; 159 rcdev->dev.parent = &pdev->dev;
160 rcdev->driver_name = GPIO_IR_DRIVER_NAME; 160 rcdev->driver_name = GPIO_IR_DRIVER_NAME;
161 rcdev->min_timeout = 0; 161 rcdev->min_timeout = 1;
162 rcdev->timeout = IR_DEFAULT_TIMEOUT; 162 rcdev->timeout = IR_DEFAULT_TIMEOUT;
163 rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; 163 rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
164 if (pdata->allowed_protos) 164 if (pdata->allowed_protos)
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index 0f0ed4ea4d06..cb6d4f1247da 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -205,7 +205,7 @@ static int igorplugusb_probe(struct usb_interface *intf,
205 rc->allowed_protocols = RC_BIT_ALL_IR_DECODER & ~(RC_BIT_NEC | 205 rc->allowed_protocols = RC_BIT_ALL_IR_DECODER & ~(RC_BIT_NEC |
206 RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_6A_20 | 206 RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_6A_20 |
207 RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | 207 RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE |
208 RC_BIT_SONY20 | RC_BIT_MCE_KBD | RC_BIT_SANYO); 208 RC_BIT_SONY20 | RC_BIT_SANYO);
209 209
210 rc->priv = ir; 210 rc->priv = ir;
211 rc->driver_name = DRIVER_NAME; 211 rc->driver_name = DRIVER_NAME;
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 89823d24a384..3489010601b5 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -2412,9 +2412,8 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf,
2412 mutex_lock(&ictx->lock); 2412 mutex_lock(&ictx->lock);
2413 2413
2414 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { 2414 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
2415 init_timer(&ictx->ttimer); 2415 setup_timer(&ictx->ttimer, imon_touch_display_timeout,
2416 ictx->ttimer.data = (unsigned long)ictx; 2416 (unsigned long)ictx);
2417 ictx->ttimer.function = imon_touch_display_timeout;
2418 } 2417 }
2419 2418
2420 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); 2419 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 8517d5153fcf..de85f1d7ce43 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -139,7 +139,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
139 } 139 }
140 140
141 if (!dev->tx_ir) { 141 if (!dev->tx_ir) {
142 ret = -ENOSYS; 142 ret = -EINVAL;
143 goto out; 143 goto out;
144 } 144 }
145 145
@@ -221,19 +221,19 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
221 /* TX settings */ 221 /* TX settings */
222 case LIRC_SET_TRANSMITTER_MASK: 222 case LIRC_SET_TRANSMITTER_MASK:
223 if (!dev->s_tx_mask) 223 if (!dev->s_tx_mask)
224 return -ENOSYS; 224 return -ENOTTY;
225 225
226 return dev->s_tx_mask(dev, val); 226 return dev->s_tx_mask(dev, val);
227 227
228 case LIRC_SET_SEND_CARRIER: 228 case LIRC_SET_SEND_CARRIER:
229 if (!dev->s_tx_carrier) 229 if (!dev->s_tx_carrier)
230 return -ENOSYS; 230 return -ENOTTY;
231 231
232 return dev->s_tx_carrier(dev, val); 232 return dev->s_tx_carrier(dev, val);
233 233
234 case LIRC_SET_SEND_DUTY_CYCLE: 234 case LIRC_SET_SEND_DUTY_CYCLE:
235 if (!dev->s_tx_duty_cycle) 235 if (!dev->s_tx_duty_cycle)
236 return -ENOSYS; 236 return -ENOTTY;
237 237
238 if (val <= 0 || val >= 100) 238 if (val <= 0 || val >= 100)
239 return -EINVAL; 239 return -EINVAL;
@@ -243,7 +243,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
243 /* RX settings */ 243 /* RX settings */
244 case LIRC_SET_REC_CARRIER: 244 case LIRC_SET_REC_CARRIER:
245 if (!dev->s_rx_carrier_range) 245 if (!dev->s_rx_carrier_range)
246 return -ENOSYS; 246 return -ENOTTY;
247 247
248 if (val <= 0) 248 if (val <= 0)
249 return -EINVAL; 249 return -EINVAL;
@@ -253,6 +253,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
253 val); 253 val);
254 254
255 case LIRC_SET_REC_CARRIER_RANGE: 255 case LIRC_SET_REC_CARRIER_RANGE:
256 if (!dev->s_rx_carrier_range)
257 return -ENOTTY;
258
256 if (val <= 0) 259 if (val <= 0)
257 return -EINVAL; 260 return -EINVAL;
258 261
@@ -260,37 +263,40 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
260 return 0; 263 return 0;
261 264
262 case LIRC_GET_REC_RESOLUTION: 265 case LIRC_GET_REC_RESOLUTION:
266 if (!dev->rx_resolution)
267 return -ENOTTY;
268
263 val = dev->rx_resolution; 269 val = dev->rx_resolution;
264 break; 270 break;
265 271
266 case LIRC_SET_WIDEBAND_RECEIVER: 272 case LIRC_SET_WIDEBAND_RECEIVER:
267 if (!dev->s_learning_mode) 273 if (!dev->s_learning_mode)
268 return -ENOSYS; 274 return -ENOTTY;
269 275
270 return dev->s_learning_mode(dev, !!val); 276 return dev->s_learning_mode(dev, !!val);
271 277
272 case LIRC_SET_MEASURE_CARRIER_MODE: 278 case LIRC_SET_MEASURE_CARRIER_MODE:
273 if (!dev->s_carrier_report) 279 if (!dev->s_carrier_report)
274 return -ENOSYS; 280 return -ENOTTY;
275 281
276 return dev->s_carrier_report(dev, !!val); 282 return dev->s_carrier_report(dev, !!val);
277 283
278 /* Generic timeout support */ 284 /* Generic timeout support */
279 case LIRC_GET_MIN_TIMEOUT: 285 case LIRC_GET_MIN_TIMEOUT:
280 if (!dev->max_timeout) 286 if (!dev->max_timeout)
281 return -ENOSYS; 287 return -ENOTTY;
282 val = DIV_ROUND_UP(dev->min_timeout, 1000); 288 val = DIV_ROUND_UP(dev->min_timeout, 1000);
283 break; 289 break;
284 290
285 case LIRC_GET_MAX_TIMEOUT: 291 case LIRC_GET_MAX_TIMEOUT:
286 if (!dev->max_timeout) 292 if (!dev->max_timeout)
287 return -ENOSYS; 293 return -ENOTTY;
288 val = dev->max_timeout / 1000; 294 val = dev->max_timeout / 1000;
289 break; 295 break;
290 296
291 case LIRC_SET_REC_TIMEOUT: 297 case LIRC_SET_REC_TIMEOUT:
292 if (!dev->max_timeout) 298 if (!dev->max_timeout)
293 return -ENOSYS; 299 return -ENOTTY;
294 300
295 tmp = val * 1000; 301 tmp = val * 1000;
296 302
@@ -305,6 +311,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
305 break; 311 break;
306 312
307 case LIRC_SET_REC_TIMEOUT_REPORTS: 313 case LIRC_SET_REC_TIMEOUT_REPORTS:
314 if (!dev->timeout)
315 return -ENOTTY;
316
308 lirc->send_timeout_reports = !!val; 317 lirc->send_timeout_reports = !!val;
309 break; 318 break;
310 319
@@ -361,8 +370,11 @@ static int ir_lirc_register(struct rc_dev *dev)
361 if (rc) 370 if (rc)
362 goto rbuf_init_failed; 371 goto rbuf_init_failed;
363 372
364 if (dev->driver_type != RC_DRIVER_IR_RAW_TX) 373 if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
365 features |= LIRC_CAN_REC_MODE2; 374 features |= LIRC_CAN_REC_MODE2;
375 if (dev->rx_resolution)
376 features |= LIRC_CAN_GET_REC_RESOLUTION;
377 }
366 if (dev->tx_ir) { 378 if (dev->tx_ir) {
367 features |= LIRC_CAN_SEND_PULSE; 379 features |= LIRC_CAN_SEND_PULSE;
368 if (dev->s_tx_mask) 380 if (dev->s_tx_mask)
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index 5226d510e847..6a4d58b88d91 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -23,7 +23,7 @@
23 * - MCIR-2 29-bit IR signals used for mouse movement and buttons 23 * - MCIR-2 29-bit IR signals used for mouse movement and buttons
24 * - MCIR-2 32-bit IR signals used for standard keyboard keys 24 * - MCIR-2 32-bit IR signals used for standard keyboard keys
25 * 25 *
26 * The media keys on the keyboard send RC-6 signals that are inditinguishable 26 * The media keys on the keyboard send RC-6 signals that are indistinguishable
27 * from the keys of the same name on the stock MCE remote, and will be handled 27 * from the keys of the same name on the stock MCE remote, and will be handled
28 * by the standard RC-6 decoder, and be made available to the system via the 28 * by the standard RC-6 decoder, and be made available to the system via the
29 * input device for the remote, rather than the keyboard/mouse one. 29 * input device for the remote, rather than the keyboard/mouse one.
@@ -339,6 +339,7 @@ again:
339 } 339 }
340 340
341 data->state = STATE_INACTIVE; 341 data->state = STATE_INACTIVE;
342 input_event(data->idev, EV_MSC, MSC_SCAN, scancode);
342 input_sync(data->idev); 343 input_sync(data->idev);
343 return 0; 344 return 0;
344 } 345 }
@@ -418,9 +419,53 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
418 return 0; 419 return 0;
419} 420}
420 421
422static const struct ir_raw_timings_manchester ir_mce_kbd_timings = {
423 .leader = MCIR2_PREFIX_PULSE,
424 .invert = 1,
425 .clock = MCIR2_UNIT,
426 .trailer_space = MCIR2_UNIT * 10,
427};
428
429/**
430 * ir_mce_kbd_encode() - Encode a scancode as a stream of raw events
431 *
432 * @protocol: protocol to encode
433 * @scancode: scancode to encode
434 * @events: array of raw ir events to write into
435 * @max: maximum size of @events
436 *
437 * Returns: The number of events written.
438 * -ENOBUFS if there isn't enough space in the array to fit the
439 * encoding. In this case all @max events will have been written.
440 */
441static int ir_mce_kbd_encode(enum rc_type protocol, u32 scancode,
442 struct ir_raw_event *events, unsigned int max)
443{
444 struct ir_raw_event *e = events;
445 int len, ret;
446 u64 raw;
447
448 if (protocol == RC_TYPE_MCIR2_KBD) {
449 raw = scancode |
450 ((u64)MCIR2_KEYBOARD_HEADER << MCIR2_KEYBOARD_NBITS);
451 len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS + 1;
452 } else {
453 raw = scancode |
454 ((u64)MCIR2_MOUSE_HEADER << MCIR2_MOUSE_NBITS);
455 len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS + 1;
456 }
457
458 ret = ir_raw_gen_manchester(&e, max, &ir_mce_kbd_timings, len, raw);
459 if (ret < 0)
460 return ret;
461
462 return e - events;
463}
464
421static struct ir_raw_handler mce_kbd_handler = { 465static struct ir_raw_handler mce_kbd_handler = {
422 .protocols = RC_BIT_MCE_KBD, 466 .protocols = RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE,
423 .decode = ir_mce_kbd_decode, 467 .decode = ir_mce_kbd_decode,
468 .encode = ir_mce_kbd_encode,
424 .raw_register = ir_mce_kbd_register, 469 .raw_register = ir_mce_kbd_register,
425 .raw_unregister = ir_mce_kbd_unregister, 470 .raw_unregister = ir_mce_kbd_unregister,
426}; 471};
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index ffe9e612f8d6..2945f99907b5 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -57,7 +57,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
57 rc-kworld-pc150u.o \ 57 rc-kworld-pc150u.o \
58 rc-kworld-plus-tv-analog.o \ 58 rc-kworld-plus-tv-analog.o \
59 rc-leadtek-y04g0051.o \ 59 rc-leadtek-y04g0051.o \
60 rc-lirc.o \
61 rc-lme2510.o \ 60 rc-lme2510.o \
62 rc-manli.o \ 61 rc-manli.o \
63 rc-medion-x10.o \ 62 rc-medion-x10.o \
diff --git a/drivers/media/rc/keymaps/rc-dvico-mce.c b/drivers/media/rc/keymaps/rc-dvico-mce.c
index e5f098c50235..d1e861f4d095 100644
--- a/drivers/media/rc/keymaps/rc-dvico-mce.c
+++ b/drivers/media/rc/keymaps/rc-dvico-mce.c
@@ -12,58 +12,58 @@
12#include <linux/module.h> 12#include <linux/module.h>
13 13
14static struct rc_map_table rc_map_dvico_mce_table[] = { 14static struct rc_map_table rc_map_dvico_mce_table[] = {
15 { 0xfe02, KEY_TV }, 15 { 0x0102, KEY_TV },
16 { 0xfe0e, KEY_MP3 }, 16 { 0x010e, KEY_MP3 },
17 { 0xfe1a, KEY_DVD }, 17 { 0x011a, KEY_DVD },
18 { 0xfe1e, KEY_FAVORITES }, 18 { 0x011e, KEY_FAVORITES },
19 { 0xfe16, KEY_SETUP }, 19 { 0x0116, KEY_SETUP },
20 { 0xfe46, KEY_POWER2 }, 20 { 0x0146, KEY_POWER2 },
21 { 0xfe0a, KEY_EPG }, 21 { 0x010a, KEY_EPG },
22 { 0xfe49, KEY_BACK }, 22 { 0x0149, KEY_BACK },
23 { 0xfe4d, KEY_MENU }, 23 { 0x014d, KEY_MENU },
24 { 0xfe51, KEY_UP }, 24 { 0x0151, KEY_UP },
25 { 0xfe5b, KEY_LEFT }, 25 { 0x015b, KEY_LEFT },
26 { 0xfe5f, KEY_RIGHT }, 26 { 0x015f, KEY_RIGHT },
27 { 0xfe53, KEY_DOWN }, 27 { 0x0153, KEY_DOWN },
28 { 0xfe5e, KEY_OK }, 28 { 0x015e, KEY_OK },
29 { 0xfe59, KEY_INFO }, 29 { 0x0159, KEY_INFO },
30 { 0xfe55, KEY_TAB }, 30 { 0x0155, KEY_TAB },
31 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */ 31 { 0x010f, KEY_PREVIOUSSONG },/* Replay */
32 { 0xfe12, KEY_NEXTSONG }, /* Skip */ 32 { 0x0112, KEY_NEXTSONG }, /* Skip */
33 { 0xfe42, KEY_ENTER }, /* Windows/Start */ 33 { 0x0142, KEY_ENTER }, /* Windows/Start */
34 { 0xfe15, KEY_VOLUMEUP }, 34 { 0x0115, KEY_VOLUMEUP },
35 { 0xfe05, KEY_VOLUMEDOWN }, 35 { 0x0105, KEY_VOLUMEDOWN },
36 { 0xfe11, KEY_CHANNELUP }, 36 { 0x0111, KEY_CHANNELUP },
37 { 0xfe09, KEY_CHANNELDOWN }, 37 { 0x0109, KEY_CHANNELDOWN },
38 { 0xfe52, KEY_CAMERA }, 38 { 0x0152, KEY_CAMERA },
39 { 0xfe5a, KEY_TUNER }, /* Live */ 39 { 0x015a, KEY_TUNER }, /* Live */
40 { 0xfe19, KEY_OPEN }, 40 { 0x0119, KEY_OPEN },
41 { 0xfe0b, KEY_1 }, 41 { 0x010b, KEY_1 },
42 { 0xfe17, KEY_2 }, 42 { 0x0117, KEY_2 },
43 { 0xfe1b, KEY_3 }, 43 { 0x011b, KEY_3 },
44 { 0xfe07, KEY_4 }, 44 { 0x0107, KEY_4 },
45 { 0xfe50, KEY_5 }, 45 { 0x0150, KEY_5 },
46 { 0xfe54, KEY_6 }, 46 { 0x0154, KEY_6 },
47 { 0xfe48, KEY_7 }, 47 { 0x0148, KEY_7 },
48 { 0xfe4c, KEY_8 }, 48 { 0x014c, KEY_8 },
49 { 0xfe58, KEY_9 }, 49 { 0x0158, KEY_9 },
50 { 0xfe13, KEY_ANGLE }, /* Aspect */ 50 { 0x0113, KEY_ANGLE }, /* Aspect */
51 { 0xfe03, KEY_0 }, 51 { 0x0103, KEY_0 },
52 { 0xfe1f, KEY_ZOOM }, 52 { 0x011f, KEY_ZOOM },
53 { 0xfe43, KEY_REWIND }, 53 { 0x0143, KEY_REWIND },
54 { 0xfe47, KEY_PLAYPAUSE }, 54 { 0x0147, KEY_PLAYPAUSE },
55 { 0xfe4f, KEY_FASTFORWARD }, 55 { 0x014f, KEY_FASTFORWARD },
56 { 0xfe57, KEY_MUTE }, 56 { 0x0157, KEY_MUTE },
57 { 0xfe0d, KEY_STOP }, 57 { 0x010d, KEY_STOP },
58 { 0xfe01, KEY_RECORD }, 58 { 0x0101, KEY_RECORD },
59 { 0xfe4e, KEY_POWER }, 59 { 0x014e, KEY_POWER },
60}; 60};
61 61
62static struct rc_map_list dvico_mce_map = { 62static struct rc_map_list dvico_mce_map = {
63 .map = { 63 .map = {
64 .scan = rc_map_dvico_mce_table, 64 .scan = rc_map_dvico_mce_table,
65 .size = ARRAY_SIZE(rc_map_dvico_mce_table), 65 .size = ARRAY_SIZE(rc_map_dvico_mce_table),
66 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ 66 .rc_type = RC_TYPE_NEC,
67 .name = RC_MAP_DVICO_MCE, 67 .name = RC_MAP_DVICO_MCE,
68 } 68 }
69}; 69};
diff --git a/drivers/media/rc/keymaps/rc-dvico-portable.c b/drivers/media/rc/keymaps/rc-dvico-portable.c
index 94ceeee94b3f..ac4cb515cbf1 100644
--- a/drivers/media/rc/keymaps/rc-dvico-portable.c
+++ b/drivers/media/rc/keymaps/rc-dvico-portable.c
@@ -12,49 +12,49 @@
12#include <linux/module.h> 12#include <linux/module.h>
13 13
14static struct rc_map_table rc_map_dvico_portable_table[] = { 14static struct rc_map_table rc_map_dvico_portable_table[] = {
15 { 0xfc02, KEY_SETUP }, /* Profile */ 15 { 0x0302, KEY_SETUP }, /* Profile */
16 { 0xfc43, KEY_POWER2 }, 16 { 0x0343, KEY_POWER2 },
17 { 0xfc06, KEY_EPG }, 17 { 0x0306, KEY_EPG },
18 { 0xfc5a, KEY_BACK }, 18 { 0x035a, KEY_BACK },
19 { 0xfc05, KEY_MENU }, 19 { 0x0305, KEY_MENU },
20 { 0xfc47, KEY_INFO }, 20 { 0x0347, KEY_INFO },
21 { 0xfc01, KEY_TAB }, 21 { 0x0301, KEY_TAB },
22 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */ 22 { 0x0342, KEY_PREVIOUSSONG },/* Replay */
23 { 0xfc49, KEY_VOLUMEUP }, 23 { 0x0349, KEY_VOLUMEUP },
24 { 0xfc09, KEY_VOLUMEDOWN }, 24 { 0x0309, KEY_VOLUMEDOWN },
25 { 0xfc54, KEY_CHANNELUP }, 25 { 0x0354, KEY_CHANNELUP },
26 { 0xfc0b, KEY_CHANNELDOWN }, 26 { 0x030b, KEY_CHANNELDOWN },
27 { 0xfc16, KEY_CAMERA }, 27 { 0x0316, KEY_CAMERA },
28 { 0xfc40, KEY_TUNER }, /* ATV/DTV */ 28 { 0x0340, KEY_TUNER }, /* ATV/DTV */
29 { 0xfc45, KEY_OPEN }, 29 { 0x0345, KEY_OPEN },
30 { 0xfc19, KEY_1 }, 30 { 0x0319, KEY_1 },
31 { 0xfc18, KEY_2 }, 31 { 0x0318, KEY_2 },
32 { 0xfc1b, KEY_3 }, 32 { 0x031b, KEY_3 },
33 { 0xfc1a, KEY_4 }, 33 { 0x031a, KEY_4 },
34 { 0xfc58, KEY_5 }, 34 { 0x0358, KEY_5 },
35 { 0xfc59, KEY_6 }, 35 { 0x0359, KEY_6 },
36 { 0xfc15, KEY_7 }, 36 { 0x0315, KEY_7 },
37 { 0xfc14, KEY_8 }, 37 { 0x0314, KEY_8 },
38 { 0xfc17, KEY_9 }, 38 { 0x0317, KEY_9 },
39 { 0xfc44, KEY_ANGLE }, /* Aspect */ 39 { 0x0344, KEY_ANGLE }, /* Aspect */
40 { 0xfc55, KEY_0 }, 40 { 0x0355, KEY_0 },
41 { 0xfc07, KEY_ZOOM }, 41 { 0x0307, KEY_ZOOM },
42 { 0xfc0a, KEY_REWIND }, 42 { 0x030a, KEY_REWIND },
43 { 0xfc08, KEY_PLAYPAUSE }, 43 { 0x0308, KEY_PLAYPAUSE },
44 { 0xfc4b, KEY_FASTFORWARD }, 44 { 0x034b, KEY_FASTFORWARD },
45 { 0xfc5b, KEY_MUTE }, 45 { 0x035b, KEY_MUTE },
46 { 0xfc04, KEY_STOP }, 46 { 0x0304, KEY_STOP },
47 { 0xfc56, KEY_RECORD }, 47 { 0x0356, KEY_RECORD },
48 { 0xfc57, KEY_POWER }, 48 { 0x0357, KEY_POWER },
49 { 0xfc41, KEY_UNKNOWN }, /* INPUT */ 49 { 0x0341, KEY_UNKNOWN }, /* INPUT */
50 { 0xfc00, KEY_UNKNOWN }, /* HD */ 50 { 0x0300, KEY_UNKNOWN }, /* HD */
51}; 51};
52 52
53static struct rc_map_list dvico_portable_map = { 53static struct rc_map_list dvico_portable_map = {
54 .map = { 54 .map = {
55 .scan = rc_map_dvico_portable_table, 55 .scan = rc_map_dvico_portable_table,
56 .size = ARRAY_SIZE(rc_map_dvico_portable_table), 56 .size = ARRAY_SIZE(rc_map_dvico_portable_table),
57 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ 57 .rc_type = RC_TYPE_NEC,
58 .name = RC_MAP_DVICO_PORTABLE, 58 .name = RC_MAP_DVICO_PORTABLE,
59 } 59 }
60}; 60};
diff --git a/drivers/media/rc/keymaps/rc-lirc.c b/drivers/media/rc/keymaps/rc-lirc.c
deleted file mode 100644
index e172f5db5803..000000000000
--- a/drivers/media/rc/keymaps/rc-lirc.c
+++ /dev/null
@@ -1,42 +0,0 @@
1/* rc-lirc.c - Empty dummy keytable, for use when its preferred to pass
2 * all raw IR data to the lirc userspace decoder.
3 *
4 * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <media/rc-core.h>
13#include <linux/module.h>
14
15static struct rc_map_table lirc[] = {
16 { },
17};
18
19static struct rc_map_list lirc_map = {
20 .map = {
21 .scan = lirc,
22 .size = ARRAY_SIZE(lirc),
23 .rc_type = RC_TYPE_OTHER,
24 .name = RC_MAP_LIRC,
25 }
26};
27
28static int __init init_rc_map_lirc(void)
29{
30 return rc_map_register(&lirc_map);
31}
32
33static void __exit exit_rc_map_lirc(void)
34{
35 rc_map_unregister(&lirc_map);
36}
37
38module_init(init_rc_map_lirc)
39module_exit(exit_rc_map_lirc)
40
41MODULE_LICENSE("GPL");
42MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 1688893a65bb..8d60c9f00df9 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -54,7 +54,8 @@ struct irctl {
54 struct lirc_buffer *buf; 54 struct lirc_buffer *buf;
55 unsigned int chunk_size; 55 unsigned int chunk_size;
56 56
57 struct cdev *cdev; 57 struct device dev;
58 struct cdev cdev;
58 59
59 struct task_struct *task; 60 struct task_struct *task;
60 long jiffies_to_wait; 61 long jiffies_to_wait;
@@ -76,15 +77,21 @@ static void lirc_irctl_init(struct irctl *ir)
76 ir->d.minor = NOPLUG; 77 ir->d.minor = NOPLUG;
77} 78}
78 79
79static void lirc_irctl_cleanup(struct irctl *ir) 80static void lirc_release(struct device *ld)
80{ 81{
81 device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); 82 struct irctl *ir = container_of(ld, struct irctl, dev);
83
84 put_device(ir->dev.parent);
82 85
83 if (ir->buf != ir->d.rbuf) { 86 if (ir->buf != ir->d.rbuf) {
84 lirc_buffer_free(ir->buf); 87 lirc_buffer_free(ir->buf);
85 kfree(ir->buf); 88 kfree(ir->buf);
86 } 89 }
87 ir->buf = NULL; 90
91 mutex_lock(&lirc_dev_lock);
92 irctls[ir->d.minor] = NULL;
93 mutex_unlock(&lirc_dev_lock);
94 kfree(ir);
88} 95}
89 96
90/* helper function 97/* helper function
@@ -157,32 +164,21 @@ static int lirc_cdev_add(struct irctl *ir)
157 struct cdev *cdev; 164 struct cdev *cdev;
158 int retval; 165 int retval;
159 166
160 cdev = cdev_alloc(); 167 cdev = &ir->cdev;
161 if (!cdev)
162 return -ENOMEM;
163 168
164 if (d->fops) { 169 if (d->fops) {
165 cdev->ops = d->fops; 170 cdev_init(cdev, d->fops);
166 cdev->owner = d->owner; 171 cdev->owner = d->owner;
167 } else { 172 } else {
168 cdev->ops = &lirc_dev_fops; 173 cdev_init(cdev, &lirc_dev_fops);
169 cdev->owner = THIS_MODULE; 174 cdev->owner = THIS_MODULE;
170 } 175 }
171 retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); 176 retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
172 if (retval) 177 if (retval)
173 goto err_out; 178 return retval;
174
175 retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
176 if (retval)
177 goto err_out;
178
179 ir->cdev = cdev;
180
181 return 0;
182 179
183err_out: 180 cdev->kobj.parent = &ir->dev.kobj;
184 cdev_del(cdev); 181 return cdev_add(cdev, ir->dev.devt, 1);
185 return retval;
186} 182}
187 183
188static int lirc_allocate_buffer(struct irctl *ir) 184static int lirc_allocate_buffer(struct irctl *ir)
@@ -304,9 +300,12 @@ static int lirc_allocate_driver(struct lirc_driver *d)
304 300
305 ir->d = *d; 301 ir->d = *d;
306 302
307 device_create(lirc_class, ir->d.dev, 303 ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor);
308 MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, 304 ir->dev.class = lirc_class;
309 "lirc%u", ir->d.minor); 305 ir->dev.parent = d->dev;
306 ir->dev.release = lirc_release;
307 dev_set_name(&ir->dev, "lirc%d", ir->d.minor);
308 device_initialize(&ir->dev);
310 309
311 if (d->sample_rate) { 310 if (d->sample_rate) {
312 ir->jiffies_to_wait = HZ / d->sample_rate; 311 ir->jiffies_to_wait = HZ / d->sample_rate;
@@ -329,14 +328,22 @@ static int lirc_allocate_driver(struct lirc_driver *d)
329 goto out_sysfs; 328 goto out_sysfs;
330 329
331 ir->attached = 1; 330 ir->attached = 1;
331
332 err = device_add(&ir->dev);
333 if (err)
334 goto out_cdev;
335
332 mutex_unlock(&lirc_dev_lock); 336 mutex_unlock(&lirc_dev_lock);
333 337
338 get_device(ir->dev.parent);
339
334 dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", 340 dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
335 ir->d.name, ir->d.minor); 341 ir->d.name, ir->d.minor);
336 return minor; 342 return minor;
337 343out_cdev:
344 cdev_del(&ir->cdev);
338out_sysfs: 345out_sysfs:
339 device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); 346 put_device(&ir->dev);
340out_lock: 347out_lock:
341 mutex_unlock(&lirc_dev_lock); 348 mutex_unlock(&lirc_dev_lock);
342 349
@@ -364,7 +371,6 @@ EXPORT_SYMBOL(lirc_register_driver);
364int lirc_unregister_driver(int minor) 371int lirc_unregister_driver(int minor)
365{ 372{
366 struct irctl *ir; 373 struct irctl *ir;
367 struct cdev *cdev;
368 374
369 if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { 375 if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
370 pr_err("minor (%d) must be between 0 and %d!\n", 376 pr_err("minor (%d) must be between 0 and %d!\n",
@@ -378,8 +384,6 @@ int lirc_unregister_driver(int minor)
378 return -ENOENT; 384 return -ENOENT;
379 } 385 }
380 386
381 cdev = ir->cdev;
382
383 mutex_lock(&lirc_dev_lock); 387 mutex_lock(&lirc_dev_lock);
384 388
385 if (ir->d.minor != minor) { 389 if (ir->d.minor != minor) {
@@ -401,22 +405,20 @@ int lirc_unregister_driver(int minor)
401 dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", 405 dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n",
402 ir->d.name, ir->d.minor); 406 ir->d.name, ir->d.minor);
403 wake_up_interruptible(&ir->buf->wait_poll); 407 wake_up_interruptible(&ir->buf->wait_poll);
404 mutex_lock(&ir->irctl_lock); 408 }
405 409
406 if (ir->d.set_use_dec) 410 mutex_lock(&ir->irctl_lock);
407 ir->d.set_use_dec(ir->d.data);
408 411
409 module_put(cdev->owner); 412 if (ir->d.set_use_dec)
410 mutex_unlock(&ir->irctl_lock); 413 ir->d.set_use_dec(ir->d.data);
411 } else {
412 lirc_irctl_cleanup(ir);
413 cdev_del(cdev);
414 kfree(ir);
415 irctls[minor] = NULL;
416 }
417 414
415 mutex_unlock(&ir->irctl_lock);
418 mutex_unlock(&lirc_dev_lock); 416 mutex_unlock(&lirc_dev_lock);
419 417
418 device_del(&ir->dev);
419 cdev_del(&ir->cdev);
420 put_device(&ir->dev);
421
420 return 0; 422 return 0;
421} 423}
422EXPORT_SYMBOL(lirc_unregister_driver); 424EXPORT_SYMBOL(lirc_unregister_driver);
@@ -424,7 +426,6 @@ EXPORT_SYMBOL(lirc_unregister_driver);
424int lirc_dev_fop_open(struct inode *inode, struct file *file) 426int lirc_dev_fop_open(struct inode *inode, struct file *file)
425{ 427{
426 struct irctl *ir; 428 struct irctl *ir;
427 struct cdev *cdev;
428 int retval = 0; 429 int retval = 0;
429 430
430 if (iminor(inode) >= MAX_IRCTL_DEVICES) { 431 if (iminor(inode) >= MAX_IRCTL_DEVICES) {
@@ -461,18 +462,14 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
461 goto error; 462 goto error;
462 } 463 }
463 464
464 cdev = ir->cdev; 465 ir->open++;
465 if (try_module_get(cdev->owner)) { 466 if (ir->d.set_use_inc)
466 ir->open++; 467 retval = ir->d.set_use_inc(ir->d.data);
467 if (ir->d.set_use_inc) 468 if (retval) {
468 retval = ir->d.set_use_inc(ir->d.data); 469 ir->open--;
469 470 } else {
470 if (retval) { 471 if (ir->buf)
471 module_put(cdev->owner);
472 ir->open--;
473 } else if (ir->buf) {
474 lirc_buffer_clear(ir->buf); 472 lirc_buffer_clear(ir->buf);
475 }
476 if (ir->task) 473 if (ir->task)
477 wake_up_process(ir->task); 474 wake_up_process(ir->task);
478 } 475 }
@@ -487,7 +484,6 @@ EXPORT_SYMBOL(lirc_dev_fop_open);
487int lirc_dev_fop_close(struct inode *inode, struct file *file) 484int lirc_dev_fop_close(struct inode *inode, struct file *file)
488{ 485{
489 struct irctl *ir = irctls[iminor(inode)]; 486 struct irctl *ir = irctls[iminor(inode)];
490 struct cdev *cdev;
491 int ret; 487 int ret;
492 488
493 if (!ir) { 489 if (!ir) {
@@ -495,25 +491,14 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file)
495 return -EINVAL; 491 return -EINVAL;
496 } 492 }
497 493
498 cdev = ir->cdev;
499
500 ret = mutex_lock_killable(&lirc_dev_lock); 494 ret = mutex_lock_killable(&lirc_dev_lock);
501 WARN_ON(ret); 495 WARN_ON(ret);
502 496
503 rc_close(ir->d.rdev); 497 rc_close(ir->d.rdev);
504 498
505 ir->open--; 499 ir->open--;
506 if (ir->attached) { 500 if (ir->d.set_use_dec)
507 if (ir->d.set_use_dec) 501 ir->d.set_use_dec(ir->d.data);
508 ir->d.set_use_dec(ir->d.data);
509 module_put(cdev->owner);
510 } else {
511 lirc_irctl_cleanup(ir);
512 cdev_del(cdev);
513 irctls[ir->d.minor] = NULL;
514 kfree(ir);
515 }
516
517 if (!ret) 502 if (!ret)
518 mutex_unlock(&lirc_dev_lock); 503 mutex_unlock(&lirc_dev_lock);
519 504
@@ -623,7 +608,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
623 result = put_user(ir->d.max_timeout, (__u32 __user *)arg); 608 result = put_user(ir->d.max_timeout, (__u32 __user *)arg);
624 break; 609 break;
625 default: 610 default:
626 result = -EINVAL; 611 result = -ENOTTY;
627 } 612 }
628 613
629 mutex_unlock(&ir->irctl_lock); 614 mutex_unlock(&ir->irctl_lock);
@@ -780,15 +765,12 @@ static int __init lirc_dev_init(void)
780 return retval; 765 return retval;
781 } 766 }
782 767
783
784 pr_info("IR Remote Control driver registered, major %d\n", 768 pr_info("IR Remote Control driver registered, major %d\n",
785 MAJOR(lirc_base_dev)); 769 MAJOR(lirc_base_dev));
786 770
787 return 0; 771 return 0;
788} 772}
789 773
790
791
792static void __exit lirc_dev_exit(void) 774static void __exit lirc_dev_exit(void)
793{ 775{
794 class_destroy(lirc_class); 776 class_destroy(lirc_class);
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 238d8eaf7d94..93b16fe3ab38 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1288,8 +1288,8 @@ static int mceusb_dev_probe(struct usb_interface *intf,
1288 } 1288 }
1289 } 1289 }
1290 } 1290 }
1291 if (ep_in == NULL) { 1291 if (!ep_in || !ep_out) {
1292 dev_dbg(&intf->dev, "inbound and/or endpoint not found"); 1292 dev_dbg(&intf->dev, "required endpoints not found\n");
1293 return -ENODEV; 1293 return -ENODEV;
1294 } 1294 }
1295 1295
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index a70a5c557434..0455b273c2fc 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -185,7 +185,7 @@ struct ir_raw_timings_manchester {
185 185
186int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, 186int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
187 const struct ir_raw_timings_manchester *timings, 187 const struct ir_raw_timings_manchester *timings,
188 unsigned int n, unsigned int data); 188 unsigned int n, u64 data);
189 189
190/** 190/**
191 * ir_raw_gen_pulse_space() - generate pulse and space raw events. 191 * ir_raw_gen_pulse_space() - generate pulse and space raw events.
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 7fa84b64a2ae..90f66dc7c0d7 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -258,13 +258,13 @@ static void ir_raw_disable_protocols(struct rc_dev *dev, u64 protocols)
258 */ 258 */
259int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, 259int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
260 const struct ir_raw_timings_manchester *timings, 260 const struct ir_raw_timings_manchester *timings,
261 unsigned int n, unsigned int data) 261 unsigned int n, u64 data)
262{ 262{
263 bool need_pulse; 263 bool need_pulse;
264 unsigned int i; 264 u64 i;
265 int ret = -ENOBUFS; 265 int ret = -ENOBUFS;
266 266
267 i = 1 << (n - 1); 267 i = BIT_ULL(n - 1);
268 268
269 if (timings->leader) { 269 if (timings->leader) {
270 if (!max--) 270 if (!max--)
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index d84533699668..6ec73357fa47 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -746,6 +746,8 @@ static int rc_validate_filter(struct rc_dev *dev,
746 [RC_TYPE_NECX] = 0xffffff, 746 [RC_TYPE_NECX] = 0xffffff,
747 [RC_TYPE_NEC32] = 0xffffffff, 747 [RC_TYPE_NEC32] = 0xffffffff,
748 [RC_TYPE_SANYO] = 0x1fffff, 748 [RC_TYPE_SANYO] = 0x1fffff,
749 [RC_TYPE_MCIR2_KBD] = 0xffff,
750 [RC_TYPE_MCIR2_MSE] = 0x1fffff,
749 [RC_TYPE_RC6_0] = 0xffff, 751 [RC_TYPE_RC6_0] = 0xffff,
750 [RC_TYPE_RC6_6A_20] = 0xfffff, 752 [RC_TYPE_RC6_6A_20] = 0xfffff,
751 [RC_TYPE_RC6_6A_24] = 0xffffff, 753 [RC_TYPE_RC6_6A_24] = 0xffffff,
@@ -878,7 +880,8 @@ static const struct {
878 { RC_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" }, 880 { RC_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" },
879 { RC_BIT_SANYO, "sanyo", "ir-sanyo-decoder" }, 881 { RC_BIT_SANYO, "sanyo", "ir-sanyo-decoder" },
880 { RC_BIT_SHARP, "sharp", "ir-sharp-decoder" }, 882 { RC_BIT_SHARP, "sharp", "ir-sharp-decoder" },
881 { RC_BIT_MCE_KBD, "mce_kbd", "ir-mce_kbd-decoder" }, 883 { RC_BIT_MCIR2_KBD |
884 RC_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" },
882 { RC_BIT_XMP, "xmp", "ir-xmp-decoder" }, 885 { RC_BIT_XMP, "xmp", "ir-xmp-decoder" },
883 { RC_BIT_CEC, "cec", NULL }, 886 { RC_BIT_CEC, "cec", NULL },
884}; 887};
@@ -1346,7 +1349,8 @@ static const char * const proto_variant_names[] = {
1346 [RC_TYPE_NECX] = "nec-x", 1349 [RC_TYPE_NECX] = "nec-x",
1347 [RC_TYPE_NEC32] = "nec-32", 1350 [RC_TYPE_NEC32] = "nec-32",
1348 [RC_TYPE_SANYO] = "sanyo", 1351 [RC_TYPE_SANYO] = "sanyo",
1349 [RC_TYPE_MCE_KBD] = "mce_kbd", 1352 [RC_TYPE_MCIR2_KBD] = "mcir2-kbd",
1353 [RC_TYPE_MCIR2_MSE] = "mcir2-mse",
1350 [RC_TYPE_RC6_0] = "rc-6-0", 1354 [RC_TYPE_RC6_0] = "rc-6-0",
1351 [RC_TYPE_RC6_6A_20] = "rc-6-6a-20", 1355 [RC_TYPE_RC6_6A_20] = "rc-6-6a-20",
1352 [RC_TYPE_RC6_6A_24] = "rc-6-6a-24", 1356 [RC_TYPE_RC6_6A_24] = "rc-6-6a-24",
diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c
index 41b54e40176c..2f0a0d248936 100644
--- a/drivers/media/rc/serial_ir.c
+++ b/drivers/media/rc/serial_ir.c
@@ -56,7 +56,7 @@ struct serial_ir_hw {
56static int type; 56static int type;
57static int io; 57static int io;
58static int irq; 58static int irq;
59static bool iommap; 59static ulong iommap;
60static int ioshift; 60static int ioshift;
61static bool softcarrier = true; 61static bool softcarrier = true;
62static bool share_irq; 62static bool share_irq;
@@ -837,7 +837,7 @@ module_param(io, int, 0444);
837MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); 837MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
838 838
839/* some architectures (e.g. intel xscale) have memory mapped registers */ 839/* some architectures (e.g. intel xscale) have memory mapped registers */
840module_param(iommap, bool, 0444); 840module_param(iommap, ulong, 0444);
841MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)"); 841MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O (0 = no memory mapped io)");
842 842
843/* 843/*
diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c
new file mode 100644
index 000000000000..e12ec50bf0bf
--- /dev/null
+++ b/drivers/media/rc/sir_ir.c
@@ -0,0 +1,438 @@
1/*
2 * IR SIR driver, (C) 2000 Milan Pikula <www@fornax.sk>
3 *
4 * sir_ir - Device driver for use with SIR (serial infra red)
5 * mode of IrDA on many notebooks.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <linux/serial_reg.h>
19#include <linux/ktime.h>
20#include <linux/delay.h>
21#include <linux/platform_device.h>
22
23#include <media/rc-core.h>
24
25/* SECTION: Definitions */
26#define PULSE '['
27
28/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/
29#define TIME_CONST (9000000ul / 115200ul)
30
31/* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */
32#define SIR_TIMEOUT (HZ * 5 / 100)
33
34/* onboard sir ports are typically com3 */
35static int io = 0x3e8;
36static int irq = 4;
37static int threshold = 3;
38
39static DEFINE_SPINLOCK(timer_lock);
40static struct timer_list timerlist;
41/* time of last signal change detected */
42static ktime_t last;
43/* time of last UART data ready interrupt */
44static ktime_t last_intr_time;
45static int last_value;
46static struct rc_dev *rcdev;
47
48static struct platform_device *sir_ir_dev;
49
50static DEFINE_SPINLOCK(hardware_lock);
51
52/* SECTION: Prototypes */
53
54/* Communication with user-space */
55static void add_read_queue(int flag, unsigned long val);
56static int init_chrdev(void);
57/* Hardware */
58static irqreturn_t sir_interrupt(int irq, void *dev_id);
59static void send_space(unsigned long len);
60static void send_pulse(unsigned long len);
61static int init_hardware(void);
62static void drop_hardware(void);
63/* Initialisation */
64static int init_port(void);
65static void drop_port(void);
66
67static inline unsigned int sinp(int offset)
68{
69 return inb(io + offset);
70}
71
72static inline void soutp(int offset, int value)
73{
74 outb(value, io + offset);
75}
76
77/* SECTION: Communication with user-space */
78static int sir_tx_ir(struct rc_dev *dev, unsigned int *tx_buf,
79 unsigned int count)
80{
81 unsigned long flags;
82 int i;
83
84 local_irq_save(flags);
85 for (i = 0; i < count;) {
86 if (tx_buf[i])
87 send_pulse(tx_buf[i]);
88 i++;
89 if (i >= count)
90 break;
91 if (tx_buf[i])
92 send_space(tx_buf[i]);
93 i++;
94 }
95 local_irq_restore(flags);
96
97 return count;
98}
99
100static void add_read_queue(int flag, unsigned long val)
101{
102 DEFINE_IR_RAW_EVENT(ev);
103
104 pr_debug("add flag %d with val %lu\n", flag, val);
105
106 /*
107 * statistically, pulses are ~TIME_CONST/2 too long. we could
108 * maybe make this more exact, but this is good enough
109 */
110 if (flag) {
111 /* pulse */
112 if (val > TIME_CONST / 2)
113 val -= TIME_CONST / 2;
114 else /* should not ever happen */
115 val = 1;
116 ev.pulse = true;
117 } else {
118 val += TIME_CONST / 2;
119 }
120 ev.duration = US_TO_NS(val);
121
122 ir_raw_event_store_with_filter(rcdev, &ev);
123}
124
125static int init_chrdev(void)
126{
127 rcdev = devm_rc_allocate_device(&sir_ir_dev->dev, RC_DRIVER_IR_RAW);
128 if (!rcdev)
129 return -ENOMEM;
130
131 rcdev->input_name = "SIR IrDA port";
132 rcdev->input_phys = KBUILD_MODNAME "/input0";
133 rcdev->input_id.bustype = BUS_HOST;
134 rcdev->input_id.vendor = 0x0001;
135 rcdev->input_id.product = 0x0001;
136 rcdev->input_id.version = 0x0100;
137 rcdev->tx_ir = sir_tx_ir;
138 rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
139 rcdev->driver_name = KBUILD_MODNAME;
140 rcdev->map_name = RC_MAP_RC6_MCE;
141 rcdev->timeout = IR_DEFAULT_TIMEOUT;
142 rcdev->dev.parent = &sir_ir_dev->dev;
143
144 return devm_rc_register_device(&sir_ir_dev->dev, rcdev);
145}
146
147/* SECTION: Hardware */
148static void sir_timeout(unsigned long data)
149{
150 /*
151 * if last received signal was a pulse, but receiving stopped
152 * within the 9 bit frame, we need to finish this pulse and
153 * simulate a signal change to from pulse to space. Otherwise
154 * upper layers will receive two sequences next time.
155 */
156
157 unsigned long flags;
158 unsigned long pulse_end;
159
160 /* avoid interference with interrupt */
161 spin_lock_irqsave(&timer_lock, flags);
162 if (last_value) {
163 /* clear unread bits in UART and restart */
164 outb(UART_FCR_CLEAR_RCVR, io + UART_FCR);
165 /* determine 'virtual' pulse end: */
166 pulse_end = min_t(unsigned long,
167 ktime_us_delta(last, last_intr_time),
168 IR_MAX_DURATION);
169 dev_dbg(&sir_ir_dev->dev, "timeout add %d for %lu usec\n",
170 last_value, pulse_end);
171 add_read_queue(last_value, pulse_end);
172 last_value = 0;
173 last = last_intr_time;
174 }
175 spin_unlock_irqrestore(&timer_lock, flags);
176 ir_raw_event_handle(rcdev);
177}
178
179static irqreturn_t sir_interrupt(int irq, void *dev_id)
180{
181 unsigned char data;
182 ktime_t curr_time;
183 static unsigned long delt;
184 unsigned long deltintr;
185 unsigned long flags;
186 int iir, lsr;
187
188 while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) {
189 switch (iir & UART_IIR_ID) { /* FIXME toto treba preriedit */
190 case UART_IIR_MSI:
191 (void)inb(io + UART_MSR);
192 break;
193 case UART_IIR_RLSI:
194 case UART_IIR_THRI:
195 (void)inb(io + UART_LSR);
196 break;
197 case UART_IIR_RDI:
198 /* avoid interference with timer */
199 spin_lock_irqsave(&timer_lock, flags);
200 do {
201 del_timer(&timerlist);
202 data = inb(io + UART_RX);
203 curr_time = ktime_get();
204 delt = min_t(unsigned long,
205 ktime_us_delta(last, curr_time),
206 IR_MAX_DURATION);
207 deltintr = min_t(unsigned long,
208 ktime_us_delta(last_intr_time,
209 curr_time),
210 IR_MAX_DURATION);
211 dev_dbg(&sir_ir_dev->dev, "t %lu, d %d\n",
212 deltintr, (int)data);
213 /*
214 * if nothing came in last X cycles,
215 * it was gap
216 */
217 if (deltintr > TIME_CONST * threshold) {
218 if (last_value) {
219 dev_dbg(&sir_ir_dev->dev, "GAP\n");
220 /* simulate signal change */
221 add_read_queue(last_value,
222 delt -
223 deltintr);
224 last_value = 0;
225 last = last_intr_time;
226 delt = deltintr;
227 }
228 }
229 data = 1;
230 if (data ^ last_value) {
231 /*
232 * deltintr > 2*TIME_CONST, remember?
233 * the other case is timeout
234 */
235 add_read_queue(last_value,
236 delt - TIME_CONST);
237 last_value = data;
238 last = curr_time;
239 last = ktime_sub_us(last,
240 TIME_CONST);
241 }
242 last_intr_time = curr_time;
243 if (data) {
244 /*
245 * start timer for end of
246 * sequence detection
247 */
248 timerlist.expires = jiffies +
249 SIR_TIMEOUT;
250 add_timer(&timerlist);
251 }
252
253 lsr = inb(io + UART_LSR);
254 } while (lsr & UART_LSR_DR); /* data ready */
255 spin_unlock_irqrestore(&timer_lock, flags);
256 break;
257 default:
258 break;
259 }
260 }
261 ir_raw_event_handle(rcdev);
262 return IRQ_RETVAL(IRQ_HANDLED);
263}
264
265static void send_space(unsigned long len)
266{
267 usleep_range(len, len + 25);
268}
269
270static void send_pulse(unsigned long len)
271{
272 long bytes_out = len / TIME_CONST;
273
274 if (bytes_out == 0)
275 bytes_out++;
276
277 while (bytes_out--) {
278 outb(PULSE, io + UART_TX);
279 /* FIXME treba seriozne cakanie z char/serial.c */
280 while (!(inb(io + UART_LSR) & UART_LSR_THRE))
281 ;
282 }
283}
284
285static int init_hardware(void)
286{
287 unsigned long flags;
288
289 spin_lock_irqsave(&hardware_lock, flags);
290 /* reset UART */
291 outb(0, io + UART_MCR);
292 outb(0, io + UART_IER);
293 /* init UART */
294 /* set DLAB, speed = 115200 */
295 outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR);
296 outb(1, io + UART_DLL); outb(0, io + UART_DLM);
297 /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */
298 outb(UART_LCR_WLEN7, io + UART_LCR);
299 /* FIFO operation */
300 outb(UART_FCR_ENABLE_FIFO, io + UART_FCR);
301 /* interrupts */
302 /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */
303 outb(UART_IER_RDI, io + UART_IER);
304 /* turn on UART */
305 outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, io + UART_MCR);
306 spin_unlock_irqrestore(&hardware_lock, flags);
307 return 0;
308}
309
310static void drop_hardware(void)
311{
312 unsigned long flags;
313
314 spin_lock_irqsave(&hardware_lock, flags);
315
316 /* turn off interrupts */
317 outb(0, io + UART_IER);
318
319 spin_unlock_irqrestore(&hardware_lock, flags);
320}
321
322/* SECTION: Initialisation */
323
324static int init_port(void)
325{
326 int retval;
327
328 setup_timer(&timerlist, sir_timeout, 0);
329
330 /* get I/O port access and IRQ line */
331 if (!request_region(io, 8, KBUILD_MODNAME)) {
332 pr_err("i/o port 0x%.4x already in use.\n", io);
333 return -EBUSY;
334 }
335 retval = request_irq(irq, sir_interrupt, 0,
336 KBUILD_MODNAME, NULL);
337 if (retval < 0) {
338 release_region(io, 8);
339 pr_err("IRQ %d already in use.\n", irq);
340 return retval;
341 }
342 pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq);
343
344 return 0;
345}
346
347static void drop_port(void)
348{
349 free_irq(irq, NULL);
350 del_timer_sync(&timerlist);
351 release_region(io, 8);
352}
353
354static int init_sir_ir(void)
355{
356 int retval;
357
358 retval = init_port();
359 if (retval < 0)
360 return retval;
361 init_hardware();
362 return 0;
363}
364
365static int sir_ir_probe(struct platform_device *dev)
366{
367 int retval;
368
369 retval = init_chrdev();
370 if (retval < 0)
371 return retval;
372
373 return init_sir_ir();
374}
375
376static int sir_ir_remove(struct platform_device *dev)
377{
378 return 0;
379}
380
381static struct platform_driver sir_ir_driver = {
382 .probe = sir_ir_probe,
383 .remove = sir_ir_remove,
384 .driver = {
385 .name = "sir_ir",
386 },
387};
388
389static int __init sir_ir_init(void)
390{
391 int retval;
392
393 retval = platform_driver_register(&sir_ir_driver);
394 if (retval)
395 return retval;
396
397 sir_ir_dev = platform_device_alloc("sir_ir", 0);
398 if (!sir_ir_dev) {
399 retval = -ENOMEM;
400 goto pdev_alloc_fail;
401 }
402
403 retval = platform_device_add(sir_ir_dev);
404 if (retval)
405 goto pdev_add_fail;
406
407 return 0;
408
409pdev_add_fail:
410 platform_device_put(sir_ir_dev);
411pdev_alloc_fail:
412 platform_driver_unregister(&sir_ir_driver);
413 return retval;
414}
415
416static void __exit sir_ir_exit(void)
417{
418 drop_hardware();
419 drop_port();
420 platform_device_unregister(sir_ir_dev);
421 platform_driver_unregister(&sir_ir_driver);
422}
423
424module_init(sir_ir_init);
425module_exit(sir_ir_exit);
426
427MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports");
428MODULE_AUTHOR("Milan Pikula");
429MODULE_LICENSE("GPL");
430
431module_param(io, int, 0444);
432MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
433
434module_param(irq, int, 0444);
435MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
436
437module_param(threshold, int, 0444);
438MODULE_PARM_DESC(threshold, "space detection threshold (3)");
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index f0d7190e3919..a08e1dd06124 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -165,8 +165,7 @@ static void st_rc_hardware_init(struct st_rc_device *dev)
165 unsigned int rx_sampling_freq_div; 165 unsigned int rx_sampling_freq_div;
166 166
167 /* Enable the IP */ 167 /* Enable the IP */
168 if (dev->rstc) 168 reset_control_deassert(dev->rstc);
169 reset_control_deassert(dev->rstc);
170 169
171 clk_prepare_enable(dev->sys_clock); 170 clk_prepare_enable(dev->sys_clock);
172 baseclock = clk_get_rate(dev->sys_clock); 171 baseclock = clk_get_rate(dev->sys_clock);
@@ -281,10 +280,11 @@ static int st_rc_probe(struct platform_device *pdev)
281 else 280 else
282 rc_dev->rx_base = rc_dev->base; 281 rc_dev->rx_base = rc_dev->base;
283 282
284
285 rc_dev->rstc = reset_control_get_optional(dev, NULL); 283 rc_dev->rstc = reset_control_get_optional(dev, NULL);
286 if (IS_ERR(rc_dev->rstc)) 284 if (IS_ERR(rc_dev->rstc)) {
287 rc_dev->rstc = NULL; 285 ret = PTR_ERR(rc_dev->rstc);
286 goto err;
287 }
288 288
289 rc_dev->dev = dev; 289 rc_dev->dev = dev;
290 platform_set_drvdata(pdev, rc_dev); 290 platform_set_drvdata(pdev, rc_dev);
@@ -298,7 +298,7 @@ static int st_rc_probe(struct platform_device *pdev)
298 rdev->open = st_rc_open; 298 rdev->open = st_rc_open;
299 rdev->close = st_rc_close; 299 rdev->close = st_rc_close;
300 rdev->driver_name = IR_ST_NAME; 300 rdev->driver_name = IR_ST_NAME;
301 rdev->map_name = RC_MAP_LIRC; 301 rdev->map_name = RC_MAP_EMPTY;
302 rdev->input_name = "ST Remote Control Receiver"; 302 rdev->input_name = "ST Remote Control Receiver";
303 303
304 ret = rc_register_device(rdev); 304 ret = rc_register_device(rdev);
@@ -352,8 +352,7 @@ static int st_rc_suspend(struct device *dev)
352 writel(0x00, rc_dev->rx_base + IRB_RX_EN); 352 writel(0x00, rc_dev->rx_base + IRB_RX_EN);
353 writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN); 353 writel(0x00, rc_dev->rx_base + IRB_RX_INT_EN);
354 clk_disable_unprepare(rc_dev->sys_clock); 354 clk_disable_unprepare(rc_dev->sys_clock);
355 if (rc_dev->rstc) 355 reset_control_assert(rc_dev->rstc);
356 reset_control_assert(rc_dev->rstc);
357 } 356 }
358 357
359 return 0; 358 return 0;
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
index 25b006167810..4b785dd775c1 100644
--- a/drivers/media/rc/sunxi-cir.c
+++ b/drivers/media/rc/sunxi-cir.c
@@ -174,16 +174,11 @@ static int sunxi_ir_probe(struct platform_device *pdev)
174 174
175 /* Reset (optional) */ 175 /* Reset (optional) */
176 ir->rst = devm_reset_control_get_optional(dev, NULL); 176 ir->rst = devm_reset_control_get_optional(dev, NULL);
177 if (IS_ERR(ir->rst)) { 177 if (IS_ERR(ir->rst))
178 ret = PTR_ERR(ir->rst); 178 return PTR_ERR(ir->rst);
179 if (ret == -EPROBE_DEFER) 179 ret = reset_control_deassert(ir->rst);
180 return ret; 180 if (ret)
181 ir->rst = NULL; 181 return ret;
182 } else {
183 ret = reset_control_deassert(ir->rst);
184 if (ret)
185 return ret;
186 }
187 182
188 ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK); 183 ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK);
189 if (ret) { 184 if (ret) {
@@ -291,8 +286,7 @@ exit_clkdisable_clk:
291exit_clkdisable_apb_clk: 286exit_clkdisable_apb_clk:
292 clk_disable_unprepare(ir->apb_clk); 287 clk_disable_unprepare(ir->apb_clk);
293exit_reset_assert: 288exit_reset_assert:
294 if (ir->rst) 289 reset_control_assert(ir->rst);
295 reset_control_assert(ir->rst);
296 290
297 return ret; 291 return ret;
298} 292}
@@ -304,8 +298,7 @@ static int sunxi_ir_remove(struct platform_device *pdev)
304 298
305 clk_disable_unprepare(ir->clk); 299 clk_disable_unprepare(ir->clk);
306 clk_disable_unprepare(ir->apb_clk); 300 clk_disable_unprepare(ir->apb_clk);
307 if (ir->rst) 301 reset_control_assert(ir->rst);
308 reset_control_assert(ir->rst);
309 302
310 spin_lock_irqsave(&ir->ir_lock, flags); 303 spin_lock_irqsave(&ir->ir_lock, flags);
311 /* disable IR IRQ */ 304 /* disable IR IRQ */
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index dc1c8305ad23..5a4d4a611197 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1082,7 +1082,9 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1082 data->dev->tx_ir = wbcir_tx; 1082 data->dev->tx_ir = wbcir_tx;
1083 data->dev->priv = data; 1083 data->dev->priv = data;
1084 data->dev->dev.parent = &device->dev; 1084 data->dev->dev.parent = &device->dev;
1085 data->dev->timeout = MS_TO_NS(100); 1085 data->dev->min_timeout = 1;
1086 data->dev->timeout = IR_DEFAULT_TIMEOUT;
1087 data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
1086 data->dev->rx_resolution = US_TO_NS(2); 1088 data->dev->rx_resolution = US_TO_NS(2);
1087 data->dev->allowed_protocols = RC_BIT_ALL_IR_DECODER; 1089 data->dev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
1088 data->dev->allowed_wakeup_protocols = RC_BIT_NEC | RC_BIT_NECX | 1090 data->dev->allowed_wakeup_protocols = RC_BIT_NEC | RC_BIT_NECX |
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 57b250847cd3..e35b1faf0ddc 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -106,6 +106,9 @@ static int si2157_init(struct dvb_frontend *fe)
106 if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { 106 if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
107 memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); 107 memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
108 cmd.wlen = 9; 108 cmd.wlen = 9;
109 } else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
110 memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
111 cmd.wlen = 10;
109 } else { 112 } else {
110 memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15); 113 memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
111 cmd.wlen = 15; 114 cmd.wlen = 15;
@@ -115,6 +118,15 @@ static int si2157_init(struct dvb_frontend *fe)
115 if (ret) 118 if (ret)
116 goto err; 119 goto err;
117 120
121 /* Si2141 needs a second command before it answers the revision query */
122 if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
123 memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7);
124 cmd.wlen = 7;
125 ret = si2157_cmd_execute(client, &cmd);
126 if (ret)
127 goto err;
128 }
129
118 /* query chip revision */ 130 /* query chip revision */
119 memcpy(cmd.args, "\x02", 1); 131 memcpy(cmd.args, "\x02", 1);
120 cmd.wlen = 1; 132 cmd.wlen = 1;
@@ -131,12 +143,16 @@ static int si2157_init(struct dvb_frontend *fe)
131 #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0) 143 #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
132 #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0) 144 #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
133 #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0) 145 #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
146 #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
134 147
135 switch (chip_id) { 148 switch (chip_id) {
136 case SI2158_A20: 149 case SI2158_A20:
137 case SI2148_A20: 150 case SI2148_A20:
138 fw_name = SI2158_A20_FIRMWARE; 151 fw_name = SI2158_A20_FIRMWARE;
139 break; 152 break;
153 case SI2141_A10:
154 fw_name = SI2141_A10_FIRMWARE;
155 break;
140 case SI2157_A30: 156 case SI2157_A30:
141 case SI2147_A30: 157 case SI2147_A30:
142 case SI2146_A10: 158 case SI2146_A10:
@@ -371,7 +387,7 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
371 387
372static const struct dvb_tuner_ops si2157_ops = { 388static const struct dvb_tuner_ops si2157_ops = {
373 .info = { 389 .info = {
374 .name = "Silicon Labs Si2146/2147/2148/2157/2158", 390 .name = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
375 .frequency_min = 42000000, 391 .frequency_min = 42000000,
376 .frequency_max = 870000000, 392 .frequency_max = 870000000,
377 }, 393 },
@@ -471,6 +487,7 @@ static int si2157_probe(struct i2c_client *client,
471#endif 487#endif
472 488
473 dev_info(&client->dev, "Silicon Labs %s successfully attached\n", 489 dev_info(&client->dev, "Silicon Labs %s successfully attached\n",
490 dev->chiptype == SI2157_CHIPTYPE_SI2141 ? "Si2141" :
474 dev->chiptype == SI2157_CHIPTYPE_SI2146 ? 491 dev->chiptype == SI2157_CHIPTYPE_SI2146 ?
475 "Si2146" : "Si2147/2148/2157/2158"); 492 "Si2146" : "Si2147/2148/2157/2158");
476 493
@@ -508,6 +525,7 @@ static int si2157_remove(struct i2c_client *client)
508static const struct i2c_device_id si2157_id_table[] = { 525static const struct i2c_device_id si2157_id_table[] = {
509 {"si2157", SI2157_CHIPTYPE_SI2157}, 526 {"si2157", SI2157_CHIPTYPE_SI2157},
510 {"si2146", SI2157_CHIPTYPE_SI2146}, 527 {"si2146", SI2157_CHIPTYPE_SI2146},
528 {"si2141", SI2157_CHIPTYPE_SI2141},
511 {} 529 {}
512}; 530};
513MODULE_DEVICE_TABLE(i2c, si2157_id_table); 531MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -524,7 +542,8 @@ static struct i2c_driver si2157_driver = {
524 542
525module_i2c_driver(si2157_driver); 543module_i2c_driver(si2157_driver);
526 544
527MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver"); 545MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver");
528MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 546MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
529MODULE_LICENSE("GPL"); 547MODULE_LICENSE("GPL");
530MODULE_FIRMWARE(SI2158_A20_FIRMWARE); 548MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
549MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index d6b2c7b44053..e6436f74abaa 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -42,6 +42,7 @@ struct si2157_dev {
42 42
43#define SI2157_CHIPTYPE_SI2157 0 43#define SI2157_CHIPTYPE_SI2157 0
44#define SI2157_CHIPTYPE_SI2146 1 44#define SI2157_CHIPTYPE_SI2146 1
45#define SI2157_CHIPTYPE_SI2141 2
45 46
46/* firmware command struct */ 47/* firmware command struct */
47#define SI2157_ARGLEN 30 48#define SI2157_ARGLEN 30
@@ -52,5 +53,6 @@ struct si2157_cmd {
52}; 53};
53 54
54#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw" 55#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
56#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
55 57
56#endif 58#endif
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 91947cf1950e..e823aafce276 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -1184,8 +1184,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
1184 /* Start the tuner self-calibration process */ 1184 /* Start the tuner self-calibration process */
1185 ret = xc_initialize(priv); 1185 ret = xc_initialize(priv);
1186 if (ret) { 1186 if (ret) {
1187 printk(KERN_ERR 1187 printk(KERN_ERR "xc5000: Can't request self-calibration.");
1188 "xc5000: Can't request Self-callibration.");
1189 continue; 1188 continue;
1190 } 1189 }
1191 1190
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index c9644b62f91a..b24e753c4766 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -63,6 +63,7 @@ endif
63if MEDIA_CEC_SUPPORT 63if MEDIA_CEC_SUPPORT
64 comment "USB HDMI CEC adapters" 64 comment "USB HDMI CEC adapters"
65source "drivers/media/usb/pulse8-cec/Kconfig" 65source "drivers/media/usb/pulse8-cec/Kconfig"
66source "drivers/media/usb/rainshadow-cec/Kconfig"
66endif 67endif
67 68
68endif #MEDIA_USB_SUPPORT 69endif #MEDIA_USB_SUPPORT
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 0f15e3351ddc..738b993ec8b0 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_VIDEO_USBTV) += usbtv/
25obj-$(CONFIG_VIDEO_GO7007) += go7007/ 25obj-$(CONFIG_VIDEO_GO7007) += go7007/
26obj-$(CONFIG_DVB_AS102) += as102/ 26obj-$(CONFIG_DVB_AS102) += as102/
27obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/ 27obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/
28obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec/
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index 313f659f0bfb..43bfa778b070 100644
--- a/drivers/media/usb/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -153,7 +153,7 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
153{ 153{
154 struct tveeprom tv; 154 struct tveeprom tv;
155 155
156 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); 156 tveeprom_hauppauge_analog(&tv, eeprom_data);
157 dev->board.tuner_type = tv.tuner_type; 157 dev->board.tuner_type = tv.tuner_type;
158 158
159 /* Make sure we support the board model */ 159 /* Make sure we support the board model */
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 16f9125a985a..2a255bd32bb3 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -809,16 +809,9 @@ static void au0828_analog_stream_reset(struct au0828_dev *dev)
809 */ 809 */
810static int au0828_stream_interrupt(struct au0828_dev *dev) 810static int au0828_stream_interrupt(struct au0828_dev *dev)
811{ 811{
812 int ret = 0;
813
814 dev->stream_state = STREAM_INTERRUPT; 812 dev->stream_state = STREAM_INTERRUPT;
815 if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) 813 if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
816 return -ENODEV; 814 return -ENODEV;
817 else if (ret) {
818 set_bit(DEV_MISCONFIGURED, &dev->dev_state);
819 dprintk(1, "%s device is misconfigured!\n", __func__);
820 return ret;
821 }
822 return 0; 815 return 0;
823} 816}
824 817
diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index cf80842dfa08..a050d125934c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
@@ -670,10 +670,8 @@ static int cx231xx_audio_init(struct cx231xx *dev)
670 670
671 spin_lock_init(&adev->slock); 671 spin_lock_init(&adev->slock);
672 err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm); 672 err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
673 if (err < 0) { 673 if (err < 0)
674 snd_card_free(card); 674 goto err_free_card;
675 return err;
676 }
677 675
678 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 676 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
679 &snd_cx231xx_pcm_capture); 677 &snd_cx231xx_pcm_capture);
@@ -687,10 +685,9 @@ static int cx231xx_audio_init(struct cx231xx *dev)
687 INIT_WORK(&dev->wq_trigger, audio_trigger); 685 INIT_WORK(&dev->wq_trigger, audio_trigger);
688 686
689 err = snd_card_register(card); 687 err = snd_card_register(card);
690 if (err < 0) { 688 if (err < 0)
691 snd_card_free(card); 689 goto err_free_card;
692 return err; 690
693 }
694 adev->sndcard = card; 691 adev->sndcard = card;
695 adev->udev = dev->udev; 692 adev->udev = dev->udev;
696 693
@@ -700,6 +697,11 @@ static int cx231xx_audio_init(struct cx231xx *dev)
700 hs_config_info[0].interface_info. 697 hs_config_info[0].interface_info.
701 audio_index + 1]; 698 audio_index + 1];
702 699
700 if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
701 err = -ENODEV;
702 goto err_free_card;
703 }
704
703 adev->end_point_addr = 705 adev->end_point_addr =
704 uif->altsetting[0].endpoint[isoc_pipe].desc. 706 uif->altsetting[0].endpoint[isoc_pipe].desc.
705 bEndpointAddress; 707 bEndpointAddress;
@@ -709,13 +711,20 @@ static int cx231xx_audio_init(struct cx231xx *dev)
709 "audio EndPoint Addr 0x%x, Alternate settings: %i\n", 711 "audio EndPoint Addr 0x%x, Alternate settings: %i\n",
710 adev->end_point_addr, adev->num_alt); 712 adev->end_point_addr, adev->num_alt);
711 adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); 713 adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
712 714 if (!adev->alt_max_pkt_size) {
713 if (adev->alt_max_pkt_size == NULL) 715 err = -ENOMEM;
714 return -ENOMEM; 716 goto err_free_card;
717 }
715 718
716 for (i = 0; i < adev->num_alt; i++) { 719 for (i = 0; i < adev->num_alt; i++) {
717 u16 tmp = 720 u16 tmp;
718 le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc. 721
722 if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
723 err = -ENODEV;
724 goto err_free_pkt_size;
725 }
726
727 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
719 wMaxPacketSize); 728 wMaxPacketSize);
720 adev->alt_max_pkt_size[i] = 729 adev->alt_max_pkt_size[i] =
721 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 730 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -725,6 +734,13 @@ static int cx231xx_audio_init(struct cx231xx *dev)
725 } 734 }
726 735
727 return 0; 736 return 0;
737
738err_free_pkt_size:
739 kfree(adev->alt_max_pkt_size);
740err_free_card:
741 snd_card_free(card);
742
743 return err;
728} 744}
729 745
730static int cx231xx_audio_fini(struct cx231xx *dev) 746static int cx231xx_audio_fini(struct cx231xx *dev)
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index f730fdbc9156..a1007d005290 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1165,8 +1165,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
1165 e->client.addr = 0xa0 >> 1; 1165 e->client.addr = 0xa0 >> 1;
1166 1166
1167 read_eeprom(dev, &e->client, e->eeprom, sizeof(e->eeprom)); 1167 read_eeprom(dev, &e->client, e->eeprom, sizeof(e->eeprom));
1168 tveeprom_hauppauge_analog(&e->client, 1168 tveeprom_hauppauge_analog(&e->tvee, e->eeprom + 0xc0);
1169 &e->tvee, e->eeprom + 0xc0);
1170 kfree(e); 1169 kfree(e);
1171 break; 1170 break;
1172 } 1171 }
@@ -1426,6 +1425,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev,
1426 1425
1427 uif = udev->actconfig->interface[idx]; 1426 uif = udev->actconfig->interface[idx];
1428 1427
1428 if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
1429 return -ENODEV;
1430
1429 dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; 1431 dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress;
1430 dev->video_mode.num_alt = uif->num_altsetting; 1432 dev->video_mode.num_alt = uif->num_altsetting;
1431 1433
@@ -1439,7 +1441,12 @@ static int cx231xx_init_v4l2(struct cx231xx *dev,
1439 return -ENOMEM; 1441 return -ENOMEM;
1440 1442
1441 for (i = 0; i < dev->video_mode.num_alt; i++) { 1443 for (i = 0; i < dev->video_mode.num_alt; i++) {
1442 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); 1444 u16 tmp;
1445
1446 if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
1447 return -ENODEV;
1448
1449 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
1443 dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 1450 dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1444 dev_dbg(dev->dev, 1451 dev_dbg(dev->dev,
1445 "Alternate setting %i, max size= %i\n", i, 1452 "Alternate setting %i, max size= %i\n", i,
@@ -1456,6 +1463,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev,
1456 } 1463 }
1457 uif = udev->actconfig->interface[idx]; 1464 uif = udev->actconfig->interface[idx];
1458 1465
1466 if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
1467 return -ENODEV;
1468
1459 dev->vbi_mode.end_point_addr = 1469 dev->vbi_mode.end_point_addr =
1460 uif->altsetting[0].endpoint[isoc_pipe].desc. 1470 uif->altsetting[0].endpoint[isoc_pipe].desc.
1461 bEndpointAddress; 1471 bEndpointAddress;
@@ -1472,8 +1482,12 @@ static int cx231xx_init_v4l2(struct cx231xx *dev,
1472 return -ENOMEM; 1482 return -ENOMEM;
1473 1483
1474 for (i = 0; i < dev->vbi_mode.num_alt; i++) { 1484 for (i = 0; i < dev->vbi_mode.num_alt; i++) {
1475 u16 tmp = 1485 u16 tmp;
1476 le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. 1486
1487 if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
1488 return -ENODEV;
1489
1490 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
1477 desc.wMaxPacketSize); 1491 desc.wMaxPacketSize);
1478 dev->vbi_mode.alt_max_pkt_size[i] = 1492 dev->vbi_mode.alt_max_pkt_size[i] =
1479 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 1493 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -1493,6 +1507,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev,
1493 } 1507 }
1494 uif = udev->actconfig->interface[idx]; 1508 uif = udev->actconfig->interface[idx];
1495 1509
1510 if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
1511 return -ENODEV;
1512
1496 dev->sliced_cc_mode.end_point_addr = 1513 dev->sliced_cc_mode.end_point_addr =
1497 uif->altsetting[0].endpoint[isoc_pipe].desc. 1514 uif->altsetting[0].endpoint[isoc_pipe].desc.
1498 bEndpointAddress; 1515 bEndpointAddress;
@@ -1507,7 +1524,12 @@ static int cx231xx_init_v4l2(struct cx231xx *dev,
1507 return -ENOMEM; 1524 return -ENOMEM;
1508 1525
1509 for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { 1526 for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
1510 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. 1527 u16 tmp;
1528
1529 if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
1530 return -ENODEV;
1531
1532 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
1511 desc.wMaxPacketSize); 1533 desc.wMaxPacketSize);
1512 dev->sliced_cc_mode.alt_max_pkt_size[i] = 1534 dev->sliced_cc_mode.alt_max_pkt_size[i] =
1513 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 1535 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -1676,6 +1698,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1676 } 1698 }
1677 uif = udev->actconfig->interface[idx]; 1699 uif = udev->actconfig->interface[idx];
1678 1700
1701 if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
1702 retval = -ENODEV;
1703 goto err_video_alt;
1704 }
1705
1679 dev->ts1_mode.end_point_addr = 1706 dev->ts1_mode.end_point_addr =
1680 uif->altsetting[0].endpoint[isoc_pipe]. 1707 uif->altsetting[0].endpoint[isoc_pipe].
1681 desc.bEndpointAddress; 1708 desc.bEndpointAddress;
@@ -1693,7 +1720,14 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1693 } 1720 }
1694 1721
1695 for (i = 0; i < dev->ts1_mode.num_alt; i++) { 1722 for (i = 0; i < dev->ts1_mode.num_alt; i++) {
1696 u16 tmp = le16_to_cpu(uif->altsetting[i]. 1723 u16 tmp;
1724
1725 if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
1726 retval = -ENODEV;
1727 goto err_video_alt;
1728 }
1729
1730 tmp = le16_to_cpu(uif->altsetting[i].
1697 endpoint[isoc_pipe].desc. 1731 endpoint[isoc_pipe].desc.
1698 wMaxPacketSize); 1732 wMaxPacketSize);
1699 dev->ts1_mode.alt_max_pkt_size[i] = 1733 dev->ts1_mode.alt_max_pkt_size[i] =
diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c
index dff514e147da..8d95b1154e12 100644
--- a/drivers/media/usb/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c
@@ -491,20 +491,24 @@ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port)
491{ 491{
492 unsigned char buf; 492 unsigned char buf;
493 int i, rc; 493 int i, rc;
494 struct i2c_client client; 494 struct i2c_adapter *adap;
495 struct i2c_msg msg = {
496 .flags = I2C_M_RD,
497 .len = 1,
498 .buf = &buf,
499 };
495 500
496 if (!i2c_scan) 501 if (!i2c_scan)
497 return; 502 return;
498 503
499 /* Don't generate I2C errors during scan */ 504 /* Don't generate I2C errors during scan */
500 dev->i2c_scan_running = true; 505 dev->i2c_scan_running = true;
501 506 adap = cx231xx_get_i2c_adap(dev, i2c_port);
502 memset(&client, 0, sizeof(client));
503 client.adapter = cx231xx_get_i2c_adap(dev, i2c_port);
504 507
505 for (i = 0; i < 128; i++) { 508 for (i = 0; i < 128; i++) {
506 client.addr = i; 509 msg.addr = i;
507 rc = i2c_master_recv(&client, &buf, 0); 510 rc = i2c_transfer(adap, &msg, 1);
511
508 if (rc < 0) 512 if (rc < 0)
509 continue; 513 continue;
510 dev_info(dev->dev, 514 dev_info(dev->dev,
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index 80c635980526..abf69d8fa469 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -919,7 +919,12 @@ static int mxl111sf_init(struct dvb_usb_device *d)
919 struct mxl111sf_state *state = d_to_priv(d); 919 struct mxl111sf_state *state = d_to_priv(d);
920 int ret; 920 int ret;
921 static u8 eeprom[256]; 921 static u8 eeprom[256];
922 struct i2c_client c; 922 u8 reg = 0;
923 struct i2c_msg msg[2] = {
924 { .addr = 0xa0 >> 1, .len = 1, .buf = &reg },
925 { .addr = 0xa0 >> 1, .flags = I2C_M_RD,
926 .len = sizeof(eeprom), .buf = eeprom },
927 };
923 928
924 ret = get_chip_info(state); 929 ret = get_chip_info(state);
925 if (mxl_fail(ret)) 930 if (mxl_fail(ret))
@@ -930,14 +935,11 @@ static int mxl111sf_init(struct dvb_usb_device *d)
930 if (state->chip_rev > MXL111SF_V6) 935 if (state->chip_rev > MXL111SF_V6)
931 mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1); 936 mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
932 937
933 c.adapter = &d->i2c_adap; 938 ret = i2c_transfer(&d->i2c_adap, msg, 2);
934 c.addr = 0xa0 >> 1;
935
936 ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
937 if (mxl_fail(ret)) 939 if (mxl_fail(ret))
938 return 0; 940 return 0;
939 tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ? 941 tveeprom_hauppauge_analog(&state->tv, (0x84 == eeprom[0xa0]) ?
940 eeprom + 0xa0 : eeprom + 0x80); 942 eeprom + 0xa0 : eeprom + 0x80);
941#if 0 943#if 0
942 switch (state->tv.model) { 944 switch (state->tv.model) {
943 case 117001: 945 case 117001:
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 51620e02292f..99a3f3625944 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -458,8 +458,8 @@ static int cxusb_rc_query(struct dvb_usb_device *d)
458 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); 458 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
459 459
460 if (ircode[2] || ircode[3]) 460 if (ircode[2] || ircode[3])
461 rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, 461 rc_keydown(d->rc_dev, RC_TYPE_NEC,
462 RC_SCANCODE_RC5(ircode[2], ircode[3]), 0); 462 RC_SCANCODE_NEC(~ircode[2] & 0xff, ircode[3]), 0);
463 return 0; 463 return 0;
464} 464}
465 465
@@ -473,8 +473,8 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d)
473 return 0; 473 return 0;
474 474
475 if (ircode[1] || ircode[2]) 475 if (ircode[1] || ircode[2])
476 rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, 476 rc_keydown(d->rc_dev, RC_TYPE_NEC,
477 RC_SCANCODE_RC5(ircode[1], ircode[2]), 0); 477 RC_SCANCODE_NEC(~ircode[1] & 0xff, ircode[2]), 0);
478 return 0; 478 return 0;
479} 479}
480 480
@@ -1239,6 +1239,82 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
1239 return 0; 1239 return 0;
1240} 1240}
1241 1241
1242static int cxusb_mygica_t230c_frontend_attach(struct dvb_usb_adapter *adap)
1243{
1244 struct dvb_usb_device *d = adap->dev;
1245 struct cxusb_state *st = d->priv;
1246 struct i2c_adapter *adapter;
1247 struct i2c_client *client_demod;
1248 struct i2c_client *client_tuner;
1249 struct i2c_board_info info;
1250 struct si2168_config si2168_config;
1251 struct si2157_config si2157_config;
1252
1253 /* Select required USB configuration */
1254 if (usb_set_interface(d->udev, 0, 0) < 0)
1255 err("set interface failed");
1256
1257 /* Unblock all USB pipes */
1258 usb_clear_halt(d->udev,
1259 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1260 usb_clear_halt(d->udev,
1261 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1262 usb_clear_halt(d->udev,
1263 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1264
1265 /* attach frontend */
1266 memset(&si2168_config, 0, sizeof(si2168_config));
1267 si2168_config.i2c_adapter = &adapter;
1268 si2168_config.fe = &adap->fe_adap[0].fe;
1269 si2168_config.ts_mode = SI2168_TS_PARALLEL;
1270 si2168_config.ts_clock_inv = 1;
1271 memset(&info, 0, sizeof(struct i2c_board_info));
1272 strlcpy(info.type, "si2168", I2C_NAME_SIZE);
1273 info.addr = 0x64;
1274 info.platform_data = &si2168_config;
1275 request_module(info.type);
1276 client_demod = i2c_new_device(&d->i2c_adap, &info);
1277 if (client_demod == NULL || client_demod->dev.driver == NULL)
1278 return -ENODEV;
1279
1280 if (!try_module_get(client_demod->dev.driver->owner)) {
1281 i2c_unregister_device(client_demod);
1282 return -ENODEV;
1283 }
1284
1285 /* attach tuner */
1286 memset(&si2157_config, 0, sizeof(si2157_config));
1287 si2157_config.fe = adap->fe_adap[0].fe;
1288 memset(&info, 0, sizeof(struct i2c_board_info));
1289 strlcpy(info.type, "si2141", I2C_NAME_SIZE);
1290 info.addr = 0x60;
1291 info.platform_data = &si2157_config;
1292 request_module("si2157");
1293 client_tuner = i2c_new_device(adapter, &info);
1294 if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
1295 module_put(client_demod->dev.driver->owner);
1296 i2c_unregister_device(client_demod);
1297 return -ENODEV;
1298 }
1299 if (!try_module_get(client_tuner->dev.driver->owner)) {
1300 i2c_unregister_device(client_tuner);
1301 module_put(client_demod->dev.driver->owner);
1302 i2c_unregister_device(client_demod);
1303 return -ENODEV;
1304 }
1305
1306 st->i2c_client_demod = client_demod;
1307 st->i2c_client_tuner = client_tuner;
1308
1309 /* hook fe: need to resync the slave fifo when signal locks. */
1310 mutex_init(&st->stream_mutex);
1311 st->last_lock = 0;
1312 st->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
1313 adap->fe_adap[0].fe->ops.read_status = cxusb_read_status;
1314
1315 return 0;
1316}
1317
1242/* 1318/*
1243 * DViCO has shipped two devices with the same USB ID, but only one of them 1319 * DViCO has shipped two devices with the same USB ID, but only one of them
1244 * needs a firmware download. Check the device class details to see if they 1320 * needs a firmware download. Check the device class details to see if they
@@ -1321,6 +1397,7 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1321static struct dvb_usb_device_properties cxusb_d680_dmb_properties; 1397static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1322static struct dvb_usb_device_properties cxusb_mygica_d689_properties; 1398static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1323static struct dvb_usb_device_properties cxusb_mygica_t230_properties; 1399static struct dvb_usb_device_properties cxusb_mygica_t230_properties;
1400static struct dvb_usb_device_properties cxusb_mygica_t230c_properties;
1324 1401
1325static int cxusb_probe(struct usb_interface *intf, 1402static int cxusb_probe(struct usb_interface *intf,
1326 const struct usb_device_id *id) 1403 const struct usb_device_id *id)
@@ -1353,6 +1430,8 @@ static int cxusb_probe(struct usb_interface *intf,
1353 THIS_MODULE, NULL, adapter_nr) || 1430 THIS_MODULE, NULL, adapter_nr) ||
1354 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, 1431 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties,
1355 THIS_MODULE, NULL, adapter_nr) || 1432 THIS_MODULE, NULL, adapter_nr) ||
1433 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230c_properties,
1434 THIS_MODULE, NULL, adapter_nr) ||
1356 0) 1435 0)
1357 return 0; 1436 return 0;
1358 1437
@@ -1404,6 +1483,7 @@ enum cxusb_table_index {
1404 CONEXANT_D680_DMB, 1483 CONEXANT_D680_DMB,
1405 MYGICA_D689, 1484 MYGICA_D689,
1406 MYGICA_T230, 1485 MYGICA_T230,
1486 MYGICA_T230C,
1407 NR__cxusb_table_index 1487 NR__cxusb_table_index
1408}; 1488};
1409 1489
@@ -1471,6 +1551,9 @@ static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = {
1471 [MYGICA_T230] = { 1551 [MYGICA_T230] = {
1472 USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) 1552 USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230)
1473 }, 1553 },
1554 [MYGICA_T230C] = {
1555 USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230+1)
1556 },
1474 {} /* Terminating entry */ 1557 {} /* Terminating entry */
1475}; 1558};
1476MODULE_DEVICE_TABLE (usb, cxusb_table); 1559MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1563,7 +1646,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
1563 .rc_codes = RC_MAP_DVICO_PORTABLE, 1646 .rc_codes = RC_MAP_DVICO_PORTABLE,
1564 .module_name = KBUILD_MODNAME, 1647 .module_name = KBUILD_MODNAME,
1565 .rc_query = cxusb_rc_query, 1648 .rc_query = cxusb_rc_query,
1566 .allowed_protos = RC_BIT_UNKNOWN, 1649 .allowed_protos = RC_BIT_NEC,
1567 }, 1650 },
1568 1651
1569 .generic_bulk_ctrl_endpoint = 0x01, 1652 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1620,7 +1703,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
1620 .rc_codes = RC_MAP_DVICO_MCE, 1703 .rc_codes = RC_MAP_DVICO_MCE,
1621 .module_name = KBUILD_MODNAME, 1704 .module_name = KBUILD_MODNAME,
1622 .rc_query = cxusb_rc_query, 1705 .rc_query = cxusb_rc_query,
1623 .allowed_protos = RC_BIT_UNKNOWN, 1706 .allowed_protos = RC_BIT_NEC,
1624 }, 1707 },
1625 1708
1626 .generic_bulk_ctrl_endpoint = 0x01, 1709 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1685,7 +1768,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1685 .rc_codes = RC_MAP_DVICO_PORTABLE, 1768 .rc_codes = RC_MAP_DVICO_PORTABLE,
1686 .module_name = KBUILD_MODNAME, 1769 .module_name = KBUILD_MODNAME,
1687 .rc_query = cxusb_rc_query, 1770 .rc_query = cxusb_rc_query,
1688 .allowed_protos = RC_BIT_UNKNOWN, 1771 .allowed_protos = RC_BIT_NEC,
1689 }, 1772 },
1690 1773
1691 .generic_bulk_ctrl_endpoint = 0x01, 1774 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1741,7 +1824,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1741 .rc_codes = RC_MAP_DVICO_PORTABLE, 1824 .rc_codes = RC_MAP_DVICO_PORTABLE,
1742 .module_name = KBUILD_MODNAME, 1825 .module_name = KBUILD_MODNAME,
1743 .rc_query = cxusb_rc_query, 1826 .rc_query = cxusb_rc_query,
1744 .allowed_protos = RC_BIT_UNKNOWN, 1827 .allowed_protos = RC_BIT_NEC,
1745 }, 1828 },
1746 1829
1747 .generic_bulk_ctrl_endpoint = 0x01, 1830 .generic_bulk_ctrl_endpoint = 0x01,
@@ -1796,7 +1879,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1796 .rc_codes = RC_MAP_DVICO_MCE, 1879 .rc_codes = RC_MAP_DVICO_MCE,
1797 .module_name = KBUILD_MODNAME, 1880 .module_name = KBUILD_MODNAME,
1798 .rc_query = cxusb_bluebird2_rc_query, 1881 .rc_query = cxusb_bluebird2_rc_query,
1799 .allowed_protos = RC_BIT_UNKNOWN, 1882 .allowed_protos = RC_BIT_NEC,
1800 }, 1883 },
1801 1884
1802 .num_device_descs = 1, 1885 .num_device_descs = 1,
@@ -1850,7 +1933,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1850 .rc_codes = RC_MAP_DVICO_PORTABLE, 1933 .rc_codes = RC_MAP_DVICO_PORTABLE,
1851 .module_name = KBUILD_MODNAME, 1934 .module_name = KBUILD_MODNAME,
1852 .rc_query = cxusb_bluebird2_rc_query, 1935 .rc_query = cxusb_bluebird2_rc_query,
1853 .allowed_protos = RC_BIT_UNKNOWN, 1936 .allowed_protos = RC_BIT_NEC,
1854 }, 1937 },
1855 1938
1856 .num_device_descs = 1, 1939 .num_device_descs = 1,
@@ -1906,7 +1989,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
1906 .rc_codes = RC_MAP_DVICO_PORTABLE, 1989 .rc_codes = RC_MAP_DVICO_PORTABLE,
1907 .module_name = KBUILD_MODNAME, 1990 .module_name = KBUILD_MODNAME,
1908 .rc_query = cxusb_rc_query, 1991 .rc_query = cxusb_rc_query,
1909 .allowed_protos = RC_BIT_UNKNOWN, 1992 .allowed_protos = RC_BIT_NEC,
1910 }, 1993 },
1911 1994
1912 .num_device_descs = 1, 1995 .num_device_descs = 1,
@@ -2005,7 +2088,7 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
2005 .rc_codes = RC_MAP_DVICO_MCE, 2088 .rc_codes = RC_MAP_DVICO_MCE,
2006 .module_name = KBUILD_MODNAME, 2089 .module_name = KBUILD_MODNAME,
2007 .rc_query = cxusb_rc_query, 2090 .rc_query = cxusb_rc_query,
2008 .allowed_protos = RC_BIT_UNKNOWN, 2091 .allowed_protos = RC_BIT_NEC,
2009 }, 2092 },
2010 2093
2011 .num_device_descs = 1, 2094 .num_device_descs = 1,
@@ -2165,7 +2248,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = {
2165 2248
2166 .rc.core = { 2249 .rc.core = {
2167 .rc_interval = 100, 2250 .rc_interval = 100,
2168 .rc_codes = RC_MAP_D680_DMB, 2251 .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02,
2169 .module_name = KBUILD_MODNAME, 2252 .module_name = KBUILD_MODNAME,
2170 .rc_query = cxusb_d680_dmb_rc_query, 2253 .rc_query = cxusb_d680_dmb_rc_query,
2171 .allowed_protos = RC_BIT_UNKNOWN, 2254 .allowed_protos = RC_BIT_UNKNOWN,
@@ -2181,6 +2264,60 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = {
2181 } 2264 }
2182}; 2265};
2183 2266
2267static struct dvb_usb_device_properties cxusb_mygica_t230c_properties = {
2268 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
2269
2270 .usb_ctrl = CYPRESS_FX2,
2271
2272 .size_of_priv = sizeof(struct cxusb_state),
2273
2274 .num_adapters = 1,
2275 .adapter = {
2276 {
2277 .num_frontends = 1,
2278 .fe = {{
2279 .streaming_ctrl = cxusb_streaming_ctrl,
2280 .frontend_attach = cxusb_mygica_t230c_frontend_attach,
2281
2282 /* parameter for the MPEG2-data transfer */
2283 .stream = {
2284 .type = USB_BULK,
2285 .count = 5,
2286 .endpoint = 0x02,
2287 .u = {
2288 .bulk = {
2289 .buffersize = 8192,
2290 }
2291 }
2292 },
2293 } },
2294 },
2295 },
2296
2297 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2298
2299 .i2c_algo = &cxusb_i2c_algo,
2300
2301 .generic_bulk_ctrl_endpoint = 0x01,
2302
2303 .rc.core = {
2304 .rc_interval = 100,
2305 .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02,
2306 .module_name = KBUILD_MODNAME,
2307 .rc_query = cxusb_d680_dmb_rc_query,
2308 .allowed_protos = RC_BIT_UNKNOWN,
2309 },
2310
2311 .num_device_descs = 1,
2312 .devices = {
2313 {
2314 "Mygica T230C DVB-T/T2/C",
2315 { NULL },
2316 { &cxusb_table[MYGICA_T230C], NULL },
2317 },
2318 }
2319};
2320
2184static struct usb_driver cxusb_driver = { 2321static struct usb_driver cxusb_driver = {
2185 .name = "dvb_usb_cxusb", 2322 .name = "dvb_usb_cxusb",
2186 .probe = cxusb_probe, 2323 .probe = cxusb_probe,
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index dd5edd3a17ee..08acdd32e412 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -809,6 +809,9 @@ int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf)
809 809
810 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ 810 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
811 811
812 if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1)
813 return -ENODEV;
814
812 purb = usb_alloc_urb(0, GFP_KERNEL); 815 purb = usb_alloc_urb(0, GFP_KERNEL);
813 if (purb == NULL) 816 if (purb == NULL)
814 return -ENOMEM; 817 return -ENOMEM;
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc-common.c b/drivers/media/usb/dvb-usb/dibusb-mc-common.c
index c989cac9343d..0c2bc97436d5 100644
--- a/drivers/media/usb/dvb-usb/dibusb-mc-common.c
+++ b/drivers/media/usb/dvb-usb/dibusb-mc-common.c
@@ -11,6 +11,8 @@
11 11
12#include "dibusb.h" 12#include "dibusb.h"
13 13
14MODULE_LICENSE("GPL");
15
14/* 3000MC/P stuff */ 16/* 3000MC/P stuff */
15// Config Adjacent channels Perf -cal22 17// Config Adjacent channels Perf -cal22
16static struct dibx000_agc_config dib3000p_mt2060_agc_config = { 18static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index 4284f6984dc1..475a3c0cdee7 100644
--- a/drivers/media/usb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -33,6 +33,9 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
33 33
34 wo = (rbuf == NULL || rlen == 0); /* write-only */ 34 wo = (rbuf == NULL || rlen == 0); /* write-only */
35 35
36 if (wlen > 4 || rlen > 4)
37 return -EIO;
38
36 memset(st->sndbuf, 0, 7); 39 memset(st->sndbuf, 0, 7);
37 memset(st->rcvbuf, 0, 7); 40 memset(st->rcvbuf, 0, 7);
38 41
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index 4f42d57f81d9..6e654e5026dd 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -204,6 +204,20 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
204 204
205 switch (num) { 205 switch (num) {
206 case 2: 206 case 2:
207 if (msg[0].len != 1) {
208 warn("i2c rd: len=%d is not 1!\n",
209 msg[0].len);
210 num = -EOPNOTSUPP;
211 break;
212 }
213
214 if (2 + msg[1].len > sizeof(buf6)) {
215 warn("i2c rd: len=%d is too big!\n",
216 msg[1].len);
217 num = -EOPNOTSUPP;
218 break;
219 }
220
207 /* read si2109 register by number */ 221 /* read si2109 register by number */
208 buf6[0] = msg[0].addr << 1; 222 buf6[0] = msg[0].addr << 1;
209 buf6[1] = msg[0].len; 223 buf6[1] = msg[0].len;
@@ -219,6 +233,13 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
219 case 1: 233 case 1:
220 switch (msg[0].addr) { 234 switch (msg[0].addr) {
221 case 0x68: 235 case 0x68:
236 if (2 + msg[0].len > sizeof(buf6)) {
237 warn("i2c wr: len=%d is too big!\n",
238 msg[0].len);
239 num = -EOPNOTSUPP;
240 break;
241 }
242
222 /* write to si2109 register */ 243 /* write to si2109 register */
223 buf6[0] = msg[0].addr << 1; 244 buf6[0] = msg[0].addr << 1;
224 buf6[1] = msg[0].len; 245 buf6[1] = msg[0].len;
@@ -262,6 +283,13 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
262 /* first write first register number */ 283 /* first write first register number */
263 u8 ibuf[MAX_XFER_SIZE], obuf[3]; 284 u8 ibuf[MAX_XFER_SIZE], obuf[3];
264 285
286 if (2 + msg[0].len != sizeof(obuf)) {
287 warn("i2c rd: len=%d is not 1!\n",
288 msg[0].len);
289 ret = -EOPNOTSUPP;
290 goto unlock;
291 }
292
265 if (2 + msg[1].len > sizeof(ibuf)) { 293 if (2 + msg[1].len > sizeof(ibuf)) {
266 warn("i2c rd: len=%d is too big!\n", 294 warn("i2c rd: len=%d is too big!\n",
267 msg[1].len); 295 msg[1].len);
@@ -462,6 +490,12 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
462 /* first write first register number */ 490 /* first write first register number */
463 u8 ibuf[MAX_XFER_SIZE], obuf[3]; 491 u8 ibuf[MAX_XFER_SIZE], obuf[3];
464 492
493 if (2 + msg[0].len != sizeof(obuf)) {
494 warn("i2c rd: len=%d is not 1!\n",
495 msg[0].len);
496 ret = -EOPNOTSUPP;
497 goto unlock;
498 }
465 if (2 + msg[1].len > sizeof(ibuf)) { 499 if (2 + msg[1].len > sizeof(ibuf)) {
466 warn("i2c rd: len=%d is too big!\n", 500 warn("i2c rd: len=%d is too big!\n",
467 msg[1].len); 501 msg[1].len);
@@ -696,6 +730,13 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
696 msg[0].buf[0] = state->data[1]; 730 msg[0].buf[0] = state->data[1];
697 break; 731 break;
698 default: 732 default:
733 if (3 + msg[0].len > sizeof(state->data)) {
734 warn("i2c wr: len=%d is too big!\n",
735 msg[0].len);
736 num = -EOPNOTSUPP;
737 break;
738 }
739
699 /* always i2c write*/ 740 /* always i2c write*/
700 state->data[0] = 0x08; 741 state->data[0] = 0x08;
701 state->data[1] = msg[0].addr; 742 state->data[1] = msg[0].addr;
@@ -711,6 +752,19 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
711 break; 752 break;
712 case 2: 753 case 2:
713 /* always i2c read */ 754 /* always i2c read */
755 if (4 + msg[0].len > sizeof(state->data)) {
756 warn("i2c rd: len=%d is too big!\n",
757 msg[0].len);
758 num = -EOPNOTSUPP;
759 break;
760 }
761 if (1 + msg[1].len > sizeof(state->data)) {
762 warn("i2c rd: len=%d is too big!\n",
763 msg[1].len);
764 num = -EOPNOTSUPP;
765 break;
766 }
767
714 state->data[0] = 0x09; 768 state->data[0] = 0x09;
715 state->data[1] = msg[0].len; 769 state->data[1] = msg[0].len;
716 state->data[2] = msg[1].len; 770 state->data[2] = msg[1].len;
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index ecc207fbaf3c..9e0d6a4166d2 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -78,6 +78,9 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
78 u8 *s, *r = NULL; 78 u8 *s, *r = NULL;
79 int ret = 0; 79 int ret = 0;
80 80
81 if (4 + rlen > 64)
82 return -EIO;
83
81 s = kzalloc(wlen+4, GFP_KERNEL); 84 s = kzalloc(wlen+4, GFP_KERNEL);
82 if (!s) 85 if (!s)
83 return -ENOMEM; 86 return -ENOMEM;
@@ -381,6 +384,22 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
381 write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD); 384 write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
382 read = msg[i].flags & I2C_M_RD; 385 read = msg[i].flags & I2C_M_RD;
383 386
387 if (3 + msg[i].len > sizeof(obuf)) {
388 err("i2c wr len=%d too high", msg[i].len);
389 break;
390 }
391 if (write_read) {
392 if (3 + msg[i+1].len > sizeof(ibuf)) {
393 err("i2c rd len=%d too high", msg[i+1].len);
394 break;
395 }
396 } else if (read) {
397 if (3 + msg[i].len > sizeof(ibuf)) {
398 err("i2c rd len=%d too high", msg[i].len);
399 break;
400 }
401 }
402
384 obuf[0] = (msg[i].addr << 1) | (write_read | read); 403 obuf[0] = (msg[i].addr << 1) | (write_read | read);
385 if (read) 404 if (read)
386 obuf[1] = 0; 405 obuf[1] = 0;
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
index aa131cf9989b..4cc029f18aa8 100644
--- a/drivers/media/usb/em28xx/Kconfig
+++ b/drivers/media/usb/em28xx/Kconfig
@@ -12,7 +12,7 @@ config VIDEO_EM28XX_V4L2
12 select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT 12 select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT
13 select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT 13 select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT
14 select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT 14 select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT
15 15 select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT
16 ---help--- 16 ---help---
17 This is a video4linux driver for Empia 28xx based TV cards. 17 This is a video4linux driver for Empia 28xx based TV cards.
18 18
@@ -39,6 +39,7 @@ config VIDEO_EM28XX_DVB
39 depends on VIDEO_EM28XX && DVB_CORE 39 depends on VIDEO_EM28XX && DVB_CORE
40 select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT 40 select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
41 select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT 41 select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
42 select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT
42 select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT 43 select DVB_ZL10353 if MEDIA_SUBDRV_AUTOSELECT
43 select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT 44 select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
44 select DVB_S921 if MEDIA_SUBDRV_AUTOSELECT 45 select DVB_S921 if MEDIA_SUBDRV_AUTOSELECT
@@ -61,6 +62,10 @@ config VIDEO_EM28XX_DVB
61 select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT 62 select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
62 select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT 63 select DVB_TC90522 if MEDIA_SUBDRV_AUTOSELECT
63 select MEDIA_TUNER_QM1D1C0042 if MEDIA_SUBDRV_AUTOSELECT 64 select MEDIA_TUNER_QM1D1C0042 if MEDIA_SUBDRV_AUTOSELECT
65 select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
66 select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
67 select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
68 select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
64 ---help--- 69 ---help---
65 This adds support for DVB cards based on the 70 This adds support for DVB cards based on the
66 Empiatech em28xx chips. 71 Empiatech em28xx chips.
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c
index 89c890ba7dd6..ae87dd3e671f 100644
--- a/drivers/media/usb/em28xx/em28xx-camera.c
+++ b/drivers/media/usb/em28xx/em28xx-camera.c
@@ -23,9 +23,7 @@
23 23
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/usb.h> 25#include <linux/usb.h>
26#include <media/soc_camera.h>
27#include <media/i2c/mt9v011.h> 26#include <media/i2c/mt9v011.h>
28#include <media/v4l2-clk.h>
29#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
30 28
31/* Possible i2c addresses of Micron sensors */ 29/* Possible i2c addresses of Micron sensors */
@@ -43,13 +41,6 @@ static unsigned short omnivision_sensor_addrs[] = {
43 I2C_CLIENT_END 41 I2C_CLIENT_END
44}; 42};
45 43
46static struct soc_camera_link camlink = {
47 .bus_id = 0,
48 .flags = 0,
49 .module_name = "em28xx",
50 .unbalanced_power = true,
51};
52
53/* FIXME: Should be replaced by a proper mt9m111 driver */ 44/* FIXME: Should be replaced by a proper mt9m111 driver */
54static int em28xx_initialize_mt9m111(struct em28xx *dev) 45static int em28xx_initialize_mt9m111(struct em28xx *dev)
55{ 46{
@@ -106,55 +97,35 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev)
106{ 97{
107 int ret, i; 98 int ret, i;
108 char *name; 99 char *name;
109 u8 reg;
110 __be16 id_be;
111 u16 id; 100 u16 id;
112 101
113 struct i2c_client client = dev->i2c_client[dev->def_i2c_bus]; 102 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];
114 103
115 dev->em28xx_sensor = EM28XX_NOSENSOR; 104 dev->em28xx_sensor = EM28XX_NOSENSOR;
116 for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) { 105 for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) {
117 client.addr = micron_sensor_addrs[i]; 106 client->addr = micron_sensor_addrs[i];
118 /* NOTE: i2c_smbus_read_word_data() doesn't work with BE data */
119 /* Read chip ID from register 0x00 */ 107 /* Read chip ID from register 0x00 */
120 reg = 0x00; 108 ret = i2c_smbus_read_word_data(client, 0x00); /* assumes LE */
121 ret = i2c_master_send(&client, &reg, 1);
122 if (ret < 0) { 109 if (ret < 0) {
123 if (ret != -ENXIO) 110 if (ret != -ENXIO)
124 dev_err(&dev->intf->dev, 111 dev_err(&dev->intf->dev,
125 "couldn't read from i2c device 0x%02x: error %i\n", 112 "couldn't read from i2c device 0x%02x: error %i\n",
126 client.addr << 1, ret); 113 client->addr << 1, ret);
127 continue;
128 }
129 ret = i2c_master_recv(&client, (u8 *)&id_be, 2);
130 if (ret < 0) {
131 dev_err(&dev->intf->dev,
132 "couldn't read from i2c device 0x%02x: error %i\n",
133 client.addr << 1, ret);
134 continue; 114 continue;
135 } 115 }
136 id = be16_to_cpu(id_be); 116 id = swab16(ret); /* LE -> BE */
137 /* Read chip ID from register 0xff */ 117 /* Read chip ID from register 0xff */
138 reg = 0xff; 118 ret = i2c_smbus_read_word_data(client, 0xff);
139 ret = i2c_master_send(&client, &reg, 1);
140 if (ret < 0) { 119 if (ret < 0) {
141 dev_err(&dev->intf->dev, 120 dev_err(&dev->intf->dev,
142 "couldn't read from i2c device 0x%02x: error %i\n", 121 "couldn't read from i2c device 0x%02x: error %i\n",
143 client.addr << 1, ret); 122 client->addr << 1, ret);
144 continue;
145 }
146 ret = i2c_master_recv(&client, (u8 *)&id_be, 2);
147 if (ret < 0) {
148 dev_err(&dev->intf->dev,
149 "couldn't read from i2c device 0x%02x: error %i\n",
150 client.addr << 1, ret);
151 continue; 123 continue;
152 } 124 }
153 /* Validate chip ID to be sure we have a Micron device */ 125 /* Validate chip ID to be sure we have a Micron device */
154 if (id != be16_to_cpu(id_be)) 126 if (id != swab16(ret))
155 continue; 127 continue;
156 /* Check chip ID */ 128 /* Check chip ID */
157 id = be16_to_cpu(id_be);
158 switch (id) { 129 switch (id) {
159 case 0x1222: 130 case 0x1222:
160 name = "MT9V012"; /* MI370 */ /* 640x480 */ 131 name = "MT9V012"; /* MI370 */ /* 640x480 */
@@ -197,7 +168,6 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev)
197 dev_info(&dev->intf->dev, 168 dev_info(&dev->intf->dev,
198 "sensor %s detected\n", name); 169 "sensor %s detected\n", name);
199 170
200 dev->i2c_client[dev->def_i2c_bus].addr = client.addr;
201 return 0; 171 return 0;
202 } 172 }
203 173
@@ -213,30 +183,30 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev)
213 char *name; 183 char *name;
214 u8 reg; 184 u8 reg;
215 u16 id; 185 u16 id;
216 struct i2c_client client = dev->i2c_client[dev->def_i2c_bus]; 186 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];
217 187
218 dev->em28xx_sensor = EM28XX_NOSENSOR; 188 dev->em28xx_sensor = EM28XX_NOSENSOR;
219 /* NOTE: these devices have the register auto incrementation disabled 189 /* NOTE: these devices have the register auto incrementation disabled
220 * by default, so we have to use single byte reads ! */ 190 * by default, so we have to use single byte reads ! */
221 for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) { 191 for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) {
222 client.addr = omnivision_sensor_addrs[i]; 192 client->addr = omnivision_sensor_addrs[i];
223 /* Read manufacturer ID from registers 0x1c-0x1d (BE) */ 193 /* Read manufacturer ID from registers 0x1c-0x1d (BE) */
224 reg = 0x1c; 194 reg = 0x1c;
225 ret = i2c_smbus_read_byte_data(&client, reg); 195 ret = i2c_smbus_read_byte_data(client, reg);
226 if (ret < 0) { 196 if (ret < 0) {
227 if (ret != -ENXIO) 197 if (ret != -ENXIO)
228 dev_err(&dev->intf->dev, 198 dev_err(&dev->intf->dev,
229 "couldn't read from i2c device 0x%02x: error %i\n", 199 "couldn't read from i2c device 0x%02x: error %i\n",
230 client.addr << 1, ret); 200 client->addr << 1, ret);
231 continue; 201 continue;
232 } 202 }
233 id = ret << 8; 203 id = ret << 8;
234 reg = 0x1d; 204 reg = 0x1d;
235 ret = i2c_smbus_read_byte_data(&client, reg); 205 ret = i2c_smbus_read_byte_data(client, reg);
236 if (ret < 0) { 206 if (ret < 0) {
237 dev_err(&dev->intf->dev, 207 dev_err(&dev->intf->dev,
238 "couldn't read from i2c device 0x%02x: error %i\n", 208 "couldn't read from i2c device 0x%02x: error %i\n",
239 client.addr << 1, ret); 209 client->addr << 1, ret);
240 continue; 210 continue;
241 } 211 }
242 id += ret; 212 id += ret;
@@ -245,20 +215,20 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev)
245 continue; 215 continue;
246 /* Read product ID from registers 0x0a-0x0b (BE) */ 216 /* Read product ID from registers 0x0a-0x0b (BE) */
247 reg = 0x0a; 217 reg = 0x0a;
248 ret = i2c_smbus_read_byte_data(&client, reg); 218 ret = i2c_smbus_read_byte_data(client, reg);
249 if (ret < 0) { 219 if (ret < 0) {
250 dev_err(&dev->intf->dev, 220 dev_err(&dev->intf->dev,
251 "couldn't read from i2c device 0x%02x: error %i\n", 221 "couldn't read from i2c device 0x%02x: error %i\n",
252 client.addr << 1, ret); 222 client->addr << 1, ret);
253 continue; 223 continue;
254 } 224 }
255 id = ret << 8; 225 id = ret << 8;
256 reg = 0x0b; 226 reg = 0x0b;
257 ret = i2c_smbus_read_byte_data(&client, reg); 227 ret = i2c_smbus_read_byte_data(client, reg);
258 if (ret < 0) { 228 if (ret < 0) {
259 dev_err(&dev->intf->dev, 229 dev_err(&dev->intf->dev,
260 "couldn't read from i2c device 0x%02x: error %i\n", 230 "couldn't read from i2c device 0x%02x: error %i\n",
261 client.addr << 1, ret); 231 client->addr << 1, ret);
262 continue; 232 continue;
263 } 233 }
264 id += ret; 234 id += ret;
@@ -309,7 +279,6 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev)
309 dev_info(&dev->intf->dev, 279 dev_info(&dev->intf->dev,
310 "sensor %s detected\n", name); 280 "sensor %s detected\n", name);
311 281
312 dev->i2c_client[dev->def_i2c_bus].addr = client.addr;
313 return 0; 282 return 0;
314 } 283 }
315 284
@@ -341,17 +310,9 @@ int em28xx_detect_sensor(struct em28xx *dev)
341 310
342int em28xx_init_camera(struct em28xx *dev) 311int em28xx_init_camera(struct em28xx *dev)
343{ 312{
344 char clk_name[V4L2_CLK_NAME_SIZE];
345 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; 313 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];
346 struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus]; 314 struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus];
347 struct em28xx_v4l2 *v4l2 = dev->v4l2; 315 struct em28xx_v4l2 *v4l2 = dev->v4l2;
348 int ret = 0;
349
350 v4l2_clk_name_i2c(clk_name, sizeof(clk_name),
351 i2c_adapter_id(adap), client->addr);
352 v4l2->clk = v4l2_clk_register_fixed(clk_name, -EINVAL);
353 if (IS_ERR(v4l2->clk))
354 return PTR_ERR(v4l2->clk);
355 316
356 switch (dev->em28xx_sensor) { 317 switch (dev->em28xx_sensor) {
357 case EM28XX_MT9V011: 318 case EM28XX_MT9V011:
@@ -381,12 +342,9 @@ int em28xx_init_camera(struct em28xx *dev)
381 pdata.xtal = v4l2->sensor_xtal; 342 pdata.xtal = v4l2->sensor_xtal;
382 if (NULL == 343 if (NULL ==
383 v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, 344 v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap,
384 &mt9v011_info, NULL)) { 345 &mt9v011_info, NULL))
385 ret = -ENODEV; 346 return -ENODEV;
386 break; 347 v4l2->vinmode = EM28XX_VINMODE_RGB8_GRBG;
387 }
388 /* probably means GRGB 16 bit bayer */
389 v4l2->vinmode = 0x0d;
390 v4l2->vinctl = 0x00; 348 v4l2->vinctl = 0x00;
391 349
392 break; 350 break;
@@ -397,8 +355,7 @@ int em28xx_init_camera(struct em28xx *dev)
397 355
398 em28xx_initialize_mt9m001(dev); 356 em28xx_initialize_mt9m001(dev);
399 357
400 /* probably means BGGR 16 bit bayer */ 358 v4l2->vinmode = EM28XX_VINMODE_RGB8_BGGR;
401 v4l2->vinmode = 0x0c;
402 v4l2->vinctl = 0x00; 359 v4l2->vinctl = 0x00;
403 360
404 break; 361 break;
@@ -410,7 +367,7 @@ int em28xx_init_camera(struct em28xx *dev)
410 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); 367 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk);
411 em28xx_initialize_mt9m111(dev); 368 em28xx_initialize_mt9m111(dev);
412 369
413 v4l2->vinmode = 0x0a; 370 v4l2->vinmode = EM28XX_VINMODE_YUV422_UYVY;
414 v4l2->vinctl = 0x00; 371 v4l2->vinctl = 0x00;
415 372
416 break; 373 break;
@@ -421,7 +378,6 @@ int em28xx_init_camera(struct em28xx *dev)
421 .type = "ov2640", 378 .type = "ov2640",
422 .flags = I2C_CLIENT_SCCB, 379 .flags = I2C_CLIENT_SCCB,
423 .addr = client->addr, 380 .addr = client->addr,
424 .platform_data = &camlink,
425 }; 381 };
426 struct v4l2_subdev_format format = { 382 struct v4l2_subdev_format format = {
427 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 383 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
@@ -441,10 +397,8 @@ int em28xx_init_camera(struct em28xx *dev)
441 subdev = 397 subdev =
442 v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, 398 v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap,
443 &ov2640_info, NULL); 399 &ov2640_info, NULL);
444 if (NULL == subdev) { 400 if (subdev == NULL)
445 ret = -ENODEV; 401 return -ENODEV;
446 break;
447 }
448 402
449 format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; 403 format.format.code = MEDIA_BUS_FMT_YUYV8_2X8;
450 format.format.width = 640; 404 format.format.width = 640;
@@ -454,21 +408,16 @@ int em28xx_init_camera(struct em28xx *dev)
454 /* NOTE: for UXGA=1600x1200 switch to 12MHz */ 408 /* NOTE: for UXGA=1600x1200 switch to 12MHz */
455 dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; 409 dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ;
456 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); 410 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk);
457 v4l2->vinmode = 0x08; 411 v4l2->vinmode = EM28XX_VINMODE_YUV422_YUYV;
458 v4l2->vinctl = 0x00; 412 v4l2->vinctl = 0x00;
459 413
460 break; 414 break;
461 } 415 }
462 case EM28XX_NOSENSOR: 416 case EM28XX_NOSENSOR:
463 default: 417 default:
464 ret = -EINVAL; 418 return -EINVAL;
465 } 419 }
466 420
467 if (ret < 0) { 421 return 0;
468 v4l2_clk_unregister_fixed(v4l2->clk);
469 v4l2->clk = NULL;
470 }
471
472 return ret;
473} 422}
474EXPORT_SYMBOL_GPL(em28xx_init_camera); 423EXPORT_SYMBOL_GPL(em28xx_init_camera);
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 5f90d0899a45..a12b599a1fa2 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -2600,6 +2600,8 @@ struct usb_device_id em28xx_id_table[] = {
2600 .driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD }, 2600 .driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD },
2601 { USB_DEVICE(0x3275, 0x0085), 2601 { USB_DEVICE(0x3275, 0x0085),
2602 .driver_info = EM28178_BOARD_PLEX_PX_BCUD }, 2602 .driver_info = EM28178_BOARD_PLEX_PX_BCUD },
2603 { USB_DEVICE(0xeb1a, 0x5051), /* Ion Video 2 PC MKII / Startech svid2usb23 / Raygo R12-41373 */
2604 .driver_info = EM2860_BOARD_TVP5150_REFERENCE_DESIGN },
2603 { }, 2605 { },
2604}; 2606};
2605MODULE_DEVICE_TABLE(usb, em28xx_id_table); 2607MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2917,7 +2919,9 @@ static void em28xx_card_setup(struct em28xx *dev)
2917 * If sensor is not found, then it isn't a webcam. 2919 * If sensor is not found, then it isn't a webcam.
2918 */ 2920 */
2919 if (dev->board.is_webcam) { 2921 if (dev->board.is_webcam) {
2920 if (em28xx_detect_sensor(dev) < 0) 2922 em28xx_detect_sensor(dev);
2923 if (dev->em28xx_sensor == EM28XX_NOSENSOR)
2924 /* NOTE: error/unknown sensor/no sensor */
2921 dev->board.is_webcam = 0; 2925 dev->board.is_webcam = 0;
2922 } 2926 }
2923 2927
@@ -2974,8 +2978,7 @@ static void em28xx_card_setup(struct em28xx *dev)
2974#endif 2978#endif
2975 /* Call first TVeeprom */ 2979 /* Call first TVeeprom */
2976 2980
2977 dev->i2c_client[dev->def_i2c_bus].addr = 0xa0 >> 1; 2981 tveeprom_hauppauge_analog(&tv, dev->eedata);
2978 tveeprom_hauppauge_analog(&dev->i2c_client[dev->def_i2c_bus], &tv, dev->eedata);
2979 2982
2980 dev->tuner_type = tv.tuner_type; 2983 dev->tuner_type = tv.tuner_type;
2981 2984
@@ -3666,9 +3669,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3666 try_bulk = usb_xfer_mode > 0; 3669 try_bulk = usb_xfer_mode > 0;
3667 } 3670 }
3668 3671
3669 /* Disable V4L2 if the device doesn't have a decoder */ 3672 /* Disable V4L2 if the device doesn't have a decoder or image sensor */
3670 if (has_video && 3673 if (has_video &&
3671 dev->board.decoder == EM28XX_NODECODER && !dev->board.is_webcam) { 3674 dev->board.decoder == EM28XX_NODECODER &&
3675 dev->em28xx_sensor == EM28XX_NOSENSOR) {
3676
3672 dev_err(&interface->dev, 3677 dev_err(&interface->dev,
3673 "Currently, V4L2 is not supported on this model\n"); 3678 "Currently, V4L2 is not supported on this model\n");
3674 has_video = false; 3679 has_video = false;
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index afe7a66d7dc8..747525ca7ed5 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -93,6 +93,24 @@
93#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b 93#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b
94 94
95#define EM28XX_R10_VINMODE 0x10 95#define EM28XX_R10_VINMODE 0x10
96 /* used by all non-camera devices: */
97#define EM28XX_VINMODE_YUV422_CbYCrY 0x10
98 /* used by camera devices: */
99#define EM28XX_VINMODE_YUV422_YUYV 0x08
100#define EM28XX_VINMODE_YUV422_YVYU 0x09
101#define EM28XX_VINMODE_YUV422_UYVY 0x0a
102#define EM28XX_VINMODE_YUV422_VYUY 0x0b
103#define EM28XX_VINMODE_RGB8_BGGR 0x0c
104#define EM28XX_VINMODE_RGB8_GRBG 0x0d
105#define EM28XX_VINMODE_RGB8_GBRG 0x0e
106#define EM28XX_VINMODE_RGB8_RGGB 0x0f
107 /*
108 * apparently:
109 * bit 0: swap component 1+2 with 3+4
110 * => e.g.: YUYV => YVYU, BGGR => GRBG
111 * bit 1: swap component 1 with 2 and 3 with 4
112 * => e.g.: YUYV => UYVY, BGGR => GBRG
113 */
96 114
97#define EM28XX_R11_VINCTRL 0x11 115#define EM28XX_R11_VINCTRL 0x11
98 116
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 8d93100334ea..8d253a5df0a9 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -43,7 +43,6 @@
43#include <media/v4l2-common.h> 43#include <media/v4l2-common.h>
44#include <media/v4l2-ioctl.h> 44#include <media/v4l2-ioctl.h>
45#include <media/v4l2-event.h> 45#include <media/v4l2-event.h>
46#include <media/v4l2-clk.h>
47#include <media/drv-intf/msp3400.h> 46#include <media/drv-intf/msp3400.h>
48#include <media/tuner.h> 47#include <media/tuner.h>
49 48
@@ -117,6 +116,11 @@ static struct em28xx_fmt format[] = {
117 .depth = 16, 116 .depth = 16,
118 .reg = EM28XX_OUTFMT_RGB_16_656, 117 .reg = EM28XX_OUTFMT_RGB_16_656,
119 }, { 118 }, {
119 .name = "8 bpp Bayer RGRG..GBGB",
120 .fourcc = V4L2_PIX_FMT_SRGGB8,
121 .depth = 8,
122 .reg = EM28XX_OUTFMT_RGB_8_RGRG,
123 }, {
120 .name = "8 bpp Bayer BGBG..GRGR", 124 .name = "8 bpp Bayer BGBG..GRGR",
121 .fourcc = V4L2_PIX_FMT_SBGGR8, 125 .fourcc = V4L2_PIX_FMT_SBGGR8,
122 .depth = 8, 126 .depth = 8,
@@ -2140,11 +2144,6 @@ static int em28xx_v4l2_fini(struct em28xx *dev)
2140 v4l2_ctrl_handler_free(&v4l2->ctrl_handler); 2144 v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
2141 v4l2_device_unregister(&v4l2->v4l2_dev); 2145 v4l2_device_unregister(&v4l2->v4l2_dev);
2142 2146
2143 if (v4l2->clk) {
2144 v4l2_clk_unregister_fixed(v4l2->clk);
2145 v4l2->clk = NULL;
2146 }
2147
2148 kref_put(&v4l2->ref, em28xx_free_v4l2); 2147 kref_put(&v4l2->ref, em28xx_free_v4l2);
2149 2148
2150 mutex_unlock(&dev->lock); 2149 mutex_unlock(&dev->lock);
@@ -2465,7 +2464,7 @@ static int em28xx_v4l2_init(struct em28xx *dev)
2465 /* 2464 /*
2466 * Default format, used for tvp5150 or saa711x output formats 2465 * Default format, used for tvp5150 or saa711x output formats
2467 */ 2466 */
2468 v4l2->vinmode = 0x10; 2467 v4l2->vinmode = EM28XX_VINMODE_YUV422_CbYCrY;
2469 v4l2->vinctl = EM28XX_VINCTRL_INTERLACED | 2468 v4l2->vinctl = EM28XX_VINCTRL_INTERLACED |
2470 EM28XX_VINCTRL_CCIR656_ENABLE; 2469 EM28XX_VINCTRL_CCIR656_ENABLE;
2471 2470
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index e9f379959fa5..e8d97d5ec161 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -510,7 +510,6 @@ struct em28xx_v4l2 {
510 510
511 struct v4l2_device v4l2_dev; 511 struct v4l2_device v4l2_dev;
512 struct v4l2_ctrl_handler ctrl_handler; 512 struct v4l2_ctrl_handler ctrl_handler;
513 struct v4l2_clk *clk;
514 513
515 struct video_device vdev; 514 struct video_device vdev;
516 struct video_device vbi_dev; 515 struct video_device vbi_dev;
diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c
index 4eaba0c24629..ed5ec9773969 100644
--- a/drivers/media/usb/go7007/go7007-v4l2.c
+++ b/drivers/media/usb/go7007/go7007-v4l2.c
@@ -792,14 +792,13 @@ static int vidioc_subscribe_event(struct v4l2_fh *fh,
792{ 792{
793 793
794 switch (sub->type) { 794 switch (sub->type) {
795 case V4L2_EVENT_CTRL:
796 return v4l2_ctrl_subscribe_event(fh, sub);
797 case V4L2_EVENT_MOTION_DET: 795 case V4L2_EVENT_MOTION_DET:
798 /* Allow for up to 30 events (1 second for NTSC) to be 796 /* Allow for up to 30 events (1 second for NTSC) to be
799 * stored. */ 797 * stored. */
800 return v4l2_event_subscribe(fh, sub, 30, NULL); 798 return v4l2_event_subscribe(fh, sub, 30, NULL);
799 default:
800 return v4l2_ctrl_subscribe_event(fh, sub);
801 } 801 }
802 return -EINVAL;
803} 802}
804 803
805 804
diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c
index 71f273377f83..31b2117e8f1d 100644
--- a/drivers/media/usb/gspca/konica.c
+++ b/drivers/media/usb/gspca/konica.c
@@ -184,6 +184,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
184 return -EIO; 184 return -EIO;
185 } 185 }
186 186
187 if (alt->desc.bNumEndpoints < 2)
188 return -ENODEV;
189
187 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); 190 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
188 191
189 n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 192 n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
diff --git a/drivers/media/usb/pulse8-cec/Kconfig b/drivers/media/usb/pulse8-cec/Kconfig
index 6ffc407de62f..8937f3986a01 100644
--- a/drivers/media/usb/pulse8-cec/Kconfig
+++ b/drivers/media/usb/pulse8-cec/Kconfig
@@ -1,6 +1,6 @@
1config USB_PULSE8_CEC 1config USB_PULSE8_CEC
2 tristate "Pulse Eight HDMI CEC" 2 tristate "Pulse Eight HDMI CEC"
3 depends on USB_ACM && MEDIA_CEC_SUPPORT 3 depends on USB_ACM && CEC_CORE
4 select SERIO 4 select SERIO
5 select SERIO_SERPORT 5 select SERIO_SERPORT
6 ---help--- 6 ---help---
diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c
index 7c18daeb0ade..1dfc2de1fe77 100644
--- a/drivers/media/usb/pulse8-cec/pulse8-cec.c
+++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c
@@ -461,7 +461,7 @@ static int pulse8_apply_persistent_config(struct pulse8 *pulse8,
461 461
462static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) 462static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
463{ 463{
464 struct pulse8 *pulse8 = adap->priv; 464 struct pulse8 *pulse8 = cec_get_drvdata(adap);
465 u8 cmd[16]; 465 u8 cmd[16];
466 int err; 466 int err;
467 467
@@ -474,7 +474,7 @@ static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
474 474
475static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) 475static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
476{ 476{
477 struct pulse8 *pulse8 = adap->priv; 477 struct pulse8 *pulse8 = cec_get_drvdata(adap);
478 u16 mask = 0; 478 u16 mask = 0;
479 u16 pa = adap->phys_addr; 479 u16 pa = adap->phys_addr;
480 u8 cmd[16]; 480 u8 cmd[16];
@@ -594,7 +594,7 @@ unlock:
594static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 594static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
595 u32 signal_free_time, struct cec_msg *msg) 595 u32 signal_free_time, struct cec_msg *msg)
596{ 596{
597 struct pulse8 *pulse8 = adap->priv; 597 struct pulse8 *pulse8 = cec_get_drvdata(adap);
598 u8 cmd[2]; 598 u8 cmd[2];
599 unsigned int i; 599 unsigned int i;
600 int err; 600 int err;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
index 4af2fb5c85d5..8b643d511a0b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
@@ -118,15 +118,10 @@ int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
118 memset(&tvdata,0,sizeof(tvdata)); 118 memset(&tvdata,0,sizeof(tvdata));
119 119
120 eeprom = pvr2_eeprom_fetch(hdw); 120 eeprom = pvr2_eeprom_fetch(hdw);
121 if (!eeprom) return -EINVAL; 121 if (!eeprom)
122 122 return -EINVAL;
123 { 123
124 struct i2c_client fake_client; 124 tveeprom_hauppauge_analog(&tvdata, eeprom);
125 /* Newer version expects a useless client interface */
126 fake_client.addr = hdw->eeprom_addr;
127 fake_client.adapter = &hdw->i2c_adap;
128 tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
129 }
130 125
131 trace_eeprom("eeprom assumed v4l tveeprom module"); 126 trace_eeprom("eeprom assumed v4l tveeprom module");
132 trace_eeprom("eeprom direct call results:"); 127 trace_eeprom("eeprom direct call results:");
diff --git a/drivers/media/usb/rainshadow-cec/Kconfig b/drivers/media/usb/rainshadow-cec/Kconfig
new file mode 100644
index 000000000000..3eb86607efb8
--- /dev/null
+++ b/drivers/media/usb/rainshadow-cec/Kconfig
@@ -0,0 +1,10 @@
1config USB_RAINSHADOW_CEC
2 tristate "RainShadow Tech HDMI CEC"
3 depends on USB_ACM && CEC_CORE
4 select SERIO
5 select SERIO_SERPORT
6 ---help---
7 This is a cec driver for the RainShadow Tech HDMI CEC device.
8
9 To compile this driver as a module, choose M here: the
10 module will be called rainshadow-cec.
diff --git a/drivers/media/usb/rainshadow-cec/Makefile b/drivers/media/usb/rainshadow-cec/Makefile
new file mode 100644
index 000000000000..a79fbc77e1f7
--- /dev/null
+++ b/drivers/media/usb/rainshadow-cec/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec.o
diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
new file mode 100644
index 000000000000..541ca543f71f
--- /dev/null
+++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
@@ -0,0 +1,388 @@
1/*
2 * RainShadow Tech HDMI CEC driver
3 *
4 * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version of 2 of the License, or (at your
9 * option) any later version. See the file COPYING in the main directory of
10 * this archive for more details.
11 */
12
13/*
14 * Notes:
15 *
16 * The higher level protocols are currently disabled. This can be added
17 * later, similar to how this is done for the Pulse Eight CEC driver.
18 *
19 * Documentation of the protocol is available here:
20 *
21 * http://rainshadowtech.com/doc/HDMICECtoUSBandRS232v2.0.pdf
22 */
23
24#include <linux/completion.h>
25#include <linux/ctype.h>
26#include <linux/delay.h>
27#include <linux/init.h>
28#include <linux/interrupt.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/serio.h>
32#include <linux/slab.h>
33#include <linux/spinlock.h>
34#include <linux/time.h>
35#include <linux/workqueue.h>
36
37#include <media/cec.h>
38
39MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
40MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
41MODULE_LICENSE("GPL");
42
43#define DATA_SIZE 256
44
45struct rain {
46 struct device *dev;
47 struct serio *serio;
48 struct cec_adapter *adap;
49 struct completion cmd_done;
50 struct work_struct work;
51
52 /* Low-level ringbuffer, collecting incoming characters */
53 char buf[DATA_SIZE];
54 unsigned int buf_rd_idx;
55 unsigned int buf_wr_idx;
56 unsigned int buf_len;
57 spinlock_t buf_lock;
58
59 /* command buffer */
60 char cmd[DATA_SIZE];
61 unsigned int cmd_idx;
62 bool cmd_started;
63
64 /* reply to a command, only used to store the firmware version */
65 char cmd_reply[DATA_SIZE];
66
67 struct mutex write_lock;
68};
69
70static void rain_process_msg(struct rain *rain)
71{
72 struct cec_msg msg = {};
73 const char *cmd = rain->cmd + 3;
74 int stat = -1;
75
76 for (; *cmd; cmd++) {
77 if (!isxdigit(*cmd))
78 continue;
79 if (isxdigit(cmd[0]) && isxdigit(cmd[1])) {
80 if (msg.len == CEC_MAX_MSG_SIZE)
81 break;
82 if (hex2bin(msg.msg + msg.len, cmd, 1))
83 continue;
84 msg.len++;
85 cmd++;
86 continue;
87 }
88 if (!cmd[1])
89 stat = hex_to_bin(cmd[0]);
90 break;
91 }
92
93 if (rain->cmd[0] == 'R') {
94 if (stat == 1 || stat == 2)
95 cec_received_msg(rain->adap, &msg);
96 return;
97 }
98
99 switch (stat) {
100 case 1:
101 cec_transmit_done(rain->adap, CEC_TX_STATUS_OK,
102 0, 0, 0, 0);
103 break;
104 case 2:
105 cec_transmit_done(rain->adap, CEC_TX_STATUS_NACK,
106 0, 1, 0, 0);
107 break;
108 default:
109 cec_transmit_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE,
110 0, 0, 0, 1);
111 break;
112 }
113}
114
115static void rain_irq_work_handler(struct work_struct *work)
116{
117 struct rain *rain =
118 container_of(work, struct rain, work);
119
120 while (true) {
121 unsigned long flags;
122 bool exit_loop;
123 char data;
124
125 spin_lock_irqsave(&rain->buf_lock, flags);
126 exit_loop = rain->buf_len == 0;
127 if (rain->buf_len) {
128 data = rain->buf[rain->buf_rd_idx];
129 rain->buf_len--;
130 rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff;
131 }
132 spin_unlock_irqrestore(&rain->buf_lock, flags);
133
134 if (exit_loop)
135 break;
136
137 if (!rain->cmd_started && data != '?')
138 continue;
139
140 switch (data) {
141 case '\r':
142 rain->cmd[rain->cmd_idx] = '\0';
143 dev_dbg(rain->dev, "received: %s\n", rain->cmd);
144 if (!memcmp(rain->cmd, "REC", 3) ||
145 !memcmp(rain->cmd, "STA", 3)) {
146 rain_process_msg(rain);
147 } else {
148 strcpy(rain->cmd_reply, rain->cmd);
149 complete(&rain->cmd_done);
150 }
151 rain->cmd_idx = 0;
152 rain->cmd_started = false;
153 break;
154
155 case '\n':
156 rain->cmd_idx = 0;
157 rain->cmd_started = false;
158 break;
159
160 case '?':
161 rain->cmd_idx = 0;
162 rain->cmd_started = true;
163 break;
164
165 default:
166 if (rain->cmd_idx >= DATA_SIZE - 1) {
167 dev_dbg(rain->dev,
168 "throwing away %d bytes of garbage\n", rain->cmd_idx);
169 rain->cmd_idx = 0;
170 }
171 rain->cmd[rain->cmd_idx++] = data;
172 break;
173 }
174 }
175}
176
177static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data,
178 unsigned int flags)
179{
180 struct rain *rain = serio_get_drvdata(serio);
181
182 if (rain->buf_len == DATA_SIZE) {
183 dev_warn_once(rain->dev, "buffer overflow\n");
184 return IRQ_HANDLED;
185 }
186 spin_lock(&rain->buf_lock);
187 rain->buf_len++;
188 rain->buf[rain->buf_wr_idx] = data;
189 rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff;
190 spin_unlock(&rain->buf_lock);
191 schedule_work(&rain->work);
192 return IRQ_HANDLED;
193}
194
195static void rain_disconnect(struct serio *serio)
196{
197 struct rain *rain = serio_get_drvdata(serio);
198
199 cancel_work_sync(&rain->work);
200 cec_unregister_adapter(rain->adap);
201 dev_info(&serio->dev, "disconnected\n");
202 serio_close(serio);
203 serio_set_drvdata(serio, NULL);
204 kfree(rain);
205}
206
207static int rain_send(struct rain *rain, const char *command)
208{
209 int err = serio_write(rain->serio, '!');
210
211 dev_dbg(rain->dev, "send: %s\n", command);
212 while (!err && *command)
213 err = serio_write(rain->serio, *command++);
214 if (!err)
215 err = serio_write(rain->serio, '~');
216
217 return err;
218}
219
220static int rain_send_and_wait(struct rain *rain,
221 const char *cmd, const char *reply)
222{
223 int err;
224
225 init_completion(&rain->cmd_done);
226
227 mutex_lock(&rain->write_lock);
228 err = rain_send(rain, cmd);
229 if (err)
230 goto err;
231
232 if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) {
233 err = -ETIMEDOUT;
234 goto err;
235 }
236 if (reply && strncmp(rain->cmd_reply, reply, strlen(reply))) {
237 dev_dbg(rain->dev,
238 "transmit of '%s': received '%s' instead of '%s'\n",
239 cmd, rain->cmd_reply, reply);
240 err = -EIO;
241 }
242err:
243 mutex_unlock(&rain->write_lock);
244 return err;
245}
246
247static int rain_setup(struct rain *rain, struct serio *serio,
248 struct cec_log_addrs *log_addrs, u16 *pa)
249{
250 int err;
251
252 err = rain_send_and_wait(rain, "R", "REV");
253 if (err)
254 return err;
255 dev_info(rain->dev, "Firmware version %s\n", rain->cmd_reply + 4);
256
257 err = rain_send_and_wait(rain, "Q 1", "QTY");
258 if (err)
259 return err;
260 err = rain_send_and_wait(rain, "c0000", "CFG");
261 if (err)
262 return err;
263 return rain_send_and_wait(rain, "A F 0000", "ADR");
264}
265
266static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable)
267{
268 return 0;
269}
270
271static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
272{
273 struct rain *rain = cec_get_drvdata(adap);
274 u8 cmd[16];
275
276 if (log_addr == CEC_LOG_ADDR_INVALID)
277 log_addr = CEC_LOG_ADDR_UNREGISTERED;
278 snprintf(cmd, sizeof(cmd), "A %x", log_addr);
279 return rain_send_and_wait(rain, cmd, "ADR");
280}
281
282static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
283 u32 signal_free_time, struct cec_msg *msg)
284{
285 struct rain *rain = cec_get_drvdata(adap);
286 char cmd[2 * CEC_MAX_MSG_SIZE + 16];
287 unsigned int i;
288 int err;
289
290 if (msg->len == 1) {
291 snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg));
292 } else {
293 char hex[3];
294
295 snprintf(cmd, sizeof(cmd), "x%x %02x ",
296 cec_msg_destination(msg), msg->msg[1]);
297 for (i = 2; i < msg->len; i++) {
298 snprintf(hex, sizeof(hex), "%02x", msg->msg[i]);
299 strncat(cmd, hex, sizeof(cmd));
300 }
301 }
302 mutex_lock(&rain->write_lock);
303 err = rain_send(rain, cmd);
304 mutex_unlock(&rain->write_lock);
305 return err;
306}
307
308static const struct cec_adap_ops rain_cec_adap_ops = {
309 .adap_enable = rain_cec_adap_enable,
310 .adap_log_addr = rain_cec_adap_log_addr,
311 .adap_transmit = rain_cec_adap_transmit,
312};
313
314static int rain_connect(struct serio *serio, struct serio_driver *drv)
315{
316 u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR |
317 CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL;
318 struct rain *rain;
319 int err = -ENOMEM;
320 struct cec_log_addrs log_addrs = {};
321 u16 pa = CEC_PHYS_ADDR_INVALID;
322
323 rain = kzalloc(sizeof(*rain), GFP_KERNEL);
324
325 if (!rain)
326 return -ENOMEM;
327
328 rain->serio = serio;
329 rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain,
330 "HDMI CEC", caps, 1);
331 err = PTR_ERR_OR_ZERO(rain->adap);
332 if (err < 0)
333 goto free_device;
334
335 rain->dev = &serio->dev;
336 serio_set_drvdata(serio, rain);
337 INIT_WORK(&rain->work, rain_irq_work_handler);
338 mutex_init(&rain->write_lock);
339
340 err = serio_open(serio, drv);
341 if (err)
342 goto delete_adap;
343
344 err = rain_setup(rain, serio, &log_addrs, &pa);
345 if (err)
346 goto close_serio;
347
348 err = cec_register_adapter(rain->adap, &serio->dev);
349 if (err < 0)
350 goto close_serio;
351
352 rain->dev = &rain->adap->devnode.dev;
353 return 0;
354
355close_serio:
356 serio_close(serio);
357delete_adap:
358 cec_delete_adapter(rain->adap);
359 serio_set_drvdata(serio, NULL);
360free_device:
361 kfree(rain);
362 return err;
363}
364
365static struct serio_device_id rain_serio_ids[] = {
366 {
367 .type = SERIO_RS232,
368 .proto = SERIO_RAINSHADOW_CEC,
369 .id = SERIO_ANY,
370 .extra = SERIO_ANY,
371 },
372 { 0 }
373};
374
375MODULE_DEVICE_TABLE(serio, rain_serio_ids);
376
377static struct serio_driver rain_drv = {
378 .driver = {
379 .name = "rainshadow-cec",
380 },
381 .description = "RainShadow Tech HDMI CEC driver",
382 .id_table = rain_serio_ids,
383 .interrupt = rain_interrupt,
384 .connect = rain_connect,
385 .disconnect = rain_disconnect,
386};
387
388module_serio_driver(rain_drv);
diff --git a/drivers/media/usb/stk1160/Kconfig b/drivers/media/usb/stk1160/Kconfig
index 22dff4f3b921..425ed00e2599 100644
--- a/drivers/media/usb/stk1160/Kconfig
+++ b/drivers/media/usb/stk1160/Kconfig
@@ -6,7 +6,11 @@ config VIDEO_STK1160_COMMON
6 This is a video4linux driver for STK1160 based video capture devices. 6 This is a video4linux driver for STK1160 based video capture devices.
7 7
8 To compile this driver as a module, choose M here: the 8 To compile this driver as a module, choose M here: the
9 module will be called stk1160 9 module will be called stk1160.
10
11 This driver only provides support for video capture. For audio
12 capture, you need to select the snd-usb-audio driver (i.e.
13 CONFIG_SND_USB_AUDIO).
10 14
11config VIDEO_STK1160 15config VIDEO_STK1160
12 tristate 16 tristate
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index c4fdc1fa32ef..7e960d0a5b92 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -631,7 +631,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
631 urb = usb_alloc_urb(max_packets, GFP_KERNEL); 631 urb = usb_alloc_urb(max_packets, GFP_KERNEL);
632 if (!urb) { 632 if (!urb) {
633 tm6000_uninit_isoc(dev); 633 tm6000_uninit_isoc(dev);
634 usb_free_urb(urb); 634 tm6000_free_urb_buffers(dev);
635 return -ENOMEM; 635 return -ENOMEM;
636 } 636 }
637 dev->isoc_ctl.urb[i] = urb; 637 dev->isoc_ctl.urb[i] = urb;
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index f5c635a67d74..f9c3325aa4d4 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1501,7 +1501,14 @@ static int usbvision_probe(struct usb_interface *intf,
1501 } 1501 }
1502 1502
1503 for (i = 0; i < usbvision->num_alt; i++) { 1503 for (i = 0; i < usbvision->num_alt; i++) {
1504 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. 1504 u16 tmp;
1505
1506 if (uif->altsetting[i].desc.bNumEndpoints < 2) {
1507 ret = -ENODEV;
1508 goto err_pkt;
1509 }
1510
1511 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
1505 wMaxPacketSize); 1512 wMaxPacketSize);
1506 usbvision->alt_max_pkt_size[i] = 1513 usbvision->alt_max_pkt_size[i] =
1507 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); 1514 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 04bf35063c4c..46d6be0bb316 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -188,6 +188,21 @@ static struct uvc_format_desc uvc_fmts[] = {
188 .guid = UVC_GUID_FORMAT_GR16, 188 .guid = UVC_GUID_FORMAT_GR16,
189 .fcc = V4L2_PIX_FMT_SGRBG16, 189 .fcc = V4L2_PIX_FMT_SGRBG16,
190 }, 190 },
191 {
192 .name = "Depth data 16-bit (Z16)",
193 .guid = UVC_GUID_FORMAT_INVZ,
194 .fcc = V4L2_PIX_FMT_Z16,
195 },
196 {
197 .name = "Greyscale 10-bit (Y10 )",
198 .guid = UVC_GUID_FORMAT_INVI,
199 .fcc = V4L2_PIX_FMT_Y10,
200 },
201 {
202 .name = "IR:Depth 26-bit (INZI)",
203 .guid = UVC_GUID_FORMAT_INZI,
204 .fcc = V4L2_PIX_FMT_INZI,
205 },
191}; 206};
192 207
193/* ------------------------------------------------------------------------ 208/* ------------------------------------------------------------------------
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 07a6c833ef7b..47d93a938dde 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -818,7 +818,7 @@ static void uvc_video_stats_decode(struct uvc_streaming *stream,
818 818
819 /* Update the packets counters. */ 819 /* Update the packets counters. */
820 stream->stats.frame.nb_packets++; 820 stream->stats.frame.nb_packets++;
821 if (len > header_size) 821 if (len <= header_size)
822 stream->stats.frame.nb_empty++; 822 stream->stats.frame.nb_empty++;
823 823
824 if (data[1] & UVC_STREAM_ERR) 824 if (data[1] & UVC_STREAM_ERR)
@@ -868,14 +868,8 @@ size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
868 struct timespec ts; 868 struct timespec ts;
869 size_t count = 0; 869 size_t count = 0;
870 870
871 ts.tv_sec = stream->stats.stream.stop_ts.tv_sec 871 ts = timespec_sub(stream->stats.stream.stop_ts,
872 - stream->stats.stream.start_ts.tv_sec; 872 stream->stats.stream.start_ts);
873 ts.tv_nsec = stream->stats.stream.stop_ts.tv_nsec
874 - stream->stats.stream.start_ts.tv_nsec;
875 if (ts.tv_nsec < 0) {
876 ts.tv_sec--;
877 ts.tv_nsec += 1000000000;
878 }
879 873
880 /* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF 874 /* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF
881 * frequency this will not overflow before more than 1h. 875 * frequency this will not overflow before more than 1h.
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 4205e7a423f0..15e415e32c7f 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -143,6 +143,15 @@
143#define UVC_GUID_FORMAT_RW10 \ 143#define UVC_GUID_FORMAT_RW10 \
144 { 'R', 'W', '1', '0', 0x00, 0x00, 0x10, 0x00, \ 144 { 'R', 'W', '1', '0', 0x00, 0x00, 0x10, 0x00, \
145 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 145 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
146#define UVC_GUID_FORMAT_INVZ \
147 { 'I', 'N', 'V', 'Z', 0x90, 0x2d, 0x58, 0x4a, \
148 0x92, 0x0b, 0x77, 0x3f, 0x1f, 0x2c, 0x55, 0x6b}
149#define UVC_GUID_FORMAT_INZI \
150 { 'I', 'N', 'Z', 'I', 0x66, 0x1a, 0x42, 0xa2, \
151 0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a}
152#define UVC_GUID_FORMAT_INVI \
153 { 'I', 'N', 'V', 'I', 0xdb, 0x57, 0x49, 0x5e, \
154 0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f}
146 155
147/* ------------------------------------------------------------------------ 156/* ------------------------------------------------------------------------
148 * Driver specific constants. 157 * Driver specific constants.
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
index f2d6fc03dda0..efdcd5bd6a4c 100644
--- a/drivers/media/usb/zr364xx/zr364xx.c
+++ b/drivers/media/usb/zr364xx/zr364xx.c
@@ -600,6 +600,14 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
600 ptr = pdest = frm->lpvbits; 600 ptr = pdest = frm->lpvbits;
601 601
602 if (frm->ulState == ZR364XX_READ_IDLE) { 602 if (frm->ulState == ZR364XX_READ_IDLE) {
603 if (purb->actual_length < 128) {
604 /* header incomplete */
605 dev_info(&cam->udev->dev,
606 "%s: buffer (%d bytes) too small to hold jpeg header. Discarding.\n",
607 __func__, purb->actual_length);
608 return -EINVAL;
609 }
610
603 frm->ulState = ZR364XX_READ_FRAME; 611 frm->ulState = ZR364XX_READ_FRAME;
604 frm->cur_size = 0; 612 frm->cur_size = 0;
605 613
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index eac9565dc3d8..6f52970f8b54 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -161,6 +161,20 @@ static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sd
161 return 0; 161 return 0;
162} 162}
163 163
164static inline int get_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
165{
166 if (copy_from_user(kp, up, sizeof(struct v4l2_meta_format)))
167 return -EFAULT;
168 return 0;
169}
170
171static inline int put_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
172{
173 if (copy_to_user(up, kp, sizeof(struct v4l2_meta_format)))
174 return -EFAULT;
175 return 0;
176}
177
164struct v4l2_format32 { 178struct v4l2_format32 {
165 __u32 type; /* enum v4l2_buf_type */ 179 __u32 type; /* enum v4l2_buf_type */
166 union { 180 union {
@@ -170,6 +184,7 @@ struct v4l2_format32 {
170 struct v4l2_vbi_format vbi; 184 struct v4l2_vbi_format vbi;
171 struct v4l2_sliced_vbi_format sliced; 185 struct v4l2_sliced_vbi_format sliced;
172 struct v4l2_sdr_format sdr; 186 struct v4l2_sdr_format sdr;
187 struct v4l2_meta_format meta;
173 __u8 raw_data[200]; /* user-defined */ 188 __u8 raw_data[200]; /* user-defined */
174 } fmt; 189 } fmt;
175}; 190};
@@ -216,6 +231,8 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
216 case V4L2_BUF_TYPE_SDR_CAPTURE: 231 case V4L2_BUF_TYPE_SDR_CAPTURE:
217 case V4L2_BUF_TYPE_SDR_OUTPUT: 232 case V4L2_BUF_TYPE_SDR_OUTPUT:
218 return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr); 233 return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
234 case V4L2_BUF_TYPE_META_CAPTURE:
235 return get_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
219 default: 236 default:
220 pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n", 237 pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
221 kp->type); 238 kp->type);
@@ -263,6 +280,8 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
263 case V4L2_BUF_TYPE_SDR_CAPTURE: 280 case V4L2_BUF_TYPE_SDR_CAPTURE:
264 case V4L2_BUF_TYPE_SDR_OUTPUT: 281 case V4L2_BUF_TYPE_SDR_OUTPUT:
265 return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr); 282 return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
283 case V4L2_BUF_TYPE_META_CAPTURE:
284 return put_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
266 default: 285 default:
267 pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n", 286 pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
268 kp->type); 287 kp->type);
@@ -990,6 +1009,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
990 if (put_v4l2_ext_controls32(&karg.v2ecs, up)) 1009 if (put_v4l2_ext_controls32(&karg.v2ecs, up))
991 err = -EFAULT; 1010 err = -EFAULT;
992 break; 1011 break;
1012 case VIDIOC_S_EDID:
1013 if (put_v4l2_edid32(&karg.v2edid, up))
1014 err = -EFAULT;
1015 break;
993 } 1016 }
994 if (err) 1017 if (err)
995 return err; 1018 return err;
@@ -1011,7 +1034,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
1011 break; 1034 break;
1012 1035
1013 case VIDIOC_G_EDID: 1036 case VIDIOC_G_EDID:
1014 case VIDIOC_S_EDID:
1015 err = put_v4l2_edid32(&karg.v2edid, up); 1037 err = put_v4l2_edid32(&karg.v2edid, up);
1016 break; 1038 break;
1017 1039
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index b9e08e3d6e0e..ec42872d11cf 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -459,8 +459,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
459 }; 459 };
460 static const char * const dv_rgb_range[] = { 460 static const char * const dv_rgb_range[] = {
461 "Automatic", 461 "Automatic",
462 "RGB limited range (16-235)", 462 "RGB Limited Range (16-235)",
463 "RGB full range (0-255)", 463 "RGB Full Range (0-255)",
464 NULL, 464 NULL,
465 }; 465 };
466 static const char * const dv_it_content_type[] = { 466 static const char * const dv_it_content_type[] = {
@@ -997,6 +997,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
997 *min = 0; 997 *min = 0;
998 *max = *step = 1; 998 *max = *step = 1;
999 break; 999 break;
1000 case V4L2_CID_ROTATE:
1001 *type = V4L2_CTRL_TYPE_INTEGER;
1002 *flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
1003 break;
1000 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: 1004 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
1001 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: 1005 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
1002 *type = V4L2_CTRL_TYPE_INTEGER; 1006 *type = V4L2_CTRL_TYPE_INTEGER;
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index fa2124cb31bd..c647ba648805 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -575,30 +575,34 @@ static void determine_valid_ioctls(struct video_device *vdev)
575 set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls); 575 set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
576 576
577 if (is_vid || is_tch) { 577 if (is_vid || is_tch) {
578 /* video specific ioctls */ 578 /* video and metadata specific ioctls */
579 if ((is_rx && (ops->vidioc_enum_fmt_vid_cap || 579 if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
580 ops->vidioc_enum_fmt_vid_cap_mplane || 580 ops->vidioc_enum_fmt_vid_cap_mplane ||
581 ops->vidioc_enum_fmt_vid_overlay)) || 581 ops->vidioc_enum_fmt_vid_overlay ||
582 ops->vidioc_enum_fmt_meta_cap)) ||
582 (is_tx && (ops->vidioc_enum_fmt_vid_out || 583 (is_tx && (ops->vidioc_enum_fmt_vid_out ||
583 ops->vidioc_enum_fmt_vid_out_mplane))) 584 ops->vidioc_enum_fmt_vid_out_mplane)))
584 set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); 585 set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
585 if ((is_rx && (ops->vidioc_g_fmt_vid_cap || 586 if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
586 ops->vidioc_g_fmt_vid_cap_mplane || 587 ops->vidioc_g_fmt_vid_cap_mplane ||
587 ops->vidioc_g_fmt_vid_overlay)) || 588 ops->vidioc_g_fmt_vid_overlay ||
589 ops->vidioc_g_fmt_meta_cap)) ||
588 (is_tx && (ops->vidioc_g_fmt_vid_out || 590 (is_tx && (ops->vidioc_g_fmt_vid_out ||
589 ops->vidioc_g_fmt_vid_out_mplane || 591 ops->vidioc_g_fmt_vid_out_mplane ||
590 ops->vidioc_g_fmt_vid_out_overlay))) 592 ops->vidioc_g_fmt_vid_out_overlay)))
591 set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); 593 set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
592 if ((is_rx && (ops->vidioc_s_fmt_vid_cap || 594 if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
593 ops->vidioc_s_fmt_vid_cap_mplane || 595 ops->vidioc_s_fmt_vid_cap_mplane ||
594 ops->vidioc_s_fmt_vid_overlay)) || 596 ops->vidioc_s_fmt_vid_overlay ||
597 ops->vidioc_s_fmt_meta_cap)) ||
595 (is_tx && (ops->vidioc_s_fmt_vid_out || 598 (is_tx && (ops->vidioc_s_fmt_vid_out ||
596 ops->vidioc_s_fmt_vid_out_mplane || 599 ops->vidioc_s_fmt_vid_out_mplane ||
597 ops->vidioc_s_fmt_vid_out_overlay))) 600 ops->vidioc_s_fmt_vid_out_overlay)))
598 set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); 601 set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
599 if ((is_rx && (ops->vidioc_try_fmt_vid_cap || 602 if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
600 ops->vidioc_try_fmt_vid_cap_mplane || 603 ops->vidioc_try_fmt_vid_cap_mplane ||
601 ops->vidioc_try_fmt_vid_overlay)) || 604 ops->vidioc_try_fmt_vid_overlay ||
605 ops->vidioc_try_fmt_meta_cap)) ||
602 (is_tx && (ops->vidioc_try_fmt_vid_out || 606 (is_tx && (ops->vidioc_try_fmt_vid_out ||
603 ops->vidioc_try_fmt_vid_out_mplane || 607 ops->vidioc_try_fmt_vid_out_mplane ||
604 ops->vidioc_try_fmt_vid_out_overlay))) 608 ops->vidioc_try_fmt_vid_out_overlay)))
@@ -664,7 +668,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
664 } 668 }
665 669
666 if (is_vid || is_vbi || is_sdr || is_tch) { 670 if (is_vid || is_vbi || is_sdr || is_tch) {
667 /* ioctls valid for video, vbi or sdr */ 671 /* ioctls valid for video, metadata, vbi or sdr */
668 SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); 672 SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
669 SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); 673 SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
670 SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); 674 SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index f364cc1b521d..937c6de85606 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -235,6 +235,9 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
235 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) 235 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
236 continue; 236 continue;
237 237
238 if (sd->devnode)
239 continue;
240
238 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); 241 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
239 if (!vdev) { 242 if (!vdev) {
240 err = -ENOMEM; 243 err = -ENOMEM;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 0c3f238a2e76..e5a2187381db 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -155,6 +155,7 @@ const char *v4l2_type_names[] = {
155 [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane", 155 [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
156 [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap", 156 [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
157 [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out", 157 [V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
158 [V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap",
158}; 159};
159EXPORT_SYMBOL(v4l2_type_names); 160EXPORT_SYMBOL(v4l2_type_names);
160 161
@@ -246,6 +247,7 @@ static void v4l_print_format(const void *arg, bool write_only)
246 const struct v4l2_sliced_vbi_format *sliced; 247 const struct v4l2_sliced_vbi_format *sliced;
247 const struct v4l2_window *win; 248 const struct v4l2_window *win;
248 const struct v4l2_sdr_format *sdr; 249 const struct v4l2_sdr_format *sdr;
250 const struct v4l2_meta_format *meta;
249 unsigned i; 251 unsigned i;
250 252
251 pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); 253 pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
@@ -325,6 +327,15 @@ static void v4l_print_format(const void *arg, bool write_only)
325 (sdr->pixelformat >> 16) & 0xff, 327 (sdr->pixelformat >> 16) & 0xff,
326 (sdr->pixelformat >> 24) & 0xff); 328 (sdr->pixelformat >> 24) & 0xff);
327 break; 329 break;
330 case V4L2_BUF_TYPE_META_CAPTURE:
331 meta = &p->fmt.meta;
332 pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
333 (meta->dataformat >> 0) & 0xff,
334 (meta->dataformat >> 8) & 0xff,
335 (meta->dataformat >> 16) & 0xff,
336 (meta->dataformat >> 24) & 0xff,
337 meta->buffersize);
338 break;
328 } 339 }
329} 340}
330 341
@@ -943,6 +954,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
943 if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out) 954 if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
944 return 0; 955 return 0;
945 break; 956 break;
957 case V4L2_BUF_TYPE_META_CAPTURE:
958 if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
959 return 0;
960 break;
946 default: 961 default:
947 break; 962 break;
948 } 963 }
@@ -1131,6 +1146,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1131 case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; 1146 case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break;
1132 case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; 1147 case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break;
1133 case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; 1148 case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break;
1149 case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break;
1134 case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; 1150 case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
1135 case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; 1151 case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break;
1136 case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; 1152 case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break;
@@ -1217,6 +1233,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
1217 case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit signed deltas"; break; 1233 case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit signed deltas"; break;
1218 case V4L2_TCH_FMT_TU16: descr = "16-bit unsigned touch data"; break; 1234 case V4L2_TCH_FMT_TU16: descr = "16-bit unsigned touch data"; break;
1219 case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break; 1235 case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break;
1236 case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;
1237 case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;
1220 1238
1221 default: 1239 default:
1222 /* Compressed formats */ 1240 /* Compressed formats */
@@ -1326,6 +1344,11 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
1326 break; 1344 break;
1327 ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg); 1345 ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
1328 break; 1346 break;
1347 case V4L2_BUF_TYPE_META_CAPTURE:
1348 if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_meta_cap))
1349 break;
1350 ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
1351 break;
1329 } 1352 }
1330 if (ret == 0) 1353 if (ret == 0)
1331 v4l_fill_fmtdesc(p); 1354 v4l_fill_fmtdesc(p);
@@ -1425,6 +1448,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
1425 if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out)) 1448 if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
1426 break; 1449 break;
1427 return ops->vidioc_g_fmt_sdr_out(file, fh, arg); 1450 return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
1451 case V4L2_BUF_TYPE_META_CAPTURE:
1452 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_meta_cap))
1453 break;
1454 return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
1428 } 1455 }
1429 return -EINVAL; 1456 return -EINVAL;
1430} 1457}
@@ -1530,6 +1557,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
1530 break; 1557 break;
1531 CLEAR_AFTER_FIELD(p, fmt.sdr); 1558 CLEAR_AFTER_FIELD(p, fmt.sdr);
1532 return ops->vidioc_s_fmt_sdr_out(file, fh, arg); 1559 return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
1560 case V4L2_BUF_TYPE_META_CAPTURE:
1561 if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_meta_cap))
1562 break;
1563 CLEAR_AFTER_FIELD(p, fmt.meta);
1564 return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
1533 } 1565 }
1534 return -EINVAL; 1566 return -EINVAL;
1535} 1567}
@@ -1615,6 +1647,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
1615 break; 1647 break;
1616 CLEAR_AFTER_FIELD(p, fmt.sdr); 1648 CLEAR_AFTER_FIELD(p, fmt.sdr);
1617 return ops->vidioc_try_fmt_sdr_out(file, fh, arg); 1649 return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
1650 case V4L2_BUF_TYPE_META_CAPTURE:
1651 if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_meta_cap))
1652 break;
1653 CLEAR_AFTER_FIELD(p, fmt.meta);
1654 return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
1618 } 1655 }
1619 return -EINVAL; 1656 return -EINVAL;
1620} 1657}
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 7c1d390ea438..94afbbf92807 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -984,11 +984,12 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb)
984 984
985 memset(planes, 0, sizeof(planes[0]) * vb->num_planes); 985 memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
986 /* Copy relevant information provided by the userspace */ 986 /* Copy relevant information provided by the userspace */
987 if (pb) 987 if (pb) {
988 ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, 988 ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
989 vb, pb, planes); 989 vb, pb, planes);
990 if (ret) 990 if (ret)
991 return ret; 991 return ret;
992 }
992 993
993 for (plane = 0; plane < vb->num_planes; ++plane) { 994 for (plane = 0; plane < vb->num_planes; ++plane) {
994 /* Skip the plane if already verified */ 995 /* Skip the plane if already verified */
@@ -1101,11 +1102,12 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb)
1101 1102
1102 memset(planes, 0, sizeof(planes[0]) * vb->num_planes); 1103 memset(planes, 0, sizeof(planes[0]) * vb->num_planes);
1103 /* Copy relevant information provided by the userspace */ 1104 /* Copy relevant information provided by the userspace */
1104 if (pb) 1105 if (pb) {
1105 ret = call_bufop(vb->vb2_queue, fill_vb2_buffer, 1106 ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
1106 vb, pb, planes); 1107 vb, pb, planes);
1107 if (ret) 1108 if (ret)
1108 return ret; 1109 return ret;
1110 }
1109 1111
1110 for (plane = 0; plane < vb->num_planes; ++plane) { 1112 for (plane = 0; plane < vb->num_planes; ++plane) {
1111 struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd); 1113 struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 2db0413f5d57..4f246d166111 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/dma-buf.h> 13#include <linux/dma-buf.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/refcount.h>
15#include <linux/scatterlist.h> 16#include <linux/scatterlist.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
@@ -34,7 +35,7 @@ struct vb2_dc_buf {
34 35
35 /* MMAP related */ 36 /* MMAP related */
36 struct vb2_vmarea_handler handler; 37 struct vb2_vmarea_handler handler;
37 atomic_t refcount; 38 refcount_t refcount;
38 struct sg_table *sgt_base; 39 struct sg_table *sgt_base;
39 40
40 /* DMABUF related */ 41 /* DMABUF related */
@@ -86,7 +87,7 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
86{ 87{
87 struct vb2_dc_buf *buf = buf_priv; 88 struct vb2_dc_buf *buf = buf_priv;
88 89
89 return atomic_read(&buf->refcount); 90 return refcount_read(&buf->refcount);
90} 91}
91 92
92static void vb2_dc_prepare(void *buf_priv) 93static void vb2_dc_prepare(void *buf_priv)
@@ -122,7 +123,7 @@ static void vb2_dc_put(void *buf_priv)
122{ 123{
123 struct vb2_dc_buf *buf = buf_priv; 124 struct vb2_dc_buf *buf = buf_priv;
124 125
125 if (!atomic_dec_and_test(&buf->refcount)) 126 if (!refcount_dec_and_test(&buf->refcount))
126 return; 127 return;
127 128
128 if (buf->sgt_base) { 129 if (buf->sgt_base) {
@@ -170,7 +171,7 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long attrs,
170 buf->handler.put = vb2_dc_put; 171 buf->handler.put = vb2_dc_put;
171 buf->handler.arg = buf; 172 buf->handler.arg = buf;
172 173
173 atomic_inc(&buf->refcount); 174 refcount_set(&buf->refcount, 1);
174 175
175 return buf; 176 return buf;
176} 177}
@@ -407,7 +408,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
407 return NULL; 408 return NULL;
408 409
409 /* dmabuf keeps reference to vb2 buffer */ 410 /* dmabuf keeps reference to vb2 buffer */
410 atomic_inc(&buf->refcount); 411 refcount_inc(&buf->refcount);
411 412
412 return dbuf; 413 return dbuf;
413} 414}
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 6fd1343b7c13..8e8798a74760 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/refcount.h>
15#include <linux/scatterlist.h> 16#include <linux/scatterlist.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
@@ -46,7 +47,7 @@ struct vb2_dma_sg_buf {
46 struct sg_table *dma_sgt; 47 struct sg_table *dma_sgt;
47 size_t size; 48 size_t size;
48 unsigned int num_pages; 49 unsigned int num_pages;
49 atomic_t refcount; 50 refcount_t refcount;
50 struct vb2_vmarea_handler handler; 51 struct vb2_vmarea_handler handler;
51 52
52 struct dma_buf_attachment *db_attach; 53 struct dma_buf_attachment *db_attach;
@@ -150,7 +151,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs,
150 buf->handler.put = vb2_dma_sg_put; 151 buf->handler.put = vb2_dma_sg_put;
151 buf->handler.arg = buf; 152 buf->handler.arg = buf;
152 153
153 atomic_inc(&buf->refcount); 154 refcount_set(&buf->refcount, 1);
154 155
155 dprintk(1, "%s: Allocated buffer of %d pages\n", 156 dprintk(1, "%s: Allocated buffer of %d pages\n",
156 __func__, buf->num_pages); 157 __func__, buf->num_pages);
@@ -176,7 +177,7 @@ static void vb2_dma_sg_put(void *buf_priv)
176 struct sg_table *sgt = &buf->sg_table; 177 struct sg_table *sgt = &buf->sg_table;
177 int i = buf->num_pages; 178 int i = buf->num_pages;
178 179
179 if (atomic_dec_and_test(&buf->refcount)) { 180 if (refcount_dec_and_test(&buf->refcount)) {
180 dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, 181 dprintk(1, "%s: Freeing buffer of %d pages\n", __func__,
181 buf->num_pages); 182 buf->num_pages);
182 dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, 183 dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
@@ -320,7 +321,7 @@ static unsigned int vb2_dma_sg_num_users(void *buf_priv)
320{ 321{
321 struct vb2_dma_sg_buf *buf = buf_priv; 322 struct vb2_dma_sg_buf *buf = buf_priv;
322 323
323 return atomic_read(&buf->refcount); 324 return refcount_read(&buf->refcount);
324} 325}
325 326
326static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma) 327static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
@@ -530,7 +531,7 @@ static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags
530 return NULL; 531 return NULL;
531 532
532 /* dmabuf keeps reference to vb2 buffer */ 533 /* dmabuf keeps reference to vb2 buffer */
533 atomic_inc(&buf->refcount); 534 refcount_inc(&buf->refcount);
534 535
535 return dbuf; 536 return dbuf;
536} 537}
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c
index 1cd322e939c7..4bb8424114ce 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -96,10 +96,10 @@ static void vb2_common_vm_open(struct vm_area_struct *vma)
96 struct vb2_vmarea_handler *h = vma->vm_private_data; 96 struct vb2_vmarea_handler *h = vma->vm_private_data;
97 97
98 pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n", 98 pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",
99 __func__, h, atomic_read(h->refcount), vma->vm_start, 99 __func__, h, refcount_read(h->refcount), vma->vm_start,
100 vma->vm_end); 100 vma->vm_end);
101 101
102 atomic_inc(h->refcount); 102 refcount_inc(h->refcount);
103} 103}
104 104
105/** 105/**
@@ -114,7 +114,7 @@ static void vb2_common_vm_close(struct vm_area_struct *vma)
114 struct vb2_vmarea_handler *h = vma->vm_private_data; 114 struct vb2_vmarea_handler *h = vma->vm_private_data;
115 115
116 pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n", 116 pr_debug("%s: %p, refcount: %d, vma: %08lx-%08lx\n",
117 __func__, h, atomic_read(h->refcount), vma->vm_start, 117 __func__, h, refcount_read(h->refcount), vma->vm_start,
118 vma->vm_end); 118 vma->vm_end);
119 119
120 h->put(h->arg); 120 h->put(h->arg);
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 3529849d2218..0c0669976bdc 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -544,6 +544,9 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
544 case V4L2_BUF_TYPE_SDR_OUTPUT: 544 case V4L2_BUF_TYPE_SDR_OUTPUT:
545 requested_sizes[0] = f->fmt.sdr.buffersize; 545 requested_sizes[0] = f->fmt.sdr.buffersize;
546 break; 546 break;
547 case V4L2_BUF_TYPE_META_CAPTURE:
548 requested_sizes[0] = f->fmt.meta.buffersize;
549 break;
547 default: 550 default:
548 return -EINVAL; 551 return -EINVAL;
549 } 552 }
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index 27d1db3bb8cf..b337d780844c 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -13,6 +13,7 @@
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/refcount.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
18#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
@@ -26,7 +27,7 @@ struct vb2_vmalloc_buf {
26 struct frame_vector *vec; 27 struct frame_vector *vec;
27 enum dma_data_direction dma_dir; 28 enum dma_data_direction dma_dir;
28 unsigned long size; 29 unsigned long size;
29 atomic_t refcount; 30 refcount_t refcount;
30 struct vb2_vmarea_handler handler; 31 struct vb2_vmarea_handler handler;
31 struct dma_buf *dbuf; 32 struct dma_buf *dbuf;
32}; 33};
@@ -56,7 +57,7 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs,
56 return ERR_PTR(-ENOMEM); 57 return ERR_PTR(-ENOMEM);
57 } 58 }
58 59
59 atomic_inc(&buf->refcount); 60 refcount_set(&buf->refcount, 1);
60 return buf; 61 return buf;
61} 62}
62 63
@@ -64,7 +65,7 @@ static void vb2_vmalloc_put(void *buf_priv)
64{ 65{
65 struct vb2_vmalloc_buf *buf = buf_priv; 66 struct vb2_vmalloc_buf *buf = buf_priv;
66 67
67 if (atomic_dec_and_test(&buf->refcount)) { 68 if (refcount_dec_and_test(&buf->refcount)) {
68 vfree(buf->vaddr); 69 vfree(buf->vaddr);
69 kfree(buf); 70 kfree(buf);
70 } 71 }
@@ -161,7 +162,7 @@ static void *vb2_vmalloc_vaddr(void *buf_priv)
161static unsigned int vb2_vmalloc_num_users(void *buf_priv) 162static unsigned int vb2_vmalloc_num_users(void *buf_priv)
162{ 163{
163 struct vb2_vmalloc_buf *buf = buf_priv; 164 struct vb2_vmalloc_buf *buf = buf_priv;
164 return atomic_read(&buf->refcount); 165 return refcount_read(&buf->refcount);
165} 166}
166 167
167static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma) 168static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
@@ -368,7 +369,7 @@ static struct dma_buf *vb2_vmalloc_get_dmabuf(void *buf_priv, unsigned long flag
368 return NULL; 369 return NULL;
369 370
370 /* dmabuf keeps reference to vb2 buffer */ 371 /* dmabuf keeps reference to vb2 buffer */
371 atomic_inc(&buf->refcount); 372 refcount_inc(&buf->refcount);
372 373
373 return dbuf; 374 return dbuf;
374} 375}